summaryrefslogtreecommitdiffstats
path: root/board/MAI/bios_emulator/scitech/src/pm/vdd/pm.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/MAI/bios_emulator/scitech/src/pm/vdd/pm.c')
-rw-r--r--board/MAI/bios_emulator/scitech/src/pm/vdd/pm.c1050
1 files changed, 1050 insertions, 0 deletions
diff --git a/board/MAI/bios_emulator/scitech/src/pm/vdd/pm.c b/board/MAI/bios_emulator/scitech/src/pm/vdd/pm.c
new file mode 100644
index 0000000000..32177f810d
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/pm/vdd/pm.c
@@ -0,0 +1,1050 @@
+/****************************************************************************
+*
+* SciTech OS Portability Manager Library
+*
+* ========================================================================
+*
+* The contents of this file are subject to the SciTech MGL Public
+* License Version 1.0 (the "License"); you may not use this file
+* except in compliance with the License. You may obtain a copy of
+* the License at http://www.scitechsoft.com/mgl-license.txt
+*
+* Software distributed under the License is distributed on an
+* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
+* implied. See the License for the specific language governing
+* rights and limitations under the License.
+*
+* The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.
+*
+* The Initial Developer of the Original Code is SciTech Software, Inc.
+* All Rights Reserved.
+*
+* ========================================================================
+*
+* Language: ANSI C
+* Environment: 32-bit OS/2 VDD
+*
+* Description: Implementation for the OS Portability Manager Library, which
+* contains functions to implement OS specific services in a
+* generic, cross platform API. Porting the OS Portability
+* Manager library is the first step to porting any SciTech
+* products to a new platform.
+*
+****************************************************************************/
+
+#include "pmapi.h"
+#include "drvlib/os/os.h"
+#include "sdd/sddhelp.h"
+#include "mtrr.h"
+
+#define TRACE(a)
+
+/*--------------------------- Global variables ----------------------------*/
+
+#define MAX_MEMORY_SHARED 100
+#define MAX_MEMORY_MAPPINGS 100
+
+// TODO: I think the global and linear members will be the same, but not sure yet.
+typedef struct {
+ void *linear;
+ ulong global;
+ ulong length;
+ int npages;
+ } memshared;
+
+typedef struct {
+ ulong physical;
+ ulong linear;
+ ulong length;
+ int npages;
+ ibool isCached;
+ } mmapping;
+
+static int numMappings = 0;
+static memshared shared[MAX_MEMORY_MAPPINGS] = {0};
+static mmapping maps[MAX_MEMORY_MAPPINGS];
+ibool _PM_haveBIOS = TRUE;
+char _PM_cntPath[PM_MAX_PATH] = ""; /* there just isn't any */
+uchar *_PM_rmBufAddr = NULL;
+ushort _VARAPI PM_savedDS = 0; /* why can't I use the underscore prefix? */
+
+HVDHSEM hevFarCallRet = NULL;
+HVDHSEM hevIRet = NULL;
+HHOOK hhookUserReturnHook = NULL;
+HHOOK hhookUserIRetHook = NULL;
+
+static void (PMAPIP fatalErrorCleanup)(void) = NULL;
+
+/*----------------------------- Implementation ----------------------------*/
+
+/* Functions to read and write CMOS registers */
+
+ulong PMAPI _PM_getPDB(void);
+uchar PMAPI _PM_readCMOS(int index);
+void PMAPI _PM_writeCMOS(int index,uchar value);
+
+VOID HOOKENTRY UserReturnHook(PVOID pRefData, PCRF pcrf);
+VOID HOOKENTRY UserIRetHook(PVOID pRefData, PCRF pcrf);
+
+void PMAPI PM_init(void)
+{
+ MTRR_init();
+
+ // Initialize VDD-specific data
+ // Note: PM_init must be (obviously) called in VDM task context!
+ VDHCreateSem(&hevFarCallRet, VDH_EVENTSEM);
+ VDHCreateSem(&hevIRet, VDH_EVENTSEM);
+ hhookUserReturnHook = VDHAllocHook(VDH_RETURN_HOOK, (PFNARM)UserReturnHook, 0);
+ hhookUserIRetHook = VDHAllocHook(VDH_RETURN_HOOK, (PFNARM)UserIRetHook, 0);
+
+ if ((hevIRet == NULL) || (hevFarCallRet == NULL) ||
+ (hhookUserReturnHook == NULL) || (hhookUserIRetHook == NULL)) {
+ // something failed, we can't go on
+ // TODO: take some action here!
+ }
+}
+
+/* Do some cleaning up */
+void PMAPI PM_exit(void)
+{
+ /* Note: Hooks allocated during or after VDM creation are deallocated automatically */
+ if (hevIRet != NULL)
+ VDHDestroySem(hevIRet);
+
+ if (hevFarCallRet != NULL)
+ VDHDestroySem(hevFarCallRet);
+}
+
+ibool PMAPI PM_haveBIOSAccess(void)
+{ return _PM_haveBIOS; }
+
+long PMAPI PM_getOSType(void)
+{ return /*_OS_OS2VDD*/ _OS_OS2; } //FIX!!
+
+int PMAPI PM_getModeType(void)
+{ return PM_386; }
+
+void PMAPI PM_backslash(char *s)
+{
+ uint pos = strlen(s);
+ if (s[pos-1] != '\\') {
+ s[pos] = '\\';
+ s[pos+1] = '\0';
+ }
+}
+
+void PMAPI PM_setFatalErrorCleanup(
+ void (PMAPIP cleanup)(void))
+{
+ fatalErrorCleanup = cleanup;
+}
+
+void PMAPI PM_fatalError(const char *msg)
+{
+ if (fatalErrorCleanup)
+ fatalErrorCleanup();
+// Fatal_Error_Handler(msg,0); TODO: implement somehow!
+}
+
+/****************************************************************************
+PARAMETERS:
+len - Place to store the length of the buffer
+rseg - Place to store the real mode segment of the buffer
+roff - Place to store the real mode offset of the buffer
+
+REMARKS:
+This function returns the address and length of the global VESA transfer
+buffer.
+****************************************************************************/
+void * PMAPI PM_getVESABuf(
+ uint *len,
+ uint *rseg,
+ uint *roff)
+{
+ if (_PM_rmBufAddr) {
+ *len = 0; //VESA_BUF_SIZE;
+ *rseg = (ulong)(_PM_rmBufAddr) >> 4;
+ *roff = (ulong)(_PM_rmBufAddr) & 0xF;
+ return _PM_rmBufAddr;
+ }
+ return NULL;
+}
+
+int PMAPI PM_int386(int intno, PMREGS *in, PMREGS *out)
+{
+ /* Unused in VDDs */
+ return 0;
+}
+
+char * PMAPI PM_getCurrentPath(char *path,int maxLen)
+{
+ strncpy(path, _PM_cntPath, maxLen);
+ path[maxLen - 1] = 0;
+ return path;
+}
+
+char PMAPI PM_getBootDrive(void)
+{
+ ulong boot = 3;
+ boot = VDHQuerySysValue(0, VDHGSV_BOOTDRV);
+ return (char)('a' + boot - 1);
+}
+
+const char * PMAPI PM_getVBEAFPath(void)
+{
+ static char path[CCHMAXPATH];
+ strcpy(path,"x:\\");
+ path[0] = PM_getBootDrive();
+ return path;
+}
+
+const char * PMAPI PM_getNucleusPath(void)
+{
+ static char path[CCHMAXPATH];
+ strcpy(path,"x:\\os2\\drivers");
+ path[0] = PM_getBootDrive();
+ PM_backslash(path);
+ strcat(path,"nucleus");
+ return path;
+}
+
+const char * PMAPI PM_getNucleusConfigPath(void)
+{
+ static char path[256];
+ strcpy(path,PM_getNucleusPath());
+ PM_backslash(path);
+ strcat(path,"config");
+ return path;
+}
+
+const char * PMAPI PM_getUniqueID(void)
+{ return PM_getMachineName(); }
+
+const char * PMAPI PM_getMachineName(void)
+{
+ return "Unknown";
+}
+
+int PMAPI PM_kbhit(void)
+{ return 1; }
+
+int PMAPI PM_getch(void)
+{ return 0; }
+
+PM_HWND PMAPI PM_openConsole(PM_HWND hwndUser,int device,int xRes,int yRes,int bpp,ibool fullScreen)
+{
+ /* Unused in VDDs */
+ return NULL;
+}
+
+int PMAPI PM_getConsoleStateSize(void)
+{
+ /* Unused in VDDs */
+ return 1;
+}
+
+void PMAPI PM_saveConsoleState(void *stateBuf,PM_HWND hwndConsole)
+{
+ /* Unused in VDDs */
+}
+
+void PMAPI PM_setSuspendAppCallback(int (_ASMAPIP saveState)(int flags))
+{
+ /* Unused in VDDs */
+}
+
+void PMAPI PM_restoreConsoleState(const void *stateBuf,PM_HWND hwndConsole)
+{
+ /* Unused in VDDs */
+}
+
+void PMAPI PM_closeConsole(PM_HWND hwndConsole)
+{
+ /* Unused in VDDs */
+}
+
+void PMAPI PM_setOSCursorLocation(int x,int y)
+{
+ uchar *_biosPtr = PM_getBIOSPointer();
+ PM_setByte(_biosPtr+0x50,x);
+ PM_setByte(_biosPtr+0x51,y);
+}
+
+void PMAPI PM_setOSScreenWidth(int width,int height)
+{
+ uchar *_biosPtr = PM_getBIOSPointer();
+ PM_setByte(_biosPtr+0x4A,width);
+ PM_setByte(_biosPtr+0x84,height-1);
+}
+
+/****************************************************************************
+REMARKS:
+Allocate a block of shared memory. For OS/2 VDD we allocate shared memory
+as locked, global memory that is accessible from any memory context
+(including interrupt time context), which allows us to load our important
+data structure and code such that we can access it directly from a ring
+0 interrupt context.
+****************************************************************************/
+void * PMAPI PM_mallocShared(long size)
+{
+ ULONG nPages = (size + 0xFFF) >> 12;
+ int i;
+
+ /* First find a free slot in our shared memory table */
+ for (i = 0; i < MAX_MEMORY_SHARED; i++) {
+ if (shared[i].linear == 0)
+ break;
+ }
+ if (i < MAX_MEMORY_SHARED) {
+ shared[i].linear = VDHAllocPages(NULL, nPages, VDHAP_SYSTEM | VDHAP_FIXED);
+ shared[i].npages = nPages;
+ shared[i].global = (ULONG)shared[i].linear;
+ return (void*)shared[i].global;
+ }
+ return NULL;
+}
+
+/****************************************************************************
+REMARKS:
+Free a block of shared memory
+****************************************************************************/
+void PMAPI PM_freeShared(void *p)
+{
+ int i;
+
+ /* Find a shared memory block in our table and free it */
+ for (i = 0; i < MAX_MEMORY_SHARED; i++) {
+ if (shared[i].global == (ulong)p) {
+ VDHFreePages(shared[i].linear);
+ shared[i].linear = 0;
+ break;
+ }
+ }
+}
+
+void * PMAPI PM_mapToProcess(void *base,ulong limit)
+{ return (void*)base; }
+
+ibool PMAPI PM_doBIOSPOST(
+ ushort axVal,
+ ulong BIOSPhysAddr,
+ void *mappedBIOS,
+ ulong BIOSLen)
+{
+ // TODO: Figure out how to do this
+ return false;
+}
+
+void * PMAPI PM_getBIOSPointer(void)
+{ return (void*)0x400; }
+
+void * PMAPI PM_getA0000Pointer(void)
+{ return PM_mapPhysicalAddr(0xA0000,0xFFFF,true); }
+
+/****************************************************************************
+PARAMETERS:
+base - Physical base address of the memory to maps in
+limit - Limit of physical memory to region to maps in
+
+RETURNS:
+Linear address of the newly mapped memory.
+
+REMARKS:
+Maps a physical memory range to a linear memory range.
+****************************************************************************/
+ulong MapPhysicalToLinear(
+ ulong base,
+ ulong limit,
+ int *npages)
+{
+ ulong linear,length = limit+1;
+ int i,ppage,flags;
+#if 0
+ ppage = base >> 12;
+ *npages = (length + (base & 0xFFF) + 4095) >> 12;
+ flags = PR_FIXED | PR_STATIC;
+ if (base == 0xA0000) {
+ /* We require the linear address to be aligned to a 64Kb boundary
+ * for mapping the banked framebuffer (so we can do efficient
+ * carry checking for bank changes in the assembler code). The only
+ * way to ensure this is to force the linear address to be aligned
+ * to a 4Mb boundary.
+ */
+ flags |= PR_4MEG;
+ }
+ if ((linear = (ulong)PageReserve(PR_SYSTEM,*npages,flags)) == (ulong)-1)
+ return 0;
+ if (!PageCommitPhys(linear >> 12,*npages,ppage,PC_INCR | PC_USER | PC_WRITEABLE))
+ return 0;
+#endif
+ return linear + (base & 0xFFF);
+}
+
+/****************************************************************************
+PARAMETERS:
+base - Physical base address of the memory to map in
+limit - Limit of physical memory to region to map in
+isCached - True if the memory should be cached, false if not
+
+RETURNS:
+Linear address of the newly mapped memory.
+
+REMARKS:
+This function maps physical memory to linear memory, which can then be used
+to create a selector or used directly from 32-bit protected mode programs.
+This is better than DPMI 0x800, since it allows you to maps physical
+memory below 1Mb, which gets this memory out of the way of the Windows VxD's
+sticky paws.
+
+NOTE: If the memory is not expected to be cached, this function will
+ directly re-program the PCD (Page Cache Disable) bit in the
+ page tables. There does not appear to be a mechanism in the VMM
+ to control this bit via the regular interface.
+****************************************************************************/
+void * PMAPI PM_mapPhysicalAddr(
+ ulong base,
+ ulong limit,
+ ibool isCached)
+{
+ ulong linear,length = limit+1;
+ int i,npages;
+ ulong PDB,*pPDB;
+
+ /* Search table of existing mappings to see if we have already mapped
+ * a region of memory that will serve this purpose.
+ */
+ for (i = 0; i < numMappings; i++) {
+ if (maps[i].physical == base && maps[i].length == length && maps[i].isCached == isCached)
+ return (void*)maps[i].linear;
+ }
+ if (numMappings == MAX_MEMORY_MAPPINGS)
+ return NULL;
+
+ /* We did not find any previously mapped memory region, so map it in.
+ * Note that we do not use MapPhysToLinear, since this function appears
+ * to have problems mapping memory in the 1Mb physical address space.
+ * Hence we use PageReserve and PageCommitPhys.
+ */
+ if ((linear = MapPhysicalToLinear(base,limit,&npages)) == 0)
+ return NULL;
+ maps[numMappings].physical = base;
+ maps[numMappings].length = length;
+ maps[numMappings].linear = linear;
+ maps[numMappings].npages = npages;
+ maps[numMappings].isCached = isCached;
+ numMappings++;
+
+#if 0
+ /* Finally disable caching where necessary */
+ if (!isCached && (PDB = _PM_getPDB()) != 0) {
+ int startPDB,endPDB,iPDB,startPage,endPage,start,end,iPage;
+ ulong pageTable,*pPageTable;
+
+ if (PDB >= 0x100000)
+ pPDB = (ulong*)MapPhysicalToLinear(PDB,0xFFF,&npages);
+ else
+ pPDB = (ulong*)PDB;
+ if (pPDB) {
+ startPDB = (linear >> 22) & 0x3FF;
+ startPage = (linear >> 12) & 0x3FF;
+ endPDB = ((linear+limit) >> 22) & 0x3FF;
+ endPage = ((linear+limit) >> 12) & 0x3FF;
+ for (iPDB = startPDB; iPDB <= endPDB; iPDB++) {
+ pageTable = pPDB[iPDB] & ~0xFFF;
+ if (pageTable >= 0x100000)
+ pPageTable = (ulong*)MapPhysicalToLinear(pageTable,0xFFF,&npages);
+ else
+ pPageTable = (ulong*)pageTable;
+ start = (iPDB == startPDB) ? startPage : 0;
+ end = (iPDB == endPDB) ? endPage : 0x3FF;
+ for (iPage = start; iPage <= end; iPage++)
+ pPageTable[iPage] |= 0x10;
+ PageFree((ulong)pPageTable,PR_STATIC);
+ }
+ PageFree((ulong)pPDB,PR_STATIC);
+ }
+ }
+#endif
+ return (void*)linear;
+}
+
+void PMAPI PM_freePhysicalAddr(void *ptr,ulong limit)
+{
+ /* We never free the mappings */
+}
+
+void PMAPI PM_sleep(ulong milliseconds)
+{
+ /* We never sleep in a VDD */
+}
+
+int PMAPI PM_getCOMPort(int port)
+{
+ // TODO: Re-code this to determine real values using the Plug and Play
+ // manager for the OS.
+ switch (port) {
+ case 0: return 0x3F8;
+ case 1: return 0x2F8;
+ }
+ return 0;
+}
+
+int PMAPI PM_getLPTPort(int port)
+{
+ // TODO: Re-code this to determine real values using the Plug and Play
+ // manager for the OS.
+ switch (port) {
+ case 0: return 0x3BC;
+ case 1: return 0x378;
+ case 2: return 0x278;
+ }
+ return 0;
+}
+
+ulong PMAPI PM_getPhysicalAddr(void *p)
+{
+ // TODO: This function should find the physical address of a linear
+ // address.
+ return 0xFFFFFFFFUL;
+}
+
+void PMAPI _PM_freeMemoryMappings(void)
+{
+ int i;
+// for (i = 0; i < numMappings; i++)
+// PageFree(maps[i].linear,PR_STATIC);
+}
+
+void * PMAPI PM_mapRealPointer(uint r_seg,uint r_off)
+{ return (void*)MK_PHYS(r_seg,r_off); }
+
+void * PMAPI PM_allocRealSeg(uint size,uint *r_seg,uint *r_off)
+{ return NULL; }
+
+void PMAPI PM_freeRealSeg(void *mem)
+{ }
+
+void PMAPI DPMI_int86(int intno, DPMI_regs *regs)
+{
+ /* Unsed in VDDs */
+}
+
+/****************************************************************************
+REMARKS:
+Load the V86 registers in the client state, and save the original state
+before loading the registers.
+****************************************************************************/
+static void LoadV86Registers(
+ PCRF saveRegs,
+ RMREGS *in,
+ RMSREGS *sregs)
+{
+ PCRF pcrf; // current client register frame
+
+ // get pointer to registers
+ pcrf = (PCRF)VDHQuerySysValue(CURRENT_VDM, VDHLSV_PCRF);
+
+ // Note: We could do VDHPushRegs instead but this should be safer as it
+ // doesn't rely on the VDM session having enough free stack space.
+ *saveRegs = *pcrf; // save all registers
+
+ pcrf->crf_eax = in->e.eax; // load new values
+ pcrf->crf_ebx = in->e.ebx;
+ pcrf->crf_ecx = in->e.ecx;
+ pcrf->crf_edx = in->e.edx;
+ pcrf->crf_esi = in->e.esi;
+ pcrf->crf_edi = in->e.edi;
+ pcrf->crf_es = sregs->es;
+ pcrf->crf_ds = sregs->ds;
+
+}
+
+/****************************************************************************
+REMARKS:
+Read the V86 registers from the client state and restore the original state.
+****************************************************************************/
+static void ReadV86Registers(
+ PCRF saveRegs,
+ RMREGS *out,
+ RMSREGS *sregs)
+{
+ PCRF pcrf; // current client register frame
+
+ // get pointer to registers
+ pcrf = (PCRF)VDHQuerySysValue(CURRENT_VDM, VDHLSV_PCRF);
+
+ // read new register values
+ out->e.eax = pcrf->crf_eax;
+ out->e.ebx = pcrf->crf_ebx;
+ out->e.ecx = pcrf->crf_ecx;
+ out->e.edx = pcrf->crf_edx;
+ out->e.esi = pcrf->crf_esi;
+ out->e.edi = pcrf->crf_edi;
+ sregs->es = pcrf->crf_es;
+ sregs->ds = pcrf->crf_ds;
+
+ // restore original client registers
+ *pcrf = *saveRegs;
+}
+
+/****************************************************************************
+REMARKS: Used for far calls into V86 code
+****************************************************************************/
+VOID HOOKENTRY UserReturnHook(
+ PVOID pRefData,
+ PCRF pcrf )
+{
+ VDHPostEventSem(hevFarCallRet);
+}
+
+/****************************************************************************
+REMARKS: Used for calling BIOS interrupts
+****************************************************************************/
+VOID HOOKENTRY UserIRetHook(
+ PVOID pRefData,
+ PCRF pcrf )
+{
+ VDHPostEventSem(hevIRet);
+}
+
+/****************************************************************************
+REMARKS:
+Call a V86 real mode function with the specified register values
+loaded before the call. The call returns with a far ret.
+Must be called from within a DOS session context!
+****************************************************************************/
+void PMAPI PM_callRealMode(
+ uint seg,
+ uint off,
+ RMREGS *regs,
+ RMSREGS *sregs)
+{
+ CRF saveRegs;
+ FPFN fnAddress;
+ ULONG rc;
+
+ TRACE("SDDHELP: Entering PM_callRealMode()\n");
+ LoadV86Registers(SSToDS(&saveRegs),regs,sregs);
+
+ // set up return hook for call
+ rc = VDHArmReturnHook(hhookUserReturnHook, VDHARH_CSEIP_HOOK);
+
+ VDHResetEventSem(hevFarCallRet);
+
+ // the address is a 16:32 pointer
+ OFFSETOF32(fnAddress) = off;
+ SEGMENTOF32(fnAddress) = seg;
+ rc = VDHPushFarCall(fnAddress);
+ VDHYield(0);
+
+ // wait until the V86 call returns - our return hook posts the semaphore
+ rc = VDHWaitEventSem(hevFarCallRet, SEM_INDEFINITE_WAIT);
+
+ ReadV86Registers(SSToDS(&saveRegs),regs,sregs);
+ TRACE("SDDHELP: Exiting PM_callRealMode()\n");
+}
+
+/****************************************************************************
+REMARKS:
+Issue a V86 real mode interrupt with the specified register values
+loaded before the interrupt.
+Must be called from within a DOS session context!
+****************************************************************************/
+int PMAPI PM_int86(
+ int intno,
+ RMREGS *in,
+ RMREGS *out)
+{
+ RMSREGS sregs = {0};
+ CRF saveRegs;
+ ushort oldDisable;
+ ULONG rc;
+
+ memset(SSToDS(&sregs), 0, sizeof(sregs));
+
+#if 0 // do we need this??
+ /* Disable pass-up to our VDD handler so we directly call BIOS */
+ TRACE("SDDHELP: Entering PM_int86()\n");
+ if (disableTSRFlag) {
+ oldDisable = *disableTSRFlag;
+ *disableTSRFlag = 0;
+ }
+#endif
+
+ LoadV86Registers(SSToDS(&saveRegs), in, SSToDS(&sregs));
+
+ VDHResetEventSem(hevIRet);
+ rc = VDHPushInt(intno);
+
+ // set up return hook for interrupt
+ rc = VDHArmReturnHook(hhookUserIRetHook, VDHARH_NORMAL_IRET);
+
+ VDHYield(0);
+
+ // wait until the V86 IRETs - our return hook posts the semaphore
+ rc = VDHWaitEventSem(hevIRet, 5000); //SEM_INDEFINITE_WAIT);
+
+ ReadV86Registers(SSToDS(&saveRegs), out, SSToDS(&sregs));
+
+#if 0
+ /* Re-enable pass-up to our VDD handler if previously enabled */
+ if (disableTSRFlag)
+ *disableTSRFlag = oldDisable;
+#endif
+
+ TRACE("SDDHELP: Exiting PM_int86()\n");
+ return out->x.ax;
+
+}
+
+/****************************************************************************
+REMARKS:
+Issue a V86 real mode interrupt with the specified register values
+loaded before the interrupt.
+****************************************************************************/
+int PMAPI PM_int86x(
+ int intno,
+ RMREGS *in,
+ RMREGS *out,
+ RMSREGS *sregs)
+{
+ CRF saveRegs;
+ ushort oldDisable;
+ ULONG rc;
+
+#if 0
+ /* Disable pass-up to our VxD handler so we directly call BIOS */
+ TRACE("SDDHELP: Entering PM_int86x()\n");
+ if (disableTSRFlag) {
+ oldDisable = *disableTSRFlag;
+ *disableTSRFlag = 0;
+ }
+#endif
+ LoadV86Registers(SSToDS(&saveRegs), in, sregs);
+
+ VDHResetEventSem(hevIRet);
+ rc = VDHPushInt(intno);
+
+ // set up return hook for interrupt
+ rc = VDHArmReturnHook(hhookUserIRetHook, VDHARH_NORMAL_IRET);
+
+ VDHYield(0);
+
+ // wait until the V86 IRETs - our return hook posts the semaphore
+ rc = VDHWaitEventSem(hevIRet, 5000); //SEM_INDEFINITE_WAIT);
+
+ ReadV86Registers(SSToDS(&saveRegs), out, sregs);
+
+#if 0
+ /* Re-enable pass-up to our VxD handler if previously enabled */
+ if (disableTSRFlag)
+ *disableTSRFlag = oldDisable;
+#endif
+
+ TRACE("SDDHELP: Exiting PM_int86x()\n");
+ return out->x.ax;
+}
+
+void PMAPI PM_availableMemory(ulong *physical,ulong *total)
+{ *physical = *total = 0; }
+
+/****************************************************************************
+REMARKS:
+Allocates a block of locked physical memory.
+****************************************************************************/
+void * PMAPI PM_allocLockedMem(
+ uint size,
+ ulong *physAddr,
+ ibool contiguous,
+ ibool below16M)
+{
+ ULONG flags = VDHAP_SYSTEM;
+ ULONG nPages = (size + 0xFFF) >> 12;
+
+ flags |= (physAddr != NULL) ? VDHAP_PHYSICAL : VDHAP_FIXED;
+
+ return VDHAllocPages(physAddr, nPages, VDHAP_SYSTEM | VDHAP_PHYSICAL);
+}
+
+/****************************************************************************
+REMARKS:
+Frees a block of locked physical memory.
+****************************************************************************/
+void PMAPI PM_freeLockedMem(
+ void *p,
+ uint size,
+ ibool contiguous)
+{
+ if (p)
+ VDHFreePages((PVOID)p);
+}
+
+/****************************************************************************
+REMARKS:
+Lock linear memory so it won't be paged.
+****************************************************************************/
+int PMAPI PM_lockDataPages(void *p,uint len,PM_lockHandle *lh)
+{
+ ULONG lockHandle;
+
+ // TODO: the lock handle is essential for the unlock operation!!
+ lockHandle = VDHLockMem(p, len, 0, (PVOID)VDHLM_NO_ADDR, NULL);
+
+ if (lockHandle != NULL)
+ return 0;
+ else
+ return 1;
+}
+
+/****************************************************************************
+REMARKS:
+Unlock linear memory so it won't be paged.
+****************************************************************************/
+int PMAPI PM_unlockDataPages(void *p,uint len,PM_lockHandle *lh)
+{
+ // TODO: implement - use a table of lock handles?
+ // VDHUnlockPages(lockHandle);
+ return 0;
+}
+
+/****************************************************************************
+REMARKS:
+Lock linear memory so it won't be paged.
+****************************************************************************/
+int PMAPI PM_lockCodePages(void (*p)(),uint len,PM_lockHandle *lh)
+{
+ return PM_lockDataPages((void*)p,len,lh);
+}
+
+/****************************************************************************
+REMARKS:
+Unlock linear memory so it won't be paged.
+****************************************************************************/
+int PMAPI PM_unlockCodePages(void (*p)(),uint len,PM_lockHandle *lh)
+{
+ return PM_unlockDataPages((void*)p,len,lh);
+}
+
+/****************************************************************************
+REMARKS:
+OS specific shared libraries not supported inside a VDD
+****************************************************************************/
+PM_MODULE PMAPI PM_loadLibrary(
+ const char *szDLLName)
+{
+ (void)szDLLName;
+ return NULL;
+}
+
+/****************************************************************************
+REMARKS:
+OS specific shared libraries not supported inside a VDD
+****************************************************************************/
+void * PMAPI PM_getProcAddress(
+ PM_MODULE hModule,
+ const char *szProcName)
+{
+ (void)hModule;
+ (void)szProcName;
+ return NULL;
+}
+
+/****************************************************************************
+REMARKS:
+OS specific shared libraries not supported inside a VDD
+****************************************************************************/
+void PMAPI PM_freeLibrary(
+ PM_MODULE hModule)
+{
+ (void)hModule;
+}
+
+/****************************************************************************
+REMARKS:
+Function to find the first file matching a search criteria in a directory.
+****************************************************************************/
+void *PMAPI PM_findFirstFile(
+ const char *filename,
+ PM_findData *findData)
+{
+ // TODO: This function should start a directory enumeration search
+ // given the filename (with wildcards). The data should be
+ // converted and returned in the findData standard form.
+ (void)filename;
+ (void)findData;
+ return PM_FILE_INVALID;
+}
+
+/****************************************************************************
+REMARKS:
+Function to find the next file matching a search criteria in a directory.
+****************************************************************************/
+ibool PMAPI PM_findNextFile(
+ void *handle,
+ PM_findData *findData)
+{
+ // TODO: This function should find the next file in directory enumeration
+ // search given the search criteria defined in the call to
+ // PM_findFirstFile. The data should be converted and returned
+ // in the findData standard form.
+ (void)handle;
+ (void)findData;
+ return false;
+}
+
+/****************************************************************************
+REMARKS:
+Function to close the find process
+****************************************************************************/
+void PMAPI PM_findClose(
+ void *handle)
+{
+ // TODO: This function should close the find process. This may do
+ // nothing for some OS'es.
+ (void)handle;
+}
+
+/****************************************************************************
+REMARKS:
+Function to determine if a drive is a valid drive or not. Under Unix this
+function will return false for anything except a value of 3 (considered
+the root drive, and equivalent to C: for non-Unix systems). The drive
+numbering is:
+
+ 1 - Drive A:
+ 2 - Drive B:
+ 3 - Drive C:
+ etc
+
+****************************************************************************/
+ibool PMAPI PM_driveValid(
+ char drive)
+{
+ // Not applicable in a VDD
+ (void)drive;
+ return false;
+}
+
+/****************************************************************************
+REMARKS:
+Function to get the current working directory for the specififed drive.
+Under Unix this will always return the current working directory regardless
+of what the value of 'drive' is.
+****************************************************************************/
+void PMAPI PM_getdcwd(
+ int drive,
+ char *dir,
+ int len)
+{
+ // Not applicable in a VDD
+ (void)drive;
+ (void)dir;
+ (void)len;
+}
+
+/****************************************************************************
+PARAMETERS:
+base - The starting physical base address of the region
+size - The size in bytes of the region
+type - Type to place into the MTRR register
+
+RETURNS:
+Error code describing the result.
+
+REMARKS:
+Function to enable write combining for the specified region of memory.
+****************************************************************************/
+int PMAPI PM_enableWriteCombine(
+ ulong base,
+ ulong size,
+ uint type)
+{
+ return MTRR_enableWriteCombine(base,size,type);
+}
+
+/****************************************************************************
+REMARKS:
+Function to change the file attributes for a specific file.
+****************************************************************************/
+void PMAPI PM_setFileAttr(
+ const char *filename,
+ uint attrib)
+{
+ // TODO: Implement this ?
+ (void)filename;
+ (void)attrib;
+ PM_fatalError("PM_setFileAttr not implemented!");
+}
+
+/****************************************************************************
+REMARKS:
+Function to get the file attributes for a specific file.
+****************************************************************************/
+uint PMAPI PM_getFileAttr(
+ const char *filename)
+{
+ // TODO: Implement this ?
+ (void)filename;
+ PM_fatalError("PM_getFileAttr not implemented!");
+ return 0;
+}
+
+/****************************************************************************
+REMARKS:
+Function to create a directory.
+****************************************************************************/
+ibool PMAPI PM_mkdir(
+ const char *filename)
+{
+ // TODO: Implement this ?
+ (void)filename;
+ PM_fatalError("PM_mkdir not implemented!");
+ return false;
+}
+
+/****************************************************************************
+REMARKS:
+Function to remove a directory.
+****************************************************************************/
+ibool PMAPI PM_rmdir(
+ const char *filename)
+{
+ // TODO: Implement this ?
+ (void)filename;
+ PM_fatalError("PM_rmdir not implemented!");
+ return false;
+}
+
+/****************************************************************************
+REMARKS:
+Function to get the file time and date for a specific file.
+****************************************************************************/
+ibool PMAPI PM_getFileTime(
+ const char *filename,
+ ibool gmTime,
+ PM_time *time)
+{
+ // TODO: Implement this ?
+ (void)filename;
+ (void)gmTime;
+ (void)time;
+ PM_fatalError("PM_getFileTime not implemented!");
+ return false;
+}
+
+/****************************************************************************
+REMARKS:
+Function to set the file time and date for a specific file.
+****************************************************************************/
+ibool PMAPI PM_setFileTime(
+ const char *filename,
+ ibool gmTime,
+ PM_time *time)
+{
+ // TODO: Implement this ?
+ (void)filename;
+ (void)gmTime;
+ (void)time;
+ PM_fatalError("PM_setFileTime not implemented!");
+ return false;
+}
OpenPOWER on IntegriCloud