// Internal data
//
///////////////////////////////////////////////////////////////////////////////////////
-CACHE_DRIVE CacheManagerDrive;
-BOOLEAN CacheManagerInitialized = FALSE;
-BOOLEAN CacheManagerDataInvalid = FALSE;
-ULONG CacheBlockCount = 0;
-ULONG CacheSizeLimit = 0;
-ULONG CacheSizeCurrent = 0;
+CACHE_DRIVE CacheManagerDrive;
+BOOLEAN CacheManagerInitialized = FALSE;
+BOOLEAN CacheManagerDataInvalid = FALSE;
+ULONG CacheBlockCount = 0;
+SIZE_T CacheSizeLimit = 0;
+SIZE_T CacheSizeCurrent = 0;
BOOLEAN CacheInitializeDrive(UCHAR DriveNumber)
{
- PCACHE_BLOCK NextCacheBlock;
- GEOMETRY DriveGeometry;
-
- // If we already have a cache for this drive then
- // by all means lets keep it, unless it is a removable
- // drive, in which case we'll invalidate the cache
- if ((CacheManagerInitialized == TRUE) &&
- (DriveNumber == CacheManagerDrive.DriveNumber) &&
- (DriveNumber >= 0x80) &&
- (CacheManagerDataInvalid != TRUE))
- {
- return TRUE;
- }
-
- CacheManagerDataInvalid = FALSE;
-
- //
- // If we have already been initialized then free
- // the old data
- //
- if (CacheManagerInitialized)
- {
- CacheManagerInitialized = FALSE;
-
- TRACE("CacheBlockCount: %d\n", CacheBlockCount);
- TRACE("CacheSizeLimit: %d\n", CacheSizeLimit);
- TRACE("CacheSizeCurrent: %d\n", CacheSizeCurrent);
- //
- // Loop through and free the cache blocks
- //
- while (!IsListEmpty(&CacheManagerDrive.CacheBlockHead))
- {
- NextCacheBlock = CONTAINING_RECORD(RemoveHeadList(&CacheManagerDrive.CacheBlockHead),
- CACHE_BLOCK,
- ListEntry);
-
- MmHeapFree(NextCacheBlock->BlockData);
- MmHeapFree(NextCacheBlock);
- }
- }
-
- // Initialize the structure
- RtlZeroMemory(&CacheManagerDrive, sizeof(CACHE_DRIVE));
- InitializeListHead(&CacheManagerDrive.CacheBlockHead);
- CacheManagerDrive.DriveNumber = DriveNumber;
- if (!MachDiskGetDriveGeometry(DriveNumber, &DriveGeometry))
- {
- return FALSE;
- }
- CacheManagerDrive.BytesPerSector = DriveGeometry.BytesPerSector;
-
- // Get the number of sectors in each cache block
- CacheManagerDrive.BlockSize = MachDiskGetCacheableBlockCount(DriveNumber);
-
- CacheBlockCount = 0;
- CacheSizeLimit = TotalPagesInLookupTable / 8 * MM_PAGE_SIZE;
- CacheSizeCurrent = 0;
- if (CacheSizeLimit < (64 * 1024))
- {
- CacheSizeLimit = (64 * 1024);
- }
-
- CacheManagerInitialized = TRUE;
-
- TRACE("Initializing BIOS drive 0x%x.\n", DriveNumber);
- TRACE("BytesPerSector: %d.\n", CacheManagerDrive.BytesPerSector);
- TRACE("BlockSize: %d.\n", CacheManagerDrive.BlockSize);
- TRACE("CacheSizeLimit: %d.\n", CacheSizeLimit);
-
- return TRUE;
+ PCACHE_BLOCK NextCacheBlock;
+ GEOMETRY DriveGeometry;
+
+ // If we already have a cache for this drive then
+ // by all means lets keep it, unless it is a removable
+ // drive, in which case we'll invalidate the cache
+ if ((CacheManagerInitialized) &&
+ (DriveNumber == CacheManagerDrive.DriveNumber) &&
+ (DriveNumber >= 0x80) &&
+ (!CacheManagerDataInvalid))
+ {
+ return TRUE;
+ }
+
+ CacheManagerDataInvalid = FALSE;
+
+ //
+ // If we have already been initialized then free
+ // the old data
+ //
+ if (CacheManagerInitialized)
+ {
+ CacheManagerInitialized = FALSE;
+
+ TRACE("CacheBlockCount: %d\n", CacheBlockCount);
+ TRACE("CacheSizeLimit: %d\n", CacheSizeLimit);
+ TRACE("CacheSizeCurrent: %d\n", CacheSizeCurrent);
+ //
+ // Loop through and free the cache blocks
+ //
+ while (!IsListEmpty(&CacheManagerDrive.CacheBlockHead))
+ {
+ NextCacheBlock = CONTAINING_RECORD(RemoveHeadList(&CacheManagerDrive.CacheBlockHead),
+ CACHE_BLOCK,
+ ListEntry);
+
+ FrLdrTempFree(NextCacheBlock->BlockData, TAG_CACHE_DATA);
+ FrLdrTempFree(NextCacheBlock, TAG_CACHE_BLOCK);
+ }
+ }
+
+ // Initialize the structure
+ RtlZeroMemory(&CacheManagerDrive, sizeof(CACHE_DRIVE));
+ InitializeListHead(&CacheManagerDrive.CacheBlockHead);
+ CacheManagerDrive.DriveNumber = DriveNumber;
+ if (!MachDiskGetDriveGeometry(DriveNumber, &DriveGeometry))
+ {
+ return FALSE;
+ }
+ CacheManagerDrive.BytesPerSector = DriveGeometry.BytesPerSector;
+
+ // Get the number of sectors in each cache block
+ CacheManagerDrive.BlockSize = MachDiskGetCacheableBlockCount(DriveNumber);
+
+ CacheBlockCount = 0;
+ CacheSizeLimit = TotalPagesInLookupTable / 8 * MM_PAGE_SIZE;
+ CacheSizeCurrent = 0;
+ if (CacheSizeLimit > TEMP_HEAP_SIZE - (128 * 1024))
+ {
+ CacheSizeLimit = TEMP_HEAP_SIZE - (128 * 1024);
+ }
+
+ CacheManagerInitialized = TRUE;
+
+ TRACE("Initializing BIOS drive 0x%x.\n", DriveNumber);
+ TRACE("BytesPerSector: %d.\n", CacheManagerDrive.BytesPerSector);
+ TRACE("BlockSize: %d.\n", CacheManagerDrive.BlockSize);
+ TRACE("CacheSizeLimit: %d.\n", CacheSizeLimit);
+
+ return TRUE;
}
VOID CacheInvalidateCacheData(VOID)
{
- CacheManagerDataInvalid = TRUE;
+ CacheManagerDataInvalid = TRUE;
}
BOOLEAN CacheReadDiskSectors(UCHAR DiskNumber, ULONGLONG StartSector, ULONG SectorCount, PVOID Buffer)
{
- PCACHE_BLOCK CacheBlock;
- ULONG StartBlock;
- ULONG SectorOffsetInStartBlock;
- ULONG CopyLengthInStartBlock;
- ULONG EndBlock;
- ULONG SectorOffsetInEndBlock;
- ULONG BlockCount;
- ULONG Idx;
-
- TRACE("CacheReadDiskSectors() DiskNumber: 0x%x StartSector: %I64d SectorCount: %d Buffer: 0x%x\n", DiskNumber, StartSector, SectorCount, Buffer);
-
- // If we aren't initialized yet then they can't do this
- if (CacheManagerInitialized == FALSE)
- {
- return FALSE;
- }
-
- //
- // Caculate which blocks we must cache
- //
- StartBlock = (ULONG)(StartSector / CacheManagerDrive.BlockSize);
- SectorOffsetInStartBlock = (ULONG)(StartSector % CacheManagerDrive.BlockSize);
- CopyLengthInStartBlock = (ULONG)((SectorCount > (CacheManagerDrive.BlockSize - SectorOffsetInStartBlock)) ? (CacheManagerDrive.BlockSize - SectorOffsetInStartBlock) : SectorCount);
- EndBlock = (ULONG)((StartSector + (SectorCount - 1)) / CacheManagerDrive.BlockSize);
- SectorOffsetInEndBlock = (ULONG)(1 + (StartSector + (SectorCount - 1)) % CacheManagerDrive.BlockSize);
- BlockCount = (EndBlock - StartBlock) + 1;
- TRACE("StartBlock: %d SectorOffsetInStartBlock: %d CopyLengthInStartBlock: %d EndBlock: %d SectorOffsetInEndBlock: %d BlockCount: %d\n", StartBlock, SectorOffsetInStartBlock, CopyLengthInStartBlock, EndBlock, SectorOffsetInEndBlock, BlockCount);
-
- //
- // Read the first block into the buffer
- //
- if (BlockCount > 0)
- {
- //
- // Get cache block pointer (this forces the disk sectors into the cache memory)
- //
- CacheBlock = CacheInternalGetBlockPointer(&CacheManagerDrive, StartBlock);
- if (CacheBlock == NULL)
- {
- return FALSE;
- }
-
- //
- // Copy the portion requested into the buffer
- //
- RtlCopyMemory(Buffer,
- (PVOID)((ULONG_PTR)CacheBlock->BlockData + (SectorOffsetInStartBlock * CacheManagerDrive.BytesPerSector)),
- (CopyLengthInStartBlock * CacheManagerDrive.BytesPerSector));
- TRACE("1 - RtlCopyMemory(0x%x, 0x%x, %d)\n", Buffer, ((ULONG_PTR)CacheBlock->BlockData + (SectorOffsetInStartBlock * CacheManagerDrive.BytesPerSector)), (CopyLengthInStartBlock * CacheManagerDrive.BytesPerSector));
-
- //
- // Update the buffer address
- //
- Buffer = (PVOID)((ULONG_PTR)Buffer + (CopyLengthInStartBlock * CacheManagerDrive.BytesPerSector));
-
- //
- // Update the block count
- //
- BlockCount--;
- }
-
- //
- // Loop through the middle blocks and read them into the buffer
- //
- for (Idx=StartBlock+1; BlockCount>1; Idx++)
- {
- //
- // Get cache block pointer (this forces the disk sectors into the cache memory)
- //
- CacheBlock = CacheInternalGetBlockPointer(&CacheManagerDrive, Idx);
- if (CacheBlock == NULL)
- {
- return FALSE;
- }
-
- //
- // Copy the portion requested into the buffer
- //
- RtlCopyMemory(Buffer,
- CacheBlock->BlockData,
- CacheManagerDrive.BlockSize * CacheManagerDrive.BytesPerSector);
- TRACE("2 - RtlCopyMemory(0x%x, 0x%x, %d)\n", Buffer, CacheBlock->BlockData, CacheManagerDrive.BlockSize * CacheManagerDrive.BytesPerSector);
-
- //
- // Update the buffer address
- //
- Buffer = (PVOID)((ULONG_PTR)Buffer + (CacheManagerDrive.BlockSize * CacheManagerDrive.BytesPerSector));
-
- //
- // Update the block count
- //
- BlockCount--;
- }
-
- //
- // Read the last block into the buffer
- //
- if (BlockCount > 0)
- {
- //
- // Get cache block pointer (this forces the disk sectors into the cache memory)
- //
- CacheBlock = CacheInternalGetBlockPointer(&CacheManagerDrive, EndBlock);
- if (CacheBlock == NULL)
- {
- return FALSE;
- }
-
- //
- // Copy the portion requested into the buffer
- //
- RtlCopyMemory(Buffer,
- CacheBlock->BlockData,
- SectorOffsetInEndBlock * CacheManagerDrive.BytesPerSector);
- TRACE("3 - RtlCopyMemory(0x%x, 0x%x, %d)\n", Buffer, CacheBlock->BlockData, SectorOffsetInEndBlock * CacheManagerDrive.BytesPerSector);
-
- //
- // Update the buffer address
- //
- Buffer = (PVOID)((ULONG_PTR)Buffer + (SectorOffsetInEndBlock * CacheManagerDrive.BytesPerSector));
-
- //
- // Update the block count
- //
- BlockCount--;
- }
-
- return TRUE;
+ PCACHE_BLOCK CacheBlock;
+ ULONG StartBlock;
+ ULONG SectorOffsetInStartBlock;
+ ULONG CopyLengthInStartBlock;
+ ULONG EndBlock;
+ ULONG SectorOffsetInEndBlock;
+ ULONG BlockCount;
+ ULONG Idx;
+
+ TRACE("CacheReadDiskSectors() DiskNumber: 0x%x StartSector: %I64d SectorCount: %d Buffer: 0x%x\n", DiskNumber, StartSector, SectorCount, Buffer);
+
+ // If we aren't initialized yet then they can't do this
+ if (CacheManagerInitialized == FALSE)
+ {
+ return FALSE;
+ }
+
+ //
+ // Calculate which blocks we must cache
+ //
+ StartBlock = (ULONG)(StartSector / CacheManagerDrive.BlockSize);
+ SectorOffsetInStartBlock = (ULONG)(StartSector % CacheManagerDrive.BlockSize);
+ CopyLengthInStartBlock = (ULONG)((SectorCount > (CacheManagerDrive.BlockSize - SectorOffsetInStartBlock)) ? (CacheManagerDrive.BlockSize - SectorOffsetInStartBlock) : SectorCount);
+ EndBlock = (ULONG)((StartSector + (SectorCount - 1)) / CacheManagerDrive.BlockSize);
+ SectorOffsetInEndBlock = (ULONG)(1 + (StartSector + (SectorCount - 1)) % CacheManagerDrive.BlockSize);
+ BlockCount = (EndBlock - StartBlock) + 1;
+ TRACE("StartBlock: %d SectorOffsetInStartBlock: %d CopyLengthInStartBlock: %d EndBlock: %d SectorOffsetInEndBlock: %d BlockCount: %d\n", StartBlock, SectorOffsetInStartBlock, CopyLengthInStartBlock, EndBlock, SectorOffsetInEndBlock, BlockCount);
+
+ //
+ // Read the first block into the buffer
+ //
+ if (BlockCount > 0)
+ {
+ //
+ // Get cache block pointer (this forces the disk sectors into the cache memory)
+ //
+ CacheBlock = CacheInternalGetBlockPointer(&CacheManagerDrive, StartBlock);
+ if (CacheBlock == NULL)
+ {
+ return FALSE;
+ }
+
+ //
+ // Copy the portion requested into the buffer
+ //
+ RtlCopyMemory(Buffer,
+ (PVOID)((ULONG_PTR)CacheBlock->BlockData + (SectorOffsetInStartBlock * CacheManagerDrive.BytesPerSector)),
+ (CopyLengthInStartBlock * CacheManagerDrive.BytesPerSector));
+ TRACE("1 - RtlCopyMemory(0x%x, 0x%x, %d)\n", Buffer, ((ULONG_PTR)CacheBlock->BlockData + (SectorOffsetInStartBlock * CacheManagerDrive.BytesPerSector)), (CopyLengthInStartBlock * CacheManagerDrive.BytesPerSector));
+
+ //
+ // Update the buffer address
+ //
+ Buffer = (PVOID)((ULONG_PTR)Buffer + (CopyLengthInStartBlock * CacheManagerDrive.BytesPerSector));
+
+ //
+ // Update the block count
+ //
+ BlockCount--;
+ }
+
+ //
+ // Loop through the middle blocks and read them into the buffer
+ //
+ for (Idx=StartBlock+1; BlockCount>1; Idx++)
+ {
+ //
+ // Get cache block pointer (this forces the disk sectors into the cache memory)
+ //
+ CacheBlock = CacheInternalGetBlockPointer(&CacheManagerDrive, Idx);
+ if (CacheBlock == NULL)
+ {
+ return FALSE;
+ }
+
+ //
+ // Copy the portion requested into the buffer
+ //
+ RtlCopyMemory(Buffer,
+ CacheBlock->BlockData,
+ CacheManagerDrive.BlockSize * CacheManagerDrive.BytesPerSector);
+ TRACE("2 - RtlCopyMemory(0x%x, 0x%x, %d)\n", Buffer, CacheBlock->BlockData, CacheManagerDrive.BlockSize * CacheManagerDrive.BytesPerSector);
+
+ //
+ // Update the buffer address
+ //
+ Buffer = (PVOID)((ULONG_PTR)Buffer + (CacheManagerDrive.BlockSize * CacheManagerDrive.BytesPerSector));
+
+ //
+ // Update the block count
+ //
+ BlockCount--;
+ }
+
+ //
+ // Read the last block into the buffer
+ //
+ if (BlockCount > 0)
+ {
+ //
+ // Get cache block pointer (this forces the disk sectors into the cache memory)
+ //
+ CacheBlock = CacheInternalGetBlockPointer(&CacheManagerDrive, EndBlock);
+ if (CacheBlock == NULL)
+ {
+ return FALSE;
+ }
+
+ //
+ // Copy the portion requested into the buffer
+ //
+ RtlCopyMemory(Buffer,
+ CacheBlock->BlockData,
+ SectorOffsetInEndBlock * CacheManagerDrive.BytesPerSector);
+ TRACE("3 - RtlCopyMemory(0x%x, 0x%x, %d)\n", Buffer, CacheBlock->BlockData, SectorOffsetInEndBlock * CacheManagerDrive.BytesPerSector);
+
+ //
+ // Update the buffer address
+ //
+ Buffer = (PVOID)((ULONG_PTR)Buffer + (SectorOffsetInEndBlock * CacheManagerDrive.BytesPerSector));
+
+ //
+ // Update the block count
+ //
+ BlockCount--;
+ }
+
+ return TRUE;
}
#if 0
BOOLEAN CacheForceDiskSectorsIntoCache(UCHAR DiskNumber, ULONGLONG StartSector, ULONG SectorCount)
{
- PCACHE_BLOCK CacheBlock;
- ULONG StartBlock;
- ULONG EndBlock;
- ULONG BlockCount;
- ULONG Idx;
-
- TRACE("CacheForceDiskSectorsIntoCache() DiskNumber: 0x%x StartSector: %d SectorCount: %d\n", DiskNumber, StartSector, SectorCount);
-
- // If we aren't initialized yet then they can't do this
- if (CacheManagerInitialized == FALSE)
- {
- return FALSE;
- }
-
- //
- // Caculate which blocks we must cache
- //
- StartBlock = StartSector / CacheManagerDrive.BlockSize;
- EndBlock = (StartSector + SectorCount) / CacheManagerDrive.BlockSize;
- BlockCount = (EndBlock - StartBlock) + 1;
-
- //
- // Loop through and cache them
- //
- for (Idx=StartBlock; Idx<(StartBlock+BlockCount); Idx++)
- {
- //
- // Get cache block pointer (this forces the disk sectors into the cache memory)
- //
- CacheBlock = CacheInternalGetBlockPointer(&CacheManagerDrive, Idx);
- if (CacheBlock == NULL)
- {
- return FALSE;
- }
-
- //
- // Lock the sectors into the cache
- //
- CacheBlock->LockedInCache = TRUE;
- }
-
- return TRUE;
+ PCACHE_BLOCK CacheBlock;
+ ULONG StartBlock;
+ ULONG EndBlock;
+ ULONG BlockCount;
+ ULONG Idx;
+
+ TRACE("CacheForceDiskSectorsIntoCache() DiskNumber: 0x%x StartSector: %d SectorCount: %d\n", DiskNumber, StartSector, SectorCount);
+
+ // If we aren't initialized yet then they can't do this
+ if (CacheManagerInitialized == FALSE)
+ {
+ return FALSE;
+ }
+
+ //
+ // Calculate which blocks we must cache
+ //
+ StartBlock = StartSector / CacheManagerDrive.BlockSize;
+ EndBlock = (StartSector + SectorCount) / CacheManagerDrive.BlockSize;
+ BlockCount = (EndBlock - StartBlock) + 1;
+
+ //
+ // Loop through and cache them
+ //
+ for (Idx=StartBlock; Idx<(StartBlock+BlockCount); Idx++)
+ {
+ //
+ // Get cache block pointer (this forces the disk sectors into the cache memory)
+ //
+ CacheBlock = CacheInternalGetBlockPointer(&CacheManagerDrive, Idx);
+ if (CacheBlock == NULL)
+ {
+ return FALSE;
+ }
+
+ //
+ // Lock the sectors into the cache
+ //
+ CacheBlock->LockedInCache = TRUE;
+ }
+
+ return TRUE;
}
#endif
BOOLEAN CacheReleaseMemory(ULONG MinimumAmountToRelease)
{
- ULONG AmountReleased;
-
- TRACE("CacheReleaseMemory() MinimumAmountToRelease = %d\n", MinimumAmountToRelease);
-
- // If we aren't initialized yet then they can't do this
- if (CacheManagerInitialized == FALSE)
- {
- return FALSE;
- }
-
- // Loop through and try to free the requested amount of memory
- for (AmountReleased=0; AmountReleased<MinimumAmountToRelease; )
- {
- // Try to free a block
- // If this fails then break out of the loop
- if (!CacheInternalFreeBlock(&CacheManagerDrive))
- {
- break;
- }
-
- // It succeeded so increment the amount of memory we have freed
- AmountReleased += CacheManagerDrive.BlockSize * CacheManagerDrive.BytesPerSector;
- }
-
- // Return status
- return (AmountReleased >= MinimumAmountToRelease);
+ ULONG AmountReleased;
+
+ TRACE("CacheReleaseMemory() MinimumAmountToRelease = %d\n", MinimumAmountToRelease);
+
+ // If we aren't initialized yet then they can't do this
+ if (CacheManagerInitialized == FALSE)
+ {
+ return FALSE;
+ }
+
+ // Loop through and try to free the requested amount of memory
+ for (AmountReleased=0; AmountReleased<MinimumAmountToRelease; )
+ {
+ // Try to free a block
+ // If this fails then break out of the loop
+ if (!CacheInternalFreeBlock(&CacheManagerDrive))
+ {
+ break;
+ }
+
+ // It succeeded so increment the amount of memory we have freed
+ AmountReleased += CacheManagerDrive.BlockSize * CacheManagerDrive.BytesPerSector;
+ }
+
+ // Return status
+ return (AmountReleased >= MinimumAmountToRelease);
}