diff options
author | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
---|---|---|
committer | Adam <you@example.com> | 2020-05-17 05:51:50 +0200 |
commit | e611b132f9b8abe35b362e5870b74bce94a1e58e (patch) | |
tree | a5781d2ec0e085eeca33cf350cf878f2efea6fe5 /private/mvdm/xms.486 | |
download | NT4.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/mvdm/xms.486')
-rw-r--r-- | private/mvdm/xms.486/alpha/sources | 1 | ||||
-rw-r--r-- | private/mvdm/xms.486/i386/sources | 3 | ||||
-rw-r--r-- | private/mvdm/xms.486/i386/xmsmem86.c | 155 | ||||
-rw-r--r-- | private/mvdm/xms.486/makefile | 9 | ||||
-rw-r--r-- | private/mvdm/xms.486/mips/sources | 1 | ||||
-rw-r--r-- | private/mvdm/xms.486/ppc/sources | 1 | ||||
-rw-r--r-- | private/mvdm/xms.486/sources | 58 | ||||
-rw-r--r-- | private/mvdm/xms.486/xms.c | 103 | ||||
-rw-r--r-- | private/mvdm/xms.486/xms.h | 156 | ||||
-rw-r--r-- | private/mvdm/xms.486/xmsa20.c | 106 | ||||
-rw-r--r-- | private/mvdm/xms.486/xmsblock.c | 247 | ||||
-rw-r--r-- | private/mvdm/xms.486/xmsdisp.c | 59 | ||||
-rw-r--r-- | private/mvdm/xms.486/xmsmemr.c | 167 | ||||
-rw-r--r-- | private/mvdm/xms.486/xmsmisc.c | 84 | ||||
-rw-r--r-- | private/mvdm/xms.486/xmsumb.c | 242 |
15 files changed, 1392 insertions, 0 deletions
diff --git a/private/mvdm/xms.486/alpha/sources b/private/mvdm/xms.486/alpha/sources new file mode 100644 index 000000000..3d33411fb --- /dev/null +++ b/private/mvdm/xms.486/alpha/sources @@ -0,0 +1 @@ +ALPHA_SOURCES=..\xmsmemr.c diff --git a/private/mvdm/xms.486/i386/sources b/private/mvdm/xms.486/i386/sources new file mode 100644 index 000000000..324c67cb3 --- /dev/null +++ b/private/mvdm/xms.486/i386/sources @@ -0,0 +1,3 @@ + +i386_SOURCES=i386\xmsmem86.c + diff --git a/private/mvdm/xms.486/i386/xmsmem86.c b/private/mvdm/xms.486/i386/xmsmem86.c new file mode 100644 index 000000000..b3f82e122 --- /dev/null +++ b/private/mvdm/xms.486/i386/xmsmem86.c @@ -0,0 +1,155 @@ +/*++ + +Copyright (c) 1992 Microsoft Corporation + +Module Name: + + xmscmt86.c + +Abstract: + + This module conains the memory commit/decommit routines + for x86. + +Author: + + Dave Hastings (daveh) creation-date 25-Jan-1994 + +Revision History: + + +--*/ +#include <xms.h> +#include <suballoc.h> + +NTSTATUS +xmsCommitBlock( + ULONG BaseAddress, + ULONG Size + ) +/*++ + +Routine Description: + + This routine commits a block of memory using NtAllocateVirtualMemory. + +Arguments: + + BaseAddress -- Supplies the base address to commit memory at + Size -- Supplies the size of the block to commit + +Return Value: + + Same as NtAllocateVirtualMemory. + +--*/ +{ + PVOID Address; + ULONG s; + NTSTATUS Status; + + // + // Copy the parameters locally, so that MM doesn't + // change them for us + // + Address = (PVOID)BaseAddress; + s = Size; + + // + // Perform the allocation + // + Status = NtAllocateVirtualMemory( + NtCurrentProcess(), + &Address, + 0L, + &s, + MEM_COMMIT, + PAGE_READWRITE + ); + + return Status; +} + +NTSTATUS +xmsDecommitBlock( + ULONG BaseAddress, + ULONG Size + ) +/*++ + +Routine Description: + + This routine commits a block of memory using NtAllocateVirtualMemory. + +Arguments: + + BaseAddress -- Supplies the base address to decommit memory at + Size -- Supplies the size of the block to decommit + +Return Value: + + Same as NtFreeVirtualMemory. + +--*/ +{ + PVOID Address; + ULONG s; + NTSTATUS Status; + + // + // Copy the parameters locally, so that MM doesn't + // change them for us + // + Address = (PVOID)BaseAddress; + s = Size; + + // + // Perform the allocation + // + Status = NtFreeVirtualMemory( NtCurrentProcess(), + &Address, + &s, + MEM_DECOMMIT + ); + + return Status; +} + +VOID +xmsMoveMemory( + ULONG Destination, + ULONG Source, + ULONG Count + ) +/*++ + +Routine Description: + + This routine moves a block of memory, and notifies the emulator. + It correctly handles overlapping source and destination + +Arguments: + + Destination -- Supplies a pointer to the destination Linear + Address + Source -- Supplies a pointer to the source Linear Address + Count -- Supplies the number of bytes to move + +Return Value: + + None. + +--*/ +{ + + // + // Move the memory + // + RtlMoveMemory( + (PVOID)Destination, + (PVOID)Source, + Count + ); + +} + diff --git a/private/mvdm/xms.486/makefile b/private/mvdm/xms.486/makefile new file mode 100644 index 000000000..445b289cb --- /dev/null +++ b/private/mvdm/xms.486/makefile @@ -0,0 +1,9 @@ +# XMS makefile +# 15-May-1991 Sudeep Bharati Created +# + +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/private/mvdm/xms.486/mips/sources b/private/mvdm/xms.486/mips/sources new file mode 100644 index 000000000..c0ccd5e5a --- /dev/null +++ b/private/mvdm/xms.486/mips/sources @@ -0,0 +1 @@ +MIPS_SOURCES=..\xmsmemr.c diff --git a/private/mvdm/xms.486/ppc/sources b/private/mvdm/xms.486/ppc/sources new file mode 100644 index 000000000..4dae141e4 --- /dev/null +++ b/private/mvdm/xms.486/ppc/sources @@ -0,0 +1 @@ +PPC_SOURCES=..\xmsmemr.c diff --git a/private/mvdm/xms.486/sources b/private/mvdm/xms.486/sources new file mode 100644 index 000000000..39181db06 --- /dev/null +++ b/private/mvdm/xms.486/sources @@ -0,0 +1,58 @@ +!IF 0 + +Copyright (c) 1989-1991 Microsoft Corporation + +Module Name: + + sources. + +Abstract: + + This file specifies the target component being built and the list of + sources files needed to build that component. Also specifies optional + compiler switches and libraries that are unique for the component being + built. + + +History: + Created 15-May-1991 by Sudeep Bharati (sudeepb) + from template created 12-Apr-1990 by Steve Wood (stevewo) + + +NOTE: Commented description of this file is in \nt\public\oak\bin\sources.tpl + +!ENDIF + +MAJORCOMP=mvdm +MINORCOMP=xms + +TARGETNAME=xms486 +TARGETPATH=\nt\public\sdk\lib +TARGETTYPE=LIBRARY +TARGETLIBS= + +SOFTPC_TREE=$(BASEDIR)\private\mvdm\softpc.new + +INCLUDES=..\inc;$(SOFTPC_TREE)\base\inc + +!IF $(ALPHA) || $(MIPS) +GPSIZE=0 +!ELSE +GPSIZE=32 +!ENDIF + + +NTPROFILEINPUT=YES + +SOURCES=xms.c \ + xmsa20.c \ + xmsblock.c \ + xmsdisp.c \ + xmsmisc.c \ + xmsumb.c + +C_DEFINES=-DWIN_32 + +UMTYPE=console +UMTEST= +UMLIBS= diff --git a/private/mvdm/xms.486/xms.c b/private/mvdm/xms.486/xms.c new file mode 100644 index 000000000..841513b42 --- /dev/null +++ b/private/mvdm/xms.486/xms.c @@ -0,0 +1,103 @@ +/* + * xms.c - Main Module of XMS DLL. + * + * Sudeepb 15-May-1991 Craeted + * williamh 25-Sept-1992 added UMB support + * williamh 10-10-1992 added A20 line support + */ + +#include <xms.h> +#include <suballoc.h> +#include "umb.h" +#include "memapi.h" + +/* XMSInit - XMS Initialiazation routine. (This name may change when XMS is + * converted to DLL). + * + * Entry + * None + * + * Exit + * None + */ + +ULONG xmsMemorySize = (ULONG)0; // Total XMS meory in K + +extern BOOL VDMForWOW; + +PVOID ExtMemSA; + +BOOL XMSInit (int argc, char *argv[]) +{ + DWORD Size; + PVOID Address; + ULONG VdmAddress, XmsSize; + NTSTATUS Status; + + if (!xmsMemorySize) + return FALSE; + + Size = 0; + Address = NULL; + // commit all free UMBs. + ReserveUMB(UMB_OWNER_RAM, &Address, &Size); + + XmsSize = xmsMemorySize * 1024 - (64*1024); + +#ifndef i386 + Status = VdmAllocateVirtualMemory(&VdmAddress, + XmsSize, + FALSE); + + if (Status == STATUS_NOT_IMPLEMENTED) { + + // Old emulator, just assume base address +#endif ; //i386 + // + // Initialize the sub allocator + // + ExtMemSA = SAInitialize( + 1024 * 1024 + 64*1024, + XmsSize, + xmsCommitBlock, + xmsDecommitBlock, + xmsMoveMemory + ); + +#ifndef i386 + } else { + + // + // New emulator. Make sure the reserve worked + // + + if (!NT_SUCCESS(Status)) { + ASSERT(FALSE); + return FALSE; + } + + // + // We only work correctly if emulator returned this value + // + if (VdmAddress != (1024 * 1024 + 64*1024)) { + ASSERT(FALSE); + return FALSE; + } + + ExtMemSA = SAInitialize( + VdmAddress, + XmsSize, + VdmCommitVirtualMemory, + VdmDeCommitVirtualMemory, + xmsMoveMemory + ); + + } +#endif // i386 + + if (ExtMemSA == NULL) { + return FALSE; + } + + return TRUE; +} diff --git a/private/mvdm/xms.486/xms.h b/private/mvdm/xms.486/xms.h new file mode 100644 index 000000000..dc9280271 --- /dev/null +++ b/private/mvdm/xms.486/xms.h @@ -0,0 +1,156 @@ +/* xms.h - main include file for dem + * + * Modification History + * + * Sudeepb 31-Mar-1991 Created + * + * williamh 25-Sept-1992 Added UMB support + */ + +/* +#define WIN +#define FLAT_32 +#include <nt.h> +#include <ntrtl.h> +#include <nturtl.h> + +#define _WINDOWS +#include <windows.h> + +*/ + +#ifdef DOS +#define SIGNALS +#endif + +#ifdef OS2_16 +#define OS2 +#define SIGNALS +#endif + +#ifdef OS2_32 +#define OS2 +#define FLAT_32 +#endif + +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <malloc.h> +#include <process.h> + +#ifdef WIN_16 +#define WIN +#define API16 +#endif + +#ifdef WIN_32 +#define WIN +#define FLAT_32 +#define TRUE_IF_WIN32 1 +#include <nt.h> +#include <ntrtl.h> +#include <nturtl.h> +#else +#define TRUE_IF_WIN32 0 +#endif + +#ifdef FLAT_32 +#ifndef i386 +#define ALIGN_32 +#else +#define NOALIGN_32 +#endif +#endif + +#ifdef WIN +#define _WINDOWS +#include <windows.h> +#endif + +#ifdef SIGNALS +#include <conio.h> +#include <signal.h> +#endif + +#ifdef OS2_32 +#include <excpt.h> +#define XCPT_SIGNAL 0xC0010003 +#endif +#include <xmsexp.h> +#include <suballoc.h> + +#define SIZE_PARAGRAPH 16 +#define XMSUMB_THRESHOLD 3 * SIZE_PARAGRAPH + +/** Basic Typedefs of XMS **/ + +typedef VOID (*PFNSVC)(VOID); + +typedef struct _ExtMemMove { + ULONG mm_len; // Move Length + USHORT mm_hSource; // Source Handle + ULONG mm_SourceOffset; // Source Offset + USHORT mm_hDest; // Dest Handle + ULONG mm_DestOffset; // Dest. offset +} EXTMEMMOVE, *PEXTMEMMOVE; + + +typedef struct _XMSUMB_ { + WORD Segment; + WORD Size; + WORD Owner; + struct _XMSUMB_ *Next; +} XMSUMB, *PXMSUMB; + +/** Function Prototypes */ + +VOID xmsA20 (VOID); +VOID xmsAllocBlock (VOID); +VOID xmsFreeBlock (VOID); +VOID xmsReallocBlock (VOID); +VOID xmsMoveBlock (VOID); +VOID xmsSysPageSize (VOID); +VOID xmsQueryExtMem (VOID); +VOID xmsQueryFreeExtMem (VOID); +ULONG xmsGetMemorySize (BOOL); +ULONG xmsGetDefaultVDMSize (VOID); +VOID xmsInitUMB (VOID); +VOID xmsRequestUMB (VOID); +VOID xmsReleaseUMB (VOID); +VOID xmsReleaseUMBNotify (PVOID, ULONG); +VOID xmsInsertUMB (PVOID, ULONG); +VOID xmsNotifyHookI15 (VOID); + +VOID xmsDisableA20Wrapping (VOID); +VOID xmsEnableA20Wrapping (VOID); + +NTSTATUS +xmsCommitBlock( + ULONG BaseAddress, + ULONG Size + ); + +NTSTATUS +xmsDecommitBlock( + ULONG BaseAddress, + ULONG Size + ); + +VOID +xmsMoveMemory( + ULONG Source, + ULONG Destination, + ULONG Count + ); + + +#ifndef i386 +BOOL sas_manage_xms (VOID * start_addr, ULONG cb, INT a_or_f); +#endif + +/** External Data */ + +extern ULONG xmsMemorySize; +extern BYTE * pHimemA20State; diff --git a/private/mvdm/xms.486/xmsa20.c b/private/mvdm/xms.486/xmsa20.c new file mode 100644 index 000000000..d52aa1d48 --- /dev/null +++ b/private/mvdm/xms.486/xmsa20.c @@ -0,0 +1,106 @@ +/* xmsa20.c - A20 related XMS routines + * + * XMSA20 + * + * Modification History: + * + * Sudeepb 15-May-1991 Created + */ + +#include "xms.h" + +#include <xmssvc.h> +#include <softpc.h> + +void sas_enable_20_bit_wrapping(void); +void sas_disable_20_bit_wrapping(void); +BOOL sas_twenty_bit_wrapping_enabled(void); + +BYTE * pHimemA20State = NULL; + + +/* xmsA20 - Handle A20 requests + * + * + * Entry - Client (AX) 0 - Disable A20 + * 1 - Enable A20 + * 2 - Query + * + * Exit + * SUCCESS + * Client (AX) = 1 + * if on entry AX=2 Then + * Cleint (AX) =1 means was enabled + * Cleint (AX) =0 means was disabled + * + * FAILURE + * Client (AX) = 0 + */ + +VOID xmsA20 (VOID) +{ + int reason; + + reason = getAX(); + + setAX(1); + + if (reason == 0) + xmsEnableA20Wrapping(); + else if (reason == 1) + xmsDisableA20Wrapping(); + else if (reason == 2) { + if (sas_twenty_bit_wrapping_enabled()) + setAX(0); + setBL(0); + } + else + setAX(0); +} +// function to enable 1MB wrapping (turn off A20 line) +VOID xmsEnableA20Wrapping(VOID) +{ + sas_enable_20_bit_wrapping(); + if (pHimemA20State != NULL) + *pHimemA20State = 0; + +#if 0 // this is not necessay because the intel space(pointed by + // HimemA20State) doesn't contain instruction + // doesn't contain instruction +#ifdef MIPS + Sim32FlushVDMPointer + ( + (((ULONG)pHimemA20State >> 4) << 16) | ((ULONG)pHimemA20State & 0xF), + 1, + pHimemA20State, + FALSE + ); + +#endif +#endif + +} + +// function to disable 1MB wrapping(turn on A20 line) +VOID xmsDisableA20Wrapping(VOID) +{ + + sas_disable_20_bit_wrapping(); + if (pHimemA20State != NULL) + *pHimemA20State = 1; +#if 0 // this is not necessay because the intel space(pointed by + // HimemA20State) doesn't contain instruction + // doesn't contain instruction +#ifdef MIPS + Sim32FlushVDMPointer + ( + (((ULONG)pHimemA20State >> 4) << 16) | ((ULONG)pHimemA20State & 0xF), + 1, + pHimemA20State, + FALSE + ); + +#endif +#endif + +} diff --git a/private/mvdm/xms.486/xmsblock.c b/private/mvdm/xms.486/xmsblock.c new file mode 100644 index 000000000..8eb2818c9 --- /dev/null +++ b/private/mvdm/xms.486/xmsblock.c @@ -0,0 +1,247 @@ +/* xmsblock.c - XMS Extended block related routines + * + * xmsAllocBlock + * xmsFreeBlock + * xmsReallocBlock + * xmsMoveBlock + * xmsQueryExtMem + * + * Modification History: + * + * Sudeepb 15-May-1991 Created + */ + +#include "xms.h" +#include <memory.h> +#include <string.h> +#include <xmssvc.h> +#include <softpc.h> +#include <mvdm.h> + + +/* xmsAllocBlock - Commit Memory for an EMB. + * + * + * Entry - DX - Size in K to allocate + * + * Exit + * SUCCESS + * Client (AX) - Start address of the EMB (in K) + * + * FAILURE + * Client (AX) = 0 + */ + +VOID xmsAllocBlock (VOID) +{ +BOOL Success; +ULONG BaseAddress; +ULONG size; + + size = getDX() * 1024; + if(size) { + + // + // Ask for a chunk of memory + // + Success = SAAllocate( + ExtMemSA, + size, + &BaseAddress + ); + + if (!Success) { + DbgPrint("xmsAllocBlock:SAAlloc failed !!!!\n"); + setAX(0); + return; + } + } + + ASSERT((USHORT)(BaseAddress / 1024) < 65535); + setAX((USHORT)(BaseAddress / 1024)); + return; +} + +/* xmsFreeBlock - Free Memory for an EMB. + * + * + * Entry - AX - Start address of the EMB (in K) + * DX - Size in K to free + * + * Exit + * SUCCESS + * Client (AX) = 1 + * + * FAILURE + * Client (AX) = 0 + */ + +VOID xmsFreeBlock (VOID) +{ +BOOL Success; +ULONG BaseAddress; +ULONG size; + + BaseAddress = (getAX() * 1024); + size = getDX() * 1024; + + Success = SAFree( + ExtMemSA, + size, + BaseAddress + ); + + if (!Success) { + DbgPrint("xmsFreeBlock:SAFree failed !!!!"); + setAX(0); + return; + } + + setAX(1); + return; +} + +/* xmsReallocBlock - Change the size of an EMB. + * + * + * Entry - AX - Start address of the EMB (in K) + * DX - Original Size in K + * BX - New size in K + * + * Exit + * SUCCESS + * Client (CX) = New base of block + * + * FAILURE + * Client (AX) = 0 + */ + +VOID xmsReallocBlock (VOID) +{ +BOOL Success; +ULONG BaseAddress; +ULONG NewAddress; +ULONG size; +ULONG NewSize; + + size = getDX() * 1024; + NewSize = getBX() * 1024; + BaseAddress = getAX() * 1024; + if(size != NewSize) { + + // + // Realloc the chunk of memory + // + Success = SAReallocate( + ExtMemSA, + size, + BaseAddress, + NewSize, + &NewAddress + ); + + if (!Success) { + DbgPrint("xmsReallocBlock:SARealloc failed !!!!\n"); + setCX(0); + return; + } + } + + ASSERT((NewAddress / 1024) < 65535); + setCX((USHORT)(NewAddress / 1024)); + return; +} + +/* xmsMoveBlock - Process Move Block Functions + * + * + * Entry - Client (SS:BP) Pointer to Ext. Memory Move Structure + * SS:BP-4 = DWORD Transfer Count in words (guaranteed even) + * SS:BP-8 = DWORD Src Linear Address + * SS:BP-12 = DWORD Dst Linear Address + * + * Exit + * SUCCESS + * Client (AX) = 1 + * + * FAILURE + * Client (AX) = 0 + * Client (BL) = error code + * + * NOTE: For Overlapping regions XMS spec says "If the Source and + * Destination blocks overlap, only forward moves (i.e. where + * the destination base is less than the source base) are + * guaranteed to work properly" + */ + +VOID xmsMoveBlock (VOID) +{ +PBYTE pExtMoveInfo,pSrc,pDst; +ULONG cbTransfer,SoftpcBase, DstSegOff; + + pExtMoveInfo = (PBYTE) GetVDMAddr(getSS(),getBP()); + (ULONG)pExtMoveInfo = (ULONG)pExtMoveInfo -4; + cbTransfer = (FETCHDWORD(*(PULONG)pExtMoveInfo)); + cbTransfer *= 2; // Get in bytes + (ULONG)pExtMoveInfo = (ULONG)pExtMoveInfo -4; + (DWORD)pSrc = FETCHDWORD(*(PULONG)pExtMoveInfo); + (ULONG)pExtMoveInfo = (ULONG)pExtMoveInfo -4; + (DWORD)pDst = FETCHDWORD(*(PULONG)pExtMoveInfo); + + // Yes, we could use memmov for handling the overlapping regions + // but XMS spec wants memcpy behaviour. + +#ifdef i386 + RtlCopyMemory (pDst,pSrc,cbTransfer); +#else + SoftpcBase = (ULONG) GetVDMAddr (0,0); + RtlCopyMemory((PVOID)((ULONG)pDst + SoftpcBase), + (PVOID)((ULONG)pSrc + SoftpcBase), + cbTransfer); + // if we touched the intel memory, tell the emulator to flush its cache + // WARNING!!!! Donot use Sim32FlushVDMPoiner unless you know the exact segment + // address. In this case, we have no idea what the segment value is, all we + // know is its "linear address". + // BUGBUG verify whether we can ignore the case with pDst > 0x110000 + sas_overwrite_memory(pDst, cbTransfer); + +#endif + setAX(1); + return; +} + +/* xmsQueryExtMem - Process query extended memory + * + * + * Entry - None + * + * Exit + * SUCCESS + * Client (AX) = Largest Free Block in K + * Client (DX) = Free Memory in K + * + * FAILURE + * Client (AX) = 0 + * Client (DX) = 0 + * + */ +VOID xmsQueryFreeExtMem(VOID) +{ + ULONG LargestFree = 0; + ULONG TotalFree = 0; + + // + // Find out how much memory remains + // + SAQueryFree( + ExtMemSA, + &TotalFree, + &LargestFree + ); + + ASSERT((TotalFree / 1024) < 65534); + setAX((USHORT)(TotalFree / 1024)); + ASSERT((LargestFree / 1024) < 65534); + setDX((USHORT)(LargestFree / 1024)); + +} diff --git a/private/mvdm/xms.486/xmsdisp.c b/private/mvdm/xms.486/xmsdisp.c new file mode 100644 index 000000000..c044159ad --- /dev/null +++ b/private/mvdm/xms.486/xmsdisp.c @@ -0,0 +1,59 @@ +/* + * xmsdisp.c - SVC dispatch module for XMS + * + * Modification History: + * + * Sudeepb 15-May-1991 Created + * + * williamh 25-Sept-1992 Added UMB support + */ + +#include <xms.h> +#include <xmsexp.h> +#include <stdio.h> +#include <softpc.h> +#include <xmssvc.h> + +PFNSVC apfnXMSSvc [] = { + xmsA20, // XMS_A20 + xmsMoveBlock, // XMS_MOVEBLOCK + xmsAllocBlock, // XMS_ALLOCBLOCK + xmsFreeBlock, // XMS_FREEBLOCK + xmsSysPageSize, // XMS_SYSTEMPAGESIZE + xmsQueryExtMem, // XMS_EXTMEM + xmsInitUMB, // XMS_INITUMB + xmsRequestUMB, // XMS_REQUESTUMB + xmsReleaseUMB, // XMS_RELEASEUMB + xmsNotifyHookI15, // XMS_NOTIFYHOOKI15 + xmsQueryFreeExtMem, // XMS_QUERYEXTMEM + xmsReallocBlock // XMS_REALLOCBLOCK +}; + +/* XMSDispatch - Dispatch SVC call to right handler. + * + * Entry - iSvc (SVC byte following SVCop) + * + * Exit - None + * + * Note - Some mechanism has to be worked out to let the emulator know + * about DOSKRNL code segment and size. Using these it will figure + * out whether SVCop (hlt for the moment) has to be passed to + * DEM or to be handled as normal invalid opcode. + */ + +BOOL XMSDispatch (ULONG iSvc) +{ + +#if DBG + + if (iSvc >= XMS_LASTSVC){ + printf("XMS:Unimplemented SVC index %x\n",iSvc); + setCF(1); + return FALSE; + } + +#endif + + (apfnXMSSvc [iSvc])(); + return TRUE; +} diff --git a/private/mvdm/xms.486/xmsmemr.c b/private/mvdm/xms.486/xmsmemr.c new file mode 100644 index 000000000..9a495d671 --- /dev/null +++ b/private/mvdm/xms.486/xmsmemr.c @@ -0,0 +1,167 @@ +/*++ + +Copyright (c) 1992 Microsoft Corporation + +Module Name: + + xmscmt86.c + +Abstract: + + This module conains the memory commit/decommit/move routines + for risc. + +Author: + + Dave Hastings (daveh) creation-date 25-Jan-1994 + +Revision History: + + +--*/ +#include <xms.h> +#include <suballoc.h> +#include <softpc.h> + +NTSTATUS +xmsCommitBlock( + ULONG BaseAddress, + ULONG Size + ) +/*++ + +Routine Description: + + This routine commits a block of memory using sas_manage_xms. + +Arguments: + + BaseAddress -- Supplies the base address to commit memory at + Size -- Supplies the size of the block to commit + +Return Value: + + 0 if successfull + +--*/ +{ + BOOL Status; + + // + // Perform the allocation + // + Status = sas_manage_xms( + (PVOID)BaseAddress, + Size, + 1 + ); + + // + // We elected to have 0 indicate success, because that allows + // us to directly pass back NTSTATUS codes. On x86 we use + // NT memory management to do the commit for us, and the returned + // status code contains more information than just success or failure + // + + if (Status) { + return STATUS_SUCCESS; + } else { + return -1; + } +} + +NTSTATUS +xmsDecommitBlock( + ULONG BaseAddress, + ULONG Size + ) +/*++ + +Routine Description: + + This routine commits a block of memory using sas_manage_xms. + +Arguments: + + BaseAddress -- Supplies the base address to decommit memory at + Size -- Supplies the size of the block to decommit + +Return Value: + + 0 if successful + +--*/ +{ + BOOL Status; + + // + // Perform the allocation + // + Status = sas_manage_xms( + (PVOID)BaseAddress, + Size, + 2 + ); + + // + // We elected to have 0 indicate success, because that allows + // us to directly pass back NTSTATUS codes. On x86 we use + // NT memory management to do the commit for us, and the returned + // status code contains more information than just success or failure + // + if (Status) { + return STATUS_SUCCESS; + } else { + return -1; + } +} + +VOID +xmsMoveMemory( + ULONG Destination, + ULONG Source, + ULONG Count + ) +/*++ + +Routine Description: + + This routine moves a block of memory, and notifies the emulator. + It correctly handles overlapping source and destination + +Arguments: + + Destination -- Supplies a pointer to the destination Intel (NOT Linear) + Address + Source -- Supplies a pointer to the source Intel Address + Count -- Supplies the number of bytes to move + +Return Value: + + None. + +--*/ +{ + ULONG SoftpcBase; + + // + // Get the linear address of the beginning of Intel memory + // + SoftpcBase = (ULONG) GetVDMAddr(0,0); + + // + // Move the memory + // + RtlMoveMemory( + (PVOID)((ULONG)Destination + SoftpcBase), + (PVOID)((ULONG)Source + SoftpcBase), + Count + ); + + // WARNING!!!! Donot use Sim32FlushVDMPoiner unless you know the exact segment + // address. In this case, we have no idea what the segment value is, all we + // know is its "linear address". + + sas_overwrite_memory((PBYTE)Destination, Count); + +} diff --git a/private/mvdm/xms.486/xmsmisc.c b/private/mvdm/xms.486/xmsmisc.c new file mode 100644 index 000000000..9f15120ec --- /dev/null +++ b/private/mvdm/xms.486/xmsmisc.c @@ -0,0 +1,84 @@ +/* xmsmisc.c - Misc. Support Functions for himem. + * + * xmsSysPageSize + * xmsQueryExtMem + * + * Modification History: + * + * Sudeepb 15-May-1991 Created + */ + +#include "xms.h" + +#include <xmssvc.h> +#include <softpc.h> + +extern void UpdateKbdInt15(WORD Seg,WORD Off); + +/* xmsSysPageSize - Get the System Page size. + * + * + * Entry - None + * + * Exit + * SUCCESS + * Client (AX) = Page Size in bytes + * + * FAILURE + * Not Valid + */ + +VOID xmsSysPageSize (VOID) +{ +SYSTEM_INFO SysInfo; + + GetSystemInfo(&SysInfo); + + setAX((USHORT)SysInfo.dwPageSize); + + return; +} + + + +/* xmsQueryExtMem - Get the extended memory for the vdm + * + * + * Entry - None + * + * Exit + * SUCCESS + * Client (AX) = Extended Memory in K + * + * FAILURE + * Not Valid + */ + +VOID xmsQueryExtMem (VOID) +{ + setAX((USHORT)(xmsMemorySize)); + return; +} + + +/* xmsNotifyHookI15 - Informs softpc that someone is hooking I15 + * - also returns the extended memory for the vdm + * + * + * Entry - Client (CS:AX) seg:off of new I15 vector + * + * Exit + * SUCCESS + * Client (CX) = Extended Memory in K + * + * FAILURE + * Not Valid + */ + +VOID xmsNotifyHookI15 (VOID) +{ + UpdateKbdInt15(getCS(), getAX()); + + setCX((USHORT)(xmsMemorySize)); + return; +} diff --git a/private/mvdm/xms.486/xmsumb.c b/private/mvdm/xms.486/xmsumb.c new file mode 100644 index 000000000..934650e6f --- /dev/null +++ b/private/mvdm/xms.486/xmsumb.c @@ -0,0 +1,242 @@ + +/*++ + +Copyright (c) 1992 Microsoft Corporation + +Module Name: + + XNSUMB.C + +Abstract: + + Routines to service XMS Request UMB and Release UMB functions. + Also includes UMB initialization routine + +Author: + + William Hsieh (williamh) Created 23-Sept-1992 + +[Environment:] + + User mode, running in the MVDM context (bop from 16bits) + +[Notes:] + + + +Revision History: + +--*/ +#include <xms.h> +#include "umb.h" +#include "softpc.h" + + + +// This global variable points to the first node(lowest address) UMB list +static PXMSUMB xmsUMBHead; +static BOOL xmsIsON = FALSE; +// ------------------------------------------------------------------ +// Initialization for UMB support. It create a single direction linked +// list and allocate all available UMBs. +// Input: client (AX:BX) = segment:offset of himem.sys A20State variable +// +// Output: list header, xmsUMBHead set. +//------------------------------------------------------------------- +VOID xmsInitUMB(VOID) +{ + PVOID Address; + ULONG Size; + PXMSUMB xmsUMB, xmsUMBNew; + xmsUMBHead = NULL; + while (ReserveUMB(UMB_OWNER_XMS, &Address, &Size) && + (xmsUMBNew = (PXMSUMB) malloc(sizeof(XMSUMB))) != NULL) { + // convert size in bytes to paragraphs + xmsUMBNew->Size = (WORD) (Size >> 4); + // convert linear address to paragraphs segment + xmsUMBNew->Segment = (WORD)((DWORD)Address >> 4); + xmsUMBNew->Owner = 0; + if (xmsUMBHead == NULL) { + xmsUMBHead = xmsUMBNew; + xmsUMBHead->Next = NULL; + } + else { + xmsUMBNew->Next = xmsUMB->Next; + xmsUMB->Next = xmsUMBNew; + } + xmsUMB = xmsUMBNew; + } + xmsIsON = TRUE; + pHimemA20State = (PBYTE) GetVDMAddr(getAX(), getBX()); + xmsEnableA20Wrapping(); + + + +} + +// This function receives control whenever there has been an UMB released +// Input: PVOID Address = the block address +// ULONG Size = the block size +VOID xmsReleaseUMBNotify( +PVOID Address, +DWORD Size +) +{ + // If the block is good and xms driver is ON, + // grab the block and insert it into our xms UMB list + if (Address != NULL && Size > 0 && xmsIsON && + ReserveUMB(UMB_OWNER_XMS, &Address, &Size)){ + xmsInsertUMB(Address, Size); + } + +} +// ------------------------------------------------------------------ +// Insert a given UMB into the list +// Input: PVOID Address = linear address of the block to be inserted +// ULONG Size = size in byte of the block +// Output: TRUE if the block was inserted to the list successfully +// FALSE if the block wasn't inserted +//------------------------------------------------------------------- + +VOID xmsInsertUMB( +PVOID Address, +ULONG Size +) +{ + PXMSUMB xmsUMB, xmsUMBNew; + WORD Segment; + + Segment = (WORD) ((DWORD)Address >> 4); + Size >>= 4; + + xmsUMB = xmsUMBNew = xmsUMBHead; + while (xmsUMBNew != NULL && xmsUMBNew->Segment < Segment) { + xmsUMB = xmsUMBNew; + xmsUMBNew = xmsUMBNew->Next; + } + // merge it with previous block if possible + if (xmsUMB != NULL && + xmsUMB->Owner == 0 && + Segment == xmsUMB->Segment + xmsUMB->Size) { + + xmsUMB->Size += (WORD) Size; + return; + } + // merge it with the after block if possible + if (xmsUMBNew != NULL && + xmsUMBNew->Owner == 0 && + xmsUMBNew->Segment == Segment + Size) { + + xmsUMBNew->Size += (WORD) Size; + xmsUMBNew->Segment = Segment; + return; + } + // create a new node for the block + if ((xmsUMBNew = (PXMSUMB)malloc(sizeof(XMSUMB))) != NULL) { + xmsUMBNew->Size = (WORD) Size; + xmsUMBNew->Segment = Segment; + xmsUMBNew->Owner = 0; + if (xmsUMBHead == NULL) { + xmsUMBHead = xmsUMBNew; + xmsUMBNew->Next = NULL; + } + else { + xmsUMBNew->Next = xmsUMB->Next; + xmsUMB->Next = xmsUMBNew; + } + } +} +// ------------------------------------------------------------------ +// XMS function 16, Request UMB. +// Input: (DX) = requested size in paragraphs +// Output: (AX) = 1 if succeed and +// (BX) has segment address(number) of the block +// (DX) has actual allocated size in paragraphs +// (AX) = 0 if failed and +// (BL) = 0xB0, (DX) = largest size available +// or +// (BL) = 0xB1 if no UMBs are available +//------------------------------------------------------------------- +VOID xmsRequestUMB(VOID) +{ + PXMSUMB xmsUMB, xmsUMBNew; + WORD SizeRequested, SizeLargest; + + xmsUMB = xmsUMBHead; + SizeRequested = getDX(); + SizeLargest = 0; + while (xmsUMB != NULL) { + if (xmsUMB->Owner == 0) { + if (xmsUMB->Size >= SizeRequested) { + if((xmsUMB->Size - SizeRequested) >= XMSUMB_THRESHOLD && + (xmsUMBNew = (PXMSUMB) malloc(sizeof(XMSUMB))) != NULL) { + + xmsUMBNew->Segment = xmsUMB->Segment + SizeRequested; + xmsUMBNew->Size = xmsUMB->Size - SizeRequested; + xmsUMBNew->Next = xmsUMB->Next; + xmsUMB->Next = xmsUMBNew; + xmsUMBNew->Owner = 0; + xmsUMB->Size -= xmsUMBNew->Size; + } + xmsUMB->Owner = 0xFFFF; + setAX(1); + setBX(xmsUMB->Segment); + setDX(xmsUMB->Size); + return; + } + else { + if (xmsUMB->Size > SizeLargest) + SizeLargest = xmsUMB->Size; + } + } + xmsUMB = xmsUMB->Next; + } + setAX(0); + setDX(SizeLargest); + if (SizeLargest > 0) + setBL(0xB0); + else + setBL(0xB1); +} + + +//------------------------------------------------------------------ +// XMS function 17, Release UMB. +// Input : (DX) = segment to be released +// Output: (AX) = 1 if succeed +// (AX) = 0 if failed and +// (BL) = 0xB2 if segment not found in the list +//------------------------------------------------------------------ +VOID xmsReleaseUMB(VOID) +{ + PXMSUMB xmsUMB, xmsUMBNext; + WORD Segment; + + xmsUMB = xmsUMBHead; + Segment = getDX(); + while (xmsUMB != NULL && xmsUMB->Segment != Segment) { + xmsUMB = xmsUMB->Next; + } + if (xmsUMB != NULL && xmsUMB->Owner != 0) { + xmsUMB->Owner = 0; + // no walk through the entire list to combine consecutive + // blocks together + xmsUMB = xmsUMBHead; + while (xmsUMB != NULL) { + while (xmsUMB->Owner == 0 && + (xmsUMBNext = xmsUMB->Next) != NULL && + xmsUMBNext->Owner == 0 && + (WORD)(xmsUMB->Segment + xmsUMB->Size) == xmsUMBNext->Segment){ + xmsUMB->Size += xmsUMBNext->Size; + xmsUMB->Next = xmsUMBNext->Next; + free(xmsUMBNext); + } + xmsUMB = xmsUMB->Next; + } + setAX(1); + } + else { + setBL(0xB2); + setAX(0); + } +} |