mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
4.0 KiB
136 lines
4.0 KiB
// TITLE("Firmware Runtime Stack Checking")
|
|
//++
|
|
//
|
|
// Copyright (c) 1993 Digital Equipment Corporation
|
|
//
|
|
// Module Name:
|
|
//
|
|
// fwchkstk.s
|
|
//
|
|
// Abstract:
|
|
//
|
|
// This module implements runtime stack checking for the Alpha AXP
|
|
// NT firmware.
|
|
//
|
|
// Original comments are from David Cutler of Microsoft and Thomas
|
|
// VanBaak of Digital.
|
|
//
|
|
// Author:
|
|
//
|
|
// John DeRosa [DEC] 26-January-1993
|
|
//
|
|
// Environment:
|
|
//
|
|
// Any mode.
|
|
//
|
|
// Revision History:
|
|
//
|
|
//
|
|
//--
|
|
|
|
#include "ksalpha.h"
|
|
#include "fwmemdef.h"
|
|
|
|
//
|
|
// Static data
|
|
//
|
|
|
|
.align 4
|
|
|
|
FwRtlStackLowerBound:
|
|
.long FW_STACK_LOWER_BOUND
|
|
|
|
SBTTL("Check Stack")
|
|
//++
|
|
//
|
|
// ULONG
|
|
// _RtlCheckStack (
|
|
// IN ULONG Allocation
|
|
// )
|
|
//
|
|
// Routine Description:
|
|
//
|
|
// This function provides runtime stack checking for local allocations
|
|
// within the executing environment of the NT Firmware. On Alpha AXP,
|
|
// the firmware runs in superpage mode (physical = virtual). The requested
|
|
// stack allocation is compared against the stack low limit, and if it
|
|
// would exceed the stack then an error message is printed on the screen.
|
|
//
|
|
// The call to the FwPrint function for the error message will wind up
|
|
// using stack space. This is accomplished by using a global variable
|
|
// (FwRtlStackPanic) to indicate that _RtlCheckStack should just
|
|
// return. Also, the 64KB underneath the Firmware stack is unused by
|
|
// the Firmware, and will be used by the FwPrint functions to output
|
|
// the error message.
|
|
//
|
|
// N.B. This routine is called using a non-standard calling sequence since
|
|
// it is typically called from within the prologue. The allocation size
|
|
// argument is in register t12 and it must be preserved. Register t11
|
|
// may contain the callers saved ra and it must be preserved. The choice
|
|
// of these registers is hard-coded into the acc C compiler. Register v0
|
|
// may contain a static link pointer (exception handlers) and so it must
|
|
// be preserved. Since this function is called from within the prolog,
|
|
// the a' registers must be preserved, as well as all the s' registers.
|
|
// Registers t8, t9, and t10 are used by this function and are not
|
|
// preserved.
|
|
//
|
|
// The typical calling sequence from the prologue is:
|
|
//
|
|
// mov ra, t11 // save return address
|
|
// ldil t12, SIZE // set requested stack frame size
|
|
// bsr ra, _RtlCheckStack // check stack page allocation
|
|
// subq sp, t12, sp // allocate stack frame
|
|
// mov t11, ra // restore return address
|
|
//
|
|
// Arguments:
|
|
//
|
|
// Allocation (t12) - Supplies the size of the allocation on the stack.
|
|
//
|
|
// Return Value:
|
|
//
|
|
// None.
|
|
//
|
|
//--
|
|
|
|
LEAF_ENTRY(_RtlCheckStack)
|
|
|
|
ldl t8, FwRtlStackPanic // do we already have a bad stack?
|
|
bne t8, 40f // branch if t8<>0, = yes a bad stack.
|
|
|
|
subq sp, t12, t8 // compute requested new stack address
|
|
ldl t9, FwRtlStackLowerBound // get low limit of stack address
|
|
|
|
//
|
|
// The requested bottom of the stack is in t8.
|
|
// The current low limit of the stack is in t9.
|
|
//
|
|
// If the new stack address is greater than the current stack limit then
|
|
// the stack is good and nothing further needs to be done.
|
|
//
|
|
|
|
cmpult t8, t9, t10 // t8<t9? new stack base within limit?
|
|
beq t10, 40f // if eq [false], then t8>=t9, so yes
|
|
|
|
|
|
//
|
|
// The requested lower stack address is below the bottom of the legal stack.
|
|
//
|
|
ldl t8, 0x1
|
|
stl t8, FwRtlStackPanic
|
|
|
|
//
|
|
// The 64KB below the bottom of the stack is unused, so it is available
|
|
// as a panic stack. The rest of the work is done in C, and there is no
|
|
// reason to save the s0--s5 registers.
|
|
//
|
|
|
|
mov t12, a2 # the requested stack allocation
|
|
mov t11, a1 # the caller of the caller
|
|
mov ra, a0 # the caller of _RtlCheckStack
|
|
jsr ra, FwErrorStackUnderflow # go do the work.
|
|
|
|
10: br zero, 10b # it should never have returned.
|
|
|
|
40: ret zero, (ra) // return
|
|
|
|
.end _RtlCheckStack
|