1
0
Files
irix-657m-src/stand/arcs/IO6prom/sysasm.s
2022-09-29 17:59:04 +03:00

532 lines
12 KiB
ArmAsm

/***********************************************************************\
* File: sysasm.s *
* *
* This file contains miscellaneous assembly language routines *
* which are called at various points. *
* *
\***********************************************************************/
#include <fault.h>
#include <asm.h>
#include <regdef.h>
#include <sys/immu.h>
#include <sys/sbd.h>
#include <sys/cpu.h>
#include <sys/loaddrs.h>
#include <sys/SN/gda.h>
#include <ml.h>
#include <hub.h>
#include "ip27prom.h"
#include "io6prom_private.h"
#ifdef SABLE
#include <sys/i8251uart.h> /* XXX */
#endif
#define BSSMAGIC 0xfeeddead
/*
* entry - IO6prom
* All CPUs are running a single copy of this code.
* set up stack for each CPU in its own node memory.
* if slave, jump to sysinit
* if global master
* Clear BSS and stack space, jump to sysinit.
*/
LEAF(entry)
.set noreorder
move s4, a0 # Diagnostics mode
jal get_nasid
nop
HUB_LED_SET_REMOTE(v0, 0, 0x55)
HUB_LED_SET_REMOTE(v0, 1, 0xaa)
GET_NASID_ASM(a0) # Pass in our nasid
jal tlb_setup # Set up our special TLB entry
# uses regs s0-s3
nop # BD
#if defined(SABLE) && defined(FAKE_PROM)
# Only let one processor run the master code.
dla k0, sable_mastercounter
# Increment the counter
1: ll a0, (k0)
add k1, a0, 1
sc k1, (k0)
beqz k1, 1b;
nop
beqz a0, 2f
nop
# Even the slaves need a stack pointer.
jal IO6prom_stack_addr
nop
move sp, v0
j ip27_slaveloop
nop
2:
/* Do some ip27prom specific init now for sable. When the real IP27PROM
really launches us, delete these 2 lines. */
jal ip27prom_asminit
nop # BD
#endif /* SABLE && FAKE_PROM */
/* Set CALIAS size to 8k to contain the SPB. */
dli k1, LOCAL_HUB(PI_CALIAS_SIZE)
dli k0, PI_CALIAS_SIZE_8K
sd k0, 0(k1)
jal IO6prom_stack_addr
nop
move sp, v0
jal hub_scratch_init # so things like hub_barrier() will work
nop
.set reorder
jal clear_prom_ram
move a0, s4 # restore diag mode arg
j sysinit
END(entry)
LEAF(hub_scratch_init)
/*
* Clear the MD_PERF_CNTx registers so the PROM can use them
* as scratch regs (see comment at beginning of hub.c).
* XXX - WARNING!!!!! do not clear if ip27prom stores required info in these
*/
sd zero, LOCAL_HUB(MD_PERF_SEL ) /* Disable counting */
sd zero, LOCAL_HUB(MD_PERF_CNT0) /* Clear all */
sd zero, LOCAL_HUB(MD_PERF_CNT1)
sd zero, LOCAL_HUB(MD_PERF_CNT2)
sd zero, LOCAL_HUB(MD_PERF_CNT3)
sd zero, LOCAL_HUB(MD_PERF_CNT4)
sd zero, LOCAL_HUB(MD_PERF_CNT5)
j ra
END(hub_scratch_init)
/*******************************************************************/
/*
* ARCS Prom entry points
*/
LEAF(Halt)
li s0,PROMOP_HALT
j arcs_common
END(Halt)
LEAF(PowerDown)
li s0,PROMOP_POWERDOWN
j arcs_common
END(PowerDown)
LEAF(Restart)
li s0,PROMOP_RESTART
j arcs_common
END(Restart)
LEAF(Reboot)
li s0,PROMOP_REBOOT
j arcs_common
END(Reboot)
/* EnterInteractive mode goes to prom menu. If called from outside the
* prom or bssmagic, or envdirty is true, do full clean-up, else just
* re-wind the stack to keep the prom responsive.
*/
LEAF(EnterInteractiveMode)
# Print a message telling us we got here
#
LA t0, _ftext
LA t1, _etext
sgeu t2,ra,t0
sleu t3,ra,t1
and t0,t2,t3
beq t0,zero,1f
# check if bssmagic was trashed
# form a 32 bit sign-extended constant to match
# the sign-extended result of the lw above.
# (The Ragnarok compiler may not treat the 'li' macro
# properly, so make it explicit.
lw v0,bssmagic # Check to see if bss valid
lui t0,(BSSMAGIC >> 16)
ori t0,(BSSMAGIC & 0xffff)
bne v0,t0,1f # If not, do full init
# check if envdirty true (program was loaded)
lw v0,envdirty
bne v0,zero,1f
jal IO6prom_stack_addr
move sp, v0
sreg sp,_fault_sp
jal main
# if main fails fall through and re-init
1:
# clear_prom_ram assumes that the SP is already setup
# if we come here from any of the beq 1f above, the
# stack will not be setup. Rewind the stack here.
jal IO6prom_stack_addr
nop
move sp, v0
sreg sp,_fault_sp
li s0,PROMOP_IMODE
j arcs_common
END(EnterInteractiveMode)
.data
e_msg: .asciiz "In EnterInteractiveMode in IO6\r\n"
l_msg: .asciiz "Doing light cleanup\r\n"
w_msg: .asciiz "Reinitializing the whole shebang\r\n"
.text
LEAF(arcs_common)
.set noreorder
LI a0, IO6PROM_SR & ~(SR_IE)
DMTC0(a0, C0_SR) # no interrupts
nop
.set reorder
move s3, s0 # make addnl copies as s0 is getting trashed
jal clear_prom_ram # clear_prom_ram initializes sp
move a0,zero
jal init_prom_soft # initialize saio and everything else
move s0, s3 # restore s0
li t0,PROMOP_IMODE
bne s0,t0,1f
jal main
j never # never gets here
1:
li t0,PROMOP_HALT
bne s0,t0,1f
jal halt
j never # never gets here
1:
li t0,PROMOP_POWERDOWN
bne s0,t0,1f
jal powerdown
j never # never gets here
1:
li t0,PROMOP_RESTART
bne s0,t0,1f
jal restart
j never # never gets here
1:
li t0,PROMOP_REBOOT
bne s0,t0,never
jal reboot
never: j _exit # never gets here
END(arcs_common)
/*
* _exit()
*
* Re-enter prom command loop without initialization
* Attempts to clean-up things as well as possible while
* still maintaining things like current enabled consoles, uart baud
* rates, and environment variables.
*/
LEAF(_exit)
.set noreorder
LI v0, IO6PROM_SR & ~(SR_IE)
DMTC0(v0,C0_SR) # back to a known sr
nop
DMTC0(zero,C0_CAUSE) # clear software interrupts
nop
.set reorder
lw v0,bssmagic # Check to see if bss valid
bne v0,BSSMAGIC,_init # If not, do a hard init
jal IO6prom_stack_addr
move sp, v0
sreg sp,_fault_sp
PTR_SUBU sp,EXSTKSZ # top 1/4 of stack for fault handling
jal config_cache # determine cache sizes
jal flush_cache # flush cache
jal enter_imode
1: b 1b # never gets here
END(_exit)
/*
* notimplemented -- deal with calls to unimplemented prom services
*/
NOTIMPFRM=(4*BPREG)+BPREG+BPREG
NESTED(notimplemented, NOTIMPFRM, zero)
PTR_SUBU sp,NOTIMPFRM
beqz fp,1f
move a0,fp
move fp,zero
j a0
1:
LA a0,notimp_msg
jal printf
jal EnterInteractiveMode
END(notimplemented)
.data
notimp_msg:
.asciiz "ERROR: call to unimplemented prom routine\n"
.text
/*******************************************************************/
/*
* Subroutines
*
*/
/*
* _init -- reinitialize prom and reenter command parser
*/
LEAF(_init)
.set noreorder
LI v0, IO6PROM_SR & ~(SR_IE)
DMTC0(v0,C0_SR)
nop
jal IO6prom_stack_addr
nop
move sp, v0
.set reorder
jal clear_prom_ram # clear_prom_ram initializes sp
move a0,zero
jal init_prom_soft
jal main
jal EnterInteractiveMode # shouldn't get here
END(_init)
/*
* clear_prom_ram -- config and init cache, clear prom bss. Note that
* This routine assumes that BSS follows the text and data sections.
*/
INITMEMFRM=(4*BPREG)+BPREG
NESTED(clear_prom_ram, INITMEMFRM, zero)
#ifndef SABLE
LA a0,_fbss # clear bss and stack
LA a1,_end # Up to stack value - NO
/* PTR_ADDU a1, IO4STACK_SIZE */
/* If SN0, v0/v1 must have the phys addrs */
#ifdef SN0
move s2, ra # store ra in s2
move s0, a1
jal kvtophys
move s1, v0
move a0, s0
jal kvtophys
move v1, v0
move v0, s1
move ra, s2 # restore ra from s2
#else
LI t0, 0x9fffffff
and v0, a0, t0
and v1, a1, t0
#endif /* SN0 */
#if 0
/* may be needed to check why the above piece of code does
not work with BD slots */
LI t0, PHYS_TO_K0(0x1300000) /* Flash buf base */
sd v0, 0(t0)
sd v1, 8(t0)
#endif
or v0, K0BASE
or v1, K0BASE
/* Clear 7 bytes, then align */
sb zero,0(v0)
sb zero,1(v0)
sb zero,2(v0)
sb zero,3(v0)
sb zero,4(v0)
sb zero,5(v0)
sb zero,6(v0)
sb zero,7(v0)
daddiu v0,7
and v0,~7
.set noreorder
1: PTR_ADDU v0,64 # clear 64 bytes at a time
sd zero, -8(v0)
sd zero, -16(v0)
sd zero, -24(v0)
sd zero, -32(v0)
sd zero, -40(v0)
sd zero, -48(v0)
sd zero, -56(v0)
bltu v0,v1,1b
sd zero,-64(v0) # (BD) Do the final store
.set reorder
#endif /* !SABLE */
XLEAF(init_prom_ram)
/*
* Remember that bss is now okay
*/
li v0,BSSMAGIC
sw v0,bssmagic
/*
* Initialize stack
* SN0 - the sp is already initted for each cpu.
* Do it again. Because when we do a init we need
* the same stack pointer we started with.
* just allocate space for the various things.
*/
PTR_SUBU sp, (4*BPREG)
sreg sp,_fault_sp # base of fault stack
PTR_SUBU sp,EXSTKSZ # top 1/4 of stack for fault handling
j ra
END(clear_prom_ram)
/* Clear all the TLB entries, but leave TLB entry 0 alone.
* TLB entry 0 is used by graphics to access the graphics
* hardware. Also leave the top entry alone. We use that
* to map the prom text! Finally, tlb entries 60, 61, and 62 are used by the
* IP27prom.
*/
LEAF(init_tlb)
.set noreorder
DMTC0(zero,C0_TLBLO_0)
DMTC0(zero,C0_TLBLO_1)
LI v0,K0BASE&TLBHI_VPNMASK
DMTC0(v0,C0_TLBHI) # invalidate entry
move v0,zero
addiu v0,1
nop
1:
DMTC0(v0,C0_INX)
nop
c0 C0_WRITEI
addiu v0,1
#ifdef SN0XXL
blt v0,NTLBENTRIES - 8,1b # entries 56..59 used by io6prom
#else
blt v0,NTLBENTRIES - 7,1b # entries 57, 58, 59 used by io6prom
#endif
nop
j ra
nop # BDSLOT
.set reorder
END(init_tlb)
#if SABLE
/*
* Routine hubuart_init
* Initializes the Hub chip UART by writing three NULLS to
* get it into a known state, doing a soft reset, and then
* bringing it into ASYNCHRONOUS mode.
*
* Arguments:
* None.
* Returns:
* Nothing.
* Uses:
* a0, a1.
*/
#define CMD 0x0
#define DATA 0x8
LEAF(hubuart_init)
LI a1, LOCAL_HUB(MD_UREG0_0)
sd zero, CMD(a1) # Clear state by writing 3 zero's
nop
sd zero, CMD(a1)
nop
sd zero, CMD(a1)
LI a0, I8251_RESET # Soft reset
sd a0, CMD(a1)
LI a0, I8251_ASYNC16X | I8251_NOPAR | I8251_8BITS | I8251_STOPB1
sd a0, CMD(a1)
LI a0, I8251_TXENB | I8251_RXENB | I8251_RESETERR
j ra
sd a0, CMD(a1) # (BD)
END(hubuart_init)
#endif /* SABLE */
LEAF(prom_flash_leds)
LI t1, IP27PROM_FLASHLEDS # Go away forever.
j t1
END(prom_flash_leds)
/*
* IO6prom_stack_addr -> returns a local stack depending on the node
* and cpu.
*/
LEAF(IO6prom_stack_addr)
LA v0, Stack
daddiu v0, IO6PROM_STACK_SIZE
dsubu v0, 16
j ra
END(IO6prom_stack_addr)
/*
* HACK - This lets us use hubuartprintf before we really define such
* a thing in the real code.
*/
LEAF(hubprintf)
j printf
END(hubprintf)
/*
* stub for IO6prom. real one only lives in IP27prom
*/
LEAF(db_printf)
j printf
END(db_printf)
/***********************************************************************
*
* Data Area
*
*/
.data
BSS(bssmagic,4)