summaryrefslogtreecommitdiffstats
path: root/private/ntos/fw/alpha/jenassem.s
diff options
context:
space:
mode:
authorAdam <you@example.com>2020-05-17 05:51:50 +0200
committerAdam <you@example.com>2020-05-17 05:51:50 +0200
commite611b132f9b8abe35b362e5870b74bce94a1e58e (patch)
treea5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/ntos/fw/alpha/jenassem.s
downloadNT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.gz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.bz2
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.lz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.xz
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.tar.zst
NT4.0-e611b132f9b8abe35b362e5870b74bce94a1e58e.zip
Diffstat (limited to 'private/ntos/fw/alpha/jenassem.s')
-rw-r--r--private/ntos/fw/alpha/jenassem.s579
1 files changed, 579 insertions, 0 deletions
diff --git a/private/ntos/fw/alpha/jenassem.s b/private/ntos/fw/alpha/jenassem.s
new file mode 100644
index 000000000..aaf4545a2
--- /dev/null
+++ b/private/ntos/fw/alpha/jenassem.s
@@ -0,0 +1,579 @@
+/*++
+
+Copyright (c) 1993 Digital Equipment Corporation
+
+
+Module Name:
+
+ jenassem.s
+
+
+Abstract:
+
+ This contains assembler code routines for the Alpha PCs.
+
+ The first section contains functions that need to explicitly
+ generate Alpha macroinstructions (e.g., mb, PALcode calls).
+ These could be asm() calls within the C code, but our compiler does
+ not now handle asm()'s and may not for some time.
+
+ The second section has linkages for "Fw" calls.
+
+ The last section has stubs for functions that should be defined
+ elsewhere, but are not. When the real code appears in the
+ Alpha build tree, these stub routines should be deleted.
+
+ Most of the "Fw" call section is directly patterned after
+ \nt\private\ntos\fw\mips\fwtrap.s, written by Lluis Abello of
+ Microsoft.
+
+
+Author:
+
+ John DeRosa [DEC] 21-May-1992
+
+
+Environment:
+
+ Executes in kernel mode.
+
+Revision History:
+
+
+--*/
+
+
+#include "ksalpha.h"
+#include "selfmap.h"
+#include "machdef.h"
+
+//
+// Static data
+//
+
+.align 4
+RegisterTable:
+.space RegisterTableSize
+
+
+/*++
+
+VOID
+FwStallExecution (
+ IN ULONG MicroSeconds
+)
+
+
+Routine Description:
+
+ This stalls for at least the requested number of microseconds.
+ Current timing on a Jensen indicates that this is pessimistic
+ by a factor of 1.2.
+
+Arguments:
+
+ Microseconds (a0) - The number of microseconds to stall.
+
+
+Return Value:
+
+ None.
+
+--*/
+
+ 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
+
+
+
+/*****************************************************************
+
+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
+
+
+
+ LEAF_ENTRY(DisableInterrupts)
+
+ callpal di
+ ret zero, (ra)
+
+ .end DisableInterrupts
+
+
+
+ LEAF_ENTRY(RegisterExceptionHandler)
+
+ lda a0, Monitor # Run monitor 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.
+
+--*/
+
+ //
+ // If the longword is zero then this is the first call from
+ // the firmware, and is not a call from an already loaded program.
+ //
+
+ lda t0, FwSavedSp
+ ldl t1, (t0)
+ beq t1, CallFromFw
+
+
+ //
+ // Here when an already loaded program wants to be replaced
+ // by another program. Therefore, the current stack and state
+ // will be trashed and a new temporary stack needs to be set.
+ // (A temporary stack is used to guarantee that there is enough
+ // stack space for the necessary calls.)
+ //
+
+ lda t0, FwTemporaryStack
+ ldl sp, (t0)
+ jsr ra, FwPrivateExecute # this does the dirty work.
+
+ //
+ // The executed program has returned. Its caller is gone.
+ // Therefore, restore the initial firmware stack and return
+ // to the firmware instead.
+ //
+
+ lda t0, FwSavedSp
+ ldl sp, (t0) # restore saved stack
+ br zero, RestoreFwState # go restore the state & return
+
+
+
+
+CallFromFw:
+
+ 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, 0x38(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 t1, 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
+
+ NESTED_ENTRY(FwMonitor, 50, ra)
+
+/*****************************************************************
+
+Linkage to the monitor from the jxboot.c boot menu and code in
+bldr\alpha\stubs.c.
+
+******************************************************************/
+
+
+ //
+ // Move registers into exception frame and call the Monitor.
+ // We cannot exactly duplicate what the PALcode creates
+ // on an exception.
+ //
+ // This used to specify the stq addresses as
+ // RegisterTable+offset(zero)
+ // but the assembler won't generate correct code that way.
+ //
+
+ subq sp, 0x8 # setup t0 with base of register table,
+ stq t0, (sp) # and use t1 to store old t0 in it.
+ lda t0, RegisterTable
+ stq t1, t1RegTable(t0)
+ ldq t1, (sp)
+ stq t1, t0RegTable(t0)
+ addq sp, 0x8
+
+ stq v0, v0RegTable(t0)
+/* stq t0, RegisterTable+t0RegTable(zero) */
+/* stq t1, RegisterTable+t1RegTable(zero) */
+ stq t2, t2RegTable(t0)
+ stq t3, t3RegTable(t0)
+ stq t4, t4RegTable(t0)
+ stq t5, t5RegTable(t0)
+ stq t6, t6RegTable(t0)
+ stq t7, t7RegTable(t0)
+ stq s0, s0RegTable(t0)
+ stq s1, s1RegTable(t0)
+ stq s2, s2RegTable(t0)
+ stq s3, s3RegTable(t0)
+ stq s4, s4RegTable(t0)
+ stq s5, s5RegTable(t0)
+ stq fp, fpRegTable(t0)
+ stq a0, a0RegTable(t0)
+ stq a1, a1RegTable(t0)
+ stq a2, a2RegTable(t0)
+ stq a3, a3RegTable(t0)
+ stq a4, a4RegTable(t0)
+ stq a5, a5RegTable(t0)
+ stq t8, t8RegTable(t0)
+ stq t9, t9RegTable(t0)
+ stq t10, t10RegTable(t0)
+ stq t11, t11RegTable(t0)
+ stq ra, raRegTable(t0)
+ stq t12, t12RegTable(t0)
+ .set noat
+ stq AT, atRegTable(t0)
+ .set at
+ stq gp, gpRegTable(t0)
+ stq sp, spRegTable(t0)
+ stq zero, zeroRegTable(t0)
+ stt f0, f0RegTable(t0)
+ stt f1, f1RegTable(t0)
+ stt f2, f2RegTable(t0)
+ stt f3, f3RegTable(t0)
+ stt f4, f4RegTable(t0)
+ stt f5, f5RegTable(t0)
+ stt f6, f6RegTable(t0)
+ stt f7, f7RegTable(t0)
+ stt f8, f8RegTable(t0)
+ stt f9, f9RegTable(t0)
+ stt f10, f10RegTable(t0)
+ stt f11, f11RegTable(t0)
+ stt f12, f12RegTable(t0)
+ stt f13, f13RegTable(t0)
+ stt f14, f14RegTable(t0)
+ stt f15, f15RegTable(t0)
+ stt f16, f16RegTable(t0)
+ stt f17, f17RegTable(t0)
+ stt f18, f18RegTable(t0)
+ stt f19, f19RegTable(t0)
+ stt f20, f20RegTable(t0)
+ stt f21, f21RegTable(t0)
+ stt f22, f22RegTable(t0)
+ stt f23, f23RegTable(t0)
+ stt f24, f24RegTable(t0)
+ stt f25, f25RegTable(t0)
+ stt f26, f26RegTable(t0)
+ stt f27, f27RegTable(t0)
+ stt f28, f28RegTable(t0)
+ stt f29, f29RegTable(t0)
+ stt f30, f30RegTable(t0)
+ stt f31, f31RegTable(t0)
+
+ ldil t1, 0xedbedbed # phony exception type
+ stl t1, ResExceptTypeRegTable(t0)
+
+ # a0 has the CallerSource argument
+ # already.
+ lda a1, RegisterTable # Frame argument
+ jsr ra, Monitor
+
+
+ //
+ // On return just restore ra from the RegisterTable.
+ // This is coded this way to get around an assembler bug...
+ //
+
+// ldq ra, RegisterTable+raRegTable
+ lda t0, RegisterTable
+ ldq ra, raRegTable(t0)
+ ret zero, (ra)
+
+ .end FwMonitor
+
+#if 0
+
+//
+// This function was used to zero out memory in the selftest.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
+
+
+#ifdef ALPHA_FW_KDHOOKS
+
+/*++
+
+VOID
+FwRfe(
+ VOID
+ )
+
+Routine Description:
+
+ This routine executes a return from exception instruction.
+ It is used to return after processing a breakpoint.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+
+ LEAF_ENTRY(FwRfe)
+
+ bis a0, zero, sp # Set the stack pointer to the
+ # exception frame pointer.
+ lda sp, -0x10(sp) # Adjust for stack empty space
+ callpal rfe # This does NOT return.
+
+ .end FwRfe
+
+#endif
+
+
+/************************************************************
+
+Stubs.
+
+*************************************************************/
+
+#ifndef ALPHA_FW_KDHOOKS
+
+//
+// This cannot be defined for kd build.
+//
+
+ LEAF_ENTRY(DebugPrompt)
+
+ callpal halt # surprise!
+ ret zero, (ra) # should never return, but...
+
+ .end DebugPrompt
+
+#endif