ReactOS 0.4.15-dev-8061-g57b775e
cache.c
Go to the documentation of this file.
1/*
2 * FreeLoader
3 * Copyright (C) 1998-2003 Brian Palmer <brianp@sginet.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20#include <freeldr.h>
21
22#include <debug.h>
24
26//
27// Internal data
28//
36
38{
39 PCACHE_BLOCK NextCacheBlock;
40 GEOMETRY DriveGeometry;
41
42 // If we already have a cache for this drive then
43 // by all means lets keep it, unless it is a removable
44 // drive, in which case we'll invalidate the cache
46 (DriveNumber == CacheManagerDrive.DriveNumber) &&
47 (DriveNumber >= 0x80) &&
49 {
50 return TRUE;
51 }
52
54
55 //
56 // If we have already been initialized then free
57 // the old data
58 //
60 {
62
63 TRACE("CacheBlockCount: %d\n", CacheBlockCount);
64 TRACE("CacheSizeLimit: %d\n", CacheSizeLimit);
65 TRACE("CacheSizeCurrent: %d\n", CacheSizeCurrent);
66 //
67 // Loop through and free the cache blocks
68 //
70 {
73 ListEntry);
74
75 FrLdrTempFree(NextCacheBlock->BlockData, TAG_CACHE_DATA);
76 FrLdrTempFree(NextCacheBlock, TAG_CACHE_BLOCK);
77 }
78 }
79
80 // Initialize the structure
83 CacheManagerDrive.DriveNumber = DriveNumber;
84 if (!MachDiskGetDriveGeometry(DriveNumber, &DriveGeometry))
85 {
86 return FALSE;
87 }
89
90 // Get the number of sectors in each cache block
92
95 CacheSizeLimit = TotalPagesInLookupTable / 8 * MM_PAGE_SIZE;
97
99
100 TRACE("Initializing BIOS drive 0x%x.\n", DriveNumber);
101 TRACE("BytesPerSector: %d.\n", CacheManagerDrive.BytesPerSector);
102 TRACE("BlockSize: %d.\n", CacheManagerDrive.BlockSize);
103 TRACE("CacheSizeLimit: %d.\n", CacheSizeLimit);
104
105 return TRUE;
106}
107
109{
111}
112
114{
115 PCACHE_BLOCK CacheBlock;
116 ULONG StartBlock;
117 ULONG SectorOffsetInStartBlock;
118 ULONG CopyLengthInStartBlock;
119 ULONG EndBlock;
120 ULONG SectorOffsetInEndBlock;
121 ULONG BlockCount;
122 ULONG Idx;
123
124 TRACE("CacheReadDiskSectors() DiskNumber: 0x%x StartSector: %I64d SectorCount: %d Buffer: 0x%x\n", DiskNumber, StartSector, SectorCount, Buffer);
125
126 // If we aren't initialized yet then they can't do this
128 {
129 return FALSE;
130 }
131
132 //
133 // Calculate which blocks we must cache
134 //
135 StartBlock = (ULONG)(StartSector / CacheManagerDrive.BlockSize);
136 SectorOffsetInStartBlock = (ULONG)(StartSector % CacheManagerDrive.BlockSize);
137 CopyLengthInStartBlock = (ULONG)((SectorCount > (CacheManagerDrive.BlockSize - SectorOffsetInStartBlock)) ? (CacheManagerDrive.BlockSize - SectorOffsetInStartBlock) : SectorCount);
138 EndBlock = (ULONG)((StartSector + (SectorCount - 1)) / CacheManagerDrive.BlockSize);
139 SectorOffsetInEndBlock = (ULONG)(1 + (StartSector + (SectorCount - 1)) % CacheManagerDrive.BlockSize);
140 BlockCount = (EndBlock - StartBlock) + 1;
141 TRACE("StartBlock: %d SectorOffsetInStartBlock: %d CopyLengthInStartBlock: %d EndBlock: %d SectorOffsetInEndBlock: %d BlockCount: %d\n", StartBlock, SectorOffsetInStartBlock, CopyLengthInStartBlock, EndBlock, SectorOffsetInEndBlock, BlockCount);
142
143 //
144 // Read the first block into the buffer
145 //
146 if (BlockCount > 0)
147 {
148 //
149 // Get cache block pointer (this forces the disk sectors into the cache memory)
150 //
151 CacheBlock = CacheInternalGetBlockPointer(&CacheManagerDrive, StartBlock);
152 if (CacheBlock == NULL)
153 {
154 return FALSE;
155 }
156
157 //
158 // Copy the portion requested into the buffer
159 //
161 (PVOID)((ULONG_PTR)CacheBlock->BlockData + (SectorOffsetInStartBlock * CacheManagerDrive.BytesPerSector)),
162 (CopyLengthInStartBlock * CacheManagerDrive.BytesPerSector));
163 TRACE("1 - RtlCopyMemory(0x%x, 0x%x, %d)\n", Buffer, ((ULONG_PTR)CacheBlock->BlockData + (SectorOffsetInStartBlock * CacheManagerDrive.BytesPerSector)), (CopyLengthInStartBlock * CacheManagerDrive.BytesPerSector));
164
165 //
166 // Update the buffer address
167 //
168 Buffer = (PVOID)((ULONG_PTR)Buffer + (CopyLengthInStartBlock * CacheManagerDrive.BytesPerSector));
169
170 //
171 // Update the block count
172 //
173 BlockCount--;
174 }
175
176 //
177 // Loop through the middle blocks and read them into the buffer
178 //
179 for (Idx=StartBlock+1; BlockCount>1; Idx++)
180 {
181 //
182 // Get cache block pointer (this forces the disk sectors into the cache memory)
183 //
185 if (CacheBlock == NULL)
186 {
187 return FALSE;
188 }
189
190 //
191 // Copy the portion requested into the buffer
192 //
194 CacheBlock->BlockData,
196 TRACE("2 - RtlCopyMemory(0x%x, 0x%x, %d)\n", Buffer, CacheBlock->BlockData, CacheManagerDrive.BlockSize * CacheManagerDrive.BytesPerSector);
197
198 //
199 // Update the buffer address
200 //
202
203 //
204 // Update the block count
205 //
206 BlockCount--;
207 }
208
209 //
210 // Read the last block into the buffer
211 //
212 if (BlockCount > 0)
213 {
214 //
215 // Get cache block pointer (this forces the disk sectors into the cache memory)
216 //
217 CacheBlock = CacheInternalGetBlockPointer(&CacheManagerDrive, EndBlock);
218 if (CacheBlock == NULL)
219 {
220 return FALSE;
221 }
222
223 //
224 // Copy the portion requested into the buffer
225 //
227 CacheBlock->BlockData,
228 SectorOffsetInEndBlock * CacheManagerDrive.BytesPerSector);
229 TRACE("3 - RtlCopyMemory(0x%x, 0x%x, %d)\n", Buffer, CacheBlock->BlockData, SectorOffsetInEndBlock * CacheManagerDrive.BytesPerSector);
230
231 //
232 // Update the buffer address
233 //
234 Buffer = (PVOID)((ULONG_PTR)Buffer + (SectorOffsetInEndBlock * CacheManagerDrive.BytesPerSector));
235
236 //
237 // Update the block count
238 //
239 BlockCount--;
240 }
241
242 return TRUE;
243}
244
245#if 0
247{
248 PCACHE_BLOCK CacheBlock;
249 ULONG StartBlock;
250 ULONG EndBlock;
251 ULONG BlockCount;
252 ULONG Idx;
253
254 TRACE("CacheForceDiskSectorsIntoCache() DiskNumber: 0x%x StartSector: %d SectorCount: %d\n", DiskNumber, StartSector, SectorCount);
255
256 // If we aren't initialized yet then they can't do this
258 {
259 return FALSE;
260 }
261
262 //
263 // Calculate which blocks we must cache
264 //
265 StartBlock = StartSector / CacheManagerDrive.BlockSize;
266 EndBlock = (StartSector + SectorCount) / CacheManagerDrive.BlockSize;
267 BlockCount = (EndBlock - StartBlock) + 1;
268
269 //
270 // Loop through and cache them
271 //
272 for (Idx=StartBlock; Idx<(StartBlock+BlockCount); Idx++)
273 {
274 //
275 // Get cache block pointer (this forces the disk sectors into the cache memory)
276 //
278 if (CacheBlock == NULL)
279 {
280 return FALSE;
281 }
282
283 //
284 // Lock the sectors into the cache
285 //
286 CacheBlock->LockedInCache = TRUE;
287 }
288
289 return TRUE;
290}
291#endif
292
293BOOLEAN CacheReleaseMemory(ULONG MinimumAmountToRelease)
294{
295 ULONG AmountReleased;
296
297 TRACE("CacheReleaseMemory() MinimumAmountToRelease = %d\n", MinimumAmountToRelease);
298
299 // If we aren't initialized yet then they can't do this
301 {
302 return FALSE;
303 }
304
305 // Loop through and try to free the requested amount of memory
306 for (AmountReleased=0; AmountReleased<MinimumAmountToRelease; )
307 {
308 // Try to free a block
309 // If this fails then break out of the loop
311 {
312 break;
313 }
314
315 // It succeeded so increment the amount of memory we have freed
317 }
318
319 // Return status
320 return (AmountReleased >= MinimumAmountToRelease);
321}
unsigned char BOOLEAN
#define TAG_CACHE_DATA
Definition: cache.h:23
BOOLEAN CacheForceDiskSectorsIntoCache(UCHAR DiskNumber, ULONGLONG StartSector, ULONG SectorCount)
BOOLEAN CacheInternalFreeBlock(PCACHE_DRIVE CacheDrive)
Definition: blocklist.c:142
PCACHE_BLOCK CacheInternalGetBlockPointer(PCACHE_DRIVE CacheDrive, ULONG BlockNumber)
Definition: blocklist.c:28
#define TAG_CACHE_BLOCK
Definition: cache.h:24
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:106
#define MachDiskGetDriveGeometry(Drive, Geom)
Definition: machine.h:128
#define MachDiskGetCacheableBlockCount(Drive)
Definition: machine.h:130
PFN_NUMBER TotalPagesInLookupTable
Definition: meminit.c:27
FORCEINLINE VOID FrLdrTempFree(PVOID Allocation, ULONG Tag)
Definition: mm.h:197
#define TEMP_HEAP_SIZE
Definition: mm.h:134
SIZE_T CacheSizeLimit
Definition: cache.c:34
VOID CacheInvalidateCacheData(VOID)
Definition: cache.c:108
BOOLEAN CacheReadDiskSectors(UCHAR DiskNumber, ULONGLONG StartSector, ULONG SectorCount, PVOID Buffer)
Definition: cache.c:113
BOOLEAN CacheManagerDataInvalid
Definition: cache.c:32
CACHE_DRIVE CacheManagerDrive
Definition: cache.c:30
BOOLEAN CacheManagerInitialized
Definition: cache.c:31
BOOLEAN CacheInitializeDrive(UCHAR DriveNumber)
Definition: cache.c:37
BOOLEAN CacheReleaseMemory(ULONG MinimumAmountToRelease)
Definition: cache.c:293
ULONG CacheBlockCount
Definition: cache.c:33
SIZE_T CacheSizeCurrent
Definition: cache.c:35
Definition: bufpool.h:45
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define RemoveHeadList(ListHead)
Definition: env_spec_w32.h:964
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define min(a, b)
Definition: monoChain.cc:55
ULONG SectorCount
Definition: part_xbox.c:31
#define TRACE(s)
Definition: solgame.cpp:4
BOOLEAN LockedInCache
Definition: cache.h:40
PVOID BlockData
Definition: cache.h:43
ULONG BytesPerSector
Definition: cache.h:57
LIST_ENTRY CacheBlockHead
Definition: cache.h:60
ULONG BlockSize
Definition: cache.h:59
UCHAR DriveNumber
Definition: cache.h:56
Definition: disk.h:25
ULONG BytesPerSector
Definition: disk.h:29
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
unsigned char UCHAR
Definition: xmlstorage.h:181