summaryrefslogtreecommitdiffstats
path: root/private/ntos/dll/mips
diff options
context:
space:
mode:
Diffstat (limited to 'private/ntos/dll/mips')
-rw-r--r--private/ntos/dll/mips/critsect.s307
-rw-r--r--private/ntos/dll/mips/evpair.s63
-rw-r--r--private/ntos/dll/mips/ldrthunk.s98
-rw-r--r--private/ntos/dll/mips/sources6
4 files changed, 474 insertions, 0 deletions
diff --git a/private/ntos/dll/mips/critsect.s b/private/ntos/dll/mips/critsect.s
new file mode 100644
index 000000000..c039c4381
--- /dev/null
+++ b/private/ntos/dll/mips/critsect.s
@@ -0,0 +1,307 @@
+// TITLE("Enter and Leave Critical Section")
+//++
+//
+// Copyright (c) 1991 Microsoft Corporation
+//
+// Module Name:
+//
+// critsect.s
+//
+// Abstract:
+//
+// This module implements functions to support user mode critical sections.
+//
+// Author:
+//
+// David N. Cutler 1-May-1992
+//
+// Environment:
+//
+// Any mode.
+//
+// Revision History:
+//
+//--
+
+#include "ksmips.h"
+
+ SBTTL("Enter Critical Section")
+//++
+//
+// NTSTATUS
+// RtlEnterCriticalSection(
+// IN PRTL_CRITICAL_SECTION CriticalSection
+// )
+//
+// Routine Description:
+//
+// This function enters a critical section.
+//
+// N.B. This function is duplicated in the runtime library.
+//
+// Arguments:
+//
+// CriticalSection (a0) - Supplies a pointer to a critical section.
+//
+// Return Value:
+//
+// STATUS_SUCCESS is returned as the function value.
+//
+//--
+
+ .struct 0
+ .space 4 * 4 // argument save area
+ .space 3 * 4 // fill
+EcRa: .space 4 // saved return address
+EcFrameLength: // length of stack frame
+EcA0: .space 4 // saved critical section address
+EcA1: .space 4 // saved unique thread id
+
+ NESTED_ENTRY(RtlEnterCriticalSection, EcFrameLength, zero)
+
+ subu sp,sp,EcFrameLength // allocate stack frame
+ sw ra,EcRa(sp) // save return address
+
+ PROLOGUE_END
+
+//
+// Attempt to enter the critical section.
+//
+
+10: ll v0,CsLockCount(a0) // get addend value
+ addu v0,v0,1 // increment addend value
+ move t0,v0 // copy updated value
+ sc t0,CsLockCount(a0) // store conditionally
+ beq zero,t0,10b // if eq, store failed
+
+//
+// If the critical section is not already owned, then initialize the owner
+// thread id, initialize the recursion count, and return a success status.
+//
+
+ li t0,UsPcr // get user PCR page address
+ lw t0,PcTeb(t0) // get address of current TEB
+ lw a1,TeClientId + 4(t0) // get current thread unique id
+ bne zero,v0,20f // if ne, lock already owned
+
+ sw a1,CsOwningThread(a0) // set critical section owner
+ li v0,STATUS_SUCCESS // set return status
+ lw ra,EcRa(sp) // restore return address
+ addu sp,sp,EcFrameLength // deallocate stack frame
+ j ra // return
+
+//
+// The critical section is owned. If the current thread is the owner, then
+// increment the recursion count, and return a success status. Otherwise,
+/// wit for critical section ownership.
+//
+
+20: lw t0,CsOwningThread(a0) // get unique id of owner thread
+ bne t0,a1,30f // if ne, current thread not owner
+ lw t0,CsRecursionCount(a0) // increment the recursion count
+ addu t0,t0,1 //
+ sw t0,CsRecursionCount(a0) //
+ li v0,STATUS_SUCCESS // set return status
+ lw ra,EcRa(sp) // restore return address
+ addu sp,sp,EcFrameLength // deallocate stack frame
+ j ra // return
+
+//
+// The critical section is owned by a thread other than the current thread.
+// Wait for ownership of the critical section.
+
+30: sw a0,EcA0(sp) // save address of critical section
+ sw a1,EcA1(sp) // save unique thread id
+ jal RtlpWaitForCriticalSection // wait for critical section
+ lw a0,EcA0(sp) // restore address of critical section
+ lw a1,EcA1(sp) // restore unique thread id
+ sw a1,CsOwningThread(a0) // set critical section owner
+ li v0,STATUS_SUCCESS // set return status
+ lw ra,EcRa(sp) // restore return address
+ addu sp,sp,EcFrameLength // deallocate stack frame
+ j ra // return
+
+ .end RtlEnterCriticalSection
+
+ SBTTL("Leave Critical Section")
+//++
+//
+// NTSTATUS
+// RtlLeaveCriticalSection(
+// IN PRTL_CRITICAL_SECTION CriticalSection
+// )
+//
+// Routine Description:
+//
+// This function leaves a critical section.
+//
+// N.B. This function is duplicated in the runtime library.
+//
+// Arguments:
+//
+// CriticalSection (a0)- Supplies a pointer to a critical section.
+//
+// Return Value:
+//
+// STATUS_SUCCESS is returned as the function value.
+//
+//--
+
+ .struct 0
+ .space 4 * 4 // argument save area
+ .space 3 * 4 // fill
+LcRa: .space 4 // saved return address
+LcFrameLength: // length of stack frame
+LcA0: .space 4 // saved critical section address
+
+ NESTED_ENTRY(RtlLeaveCriticalSection, LcFrameLength, zero)
+
+ subu sp,sp,LcFrameLength // allocate stack frame
+ sw ra,LcRa(sp) // save return address
+
+ PROLOGUE_END
+
+//
+// If the current thread is not the owner of the critical section, then
+// raise an exception.
+//
+
+#if DBG
+
+ li t0,UsPcr // get user PCR page address
+ lw t0,PcTeb(t0) // get address of current TEB
+ lw t1,CsOwningThread(a0) // get owning thread unique id
+ lw a1,TeClientId + 4(t0) // get current thread unique id
+ beq a1,t1,10f // if eq, current thread is owner
+ jal RtlpNotOwnerCriticalSection // raise exception
+ li v0,STATUS_INVALID_OWNER // set completion status
+ lw ra,LcRa(sp) // restore return address
+ addu sp,sp,LcFrameLength // deallocate stack frame
+ j ra // return
+
+#endif
+
+//
+// Decrement the recursion count. If the result is zero, then the lock
+// is no longer onwed.
+//
+
+10: lw t0,CsRecursionCount(a0) // decrement recursion count
+ subu t0,t0,1 //
+ bgez t0,30f // if gez, lock still owned
+ sw zero,CsOwningThread(a0) // clear owner thread id
+
+//
+// Decrement the lock count and check if a waiter should be continued.
+//
+
+20: ll v0,CsLockCount(a0) // get addend value
+ subu v0,v0,1 // decrement addend value
+ move t0,v0 // copy updated value
+ sc t0,CsLockCount(a0) // store conditionally
+ beq zero,t0,20b // if eq, store failed
+ bltz v0,50f // if ltz, no waiter present
+ jal RtlpUnWaitCriticalSection // unwait thread
+ li v0,STATUS_SUCCESS // set completion status
+ lw ra,LcRa(sp) // restore return address
+ addu sp,sp,LcFrameLength // deallocate stack frame
+ j ra // return
+
+//
+// Decrement the lock count and return a success status since the lock
+// is still owned.
+//
+
+30: sw t0,CsRecursionCount(a0) //
+40: ll v0,CsLockCount(a0) // get addend value
+ subu v0,v0,1 // decrement addend value
+ sc v0,CsLockCount(a0) // store conditionally
+ beq zero,v0,40b // if eq, store failed
+50: li v0,STATUS_SUCCESS // set completion status
+ lw ra,LcRa(sp) // restore return address
+ addu sp,sp,LcFrameLength // deallocate stack frame
+ j ra // return
+
+ .end RtlLeaveCriticalSection
+
+
+ SBTTL("Try to Enter Critical Section")
+//++
+//
+// BOOL
+// RtlTryEnterCriticalSection(
+// IN PRTL_CRITICAL_SECTION CriticalSection
+// )
+//
+// Routine Description:
+//
+// This function attempts to enter a critical section without blocking.
+//
+// Arguments:
+//
+// CriticalSection (a0) - Supplies a pointer to a critical section.
+//
+// Return Value:
+//
+// If the critical section was successfully entered, then a value of TRUE
+// is returned as the function value. Otherwise, a value of FALSE is returned.
+//
+//--
+
+ LEAF_ENTRY(RtlTryEnterCriticalSection)
+
+ li v0,UsPcr // get user PCR page address
+ lw v0,PcTeb(v0) // get address of current TEB
+ lw a1,TeClientId + 4(v0) // get current thread unique id
+
+//
+// Attempt to enter the critical section.
+//
+
+10: ll t0,CsLockCount(a0) // get addend value - locked
+ addu t1,t0,1 // increment addend value
+ bne zero,t1,20f // critical section owned
+ sc t1,CsLockCount(a0) // store conditionally
+ beq zero,t1,10b // if lock-flag eq zero, store failed
+
+//
+// The critical section is now owned by this thread. Initialize the owner
+// thread id and return a successful status.
+//
+ sw a1,CsOwningThread(a0) // set critical section owner
+ li v0,TRUE // set success status
+ j ra // return
+
+//
+// The critical section is already owned. If it is owned by another thread,
+// return FALSE immediately. If it is owned by this thread, we must increment
+// the lock count here.
+//
+
+20: lw t2,CsOwningThread(a0) // get current owner
+ beq t2,a1,30f // if eq, this thread is already the owner
+ li v0,FALSE // set failure status
+ j ra // return
+
+//
+// This thread is already the owner of the critical section. Perform an atomic
+// increment of the LockCount and a normal increment of the RecursionCount and
+// return success.
+//
+
+30: ll t0,CsLockCount(a0) // get addend value - locked
+ addu t1,t0,1 // increment addend value
+ sc t1,CsLockCount(a0) // store conditionally
+ beq zero,t1,30b // if eqz, store failed
+
+//
+// Increment the recursion count
+//
+
+ lw t0,CsRecursionCount(a0) //
+ addu t1,t0,1 //
+ sw t1,CsRecursionCount(a0) //
+ li v0,TRUE // set success status
+ j ra // return
+
+ .end RtlTryEnterCriticalSection
diff --git a/private/ntos/dll/mips/evpair.s b/private/ntos/dll/mips/evpair.s
new file mode 100644
index 000000000..f5cd33c9e
--- /dev/null
+++ b/private/ntos/dll/mips/evpair.s
@@ -0,0 +1,63 @@
+#if defined(R4000)
+
+// TITLE("Fast Event Pair Support")
+//++
+//
+// Copyright (c) 1992 Microsoft Corporation
+//
+// Module Name:
+//
+// evpair.s
+//
+// Abstract:
+//
+// This module contains the system call interface for the fast event pair
+// system service that is used from the client side.
+//
+// Author:
+//
+// David N. Cutler (davec) 29-Oct-1992
+//
+// Environment:
+//
+// Kernel mode.
+//
+// Revision History:
+//
+//--
+
+#include "ksmips.h"
+ SBTTL("Set Low Wait High Thread")
+//++
+//
+// NTSTATUS
+// XySetLowWaitHighThread (
+// )
+//
+// Routine Description:
+//
+// This function calls the fast event pair system service.
+//
+// N.B. The return from this routine is directly to the caller.
+//
+// Arguments:
+//
+// None.
+//
+// Return Value:
+//
+// STATUS_NO_EVENT_PAIR is returned if no event pair is associated with
+// the current thread. Otherwise, the status of the wait operation is
+// returned as the function value.
+//
+//
+//--
+
+ LEAF_ENTRY(XySetLowWaitHighThread)
+
+ li v0,SET_LOW_WAIT_HIGH // call system service
+ syscall //
+
+ .end XySetLowWaitHighThread
+
+#endif
diff --git a/private/ntos/dll/mips/ldrthunk.s b/private/ntos/dll/mips/ldrthunk.s
new file mode 100644
index 000000000..14acce0a6
--- /dev/null
+++ b/private/ntos/dll/mips/ldrthunk.s
@@ -0,0 +1,98 @@
+// TITLE("LdrInitializeThunk")
+//++
+//
+// Copyright (c) 1989 Microsoft Corporation
+//
+// Module Name:
+//
+// ldrthunk.s
+//
+// Abstract:
+//
+// This module implements the thunk for the LdrpInitialize APC routine.
+//
+// Author:
+//
+// Steven R. Wood (stevewo) 27-Apr-1990
+//
+// Environment:
+//
+// Any mode.
+//
+// Revision History:
+//
+//--
+
+#include "ksmips.h"
+
+//++
+//
+// VOID
+// LdrInitializeThunk(
+// IN PVOID NormalContext,
+// IN PVOID SystemArgument1,
+// IN PVOID SystemArgument2
+// )
+//
+// Routine Description:
+//
+// This function computes a pointer to the context record on the stack
+// and jumps to the LdrpInitialize function with that pointer as its
+// parameter.
+//
+// Arguments:
+//
+// NormalContext (a0) - User Mode APC context parameter (ignored).
+//
+// SystemArgument1 (a1) - User Mode APC system argument 1 (ignored).
+//
+// SystemArgument2 (a2) - User Mode APC system argument 2 (ignored).
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(LdrInitializeThunk)
+
+ .set noreorder
+ .set noat
+ j LdrpInitialize // Jump to LdrpInitialize
+ move a0,sp // Get address of context record
+ .set at
+ .set reorder
+
+ .end LdrInitializeThunk
+
+//++
+//
+// VOID
+// LdrpSetGp(
+// IN ULONG GpValue
+// )
+//
+// Routine Description:
+//
+// This function sets the value of the Gp register.
+//
+// Arguments:
+//
+// GpValue (a0) - Supplies the value for Gp
+//
+// Return Value:
+//
+// None.
+//
+//--
+
+ LEAF_ENTRY(LdrpSetGp)
+
+ .set noreorder
+ .set noat
+ j ra
+ move gp,a0
+ .set at
+ .set reorder
+
+ .end LdrpSetGp
diff --git a/private/ntos/dll/mips/sources b/private/ntos/dll/mips/sources
new file mode 100644
index 000000000..e401e22c6
--- /dev/null
+++ b/private/ntos/dll/mips/sources
@@ -0,0 +1,6 @@
+MIPS_DLLLIBOBJECTS=..\..\rtl\user\obj\mips\chkstk.obj
+
+MIPS_SOURCES=..\mips\critsect.s \
+ ..\mips\evpair.s \
+ mips\usrstubs.s \
+ ..\mips\ldrthunk.s