home *** CD-ROM | disk | FTP | other *** search
- /***
- * vmems.c -
- *
- * Copyright (c) 1989-1992, Microsoft Corporation. All rights reserved.
- *
- *Purpose:
- *
- * PRIVATE Functions:
- *
- * VmInitializeEms:
- *
- * VmTerminateEms:
- *
- * FVmAllocateEmsPage:
- *
- * VmMapInEmsPage:
- *
- *******************************************************************************/
-
- #pragma title("Virtual Memory Manager")
- #pragma subtitle("DOS Expanded memory support")
-
-
- #include <version.h>
- #include <vmassert.h>
- #include <system.h>
- #include <error.h>
- #include <ems.h>
- #include <vm.h>
- #include <vmp.h>
-
- #if VMFREE
- #define cVmPageQueuedEmsMost 8
- #else /* !VMFREE */
- #define cVmPageQueuedEmsMost 1
- #endif /* !VMFREE */
-
- extern char _near _fVmDisableEms = FALSE;
- static char _near _fVmUseEms;
- static HEMS _near hemsVm;
- static unsigned _near _cVmPageHems;
- static unsigned _near _cVmPageQueuedEms;
- static unsigned _near rgiVmPageQueuedEms[cVmPageQueuedEmsMost];
-
- #if VMFREE
-
- static unsigned _near iVmPageEmsNextFree;
-
- #endif /* VMFREE */
-
-
- #if VMPROFILE
-
- unsigned long _near _cVmSwapInEms;
- unsigned long _near _cVmSwapOutEms;
-
- #endif /* VMPROFILE */
-
-
- #pragma page()
-
- void PRIVATE __VmInitializeEms(void)
- {
- VmTracePrintf(("VmInitializeEms\n"));
-
- #if VMPROFILE
- _cVmSwapInEms = _cVmSwapOutEms = 0;
- #endif
-
- if (_fVmDisableEms ||
- !__FEmsCheckInstalled() ||
- (__ErrEmsAllocatePages(&hemsVm, 1) != errNoError)
- )
- {
- _fVmUseEms = FALSE;
- return;
- }
-
- _fVmUseEms = TRUE;
- _cVmPageHems = 1;
- _cVmPageQueuedEms = 1;
- rgiVmPageQueuedEms[0] = 0;
-
- #if VMFREE
- iVmPageEmsNextFree = 0xffff;
- #endif /* VMFREE */
- }
-
-
- #pragma page()
-
- void PRIVATE __VmTerminateEms(void)
- {
- VmTracePrintf(("VmTerminateEms\n"));
-
- VmProfilePrintf(("VmProfile:\t_cVmSwapInEms = %lu, _cVmSwapOutEms = %lu\n",
- _cVmSwapInEms, _cVmSwapOutEms));
-
- if (_fVmUseEms)
- {
- __ErrEmsDeallocatePages(hemsVm);
-
- _fVmUseEms = FALSE;
- }
- }
-
-
- #pragma page()
-
- void LOCAL __VmFillEmsQueue(void)
- {
- VmTracePrintf(("VmFillEmsQueue\n"));
-
- Assert(_fVmUseEms && (_cVmPageQueuedEms == 0));
-
- #if VMFREE
- if (iVmPageEmsNextFree != 0xffff)
- {
- ERR err;
- move_source_dest emsmove;
-
- /* Insert first free page in queue. */
-
- /* CONSIDER: Should more than one page be added to queue. */
- /* CONSIDER: I chose not to because a subsequent set of */
- /* CONSIDER: calls to VmFreeEmsPage could result in more */
- /* CONSIDER: EMS calls than occur by not doing so. */
-
- rgiVmPageQueuedEms[_cVmPageQueuedEms++] = iVmPageEmsNextFree;
-
- emsmove.cb = sizeof(iVmPageEmsNextFree);
- emsmove.fEmsSource = 1;
- emsmove.hemsSource = hemsVm;
- emsmove.ibSource = 0;
- emsmove.iPageSource = iVmPageEmsNextFree;
- emsmove.fEmsDest = 0;
- emsmove.hemsDest = 0;
- emsmove.ibDest = (unsigned) (void _near *) &iVmPageEmsNextFree;
- emsmove.segDest = (_segment) &iVmPageEmsNextFree;
- err = __ErrEmsMoveMemoryRegion(&emsmove);
- Assert(err == errNoError);
- }
-
- else
- #endif /* VMFREE */
- {
- if (__ErrEmsReallocatePages(hemsVm, _cVmPageHems + 1) != errNoError)
- return;
-
- rgiVmPageQueuedEms[_cVmPageQueuedEms++] = _cVmPageHems++;
-
- VmTracePrintf(("Reallocated EMS Handle. cPage = %04X.\n", _cVmPageHems));
- }
- }
-
-
- #pragma page()
-
- int PRIVATE __FVmAllocateEmsPage(PPTE ppte, VPVOID vp)
- {
- PPTE ppteBase;
- unsigned iPage;
- PTE pte;
-
- if (!_fVmUseEms)
- return(FALSE);
-
- Assert(*ppte == 0);
-
- /* Find the base of this 16K range */
-
- ppteBase = ppte - ((vp & 16383UL) / cbVmPage);
-
- /* EMS is only allocated in 16K blocks. For this allocation to */
- /* succeed, the 16K block containing this page must not contain */
- /* any pages assigned swap storage in XMS or disk. */
-
- for (iPage = 0; iPage < 16384U / cbVmPage; iPage++)
- {
- Assert(!(ppteBase[iPage] & fEmsPte));
-
- if (ppteBase[iPage] & (fXmsPte | fDiskPte))
- return(FALSE);
- }
-
- if (_cVmPageQueuedEms == 0) /* No Queued pages available. */
- __VmFillEmsQueue();
-
- if (_cVmPageQueuedEms == 0) /* Queue remains empty. No EMS left. */
- return(FALSE);
-
- pte = (rgiVmPageQueuedEms[--_cVmPageQueuedEms] * 16384UL) | fEmsPte;
-
- vp &= ~(VPVOID) (cbVmPage - 1UL); /* Virtual address of base of range */
-
- for (iPage = 0; iPage < 16384U / cbVmPage; iPage++)
- {
- HPGD hpgd;
-
- /* Remember the assigned swap location in the page tables. */
-
- ppteBase[iPage] |= pte;
-
- /* If this page is resident, the swap location must be updated in */
- /* the page descriptor as well or else the page won't be swapped */
- /* out to the correct location. */
-
- if ((ppteBase[iPage] & fAllocatedPte) &&
- ((hpgd = __HpgdSearchCache(vp)) != hpgdNil))
- PpgdOfHpgd(hpgd)->pte |= pte;
-
- pte += cbVmPage;
- vp += cbVmPage;
- }
-
- *ppte |= fAllocatedPte | fUnreferencedPte;
-
- VmTracePrintf(("FVmAllocateEmsPage: SwapLocation = %08lX.\n", *ppte & bitSwapPte));
-
- return(TRUE);
- }
-
-
- #pragma page()
-
- #if VMFREE
-
- void PRIVATE __VmFreeEmsPage(PPTE ppte)
- {
- PPTE ppteBase;
- unsigned iPage;
-
- VmTracePrintf(("VmFreeEmsPage: SwapLocation = %08lX.\n", *ppte & bitSwapPte));
-
- Assert(_fVmUseEms && (*ppte & fEmsPte) && !(*ppte & fAllocatedPte));
-
- /* Find the base of this 16K range */
-
- ppteBase = ppte - ((*ppte & bitSwapPte & 16383UL) / cbVmPage);
-
- /* If any page in this page is allocated, don't free the EMS page. */
-
- for (iPage = 0; iPage < 16384U / cbVmPage; iPage++)
- {
- Assert(ppteBase[iPage] & fEmsPte);
-
- if (ppteBase[iPage] & fAllocatedPte)
- return;
- }
-
- iPage = (unsigned) ((*ppte & bitSwapPte) / 16384UL);
-
- if (_cVmPageQueuedEms < cVmPageQueuedEmsMost)
- rgiVmPageQueuedEms[_cVmPageQueuedEms++] = iPage;
-
- else
- {
- ERR err;
- move_source_dest emsmove;
-
- emsmove.cb = sizeof(iVmPageEmsNextFree);
- emsmove.fEmsDest = 1;
- emsmove.hemsDest = hemsVm;
- emsmove.ibDest = 0;
- emsmove.iPageDest = iPage;
- emsmove.fEmsSource = 0;
- emsmove.hemsSource = 0;
- emsmove.ibSource = (unsigned) (void _near *) &iVmPageEmsNextFree;
- emsmove.segSource = (_segment) &iVmPageEmsNextFree;
- err = __ErrEmsMoveMemoryRegion(&emsmove);
- Assert(err == errNoError);
-
- iVmPageEmsNextFree = iPage;
- }
-
- for (iPage = 0; iPage < 16384U / cbVmPage; iPage++)
- ppteBase[iPage] = 0;
- }
-
- #endif /* VMFREE */
-
-
- #pragma page()
-
- int PRIVATE __FVmSwapInEmsPage(PTE pte, HPGD hpgd)
- {
- ERR err;
- move_source_dest emsmove;
-
- VmTracePrintf(("VmSwapInEmsPage: pPage = %Fp, SwapLocation = %08lX.\n",
- PPageOfHpgd(hpgd), pte & bitSwapPte));
-
- #if VMPROFILE
- _cVmSwapInEms++;
- #endif
-
- Assert(_fVmUseEms && (pte & fEmsPte));
-
- emsmove.cb = cbVmPage;
- emsmove.fEmsSource = 1;
- emsmove.hemsSource = hemsVm;
- emsmove.ibSource = (unsigned) ((pte & bitSwapPte) & 16383UL);
- emsmove.iPageSource = (unsigned) ((pte & bitSwapPte) / 16384UL);
- emsmove.fEmsDest = 0;
- emsmove.hemsDest = 0;
- emsmove.ibDest = 0;
- emsmove.segDest = PpgdOfHpgd(hpgd)->segPage;
- err = __ErrEmsMoveMemoryRegion(&emsmove);
-
- Assert(err == errNoError);
- return(err == errNoError);
- }
-
-
- #pragma page()
-
- int PRIVATE __FVmSwapOutEmsPage(PTE pte, HPGD hpgd)
- {
- ERR err;
- move_source_dest emsmove;
-
- VmTracePrintf(("VmSwapOutEmsPage: vp = %08lX, pPage = %Fp, SwapLocation = %08lX.\n",
- PpgdOfHpgd(hpgd)->vp, PPageOfHpgd(hpgd), pte & bitSwapPte));
-
- #if VMPROFILE
- _cVmSwapOutEms++;
- #endif
-
- Assert(_fVmUseEms && (pte & fEmsPte));
-
- emsmove.cb = cbVmPage;
- emsmove.fEmsSource = 0;
- emsmove.hemsSource = 0;
- emsmove.ibSource = 0;
- emsmove.segSource = PpgdOfHpgd(hpgd)->segPage;
- emsmove.fEmsDest = 1;
- emsmove.hemsDest = hemsVm;
- emsmove.ibDest = (unsigned) ((pte & bitSwapPte) & 16383U);
- emsmove.iPageDest = (unsigned) ((pte & bitSwapPte) / 16384UL);
- err = __ErrEmsMoveMemoryRegion(&emsmove);
-
- Assert(err == errNoError);
- return(err == errNoError);
- }
-