diff options
Diffstat (limited to 'private/mvdm/v86/monitor/i386/sas.c')
-rw-r--r-- | private/mvdm/v86/monitor/i386/sas.c | 1551 |
1 files changed, 1551 insertions, 0 deletions
diff --git a/private/mvdm/v86/monitor/i386/sas.c b/private/mvdm/v86/monitor/i386/sas.c new file mode 100644 index 000000000..0549ad802 --- /dev/null +++ b/private/mvdm/v86/monitor/i386/sas.c @@ -0,0 +1,1551 @@ +/*++ + +Copyright (c) 1990 Microsoft Corporation + +Module Name: + + Monitor.c +Abstract: + + This module is the user mode portion of the x86 monitor + +Author: + + Dave Hastings (daveh) 16 Mar 1991 + +Environment: + + User mode only + +Revision History: + William Hsieh 10-10-1992 Added A20 wrapping support +--*/ + +#define VDD_INTEG 1 +#include "monitorp.h" +#include <windows.h> +#include <stdio.h> +#include <malloc.h> + +// Tim Nov 92. +void sas_connect_memory( + IN sys_addr Low, + IN sys_addr High, + IN int Type + ); + +//BUGBUGBUGBUG Include file + +// from base\inc\sas.h +/* memory types for sas */ +#define SAS_RAM 0 +#define SAS_VIDEO 1 +#define SAS_ROM 2 +#define SAS_WRAP 3 +#define SAS_INACCESSIBLE 4 +#define SAS_MAX_TYPE SAS_INACCESSIBLE + +#define SIXTYFOURK 0x10000L +#define ONEMEGA 0x100000L + +void rom_init(); +void rom_checksum(); +void copyROM(); + +USHORT get_lim_backfill_segment(void); +BOOL HoldEMMBackfillMemory(ULONG Address, ULONG Size); + +#if DBG +extern unsigned short get_emm_page_size(void); +extern unsigned short get_intel_page_size(void); +#endif + +/* SYNC THESE DEFINITIONS WITH BASE\EMM.H, or sas_init will assert */ +#define EMM_PAGE_SIZE 0x4000 +#define INTEL_PAGE_SIZE 0x1000 + +typedef struct +{ + ULONG (*b_read) (); + ULONG (*w_read) (); + VOID (*str_read) (); +} READ_POINTERS; + +// Internal Data +PMEMTYPE MemType = NULL; + +// External Data +extern READ_POINTERS read_pointers; + +// M variables used by video.lib + +host_addr Start_of_M_area; /* host addr (char *) of start of M */ +sys_addr Length_of_M_area; /* sys addr (long) offset of end of M */ + +static HANDLE A20SectionHandle = NULL; +static BOOL A20IsON = FALSE; +static USHORT BackFillSegment; + + + +EXPORT +VOID +sas_init( + IN sys_addr Size + ) + +/*++ + +Routine Description: + + This routine initializes the SAS module, and allocates the linear + address space for the VDM, and loads the ROM + +Arguments: + + Size - Supplies the size of the VDMs linear address space. + +Return Value: + + None. + +--*/ + +{ + NTSTATUS Status; + ULONG ViewSize; + PVOID BaseAddress; + OBJECT_ATTRIBUTES A20ObjAttr; + LARGE_INTEGER SectionSize; + UCHAR SectionAnsiName[80]; + WCHAR SectionUnicodeName[80]; + UNICODE_STRING UnicodeString; + USHORT Pages; + ULONG BackFillBase; + +#define CONVENTIONAL_MEM_SECTION "\\BaseNamedObjects\\VdmConventionalMemory" + + // + // Create a name for the Convetional memory section + // + sprintf( + SectionAnsiName, + "%s%d", + CONVENTIONAL_MEM_SECTION, + GetCurrentProcessId() + ); + + if (MultiByteToWideChar(0, 0, SectionAnsiName, -1, SectionUnicodeName,80) + == 0 + ) { +#if DBG + DbgBreakPoint(); +#endif + // host_error(EG_MALLOC_FAILURE,ERR_QUIT,""); + TerminateVDM(); + } + + RtlInitUnicodeString(&UnicodeString, SectionUnicodeName); + + InitializeObjectAttributes( + &A20ObjAttr, + &UnicodeString, + OBJ_CASE_INSENSITIVE, + NULL, + NULL + ); + + SectionSize.HighPart = 0L; + SectionSize.LowPart = 640 * 1024 + 64 * 1024; + + Status = NtCreateSection( + &A20SectionHandle, + SECTION_MAP_WRITE|SECTION_MAP_EXECUTE, + &A20ObjAttr, + &SectionSize, + PAGE_EXECUTE_READWRITE, + SEC_RESERVE, + NULL + ); + + if (!NT_SUCCESS(Status)) { + // bugbug -williamh + // we should pop up an approiate message before we + // terminate the vdm. +#if DBG + DbgPrint("sas_init: can not create himem section, status = %lx\n", + Status); +#endif + TerminateVDM(); + } + VdmSize = Size; + + // + // N.B. We expect that process creation has reserved the first 16 MB + // for us already. If not, then this won't work worth a darn + + // free the first 640KB virtual address. + // This is done because it has been resevered before sas_init get called + BaseAddress = (PVOID)1; + ViewSize = 640 * 1024 - 1; + Status = NtFreeVirtualMemory( + NtCurrentProcess(), + &BaseAddress, + &ViewSize, + MEM_RELEASE + ); + + + if (!NT_SUCCESS(Status)) { +#if DBG + DbgPrint("sas_init: cannot free 1st 640k virtual address, status = %lx\n", + Status); +#endif + TerminateVDM(); + } + + BaseAddress =(PVOID) ONEMEGA; + ViewSize = SIXTYFOURK; + Status = NtFreeVirtualMemory( + NtCurrentProcess(), + &BaseAddress, + &ViewSize, + MEM_RELEASE + ); + + + if (!NT_SUCCESS(Status)) { +#if DBG + DbgPrint("sas_init: can not free himem virtual address, status = %lx\n", + Status); +#endif + TerminateVDM(); + } + + BaseAddress = (PVOID)VDM_BASE_ADDRESS; + ViewSize = SIXTYFOURK - (ULONG)VDM_BASE_ADDRESS; + SectionSize.HighPart = SectionSize.LowPart = 0; + + Status = NtMapViewOfSection( + A20SectionHandle, + NtCurrentProcess(), + &BaseAddress, + 0, + ViewSize, + &SectionSize, + &ViewSize, + ViewUnmap, + MEM_DOS_LIM, + PAGE_EXECUTE_READWRITE + ); + + if (!NT_SUCCESS(Status)){ +#if DBG + DbgPrint("sas_init: can not map view of 1st 64K, status = %ls\n", + Status); +#endif + TerminateVDM(); + } + BaseAddress = (PVOID) ONEMEGA; + ViewSize = SIXTYFOURK; + Status = NtMapViewOfSection(A20SectionHandle, + NtCurrentProcess(), + &BaseAddress, + 0, + ViewSize, + &SectionSize, + &ViewSize, + ViewUnmap, + MEM_DOS_LIM, + PAGE_EXECUTE_READWRITE + ); + + if (!NT_SUCCESS(Status)){ +#if DBG + DbgPrint("sas_init: can not map view of himem space, status = %lx\n", + Status); +#endif + TerminateVDM(); + } + + // get emm back fill segment address from softpc + // we cut the backfill memory area into pieces in EMM_PAGE_SIZE unit. + // this is done so that EMM manager can grab the address space + // as EMM page frame. + // note that if EMM is disabled, the backfill segment will be + // (640 * 1024 / 16). + + BackFillSegment = get_lim_backfill_segment(); + + ASSERT(BackFillSegment <= 640 * 1024 / 16); + + // + // Map the rest of conventional memory + // only map up to the emm backfill segment. + BaseAddress = (PVOID) (64 * 1024); + ViewSize = BackFillSegment * 16 - 64 * 1024; + SectionSize.LowPart = 64 * 1024; + SectionSize.HighPart = 0; + Status = NtMapViewOfSection(A20SectionHandle, + NtCurrentProcess(), + &BaseAddress, + 0, + ViewSize, + &SectionSize, + &ViewSize, + ViewUnmap, + MEM_DOS_LIM, + PAGE_EXECUTE_READWRITE + ); + if (!NT_SUCCESS(Status)){ +#if DBG + DbgPrint("sas_init: can not map view of himem space, status = %lx\n", + Status); +#endif + TerminateVDM(); + } + +// if there are any backfill memory, map it to our section initially + if (BackFillSegment < 640 * 1024 / 16) { + + /* make sure our constants are in sync with emm.h */ +#if DBG + ASSERT(EMM_PAGE_SIZE == get_emm_page_size()); + ASSERT(INTEL_PAGE_SIZE == get_intel_page_size()); +#endif + if (!HoldEMMBackFillMemory(BackFillSegment * 16, + (640 * 1024) - BackFillSegment * 16) + ) { + +#if DBG + DbgPrint("sas_init: can not map backfill space, status = %lx\n", + Status); +#endif + TerminateVDM(); + } + } + + // + // Allocate ROM area + // + BaseAddress = (PVOID)(640 * 1024); + ViewSize = 384 * 1024; + Status = NtAllocateVirtualMemory( + NtCurrentProcess(), + &BaseAddress, + 0L, + &ViewSize, + MEM_COMMIT, + PAGE_READWRITE + ); + if (!NT_SUCCESS(Status)){ +#if DBG + DbgPrint("sas_init: can not map view of himem space, status = %lx\n", + Status); +#endif + TerminateVDM(); + } + + A20IsON = FALSE; + + Start_of_M_area = 0; + Length_of_M_area = VdmSize; + sas_connect_memory(0, VdmSize + 2*SIXTYFOURK -1, SAS_RAM); +} + +#if VDD_INTEG + +EXPORT +VOID +sas_term( + VOID + ) +/*++ + +Routine Description: + + Free memory prior to reallocing it + +Arguments: + + None. + +Return Value: + + None. +--*/ +{ + PVOID BaseAddress; + NTSTATUS Status; + ULONG Size; + + BaseAddress = (PVOID)VDM_BASE_ADDRESS; + Size = VdmSize; + Status = NtFreeVirtualMemory( + NtCurrentProcess(), + &BaseAddress, + &Size, + MEM_DECOMMIT); + + if (!NT_SUCCESS(Status)) { + VDprint(VDP_LEVEL_ERROR, + ("SoftPc: NtDeCommitVirtualMemory failed !!!! Status = %lx\n", + Status)); + VDbreak(VDB_LEVEL_ERROR); + } +} + + +EXPORT +sys_addr +sas_memory_size( + VOID + ) +/*++ + +Routine Description: + + This routine returns the size of Intel memory + +Arguments: + + none + +Return Value: + + size of intel memory + +--*/ +{ + return(VdmSize); +} + + +EXPORT +VOID +sas_connect_memory( + IN sys_addr Low, + IN sys_addr High, + IN int Type + ) +/*++ + +Routine Description: + + This routine sets up a type record for the specified address region. + If the specified address region was a different type, it is changed to + the new type. + +Arguments: + + Low -- the starting address of the region + High -- the ending address of the region + Type -- the type for the region, one of SAS_RAM, SAS_VIDEO, SAS_ROM, + SAS_WRAP, SAS_INACCESSIBLE + +Return Value: + + None. +--*/ +{ + //bugbug do we handle new block contained in old block correctly? + PMEMTYPE Current, Previous, New, Temp; + + if (!MemType) { + MemType = (PMEMTYPE) ch_malloc(sizeof(MEMTYPE)); + MemType->Previous = NULL; + MemType->Next = NULL; + MemType->Start = Low; + MemType->End = High; + MemType->Type = (half_word)Type; + return; + } + + Current = MemType; + while (Current && (Low > Current->Start)) { + Previous = Current; + Current = Current->Next; + } + + if ((Current) && (Low == Current->Start) && (High == Current->End)) { + Current->Type = (half_word)Type; + return; + } + + if (!Current) { + // Block goes at end of list + New = (PMEMTYPE) ch_malloc(sizeof(MEMTYPE)); + Previous->Next = New; + New->Previous = Previous; + New->Start = Low; + New->End = High; + New->Type = (half_word)Type; + New->Next = NULL; + } else { + // Block goes in front of Current + New = (PMEMTYPE) ch_malloc(sizeof(MEMTYPE)); + New->Start = Low; + New->Type = (half_word)Type; + New->End = High; + New->Previous = Current->Previous; + New->Next = Current; + Current->Previous = New; + if (!New->Previous) { + MemType = New; + } else { + New->Previous->Next = New; + } + } + + + // Block overlaps one or more existing blocks + + if (New->Previous) { + if (New->Previous->End > New->End) { + // block contained in exising block + Temp = (PMEMTYPE) ch_malloc(sizeof(MEMTYPE)); + Temp->Previous = New; + Temp->Next = New->Next; + New->Next = Temp; + if (Temp->Next) { + Temp->Next->Previous = Temp; + } + Temp->End = New->Previous->End; + New->Previous->End = New->Start - 1; + Temp->Start = New->End + 1; + Temp->Type = New->Previous->Type; + return; + } else if (New->Previous->End >= New->Start){ + // block overlaps end of exising block + New->Previous->End = New->Start - 1; + } + } + + // remove all blocks entirely contained in new block + while ((New->Next) && (New->Next->End <= New->End)) { + Temp = New->Next; + New->Next = New->Next->Next; + if (New->Next) { + New->Next->Previous = New; + } + free(Temp); + } + + // remove portion of next block overlapping new block + if ((New->Next) && (New->Next->Start <= New->End)) { + New->Next->Start = New->End + 1; + } + +} + + +EXPORT +half_word +sas_memory_type( + IN sys_addr Address + ) +/*++ + +Routine Description: + + This routine returns the type of memory at a specific address + +Arguments: + + Address -- linear address to return type for. + +Return Value: + + the type for the region, one of SAS_RAM, SAS_VIDEO, SAS_ROM, + SAS_WRAP, SAS_INACCESSIBLE +--*/ +{ + PMEMTYPE Current; + + if (Address > VdmSize) { + return SAS_INACCESSIBLE; + } + + Current = MemType; + while (Current && !((Address >= Current->Start) && + (Address <= Current->End))) { + Current = Current->Next; + } + if (!Current) { + return SAS_INACCESSIBLE; + } + return Current->Type; +} + + + +EXPORT +VOID +sas_enable_20_bit_wrapping( + VOID + ) +/*++ + +Routine Description: + + This routine causes memory addresses to wrap at 1MB + +Arguments: + + None. + +Return Value: + + None. + +--*/ +{ + NTSTATUS Status; + PVOID BaseAddress; + ULONG Size; + LARGE_INTEGER SectionOffset; + // if A20 line is off already do nothing + if (A20IsON == FALSE){ + return; + } + BaseAddress = (PVOID)ONEMEGA; + Size = SIXTYFOURK; + Status = NtUnmapViewOfSection(NtCurrentProcess(), + BaseAddress + ); + + if (!NT_SUCCESS(Status)) { +#if DBG + DbgPrint("A20OFF: Unable to unmap view of section, status = %lx\n", + Status); +#endif + TerminateVDM(); + } + SectionOffset.HighPart = SectionOffset.LowPart = 0; + Status = NtMapViewOfSection(A20SectionHandle, + NtCurrentProcess(), + &BaseAddress, + 0, + Size, + &SectionOffset, + &Size, + ViewUnmap, + MEM_DOS_LIM, + PAGE_EXECUTE_READWRITE + ); + + if (!NT_SUCCESS(Status)) { +#if DBG + DbgPrint("A20OFF: Unable to map view of section, status = %lx\n", + Status); +#endif + TerminateVDM(); + } + A20IsON = FALSE; +} + +EXPORT +VOID +sas_disable_20_bit_wrapping( + VOID + ) +/*++ + +Routine Description: + + This routine causes addressing to NOT wrap at 1MB + +Arguments: + + None. + +Return Value: + + None. + +--*/ +{ + NTSTATUS Status; + PVOID BaseAddress; + ULONG Size; + LARGE_INTEGER SectionOffset; + + // if A20 line is on already do nothing + if (A20IsON == TRUE){ + return; + } + BaseAddress = (PVOID)ONEMEGA; + Size = SIXTYFOURK; + + Status = NtUnmapViewOfSection(NtCurrentProcess(), + BaseAddress + ); + + + if (!NT_SUCCESS(Status)) { +#if DBG + DbgPrint("A20ON: Unable to unmap view of section, status = %lx\n", + Status); +#endif + TerminateVDM(); + } + SectionOffset.HighPart = 0; + SectionOffset.LowPart = 640 * 1024; + Status = NtMapViewOfSection(A20SectionHandle, + NtCurrentProcess(), + &BaseAddress, + 0, + Size, + &SectionOffset, + &Size, + ViewUnmap, + MEM_DOS_LIM, + PAGE_EXECUTE_READWRITE + ); + + if (!NT_SUCCESS(Status)) { +#if DBG + DbgPrint("A20ON: Unable to map view of section, status = %lx\n", + Status); +#endif + TerminateVDM(); + } + A20IsON = TRUE; +} + + + +EXPORT +half_word +sas_hw_at( + IN sys_addr Address + ) +/*++ + +Routine Description: + + This routine returns the byte at the specified address + +Arguments: + + Address -- address of byte to return + +Return Value: + + value of byte at specified address + +--*/ +{ + half_word RetVal; + + if (Address > VdmSize) { + return 0xFE; + } + + RetVal = *((half_word *)Address); + return RetVal; +} + + +EXPORT +word +sas_w_at( + IN sys_addr Address + ) +/*++ + +Routine Description: + + This routine returns the word at the specified address + +Arguments: + + Address -- address of word to return + +Return Value: + + value of word at specified address + +--*/ +{ + word RetVal; + +// DbgPrint("NtVdm : sas_w_at \n"); + if (Address > VdmSize) { + return 0xFEFE; + } + + RetVal = *((word *)Address); + return RetVal; +} + + +EXPORT +double_word +sas_dw_at( + IN sys_addr Address + ) +/*++ + +Routine Description: + + This routine returns the dword at the specified address + +Arguments: + + Address -- address of dword to return + +Return Value: + + value of dword at specified address + +--*/ +{ + double_word RetVal; + + //DbgPrint("NtVdm : sas_dw_at \n"); + RetVal = (double_word)(((ULONG)sas_w_at(Address + 2) << 16) + + sas_w_at(Address)); + return RetVal; +} + + +EXPORT +VOID +sas_load( + IN sys_addr Address, + IN half_word *Value + ) +/*++ + +Routine Description: + + This routine stores the byte at the specified address in the supplied + variable + +Arguments: + + Address -- address of byte to return + Value -- Variable to store the value in + +Return Value: + + None. +--*/ +{ + //DbgPrint("NtVdm : sas_load \n"); + if (Address > VdmSize) { + *Value = 0xFE; + return; + } + + *Value = *((half_word *)Address); + return; +} + + +EXPORT +VOID +sas_loadw( + IN sys_addr Address, + IN word *Value + ) +/*++ + +Routine Description: + + This routine stores the word at the specified address in the supplied + variable + +Arguments: + + Address -- address of word to return + Value -- Variable to store the value in + +Return Value: + + None. +--*/ +{ + //DbgPrint("NtVdm : sas_loadw\n"); + if (Address > VdmSize) { + *Value = 0xFEFE; + return; + } + + *Value = *((word *)Address); + //DbgPrint("NtVdm : sas_loadw word at address %lx is %x (Not video)\n",Address,*Value); + return; +} + + + +EXPORT +VOID +sas_store( + IN sys_addr Address, + IN half_word Value + ) +/*++ + +Routine Description: + + This routine stores the specified byte at the specified address + +Arguments: + + Address -- address of word to return + Value -- value to store + +Return Value: + + None. +--*/ +{ + half_word Type; + //DbgPrint("NtVdm : sas_store\n"); + if (Address <= VdmSize) { + Type = sas_memory_type(Address); + switch (Type) { + case SAS_ROM: + break; + + default: + *((half_word *)Address) = Value; + //DbgPrint("NtVdm : sas_store put byte %x at address %lx\n",Value,Address); + break; + } + } +} + + + +EXPORT +VOID +sas_storew( + IN sys_addr Address, + IN word Value + ) +/*++ + +Routine Description: + + This routine stores the specified word at the specified address + +Arguments: + + Address -- address of word to return + Value -- value to store at the specified address + +Return Value: + + None. +--*/ +{ + + //DbgPrint("NtVdm : sas_storew\n"); + if (Address + 1 <= VdmSize) { + switch (sas_memory_type(Address)) { + + case SAS_ROM: + break; + + default: + *((word *)Address) = Value; + //DbgPrint("NtVdm : sas_storew put word %x at address %lx\n",Value,Address); + break; + } + } +} + + + +EXPORT +VOID +sas_storedw( + IN sys_addr Address, + IN double_word Value + ) +/*++ + +Routine Description: + + This routine stores the specified dword at the specified address + +Arguments: + + Address -- address of word to return + Value -- value to store at the specified address + +Return Value: + + None. +--*/ +{ + //_asm int 3; + sas_storew(Address, (word)(Value & 0xFFFF)); + sas_storew(Address + 2, (word)((Value >> 16) & 0xFFFF)); +} + + +EXPORT +VOID +sas_loads( + IN sys_addr Source, + IN host_addr Destination, + IN sys_addr Length + ) +/*++ + +Routine Description: + + This routine copies the string from the specified intel address to the + specified host address + +Arguments: + + Source -- Intel address to copy from + Destination -- host address to copy the string to + Length -- length of the string to copy + +Return Value: + + None. +--*/ +{ + + //DbgPrint("NtVdm : sas_loads\n"); + RtlCopyMemory((PVOID) Destination, (PVOID) Source, Length); +} + + + +EXPORT +VOID +sas_stores( + IN sys_addr Destination, + IN host_addr Source, + IN sys_addr Length + ) +/*++ + +Routine Description: + + This routine copies the string from the specified host address to the + specified intel address + +Arguments: + + Destination -- intel address to copy the string to + Source -- host address to copy from + Length -- length of the string to copy + +Return Value: + + None. +--*/ +{ + + //DbgPrint("NtVdm : sas_stores\n"); + switch (sas_memory_type(Destination)) { + + case SAS_ROM: + break; + + default: + RtlCopyMemory((PVOID) Destination, (PVOID) Source, Length); + break; + } +} + + +EXPORT +VOID +sas_move_bytes_forward( + IN sys_addr Source, + IN sys_addr Destination, + IN sys_addr Length + ) +/*++ + +Routine Description: + + This routine copies one region of intel memory to another. + +Arguments: + + Source -- source intel address + Destination -- destination intel address + Length -- length of region to copy (in bytes) + +Return Value: + + None. +--*/ +{ + //DbgPrint("NtVdm : sas_move_bytes_forward\n"); + switch (sas_memory_type(Destination)) { + + case SAS_ROM: + break; + + default: + RtlCopyMemory((PVOID) Destination, (PVOID) Source, Length); + break; + } +} + + + +EXPORT +VOID +sas_move_words_forward( + IN sys_addr Source, + IN sys_addr Destination, + IN sys_addr Length + ) +/*++ + +Routine Description: + + This routine copies one region of intel memory to another. + +Arguments: + + Source -- source intel address + Destination -- destination intel address + Length -- length of region to copy (in words) + +Return Value: + + None. +--*/ +{ + //_asm int 3; + Length <<= 1; + switch (sas_memory_type(Destination)) { + + case SAS_ROM: + break; + + default: + RtlCopyMemory((PVOID) Destination, (PVOID) Source, Length); + break; + } +} + + + +EXPORT +VOID +sas_move_bytes_backward( + IN sys_addr Source, + IN sys_addr Destination, + IN sys_addr Length + ) +/*++ + +Routine Description: + + This routine copies one region of intel memory to another. + +Arguments: + + Source -- source intel address + Destination -- destination intel address + Length -- length of region to copy (in bytes) + +Return Value: + + None. +--*/ +{ + //_asm int 3; + switch (sas_memory_type(Destination)) { + + case SAS_ROM: + break; + + default: + RtlCopyMemory((PVOID) (Destination - Length + 1), + (PVOID) (Source - Length + 1), + Length); + break; + } +} + + + +EXPORT +VOID +sas_move_words_backward( + IN sys_addr Source, + IN sys_addr Destination, + IN sys_addr Length + ) +/*++ + +Routine Description: + + This routine copies one region of intel memory to another. + +Arguments: + + Source -- source intel address + Destination -- destination intel address + Length -- length of region to copy (in words) + +Return Value: + + None. +--*/ +{ + //_asm int 3; + Length <<= 1; + switch (sas_memory_type(Destination)) { + + case SAS_ROM: + break; + + default: + RtlCopyMemory((PVOID) (Destination - Length + 1), + (PVOID) (Source - Length + 1), + Length); + break; + } +} + +EXPORT +VOID +sas_fills( + IN sys_addr Address, + IN half_word Value, + IN sys_addr Length + ) +/*++ + +Routine Description: + + This routine fills a specified region of intel memory with a byte value + +Arguments: + + Address -- address to fill at + Value -- value to fill with + Length -- length of region to fill + +Return Value: + + None. +--*/ +{ + half_word Type; + + //DbgPrint("NtVdm : sas_fills\n"); + Type = sas_memory_type(Address); + switch (Type) { + + case SAS_ROM: + break; + + default: + RtlFillMemory((PVOID) Address, Length, Value); + break; + } +} + +EXPORT +VOID +sas_fillsw( + IN sys_addr Address, + IN word Value, + IN sys_addr Length + ) +/*++ + +Routine Description: + + This routine fills a specified region of intel memory with a word value + +Arguments: + + Address -- address to fill at + Value -- value to fill with + Length -- length of region to fill + +Return Value: + + None. +--*/ +{ + + word *p; + half_word Type; + + //DbgPrint("NtVdm : sas_fillsw\n"); + Type = sas_memory_type(Address); + switch (Type) { + + case SAS_ROM: + break; + + default: + p = (word *)Address; + while (Length--) { + *p++ = Value; + } + break; + } +} + +host_addr scratch = NULL; + +EXPORT +host_addr +sas_scratch_address( + IN sys_addr Length + ) +/*++ + +Routine Description: + + This routine supplies a scratch buffer for short term use + +Arguments + + Length -- length of buffer needed + +Return Value: + + None. + +NOTE: Sudeepb 31-Oct-1993 Converted scratch to be allocated dynamically rather + than as a static array. +--*/ +{ + //DbgPrint("NtVdm : sas_scratch_address\n"); + if (Length > 64 * 1024) { + //DbgPrint("SoftPc: sas_scratch_address requet for buffer larger than 64K\n"); + return NULL; + } + + if (scratch) + return scratch; + + if ((scratch = (host_addr) malloc (64 * 1024)) == NULL) + return NULL; + + return scratch; +} + +EXPORT +half_word +sas_hw_at_no_check( + sys_addr addr + ) +// bugbug comment +{ + //DbgPrint("NtVdm : sas_hw_at_no_check\n"); + //DbgPrint("NtVdm : sas_hw_at_no_check byte at %lx is %x\n",addr,*((half_word *)addr)); + return *((half_word *)addr); +} + +EXPORT +word +sas_w_at_no_check( + sys_addr addr + ) +// bugbug comment +{ + //DbgPrint("NtVdm : sas_w_at_no_check\n"); + //DbgPrint("NtVdm : sas_w_at_no_check word at %lx is %x\n",addr,*((word *)addr)); + return *((word *)addr); +} +EXPORT +double_word +sas_dw_at_no_check( + sys_addr addr + ) +// bugbug comment +{ + //DbgPrint("NtVdm : sas_dw_at_no_check\n"); + //DbgPrint("NtVdm : sas_dw_at_no_check double word at %lx is %lx\n",addr,*((double_word *)addr)); + return *((double_word *)addr); +} + + +EXPORT +VOID +sas_store_no_check( + sys_addr addr, + half_word val + ) +// bugbug comment +{ + //DbgPrint("NtVdm : sas_store_no_check\n"); + *((half_word *)addr) = val; + //DbgPrint("NtVdm : sas_store_no_check stored byte %x at %lx\n",val,addr); +} + +EXPORT +VOID +sas_storew_no_check( + sys_addr addr, + word val + ) +// bugbug comment +{ + //DbgPrint("NtVdm : sas_storew_no_check\n"); + *((word *)addr) = val; +} +EXPORT +double_word +effective_addr( + IN word Segment, + IN word Offset + ) +/*++ + +Routine Description: + + This routine maps effective_addr to Sim32GetVdmPointer + +Arguments: + + Segment -- segment of address + Offset -- offset of address + +Return Value: + + Actual Intel address corresponding to the address supplied +--*/ +{ + //DbgPrint("NtVdm : effective_addr\n"); + return (ULONG)Sim32GetVDMPointer(((((ULONG)Segment) << 16) | Offset), 1, + (UCHAR) (getMSW() & MSW_PE ? TRUE : FALSE)); +} + +typedef enum +{ + RAM, + VIDEO, + ROM, + IN_FRAGMENT, + NEXT_FRAGMENT +} mem_type; + +typedef struct +{ + VOID (*b_write)(); + VOID (*w_write)(); + VOID (*b_fill)(); + VOID (*w_fill)(); + VOID (*b_move)(); + VOID (*w_move)(); +} MEM_HANDLERS; +#define TYPE_RANGE ((int)SAS_INACCESSIBLE) +#define write_b_write_ptrs( offset, func ) ( b_write_ptrs[(offset)] = (func) ) +#define write_w_write_ptrs( offset, func ) ( w_write_ptrs[(offset)] = (func) ) +#define write_b_page_ptrs( offset, func ) ( b_move_ptrs[(offset)] = b_fill_ptrs[(offset)] = (func) ) +#define write_w_page_ptrs( offset, func ) ( w_move_ptrs[(offset)] = w_fill_ptrs[(offset)] = (func) ) +#define init_b_write_ptrs( offset, func ) ( b_write_ptrs[(offset)] = (func) ) +#define init_w_write_ptrs( offset, func ) ( w_write_ptrs[(offset)] = (func) ) +#define init_b_page_ptrs( offset, func ) ( b_move_ptrs[(offset)] = b_fill_ptrs[(offset)] = (func) ) +#define init_w_page_ptrs( offset, func ) ( w_move_ptrs[(offset)] = w_fill_ptrs[(offset)] = (func) ) +#define read_b_write_ptrs( offset ) ( b_write_ptrs[(offset)] ) +#define read_w_write_ptrs( offset ) ( w_write_ptrs[(offset)] ) +#define read_b_page_ptrs( offset ) ( b_move_ptrs[(offset)] ) +#define read_w_page_ptrs( offset ) ( w_move_ptrs[(offset)] ) +#define read_b_move_ptrs( offset ) ( b_move_ptrs[(offset)] ) +#define read_w_move_ptrs( offset ) ( w_move_ptrs[(offset)] ) +#define read_b_fill_ptrs( offset ) ( b_fill_ptrs[(offset)] ) +#define read_w_fill_ptrs( offset ) ( w_fill_ptrs[(offset)] ) + +/* +* The main gmi data structures are defined here +*/ +void (*(b_write_ptrs[TYPE_RANGE]))() ; /* byte write function */ +void (*(w_write_ptrs[TYPE_RANGE]))() ; /* word write function */ +void (*(b_fill_ptrs[TYPE_RANGE]))() ; /* byte str fill func */ +void (*(w_fill_ptrs[TYPE_RANGE]))() ; /* word str fill func */ +void (*(b_move_ptrs[TYPE_RANGE]))() ; /* byte str write func */ +void (*(w_move_ptrs[TYPE_RANGE]))() ; /* word str write func */ + +void gmi_define_mem(type,handlers) +mem_type type; +MEM_HANDLERS *handlers; +{ + int int_type = (int)(type); + init_b_write_ptrs(int_type, (void(*)())(handlers->b_write)); + init_w_write_ptrs(int_type, (void(*)())(handlers->w_write)); + b_move_ptrs[int_type] = (void(*)())(handlers->b_move); + w_move_ptrs[int_type] = (void(*)())(handlers->w_move); + b_fill_ptrs[int_type] = (void(*)())(handlers->b_fill); + w_fill_ptrs[int_type] = (void(*)())(handlers->w_fill); +} +#endif +BOOL sas_twenty_bit_wrapping_enabled() { + return (!A20IsON); +} + +VOID sas_part_enable_20_bit_wrapping(){ +} +VOID sas_part_disable_20_bit_wrapping(){ +} + + +/* + * This function maps the given EMM backfill memory to DOS conventional + * memory. The function is provided to EMM manager to put back + * unmapped backfill memory(hold its contents while it is not mapped). + * + * NOTE: The very first caller will be sas_init. + * + * Input: ULONG BaseAddress -- the starting address, must be in INTEL page + * boundary + * ULONG Size -- size of the range, must be a multiple of + * EMM_PAGE_SIZE. + * + * According to LouP, a view costs about 400 bytes of memory. This is why + * I make these function strictly to work on EMM_PAGE_SIZE instead of 4KB. + */ + + +BOOL +HoldEMMBackFillMemory(ULONG BaseAddress, ULONG Size) +{ + ULONG NewBase, Pages, i; + LARGE_INTEGER SectionOffset; + ULONG ViewSize; + NTSTATUS Status; + + /* this function can only be called if there is backfill at all */ + ASSERT(BackFillSegment < 640 * 1024 / 16); + + // size must be EMM_PAGE_SIZE multiple + ASSERT((Size % EMM_PAGE_SIZE) == 0); + + // address must be on INTEL page boundary + ASSERT((BaseAddress & (INTEL_PAGE_SIZE - 1)) == 0); + + for (Pages = Size / EMM_PAGE_SIZE; Pages; Pages--) { + SectionOffset.LowPart = BaseAddress; + SectionOffset.HighPart = 0; + ViewSize = EMM_PAGE_SIZE; + Status = NtMapViewOfSection(A20SectionHandle, + NtCurrentProcess(), + (PVOID *)&BaseAddress, + 0, + ViewSize, + &SectionOffset, + &ViewSize, + ViewUnmap, + MEM_DOS_LIM, + PAGE_EXECUTE_READWRITE + ); + if (!NT_SUCCESS(Status)) + break; + BaseAddress += EMM_PAGE_SIZE; + } + return (NT_SUCCESS(Status)); +} |