1
0
Files
2022-09-29 17:59:04 +03:00

966 lines
23 KiB
ArmAsm

/***********************************************************************\
* File: entry.s *
* *
* This file contains the exception vectors and startup code for *
* the Blackbird CPU. Among other things, this file initializes *
* the registers and the caches, sets up the CC functions and uart *
* and arbitrates for the status of the Boot Master. *
* *
\***********************************************************************/
#ident "$Revision: 1.105 $"
#include "ml.h"
#include <asm.h>
#include <sys/regdef.h>
#include <sys/sbd.h>
#include <sys/cpu.h>
#include <sys/fpu.h>
#include <sys/loaddrs.h>
#include <sys/EVEREST/gda.h>
#include <sys/EVEREST/everror.h>
#include <sys/EVEREST/evconfig.h>
#include "ip21prom.h"
#include "prom_leds.h"
#include "prom_config.h"
#include "pod.h"
#include "pod_failure.h"
#include "prom_intr.h"
#define EV_CELMAX 127
.text
.set noreorder
.set at
#if TFP_CC2
#define GOTO_CHANDRA_MODE \
LA k0, 8f; \
LI k1, 0x8fffffffffffffff; \
and k0, k1; \
LI k1, 0x0000000400000000; \
or k0, k1; \
jr k0; \
nop; \
8:
#else
#define GOTO_CHANDRA_MODE \
LA k0, 8f; \
LI k1, 0x8fffffffffffffff; \
and k0, k1; \
jr k0; \
nop; \
8:
#endif
/*
* The power-on vector table starts here. It is important to ensure
* that this file is loaded at 0x900000001fc00000 so that the vectors
* appear in the memory locations expected by the TFP.
*/
#define JUMP(_label) j _label ; nop
LEAF(start)
JUMP(entry) # 0x900000001fc00000
JUMP(ip21prom_restart) # 0x900000001fc00008
JUMP(ip21prom_reslave) # 0x900000001fc00010
JUMP(ip21prom_podmode) # 0x900000001fc00018
JUMP(ip21prom_epcuart_podmode) # 0x900000001fc00020
JUMP(c_ip21prom_flash_leds) # 0x900000001fc00028
JUMP(notimplemented)
JUMP(notimplemented) /* 0x040 offset */
END(start)
/*
* entry -- When the CPU begins executing it jumps
* through the power-on vector to this point.
* This routine initializes the processor and starts
* basic system configuration.
*/
LEAF(entry)
/*
* Check to see if we got an NMI. If so, jump to the NMI
* handler code.
*/
DMFC0(k0, C0_CAUSE) # Load the Cause register
and k0, CAUSE_NMI # Check for an NMI
bnez k0, bev_nmi # IF NMI, jump to NMI handler
nop
initialize:
dla k0,trap_table
DMTC0(k0,C0_TRAPBASE) /* init TrapBase register */
dli v0, PROM_SR
DMTC0(v0, C0_SR) # Put SR into known state
jal set_cc_leds # Set the LEDS
li a0, PLED_STARTUP # (BD)
jal pon_invalidate_IDcaches # Invalidate I&D cache at the same time
nop
jal set_cc_leds # Set the LEDS
li a0, PLED_TESTICACHE # (BD)
jal pon_test_Icaches # Test icache
nop
GOTO_CHANDRA_MODE # icache is inited, use it
#if TFP_ADE_EBUS_WBACK_WAR
/*
* The logic in the CC that reports address errors on EBus
* writeback channel is broken. Turn off the bit in the diag
* register. Note that the sense of the bits is reversed from
* the spec (only when we write the register)!
* For now, just slam a hard coded constant in there. If we
* ever need to touch the register for some other reason,
* we'll add #define's.
* The ip21prom writes the same value, but we do it here in case
* the system has old proms.
*/
LI v0, EV_DIAGREG
LI v1, 0x40900000 # disable error bit 4 and
sd v1, 0(v0) # preserve "in queue almost full" (9)
#endif
dli a0, EV_ERTOIP # clear all pending interrupts
ld a1, 0(a0) # read ERTOIP, we may print it later
DMTC1(a1, EV_ERTOIP_REG) # Stuff it into the FP for now
li a1, 0x0
sd a1, 0(a0)
dli a0, EV_CERTOIP # clear all pending interrupts
li a1, 0x3fff
sd a1,0(a0)
jal set_cc_leds # Set the LEDS
li a0, PLED_CHKSCACHESIZE # (BD)
jal check_scachesize # calculate scache tag ram size
nop
EV_GET_SPNUM(t0, t1) # t0 gets slot
# t1 gets proc. number
EV_SET_PROCREG(t0, t1, EV_CACHE_SZ, v0) # store in gcache size reg
jal init_cpu # Set up the main processor
nop # (BD)
/*
* Make sure that cop1 is working well enough to
* store stuff in it.
*/
dli v0, 0xa5a5a5a5a5a5a5a5 # Pick an arbitrary value
DMTC1(v0, $f5) # Stuff it into the FPGR $f5
DMFC1(v1, $f5) # Get value back (from $f5)
beq v0, v1, 1f # IF values don't match THEN
nop # (BD)
jal flash_cc_leds # Flash a death message
li a0, FLED_DEADCOP1 # ENDIF
dli v0, 0xa65a5a5a5a5a5a5a # Pick an another value
DMTC1(v0, $f5) # Stuff it into the FPGR $f5
DMFC1(v1, $f5) # Get value back (from $f5)
beq v0, v1, 1f # IF values don't match THEN
nop # (BD)
jal flash_cc_leds # Flash a death message
li a0, FLED_DEADCOP1 # ENDIF
1:
not v0 # invert pattern
DMTC1(v0, $f5) # Stuff it into the FPGR $f5
DMFC1(v1, $f5) # Get value back (from $f5)
beq v0, v1, 2f # IF values don't match THEN
nop # (BD)
jal flash_cc_leds # Flash a death message
li a0, FLED_DEADCOP1 # ENDIF
2:
SET_BSR(zero) # Clear the Boot status register
/*
* Clear the cache tags
*/
jal set_cc_leds # Set the LEDS
li a0, PLED_CLEARTAGS
jal pon_invalidate_dcache # Invalidate dcache tags
nop
/*
* Can't have all cpus doing config read/write tests at
* the same time, so delay a while. Don't have RTC set up
* yet, so just kludge it.
*/
dli a0, EV_SPNUM # Get the processor SPNUM
ld a0, 0(a0) # Load slot and processor number
and a0, EV_SLOTNUM_MASK | EV_PROCNUM_MASK
sll a0, 18
8: addi a0, -1
nop # Don't want the branch in the
nop # same quad as the target for
nop # predictable branch cache behavior
bgtz a0, 8b
nop
/*
* Initialize the local processor resource registers.
*/
jal set_cc_leds # Indicate we're gonna test the CC
ori a0, zero, PLED_CKCCLOCAL # (BD)
jal pod_check_cclocal # Call the diagnostic
nop # (BD)
jal set_cc_leds #
ori a0, zero, PLED_CCINIT1 # (BD)
jal clear_regs # clear registers initially
nop
/*
* Set up the local CC chip's configuration registers.
* Because a number of these values are sensitive to
* the processor and bus speed, we pull the appropriate
* values out of the EAROM.
*/
jal set_cc_leds # Set up for CC config reg test
ori a0, zero, PLED_CKCCCONFIG
jal pod_check_ccconfig
nop
jal set_cc_leds #
ori a0, zero, PLED_CCINIT2 # (BD)
li a1, 0 # Clear piggyback read enable
EV_SET_PROCREG(t0, t1, EV_PGBRDEN, a1)
/*
* Configure the CC UART.
*/
jal set_cc_leds #
ori a0, zero, PLED_UARTINIT
jal ccuart_init # Call the UART configuration code
nop # (BD)
jal set_cc_leds # Show completion of leds
ori a0, zero, PLED_CCUARTDONE
GET_BSR(t0)
or t0, BS_CCUART_INITED
SET_BSR(t0)
/*
* Print PROM header, which includes version and (endianess ??)
*/
SCPRINT("\r\n\nBB_EVEREST IP21 BRINGUP PROM ");
DMFC0(t0, C0_CONFIG)
and t0, CONFIG_BE
bnez t0, 1f
nop
SCPRINT("(LE)\r\n")
b 2f
nop
1:
SCPRINT("(BE)\r\n")
2:
/*
* Check and do initial configuration of the A chip.
* In order to avoid conflicts between the processors as they
* test their connection with the A chip, we introduce a delay
*/
jal set_cc_leds # Announce start of A chip init
ori a0, zero, PLED_CKACHIP # (BD)
SCPRINT("Testing A chip...\t\t\t");
dli a0, EV_SPNUM # Get the processor SPNUM
ld a0, 0(a0) # Load slot and processor number
and a0, EV_SLOTNUM_MASK | EV_PROCNUM_MASK
jal delay
sll a0, 11 # Multiply slot number by 2048
jal pod_check_achip # Call the A chip diagnostic
nop # (BD)
SCPRINT("A CHIP Test Passed\r\n")
jal set_cc_leds #
ori a0, zero, PLED_AINIT # (BD)
SCPRINT("Initializing A chip...\t\t\t")
EV_GET_SPNUM(t0,zero) # Get slot number
EV_GET_CONFIG(t0, EV_A_ERROR_CLEAR, t1)
li a1, EV_RSCTOUT
EV_SET_CONFIG(t0, EV_A_RSC_TIMEOUT, a1)
li a1, EV_AURGTOUT
EV_SET_CONFIG(t0, EV_A_URGENT_TIMEOUT, a1)
2:
SCPRINT("Done\r\n")
/*
* Check the ebus over
*/
jal set_cc_leds # Announce start of Ebus testing
ori a0, zero, PLED_CKEBUS1 # (BD)
SCPRINT("Running EBUS test...\t\t")
jal pod_check_ebus1
nop
beq v0, zero, 1f # IF the EBUS test failed THEN
nop
SCPRINT("EBUS test failed.\r\n")
jal flash_cc_leds # Flash the status message
ori a0, zero, PLED_CKEBUS1 # (BD) Just flash the base value
# ENDIF
1:
SCPRINT("EBUS Test Passed\r\n")
jal set_cc_leds # Announce SysCtlr init
ori a0, zero, PLED_SCINIT # (BD)
/*
* Perform Boot master arbitration. If this processor is
* the Boot Master, jump to the master processor thread of
* execution. Otherwise, jump to the slave thread of execution.
*/
jal set_cc_leds # Boot Master Arb
ori a0, zero, PLED_BMARB
#if 0
/* Margie added */
debug_init:
dli k1, EV_SPNUM
ld k1, 0(k1)
nop
andi k1, EV_PROCNUM_MASK
bne k1, r0, proc1_debug
nop
proc0_debug:
dli k1, 0x9000000000001000
sd r0, 0(k1)
j debug_init_done
nop
proc1_debug:
dli k1, 0x9000000000002000
sd r0, 8(k1)
debug_init_done:
#endif
SCPRINT("Starting Boot Master arbitration...\t")
j arb_bootmaster # Call subroutine to do actual arb
nop # (BD)
# DOESN'T RETURN
END(entry)
/*
* Routine to clear registers. Registers are not cleared in IP21
* after a hardware reset and so, the registers might have non-zero
* values at the beginning
*/
LEAF(clear_regs)
/* clear all level 0 interrupts(0-127) first */
dli a0, EV_CIPL0
li a1, EV_CELMAX # Highest interrupt number
clear_ints:
sd a1, 0(a0) # Clear interrupt (BD)
bne a1, zero, clear_ints
addi a1, -1 # Decrement counter (BD)
/* set CEL to 127 */
dli a0, EV_CEL
dli a1, EV_CELMAX
dli a0, EV_IGRMASK #
sd zero, 0(a0) # Turn off all Interrupt Groups
dli a0, EV_ILE #
sd zero, 0(a0) # Disable interrupts
dli a0, EV_CIPL124 #
sd zero, 0(a0) # Clear all level 1,2 ints
dli a0, EV_CERTOIP #
sd zero, 0(a0) # Clear any error states
# dli a0, EV_HPIL
# sd zero, 0(a0) # should already be 0 since we
# already set EV_CIPL0
j ra
nop
END(clear_regs)
/*
* Routine init_cpu
* Set up the TFP's basic control registers and TLB.
*
* For TFP, may need to add code for initializing Icache,
* Dcache, COP0 registers, SAQs, and Gcache.
*/
LEAF(init_cpu)
move s6, ra # Save return address
/* Initialize COP0 register. C0_TRAPBASE assumed setup before calling
* this rountine.
*/
jal set_cc_leds # Boot Master Arb
ori a0, zero, PLED_INITCOP0
dli v0, PROM_SR
DMTC0(v0, C0_SR) # Put SR into known state
DMTC0(zero, C0_TLBSET) # Clear TLBset
DMTC0(zero, C0_TLBLO) # Clear EntryLo
DMTC0(zero, C0_UBASE)
DMTC0(zero, C0_BADVADDR) # Clear VAddr
DMTC0(zero, C0_COUNT) # Clear Counts
DMTC0(zero, C0_TLBHI) # Clear EntryHi
DMTC0(zero, C0_CAUSE) # Clear interrupts
DMTC0(zero, C0_EPC) # Clear Exception Program Counter
/* No need to init Config reg. It is initialized by hardware at reset. */
DMTC0(zero, C0_WORK0)
DMTC0(zero, C0_WORK1)
DMTC0(zero, C0_PBASE)
DMTC0(zero, C0_GBASE)
DMTC0(zero, C0_WIRED)
DMTC0(zero, C0_DCACHE)
DMTC0(zero, C0_ICACHE)
ctc1 zero, fpc_csr # clear fp csr
jal set_cc_leds # Boot Master Arb
ori a0, zero, PLED_FLUSHTLB
jal flush_entire_tlb # Clear out the TLB
nop
jal set_cc_leds # Boot Master Arb
ori a0, zero, PLED_FLUSHSAQ
jal flush_SAQueue # Initialize/flush SAQs
nop
jal gcache_invalidate # Initialize G-cache
/* DEBUG_DUMP_TAGS(0x9000000000000000) */
nop
SET_BSR(zero) # Clear the BSR
DMTC0(zero, NOFAULT_REG) # Clear the fault exception pointer
DMTC0(zero, ASMHNDLR_REG) # Clear the asmfault exception ptr.
DMTC0(zero, DUARTBASE_REG) # Clear the EPC DUART base address
jal set_cc_leds # Turn off the leds
move a0, zero
j s6 # Return to caller
nop #
END(init_cpu)
/*
* Routine bev_nmi
* If the CC_UART has been initialized, jump to POD MODE
* (for now). Otherwise, just jump back to initialize and
* redo all of the system initialization.
*/
LEAF(bev_nmi)
# Make sure the floating point processor is active so
# we can store our fault vectors in the FP registers.
#
GOTO_CHANDRA_MODE # icache is inited, use it
DMFC0(k0, C0_SR) # Load the SR
dli k1, PROM_SR
or k0, k1
DMTC0(k0, C0_SR) # Switch on the FP coprocessor
DMTC0(zero, NOFAULT_REG) # Switch off the nofault support
# Setup the asm fault handler so that we can deal with a
# bad address error if memory isn't configured (which we
# expect in some cases) or some other exception (which we
# don't expect but might happen anyway).
#
dla k0, pod_wrapper # Jump to pod_wrapper on exception
DMTC0(k0, ASMHNDLR_REG)
# Try loading the NMI Vector from main memory. This
# may very well lead to an exception, but since we've
# installed the fault handler, we don't care!
#
dli k0, GDA_ADDR # Load address of global data area
lw k0, G_MAGICOFF(k0) # Snag the actual entry
li k1, GDA_MAGIC # (LD) Load magic number
bne k0, k1, 9f # Didn't work. Just goto pod_handler
nop # (BD)
dli k0, GDA_ADDR # Reload GDA address
lw k1, G_NMIVECOFF(k0) # Load the vector
nop # (LD)
beqz k1, 9f # If vec is zero, just goto pod
nop # (BD)
DMTC0(t0, C0_WORK1) # save t0 (trashes C0_WORK1)
K32TOKPHYS(k1, k0, t0) # compute nmi handler address
li k0, PLED_NMIJUMP
dli t0, EV_LED_BASE
sd k0, 0(t0) # Set the LEDs to NMI jump value.
DMFC0(t0, C0_WORK1) # restore t0
# Delay a bit so that we don't clobber the thing before
# someone else jumps through it.
#
li k0, 1000000 # Delay value
8:
bnez k0, 8b
addi k0, -1 # Decrement counter
dli k0, GDA_ADDR # ReReload GDA address
j k1 # Jump to the NMI vector
sw zero, G_NMIVECOFF(k0) # (BD) Avoid loops in NMI handler
9:
# If we get to this point, we know that memory is at least
# somewhat alive. However, we don't know whether we're
# a master or a slave processor. So we read the masterspnum
# to find out.
#
DMTC0(zero, ASMHNDLR_REG) # Zap the nofault stuff. Memory's OK
DMTC0(ra, RA_REG) # Save ra
jal pod_gprs_to_fprs
nop
dli k0, GDA_ADDR
lw k0, G_MASTEROFF(k0) # Read the master spnum
dli k1, EV_SPNUM # Load the SPNUM resource addr
ld k1, 0(k1) # Read our spnum
nop # (LD)
andi k1, EV_SPNUM_MASK # Only look at valid bits
bne k0, k1, 10f # Skip forward if we're not master
nop # (BD)
dli k0, GDA_ADDR # Reload GDA address
lw k1, G_VDSOFF(k0) # Load the debug settings
nop # (LD)
andi k1, VDS_MANUMODE # Is manumode set?
bnez k1, 11f # If manumode is on use CC UART.
nop # (BD)
# We're not in manufacturing mode so use the EPC UART
#
li a0, BS_USE_EPCUART | BS_CCUART_INITED
SET_BSR(a0)
b 12f
nop # (BD)
11:
# We're in manufacturing mode, use the CC UART
#
li a0, BS_MANUMODE | BS_CCUART_INITED
SET_BSR(a0)
12:
dla a0, nmi_msg
j pod_handler
li a1, EVDIAG_NMI # (BD)
# If we get here, we're a lame slave processor, so we just
# jump into the the prom slave loop.
10: #
# If the cheese-meister UART flag is set, turn on the CC UART, and
# jump to pod_handler instead of the slave loop.
dli k0, GDA_ADDR # Reload GDA address
lw k1, G_VDSOFF(k0) # Load the flag
nop # (LD)
andi k1, VDS_NOARB # Is noarb set?
beqz k1, 14f # If flag is zero, do nothing.
nop # (BD)
SCPRINT("Galles mode on.\r\n")
# Set-up the BSR
li a0, BS_USE_EPCUART
SET_BSR(a0)
dla a0, nmi_msg
j pod_handler
li a1, EVDIAG_NMI # (BD)
14:
SCPRINT("Galles mode off.\r\n")
li a0, BS_SLAVE
SET_BSR(a0)
j prom_slave_nmi
nop # (BD)
END(bev_nmi)
/*
* bev_panic -- General exception handler. Most of the exception handlers
* call this when problems occur.
*/
LEAF(bev_panic)
move s0, a0 # Save secret exception number
jal set_cc_leds
move s1, a1 # (BD) Save secret exception string
/*
* Check to see if the nofault vector is non-zero
* and jump to the user-specified exception vector
*/
DMFC0(a0, NOFAULT_REG) # Grab fault vector
beqz a0, 2f
nop # (BD)
j longjmp # Call longjmp (should never return)
ori a1, zero, 1 # (BD) Tell program we're returning
/*
* We didn't have any handlers in place, so just do the
* normal exception handling. We just assume that the
* UART is working. If it doesn't, too bad.
*/
GET_BSR(a0)
ori a0, BS_SLAVE
beqz a0, 2f
nop
j flash_cc_leds
move a0, s0
2:
dla a0, panic_msg
jal pod_puts
nop
/*
* Call the standard POD handler
*/
li a1, EVDIAG_PANIC
j pod_handler
move a0, s1 # (BD) Put the message in a0
j flash_cc_leds
ori a0, zero, FLED_IMPOSSIBLE1
nop
END(bev_panic)
LEAF(notimplemented)
dla a1, notimpl_msg
j bev_panic
or a0, zero, FLED_NOTIMPL
END(notimplemented)
LEAF(pod_wrapper)
# If the memory access failed, there will be an
# address error on MyRequest. Clear this.
dli k0, EV_CERTOIP
li k1, CC_ERROR_MY_ADDR
sd k1, 0(k0)
nop
GET_BSR(a0)
li a1, BS_USE_EPCUART
not a1
and a0, a1
SET_BSR(a0)
SCPRINT("Took some wacky exception.")
dla a0, nmi_exc_msg
j pod_handler
li a1, EVDIAG_NMI # (BD)
END(pod_wrapper)
/*
* reinitialize
* Reinitializes the basic system state.
*/
LEAF(reinitialize)
move s7, ra # Save return address
jal init_cpu # Reinitialize the cpu registers
nop # (BD)
SET_BSR(zero) # Reset the boot status register
jal set_cc_leds
ori a0, zero, PLED_CLEARTAGS # (BD)
jal pon_invalidate_dcache # Clear the PD Cache
nop # (BD)
#
# Set up the basic processor local resource registers
#
jal set_cc_leds
ori a0, zero, PLED_CCINIT1
dli a0, EV_IGRMASK
sd zero, 0(a0)
dli a0, EV_ILE
sd zero, 0(a0)
dli a0, EV_CIPL124
sd zero, 0(a0)
dli a0, EV_CERTOIP
sd zero, 0(a0)
EV_GET_SPNUM(t0, zero) # Get slot number
EV_GET_CONFIG(t0, EV_A_ERROR_CLEAR, zero)
j s7
nop
END(reinitialize)
/*
* ip21prom_restart
* Called from the kernel when the system wants to
* reboot or return the PROM monitor. This routine
* sets up a stack and calls the restart C routine.
* It assumes that we don't want to rearbitrate for
* boot mastership, that no diags should be run, and
* that memory is already initialized.
*/
LEAF(ip21prom_restart)
jal pon_invalidate_IDcaches # Invalidate I&D cache at the same time
nop
jal pon_test_Icaches
nop
GOTO_CHANDRA_MODE # icache is inited, use it
jal reinitialize # Reset the basic IP21 registers
nop # (BD)
# Reinitialize the caches
#
SCPRINT("Initing caches...")
jal set_cc_leds
ori a0, zero, PLED_CKSCACHE1 # (BD)
jal pon_setup_stack_in_dcache
nop # (BD)
jal pon_invalidate_IDcaches
nop # (BD)
jal gcache_invalidate
/* DEBUG_DUMP_TAGS(0x9000000000000020) */
nop # (BD)
# Reinitialize the bus tags
#
SCPRINT("Initing BUS TAGS...")
jal set_cc_leds
ori a0, zero, PLED_CKBT
jal pod_check_bustags
nop
# Set up the stack in cache
#
SCPRINT("Building stack")
jal set_cc_leds
ori a0, zero, PLED_MAKESTACK
jal get_dcachesize
nop
dli sp, POD_STACKADDR
subu v0, 8
daddu sp, v0
# Reinitialize the EPC
#
SCPRINT("Reiniting IO4")
dla a0, EVCFGINFO_ADDR
jal io4_initmaster
nop
SCPRINT("Initing EPC UART")
jal init_epc_uart
nop
GET_BSR(t0)
ori t0, BS_USE_EPCUART
SET_BSR(t0)
SCPRINT("Loading IO4 PROM...")
jal load_io4prom
nop
jal flash_cc_leds
ori a0, zero, PLED_PROMJUMP
1: b 1b
nop
END(ip21prom_restart)
/*
* ip21prom_reslave
* Reinitializes a couple parts of the system and then
* switches into slave mode. Called by non-bootmaster
* processors when the kernel is shutting down.
*/
LEAF(ip21prom_reslave)
jal pon_invalidate_IDcaches # Invalidate I&D cache at the same time
nop
GOTO_CHANDRA_MODE # icache is inited, use it
jal reinitialize # Reset the basic IP21 registers
nop # (BD)
j prom_slave # Jump back to the slave loop
nop # (BD)
END(ip21prom_reslave)
/*
* ip21prom_podmode
* Reinitializes the prom and jumps to podmode. Allows code
* like symmon or the secondary prom to get back to home base.
*/
LEAF(ip21prom_podmode)
jal pon_invalidate_IDcaches # Invalidate I&D cache at the same time
nop
GOTO_CHANDRA_MODE # icache is inited, use it
jal reinitialize # Reinitialize the basic IP21 registers
nop # (BD)
GET_BSR(t0)
ori t0, zero, BS_CCUART_INITED
SET_BSR(t0)
dla a0, podhdlr_msg # Load message pointer into a0
j pod_handler # Jump back to POD mode
li a1, EVDIAG_DEBUG # (BD)
END(ip21prom_podmode)
LEAF(ip21prom_epcuart_podmode)
jal pon_invalidate_IDcaches # Invalidate I&D cache at the same time
nop
GOTO_CHANDRA_MODE # icache is inited, use it
jal reinitialize
nop
li t0, BS_CCUART_INITED|BS_USE_EPCUART|BS_POD_MODE|BS_NO_DIAGS
SET_BSR(t0)
j prom_master
nop
END(ip21prom_epcuart_podmode)
LEAF(c_ip21prom_flash_leds)
GOTO_CHANDRA_MODE
j ip21prom_flash_leds
nop
END(c_ip21prom_flash_leds)
/*
* In order to avoid trashing the registers saved in the fprs,
* we need to check for an asm fault handler immediately when
* we enter each of the exception handlers. If one isn't set,
* we save the ra and then proceed. This stuff is written as
* macro so that we won't lose the ra.
*/
#define COMMON_CODE \
DMFC0(k0, C0_SR) ; \
dli k1, PROM_SR ; \
or k0, k1 ; \
DMTC0(k0, C0_SR) ; \
DMFC0(k0, ASMHNDLR_REG) ; \
DMTC0(zero, ASMHNDLR_REG) ; \
beqz k0, 95f ; \
nop ; \
j k0 ; \
nop ; \
95: DMTC0(ra, RA_REG)
.align 12
.globl trap_table
trap_table: /* must be page aligned */
LEAF(bev_tlbrefill) /* TrapBase + 0x000 */
COMMON_CODE
jal pod_gprs_to_fprs
nop # (BD)
dla a1, tlb_msg
j bev_panic
or a0, zero, FLED_UTLBMISS
END(bev_tlbrefill)
.align 10
LEAF(bev_ktlbrefill) /* TrapBase + 0x400 */
COMMON_CODE
jal pod_gprs_to_fprs
nop # (BD)
dla a1, ktlb_msg
j bev_panic
or a0, zero, FLED_KTLBMISS
END(bev_ktlbrefill)
.align 10
JUMP(bev_ktlbrefill) /* TrapBase + 0x800 */
.align 10
LEAF(bev_general) /* TrapBase + 0xc00 */
COMMON_CODE
jal pod_gprs_to_fprs
nop # (BD)
DMFC0(t1, C0_CAUSE)
li t0, CAUSE_EXCMASK
nop
and t0, t1
li t1, EXC_BREAK
beq t0, t1, 2f # If break point jump to break handler
nop # (BD)
dla a1, general_msg
j bev_panic
or a0, zero, FLED_GENERAL # (BD)
2: j break_handler
nop
END(bev_general)
/*
* Various messages and text strings.
*/
.data
panic_msg: .asciiz "\r\nPanic in IP21 PROM: "
epc_msg: .asciiz "\r\nEPC: "
cause_msg: .asciiz "\r\nCAUSE: "
sr_msg: .asciiz "\r\nSR: "
badvaddr_msg: .asciiz "\r\nBADVADDR: "
podhdlr_msg: .asciiz "\r\nJumping to POD mode.\r\n"
tlb_msg: .asciiz "TLB miss\r\n"
ktlb_msg: .asciiz "KTLB miss exception\r\n"
general_msg: .asciiz "General exception\r\n"
notimpl_msg: .asciiz "jump to unimplemented vector\r\n"
watch_msg: .asciiz "Watch\r\n"
pod_msg: .asciiz "Jumping to POD mode.\r\n"
nmi_msg: .asciiz "\r\n\n*** Non-maskable interrupt occurred. \r\n\n"
nmi_exc_msg: .asciiz "\r\n\n*** Non-maskable intr/exception handler \r\n"