2020-09-30 17:12:29 +02:00

353 lines
10 KiB
ArmAsm

// TITLE("Win32 Thunks")
//++
//
// Copyright (c) 1993 IBM Corporation
//
// Module Name:
//
// thunk.s
//
// Abstract:
//
// This module implements Win32 functions that must be written in
// macro.
//
// Author:
//
// Curt Fawcett (crf) 22-Sept-1993
//
// Revision History:
//
// Curt Fawcett (crf) 19-Jan-1994 Removed Register names
// as requested
//--
//
// Parameter Register Usage:
//
// r.3 - Current time low part
// r.4 - Current time high part
// r.5 - Boot time low part
// r.6 - Boot time high part
//
// r.4 - New stack address
// r.5 - Exit code
//
// Local Register Usage:
//
// r.7 - Result low part
// r.8 - Result high part
// r.9 - Temporary high part
// r.10 - Temporary low part
// r.11 - Temporary low part
// r.12 - Divide multiplier value
//
#include "ksppc.h"
//
// Define external entry points
//
.globl ..BaseFreeStackAndTerminate
.globl ..BaseAttachComplete
//
//++
//
// VOID
// BaseSwitchStackThenTerminate(
// IN PVOID StackLimit,
// IN PVOID NewStack,
// IN DWORD ExitCode
// )
//
//
// Routine Description:
//
// This API is called during thread termination to delete a
// thread's stack, switch to a stack in the thread's TEB, and then
// terminate.
//
// Arguments:
//
// StackLimit (r.3) - Supplies address of the stack to be freed.
//
// NewStack (r.4) - Supplies an address within the terminating
// threads TEB that is to be used as its
// temporary stack while exiting.
//
// ExitCode (r.5) - Supplies the termination status that the
// thread is to exit with.
//
// Return Value:
//
// None.
//
//--
LEAF_ENTRY(BaseSwitchStackThenTerminate)
mr r.sp,r.4 // Set new stack address
mr r.4,r.5 // Move exit code
b ..BaseFreeStackAndTerminate // Jump to finish
LEAF_EXIT(BaseSwitchStackThenTerminate)
SBTTL("Base Attach Complete")
//++
//
// The following code is never executed. Its purpose is to support
// unwinding through the call to the exception dispatcher.
//
//--
.set StackFrameLength, ContextFrameLength+STK_MIN_FRAME
.set ContextBase, STK_MIN_FRAME
FN_TABLE(BaseAttachCompThunk,0,0)
DUMMY_ENTRY(BaseAttachCompThunk)
mflr r.0
stwu r.sp,-StackFrameLength(r.sp)
stw r.0, (ContextBase+CxLr)(r.sp) // Save the return address
mflr r.0
stw r.0, (ContextBase+CxIar)(r.sp) // Save the return address
stw r.2, (ContextBase+CxGpr2)(r.sp) // Save the toc
stw r.13,(ContextBase+CxGpr13)(r.sp) // Save volatile registers
stw r.14,(ContextBase+CxGpr14)(r.sp) //
stw r.15,(ContextBase+CxGpr15)(r.sp) //
stw r.16,(ContextBase+CxGpr16)(r.sp) //
stw r.17,(ContextBase+CxGpr17)(r.sp) //
stw r.18,(ContextBase+CxGpr18)(r.sp) //
stw r.19,(ContextBase+CxGpr19)(r.sp) //
stw r.20,(ContextBase+CxGpr20)(r.sp) //
stw r.21,(ContextBase+CxGpr21)(r.sp) //
stw r.22,(ContextBase+CxGpr22)(r.sp) //
stw r.23,(ContextBase+CxGpr23)(r.sp) //
stw r.24,(ContextBase+CxGpr24)(r.sp) //
stw r.25,(ContextBase+CxGpr25)(r.sp) //
stw r.26,(ContextBase+CxGpr26)(r.sp) //
stw r.27,(ContextBase+CxGpr27)(r.sp) //
stw r.28,(ContextBase+CxGpr28)(r.sp) //
stw r.29,(ContextBase+CxGpr29)(r.sp) //
stw r.30,(ContextBase+CxGpr30)(r.sp) //
stw r.31,(ContextBase+CxGpr31)(r.sp) //
stfd r.14,(ContextBase+CxFpr14)(r.sp) // Store floating regs f20 - f31
stfd r.15,(ContextBase+CxFpr15)(r.sp) //
stfd r.16,(ContextBase+CxFpr16)(r.sp) //
stfd r.17,(ContextBase+CxFpr17)(r.sp) //
stfd r.18,(ContextBase+CxFpr18)(r.sp) //
stfd r.19,(ContextBase+CxFpr19)(r.sp) //
stfd r.20,(ContextBase+CxFpr20)(r.sp) //
stfd r.21,(ContextBase+CxFpr21)(r.sp) //
stfd r.22,(ContextBase+CxFpr22)(r.sp) //
stfd r.23,(ContextBase+CxFpr23)(r.sp) //
stfd r.24,(ContextBase+CxFpr24)(r.sp) //
stfd r.25,(ContextBase+CxFpr25)(r.sp) //
stfd r.26,(ContextBase+CxFpr26)(r.sp) //
stfd r.27,(ContextBase+CxFpr27)(r.sp) //
stfd r.28,(ContextBase+CxFpr28)(r.sp) //
stfd r.29,(ContextBase+CxFpr29)(r.sp) //
stfd r.30,(ContextBase+CxFpr30)(r.sp) //
stfd r.31,(ContextBase+CxFpr31)(r.sp) //
PROLOGUE_END(BaseAttachCompThunk)
//++
//
// VOID
// BaseAttachCompleteThunk(
// VOID
// )
//
//
// Routine Description:
//
// This function is called after a successful debug attach. Its
// purpose is to call portable code that does a breakpoint, followed
// by an NtContinue.
//
// Arguments:
//
// None.
//
// Return Value:
//
// None.
//
//--
ALTERNATE_ENTRY(BaseAttachCompleteThunk)
mr r.3,r.14 // Set address of context frame
b ..BaseAttachComplete
DUMMY_EXIT(BaseAttachCompThunk)
//++
//
// VOID
// SwitchToFiber(
// PFIBER NewFiber
// )
//
// Routine Description:
//
// This function saves the state of the current fiber and switches
// to the new fiber.
//
// Arguments:
//
// NewFiber (r3) - Supplies the address of the new fiber.
//
// Return Value:
//
// None
//
//--
LEAF_ENTRY(SwitchToFiber)
//
// Get current fiber pointer.
//
lwz r4, TeFiberData(r13)
//
// Save the stack limit of the current fiber.
//
lwz r5, TeStackLimit(r13)
// next two instructions move for scheduling
mflr r0 // get return address for current fiber
stw r14, CxGpr14+FbFiberContext(r4) // save r14
stw r5, FbStackLimit(r4)
//
// Save nonvolatile integer state.
//
stw r15, CxGpr15+FbFiberContext(r4)
stw r16, CxGpr16+FbFiberContext(r4)
stw r17, CxGpr17+FbFiberContext(r4)
stw r18, CxGpr18+FbFiberContext(r4)
stw r19, CxGpr19+FbFiberContext(r4)
stw r20, CxGpr20+FbFiberContext(r4)
stw r21, CxGpr21+FbFiberContext(r4)
stw r22, CxGpr22+FbFiberContext(r4)
stw r23, CxGpr23+FbFiberContext(r4)
stw r24, CxGpr24+FbFiberContext(r4)
stw r25, CxGpr25+FbFiberContext(r4)
stw r26, CxGpr26+FbFiberContext(r4)
stw r27, CxGpr27+FbFiberContext(r4)
stw r28, CxGpr28+FbFiberContext(r4)
stw r29, CxGpr29+FbFiberContext(r4)
stw r30, CxGpr30+FbFiberContext(r4)
stw r31, CxGpr31+FbFiberContext(r4)
//
// Save nonvolatile float state.
//
stfd f14, CxFpr14+FbFiberContext(r4)
stfd f15, CxFpr15+FbFiberContext(r4)
stfd f16, CxFpr16+FbFiberContext(r4)
stfd f17, CxFpr17+FbFiberContext(r4)
stfd f18, CxFpr18+FbFiberContext(r4)
stfd f19, CxFpr19+FbFiberContext(r4)
stfd f20, CxFpr20+FbFiberContext(r4)
stfd f21, CxFpr21+FbFiberContext(r4)
stfd f22, CxFpr22+FbFiberContext(r4)
stfd f23, CxFpr23+FbFiberContext(r4)
stfd f24, CxFpr24+FbFiberContext(r4)
stfd f25, CxFpr25+FbFiberContext(r4)
stfd f26, CxFpr26+FbFiberContext(r4)
stfd f27, CxFpr27+FbFiberContext(r4)
stfd f28, CxFpr28+FbFiberContext(r4)
stfd f29, CxFpr29+FbFiberContext(r4)
stfd f30, CxFpr30+FbFiberContext(r4)
stfd f31, CxFpr31+FbFiberContext(r4)
//
// Save stack pointer and return address of current fiber.
//
stw r1, CxGpr1+FbFiberContext(r4)
stw r0, CxIar+FbFiberContext(r4)
//
// Restore the stack base, stack limit, and deallocation stack address of the
// new fiber.
//
lwz r5, FbStackBase(r3)
lwz r6, FbStackLimit(r3)
lwz r7, FbDeallocationStack(r3)
lwz r0, CxIar+FbFiberContext(r3) // get return address for new fiber
stw r5, TeStackBase(r13)
stw r6, TeStackLimit(r13)
stw r7, TeDeallocationStack(r13)
//
// Restore nonvolatile integer state.
//
lwz r14, CxGpr14+FbFiberContext(r3)
lwz r15, CxGpr15+FbFiberContext(r3)
lwz r16, CxGpr16+FbFiberContext(r3)
lwz r17, CxGpr17+FbFiberContext(r3)
lwz r18, CxGpr18+FbFiberContext(r3)
lwz r19, CxGpr19+FbFiberContext(r3)
lwz r20, CxGpr20+FbFiberContext(r3)
lwz r21, CxGpr21+FbFiberContext(r3)
lwz r22, CxGpr22+FbFiberContext(r3)
lwz r23, CxGpr23+FbFiberContext(r3)
lwz r24, CxGpr24+FbFiberContext(r3)
lwz r25, CxGpr25+FbFiberContext(r3)
lwz r26, CxGpr26+FbFiberContext(r3)
lwz r27, CxGpr27+FbFiberContext(r3)
lwz r28, CxGpr28+FbFiberContext(r3)
lwz r29, CxGpr29+FbFiberContext(r3)
lwz r30, CxGpr30+FbFiberContext(r3)
lwz r31, CxGpr31+FbFiberContext(r3)
//
// Restore nonvolatile float state.
//
lfd f14, CxFpr14+FbFiberContext(r3)
lfd f15, CxFpr15+FbFiberContext(r3)
lfd f16, CxFpr16+FbFiberContext(r3)
lfd f17, CxFpr17+FbFiberContext(r3)
lfd f18, CxFpr18+FbFiberContext(r3)
lfd f19, CxFpr19+FbFiberContext(r3)
lfd f20, CxFpr20+FbFiberContext(r3)
lfd f21, CxFpr21+FbFiberContext(r3)
lfd f22, CxFpr22+FbFiberContext(r3)
lfd f23, CxFpr23+FbFiberContext(r3)
lfd f24, CxFpr24+FbFiberContext(r3)
lfd f25, CxFpr25+FbFiberContext(r3)
lfd f26, CxFpr26+FbFiberContext(r3)
lfd f27, CxFpr27+FbFiberContext(r3)
lfd f28, CxFpr28+FbFiberContext(r3)
lfd f29, CxFpr29+FbFiberContext(r3)
lfd f30, CxFpr30+FbFiberContext(r3)
lfd f31, CxFpr31+FbFiberContext(r3)
//
// Restore stack pointer and return address of new fiber.
//
lwz r1, CxGpr1+FbFiberContext(r3)
mtlr r0
//
// Set address of new fiber and continue execution in new fiber.
//
stw r3, TeFiberData(r13)
LEAF_EXIT(SwitchToFiber)