diff options
Diffstat (limited to 'private/ntos/fw/alpha/jnfsstub.s')
-rw-r--r-- | private/ntos/fw/alpha/jnfsstub.s | 353 |
1 files changed, 353 insertions, 0 deletions
diff --git a/private/ntos/fw/alpha/jnfsstub.s b/private/ntos/fw/alpha/jnfsstub.s new file mode 100644 index 000000000..83203d5d9 --- /dev/null +++ b/private/ntos/fw/alpha/jnfsstub.s @@ -0,0 +1,353 @@ +#if defined(ALPHA) + +/*++ + +Copyright (c) 1993 Digital Equipment Corporation + + +Module Name: + + jnfsstub.s + + +Abstract: + + A streamlined copy of jenassem.s, for the FailSafe Booter. + +Author: + + John DeRosa 21-October-1992 + + +Environment: + + Executes in kernel mode. + +Revision History: + + +--*/ + + +#include "ksalpha.h" +#include "selfmap.h" +#include "jnsndef.h" + +/***************************************************************** + +Simple functions to perform PALcode calls and memory barriers. + +******************************************************************/ + + + LEAF_ENTRY(AlphaInstIMB) + + callpal imb + ret zero, (ra) + + .end AlphaInstIMB + + + + LEAF_ENTRY(AlphaInstMB) + + mb + ret zero, (ra) + + .end AlphaInstMB + + + + LEAF_ENTRY(AlphaInstHalt) + + callpal halt + ret zero, (ra) # should never return, but... + + .end AlphaInstHalt + + + +#if 0 + LEAF_ENTRY(DisableInterrupts) + + callpal di + ret zero, (ra) + + .end DisableInterrupts +#endif + + + + LEAF_ENTRY(RegisterExceptionHandler) + + lda a0, FailSafeEntry # Restart main code on unexpected exceptions + callpal wrentry + ret zero, (ra) + + .end RegisterExceptionHandler + + NESTED_ENTRY(FwExecute, 0x60, ra) + + +/* + +Routine Description: + + This is the entry point for the Execute service. + + It behaves in two different ways depending on where it is called from: + + 1) If called from the Firmware, it saves the stack pointer + in a fixed location and then saves all the saved registers + in the stack. This is the stack that will be used to restore + the saved state when returning to the firmware. + + 2) If called from a loaded program, the program to be loaded + and executed can overwrite the current program and its + stack. Therefore a temporary stack is set. + +Arguments: + + a0 IN PCHAR Path, + a1 IN ULONG Argc, + a2 IN PCHAR Argv[], + a3 IN PCHAR Envp[] + +Return Value: + + ARC_STATUS returned by FwPrivateExecute. + Always returns to the Firmware. + + */ + + lda t0, FwSavedSp + subq sp, 0x60 # make room in the stack + stl sp, (t0) # save new stack pointer + + stq ra, (sp) # return address on top of stack + stq s0, 0x8(sp) # save s registers + stq s1, 0x10(sp) + stq s2, 0x18(sp) + stq s3, 0x20(sp) + stq s4, 0x28(sp) + stq s5, 0x30(sp) + stq fp, 0x38(sp) + stq gp, 0x40(sp) + jsr ra, FwPrivateExecute # go do the work. + +RestoreFwState: + ldq ra, (sp) # restore return address + ldq s0, 0x8(sp) # restore s registers + ldq s1, 0x10(sp) + ldq s2, 0x18(sp) + ldq s3, 0x20(sp) + ldq s4, 0x28(sp) + ldq s5, 0x30(sp) + ldq fp, 0x48(sp) + ldq gp, 0x40(sp) + addq sp, 0x60 # restore stack pointer + ret zero, (ra) # return to firmware control + + .end FwExecute + + NESTED_ENTRY(FwInvoke, 0x40, ra) + +/*++ +ARC_STATUS +FwInvoke( + IN ULONG ExecAddr, + IN ULONG StackAddr, + IN ULONG Argc, + IN PCHAR Argv[], + IN PCHAR Envp[] + ) + + +Routine Description: + + This routine invokes a loaded program. + +Arguments: + + ExecAddr - Supplies the address of the routine to call. + + StackAddr - Supplies the address to which the stack pointer is set. + + Argc, Argv, Envp - Supply the arguments and environment to pass to + Loaded program. + + The stack pointer is saved in register s0 so that when the loaded + program returns, the old stack pointer can be restored. + + +Return Value: + + ESUCCESS is returned if the address is valid. + EFAULT indicates an invalid address. + +--*/ + + + subq sp, 0x40 # make room on the stack + stq ra, (sp) # save ra on top of stack + stq s0, 0x8(sp) # save s0 + and a0, 3, t1 # return EFAULT if unaligned address + ldiq v0, 0x6 + bne zero, 1f # branch if address alignment error + + mov a0, t12 # save program address in t12 + + mov sp, s0 # save stack pointer + mov a1, sp # ..and load new one for program + mov a2, a0 # argc becomes first argument + mov a3, a1 # argv becomes second argument + mov a4, a2 # envp becomes third argument + + jsr ra, (t12) # call program + + // here if loaded program returns. + + mov s0, sp # restore stack pointer + mov zero, v0 # return ESUCCESS value + ldq s0, 0x8(sp) # restore things + ldq ra, (sp) +1: + addq sp, 0x40 + ret zero, (ra) + + .end FwInvoke + +#if 0 + +// +// This function was used to zero out memory in the jnfs.c module. +// We do not need to do this anymore. +// + +/**** + +VOID +WildZeroMemory( + IN ULONG StartAddress, + IN ULONG Size + ) +Routine Description: + + This routine zeroes the specified range of memory. + + At some point this may be changed to a more clever algorithm, + For now, it simply does store quads. + +Arguments: + + a0 - supplies the base physical address of the range of memory + to zero. It must be a multiple of the data cache line + size. + + a1 - supplies length of memory to zero, in bytes. This must + be a multiple of the data cache line size. + + +Return Value: + + None. + +--*/ + + LEAF_ENTRY(WildZeroMemory) + + mov a0, t0 # start address + mov a1, t1 # number of bytes to move + +1: + subqv t1, 0x20 # zero a D-cache block = 32 bytes + stq zero, (t0) + stq zero, 0x8(t0) + stq zero, 0x10(t0) + stq zero, 0x18(t0) + addqv t0, 0x20 # move to next cache block + bgt t1, 1b # t1 = 0 when done. + + ret zero, (ra) + + .end WildZeroMemory + +#endif + + +/************************************************************ + +These are stubs. When the real code appears in the Alpha build +tree, these should be deleted. Consult the "hacked" file. + +*************************************************************/ + + LEAF_ENTRY(DebugPrompt) + + callpal halt # surprise! + ret zero, (ra) # should never return, but... + + .end DebugPrompt + + + + +/* ---- + +VOID +FwStallExecution +( + ULONG Microseconds +); + + +This routine utilizes the Alpha cycle counter to delay a requested number of +microseconds. + + +---- */ + + LEAF_ENTRY( FwStallExecution) + + beq a0, 20f // exit if zero delay requested + +// lda t0, 20000(zero) // force small delays to 20 milliseconds +// subl a0, 5, t1 +// cmoveq t1, t0, a0 + +10: bsr t3, 100f // call 1 microsecond delay subroutine + + subl a0, 1, a0 // decrement requested microseconds + zap a0, 0xf0, a0 // unsigned long a0 + + bgt a0, 10b + +20: ret zero, (ra) + +// +// 1 microsecond delay subroutine +// + +100: ldl t0, CyclesPerMicrosecond // init 1 microsecond delay + + rpcc t1 // get entry time rpcc value + zap t1, 0xf0, t1 // clear <63:32> + +200: rpcc t2 // get current rpcc value + zap t2, 0xf0, t2 // clear <63:32> + + subl t2, t1, t2 // compute unsigned 32b difference + zap t2, 0xf0, t2 + + subl t0, t2, t2 // (requested delay - delay so far) > 0? + + bgt t2, 200b + + ret zero, (t3) + + .end FwStallExecution + + + +#endif // ALPHA + |