VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/FatPkg/EnhancedFatDxe/DiskCache.c@ 108794

Last change on this file since 108794 was 108794, checked in by vboxsync, 4 weeks ago

Devices/EFI/FirmwareNew: Merge edk2-stable202502 from the vendor branch and make it build for the important platforms, bugref:4643

  • Property svn:eol-style set to native
File size: 20.6 KB
Line 
1/** @file
2 Cache implementation for EFI FAT File system driver.
3
4Copyright (c) 2005 - 2013, Intel Corporation. All rights reserved.<BR>
5SPDX-License-Identifier: BSD-2-Clause-Patent
6
7**/
8
9#include "Fat.h"
10
11/**
12 Helper function to clear the dirty state of the cache line.
13
14 @param[in] CacheTag - CacheTag to clear
15
16**/
17STATIC
18VOID
19ClearCacheTagDirtyState (
20 IN CACHE_TAG *CacheTag
21 )
22{
23 if (CacheTag == NULL) {
24 ASSERT (CacheTag != NULL);
25 return;
26 }
27
28 ZeroMem (CacheTag->DirtyBlocks, sizeof (CacheTag->DirtyBlocks));
29 CacheTag->Dirty = FALSE;
30}
31
32/**
33 Helper function to set a bit in a dirty block. This is used to
34 track which blocks to later write to disk.
35
36 @param[in] BitNumber - Which bit to set in DirtyBlocks
37 @param[in] DirtyBlocks - Array of bits
38
39**/
40STATIC
41VOID
42SetBitInDirtyBlock (
43 IN UINTN BitNumber,
44 IN DIRTY_BLOCKS *DirtyBlocks
45 )
46{
47 UINTN BlockIndex;
48 UINTN BitIndex;
49
50 //
51 // ASSERTs checking BitNumber are DEBUG build only to verify the assumptions in the
52 // Fat.h defines (See Fat.h lines to describe DIRTY_BITS)
53 //
54 ASSERT (BitNumber < DIRTY_BITS);
55
56 BlockIndex = BitNumber / DIRTY_BITS_PER_BLOCK;
57 BitIndex = BitNumber % DIRTY_BITS_PER_BLOCK;
58 DirtyBlocks[BlockIndex] |= LShiftU64 (1ull, BitIndex);
59}
60
61/**
62 Helper function to check if a particular bit in a dirty block is marked dirty or not,
63 so that it can be written to the disk if it is dirty.
64
65 @param[in] BitNumber - Which bit to check in DirtyBlocks
66 @param[in] DirtyBlocks - Array of bits
67
68**/
69STATIC
70BOOLEAN
71IsBitInBlockDirty (
72 IN UINTN BitNumber,
73 IN DIRTY_BLOCKS *DirtyBlocks
74 )
75{
76 UINTN BlockIndex;
77 UINTN BitIndex;
78
79 ASSERT (BitNumber < DIRTY_BITS);
80
81 BlockIndex = BitNumber / DIRTY_BITS_PER_BLOCK;
82 BitIndex = BitNumber % DIRTY_BITS_PER_BLOCK;
83 return (DirtyBlocks[BlockIndex] & LShiftU64 (1ull, BitIndex)) != 0;
84}
85
86/**
87 Helper function to set a cache tag dirty for a given offset and length. Dirty blocks marked
88 here will be flushed to disk when the file is closed.
89
90 @param[in] DiskCache - DiskCache
91 @param[in] CacheTag - CacheTag to update
92 @param[in] Offset - Offset in the cache line to be marked modified
93 @param[in] Length - Length of the data to be marked modified
94
95**/
96STATIC
97VOID
98SetCacheTagDirty (
99 IN DISK_CACHE *DiskCache,
100 IN CACHE_TAG *CacheTag,
101 IN UINTN Offset,
102 IN UINTN Length
103 )
104{
105 UINTN Bit;
106 UINTN LastBit;
107
108 Bit = Offset / DiskCache->BlockSize;
109 LastBit = (Offset + Length - 1) / DiskCache->BlockSize;
110
111 ASSERT (Bit <= LastBit);
112 ASSERT (LastBit <= DIRTY_BITS);
113
114 do {
115 SetBitInDirtyBlock (Bit, CacheTag->DirtyBlocks);
116 } while (++Bit <= LastBit);
117
118 CacheTag->Dirty = TRUE;
119}
120
121/**
122 Cache version of FatDiskIo for writing only those LBA's with dirty data.
123
124 Keep track of LBA blocks within a cache line. Allow reads from the disk to read the
125 full cache line, and all writes to the cache line will update which Lba is dirty in DIRTY_BITS.
126
127 At flush time, when the cache line is written out, only write the blocks that are dirty, coalescing
128 adjacent writes to a single FatDiskIo write.
129
130 @param[in] CacheTag - Cache line to check for dirty bits from
131 @param[in] DataType - Type of Cache.
132 @param[in] Volume - FAT file system volume.
133 @param[in] IoMode - The access mode (disk read/write or cache access).
134 @param[in] Offset - The starting byte offset to read from.
135 @param[in] BufferSize - Size of Buffer.
136 @param[in, out] Buffer - Buffer containing read data.
137 @param[in] Task point to task instance.
138
139 @retval EFI_SUCCESS - The operation is performed successfully.
140 @retval EFI_VOLUME_CORRUPTED - The access is
141 @return Others - The status of read/write the disk
142
143**/
144STATIC
145EFI_STATUS
146CacheFatDiskIo (
147 IN CACHE_TAG *CacheTag,
148 IN CACHE_DATA_TYPE DataType,
149 IN FAT_VOLUME *Volume,
150 IN IO_MODE IoMode,
151 IN UINT64 Offset,
152 IN UINTN BufferSize,
153 IN OUT VOID *Buffer,
154 IN FAT_TASK *Task
155 )
156{
157 DISK_CACHE *DiskCache;
158 UINTN BlockIndexInTag;
159 VOID *WriteBuffer;
160 UINTN LastBit;
161 UINT64 StartPos;
162 EFI_STATUS Status;
163 UINTN WriteSize;
164
165 Status = EFI_SUCCESS;
166 if ((IoMode == WriteDisk) && (CacheTag->RealSize != 0)) {
167 DiskCache = &Volume->DiskCache[DataType];
168 WriteBuffer = Buffer;
169 LastBit = (CacheTag->RealSize - 1) / DiskCache->BlockSize;
170 StartPos = Offset;
171 BlockIndexInTag = 0;
172 WriteSize = 0;
173
174 do {
175 if (IsBitInBlockDirty (BlockIndexInTag, CacheTag->DirtyBlocks)) {
176 do {
177 WriteSize += DiskCache->BlockSize;
178 BlockIndexInTag++;
179 if (BlockIndexInTag > LastBit) {
180 break;
181 }
182 } while (IsBitInBlockDirty (BlockIndexInTag, CacheTag->DirtyBlocks));
183
184 Status = FatDiskIo (Volume, IoMode, StartPos, WriteSize, WriteBuffer, Task);
185 if (EFI_ERROR (Status)) {
186 return Status;
187 }
188
189 StartPos += WriteSize + DiskCache->BlockSize;
190 WriteBuffer = (VOID *)((UINTN)WriteBuffer + WriteSize + DiskCache->BlockSize);
191 WriteSize = 0;
192 BlockIndexInTag++;
193 } else {
194 StartPos += DiskCache->BlockSize;
195 WriteBuffer = (VOID *)((UINTN)WriteBuffer + DiskCache->BlockSize);
196 BlockIndexInTag++;
197 }
198 } while (BlockIndexInTag <= LastBit);
199
200 ASSERT (WriteSize == 0);
201 } else {
202 Status = FatDiskIo (Volume, IoMode, Offset, BufferSize, Buffer, Task);
203 if (EFI_ERROR (Status)) {
204 return Status;
205 }
206 }
207
208 return Status;
209}
210
211/**
212
213 This function is used by the Data Cache.
214
215 When this function is called by write command, all entries in this range
216 are older than the contents in disk, so they are invalid; just mark them invalid.
217
218 When this function is called by read command, if any entry in this range
219 is dirty, it means that the relative info directly read from media is older than
220 than the info in the cache; So need to update the relative info in the Buffer.
221
222 @param Volume - FAT file system volume.
223 @param IoMode - This function is called by read command or write command
224 @param StartPageNo - First PageNo to be checked in the cache.
225 @param EndPageNo - Last PageNo to be checked in the cache.
226 @param Buffer - The user buffer need to update. Only when doing the read command
227 and there is dirty cache in the cache range, this parameter will be used.
228
229**/
230STATIC
231VOID
232FatFlushDataCacheRange (
233 IN FAT_VOLUME *Volume,
234 IN IO_MODE IoMode,
235 IN UINTN StartPageNo,
236 IN UINTN EndPageNo,
237 OUT UINT8 *Buffer
238 )
239{
240 UINTN PageNo;
241 UINTN GroupNo;
242 UINTN GroupMask;
243 UINTN PageSize;
244 UINT8 PageAlignment;
245 DISK_CACHE *DiskCache;
246 CACHE_TAG *CacheTag;
247 UINT8 *BaseAddress;
248
249 DiskCache = &Volume->DiskCache[CacheData];
250 BaseAddress = DiskCache->CacheBase;
251 GroupMask = DiskCache->GroupMask;
252 PageAlignment = DiskCache->PageAlignment;
253 PageSize = (UINTN)1 << PageAlignment;
254
255 for (PageNo = StartPageNo; PageNo < EndPageNo; PageNo++) {
256 GroupNo = PageNo & GroupMask;
257 CacheTag = &DiskCache->CacheTag[GroupNo];
258 if ((CacheTag->RealSize > 0) && (CacheTag->PageNo == PageNo)) {
259 //
260 // When reading data from disk directly, if some dirty data
261 // in cache is in this range, this data in the Buffer needs to
262 // be updated with the cache's dirty data.
263 //
264 if (IoMode == ReadDisk) {
265 if (CacheTag->Dirty) {
266 CopyMem (
267 Buffer + ((PageNo - StartPageNo) << PageAlignment),
268 BaseAddress + (GroupNo << PageAlignment),
269 PageSize
270 );
271 }
272 } else {
273 //
274 // Make all valid entries in this range invalid.
275 //
276 CacheTag->RealSize = 0;
277 }
278 }
279 }
280}
281
282/**
283
284 Exchange the cache page with the image on the disk
285
286 @param Volume - FAT file system volume.
287 @param DataType - Indicate the cache type.
288 @param IoMode - Indicate whether to load this page from disk or store this page to disk.
289 @param CacheTag - The Cache Tag for the current cache page.
290 @param Task point to task instance.
291
292 @retval EFI_SUCCESS - Cache page exchanged successfully.
293 @return Others - An error occurred when exchanging cache page.
294
295**/
296STATIC
297EFI_STATUS
298FatExchangeCachePage (
299 IN FAT_VOLUME *Volume,
300 IN CACHE_DATA_TYPE DataType,
301 IN IO_MODE IoMode,
302 IN CACHE_TAG *CacheTag,
303 IN FAT_TASK *Task
304 )
305{
306 EFI_STATUS Status;
307 UINTN GroupNo;
308 UINTN PageNo;
309 UINTN WriteCount;
310 UINTN RealSize;
311 UINT64 EntryPos;
312 UINT64 MaxSize;
313 DISK_CACHE *DiskCache;
314 VOID *PageAddress;
315 UINT8 PageAlignment;
316
317 DiskCache = &Volume->DiskCache[DataType];
318 PageNo = CacheTag->PageNo;
319 GroupNo = PageNo & DiskCache->GroupMask;
320 PageAlignment = DiskCache->PageAlignment;
321 PageAddress = DiskCache->CacheBase + (GroupNo << PageAlignment);
322 EntryPos = (DiskCache->BaseAddress + LShiftU64 (PageNo, PageAlignment));
323 RealSize = CacheTag->RealSize;
324 if (IoMode == ReadDisk) {
325 RealSize = (UINTN)1 << PageAlignment;
326 MaxSize = DiskCache->LimitAddress - EntryPos;
327 if (MaxSize < RealSize) {
328 DEBUG ((DEBUG_INFO, "FatDiskIo: Cache Page OutBound occurred! \n"));
329 RealSize = (UINTN)MaxSize;
330 }
331 }
332
333 WriteCount = 1;
334 if ((DataType == CacheFat) && (IoMode == WriteDisk)) {
335 WriteCount = Volume->NumFats;
336 }
337
338 do {
339 //
340 // Only fat table writing will execute more than once
341 //
342 Status = CacheFatDiskIo (CacheTag, DataType, Volume, IoMode, EntryPos, RealSize, PageAddress, Task);
343 if (EFI_ERROR (Status)) {
344 return Status;
345 }
346
347 EntryPos += Volume->FatSize;
348 } while (--WriteCount > 0);
349
350 ClearCacheTagDirtyState (CacheTag);
351 CacheTag->RealSize = RealSize;
352 return EFI_SUCCESS;
353}
354
355/**
356
357 Get one cache page by specified PageNo.
358
359 @param Volume - FAT file system volume.
360 @param CacheDataType - The cache type: CACHE_FAT or CACHE_DATA.
361 @param PageNo - PageNo to match with the cache.
362 @param CacheTag - The Cache Tag for the current cache page.
363
364 @retval EFI_SUCCESS - Get the cache page successfully.
365 @return other - An error occurred when accessing data.
366
367**/
368STATIC
369EFI_STATUS
370FatGetCachePage (
371 IN FAT_VOLUME *Volume,
372 IN CACHE_DATA_TYPE CacheDataType,
373 IN UINTN PageNo,
374 IN CACHE_TAG *CacheTag
375 )
376{
377 EFI_STATUS Status;
378 UINTN OldPageNo;
379
380 OldPageNo = CacheTag->PageNo;
381 if ((CacheTag->RealSize > 0) && (OldPageNo == PageNo)) {
382 //
383 // Cache Hit occurred
384 //
385 return EFI_SUCCESS;
386 }
387
388 //
389 // Write dirty cache page back to disk
390 //
391 if ((CacheTag->RealSize > 0) && CacheTag->Dirty) {
392 Status = FatExchangeCachePage (Volume, CacheDataType, WriteDisk, CacheTag, NULL);
393 if (EFI_ERROR (Status)) {
394 return Status;
395 }
396 }
397
398 //
399 // Load new data from disk;
400 //
401 CacheTag->PageNo = PageNo;
402 Status = FatExchangeCachePage (Volume, CacheDataType, ReadDisk, CacheTag, NULL);
403
404 return Status;
405}
406
407/**
408
409 Read Length bytes from the position of Offset into Buffer, or
410 write Length bytes from Buffer into the position of Offset.
411
412 @param Volume - FAT file system volume.
413 @param CacheDataType - The type of cache: CACHE_DATA or CACHE_FAT.
414 @param IoMode - Indicate the type of disk access.
415 @param PageNo - The number of unaligned cache page.
416 @param Offset - The starting byte of cache page.
417 @param Length - The number of bytes that is read or written
418 @param Buffer - Buffer containing cache data.
419
420 @retval EFI_SUCCESS - The data was accessed correctly.
421 @return Others - An error occurred when accessing unaligned cache page.
422
423**/
424STATIC
425EFI_STATUS
426FatAccessUnalignedCachePage (
427 IN FAT_VOLUME *Volume,
428 IN CACHE_DATA_TYPE CacheDataType,
429 IN IO_MODE IoMode,
430 IN UINTN PageNo,
431 IN UINTN Offset,
432 IN UINTN Length,
433 IN OUT VOID *Buffer
434 )
435{
436 EFI_STATUS Status;
437 VOID *Source;
438 VOID *Destination;
439 DISK_CACHE *DiskCache;
440 CACHE_TAG *CacheTag;
441 UINTN GroupNo;
442
443 DiskCache = &Volume->DiskCache[CacheDataType];
444 GroupNo = PageNo & DiskCache->GroupMask;
445 CacheTag = &DiskCache->CacheTag[GroupNo];
446 Status = FatGetCachePage (Volume, CacheDataType, PageNo, CacheTag);
447 if (!EFI_ERROR (Status)) {
448 Source = DiskCache->CacheBase + (GroupNo << DiskCache->PageAlignment) + Offset;
449 Destination = Buffer;
450 if (IoMode != ReadDisk) {
451 SetCacheTagDirty (DiskCache, CacheTag, Offset, Length);
452 DiskCache->Dirty = TRUE;
453 Destination = Source;
454 Source = Buffer;
455 }
456
457 CopyMem (Destination, Source, Length);
458 }
459
460 return Status;
461}
462
463/**
464
465 Read BufferSize bytes from the position of Offset into Buffer,
466 or write BufferSize bytes from Buffer into the position of Offset.
467
468 Base on the parameter of CACHE_DATA_TYPE, the data access will be divided into
469 the access of FAT cache (CACHE_FAT) and the access of Data cache (CACHE_DATA):
470
471 1. Access of FAT cache (CACHE_FAT): Access the data in the FAT cache, if there is cache
472 page hit, just return the cache page; else update the related cache page and return
473 the right cache page.
474 2. Access of Data cache (CACHE_DATA):
475 The access data will be divided into UnderRun data, Aligned data and OverRun data;
476 The UnderRun data and OverRun data will be accessed by the Data cache,
477 but the Aligned data will be accessed with disk directly.
478
479 @param Volume - FAT file system volume.
480 @param CacheDataType - The type of cache: CACHE_DATA or CACHE_FAT.
481 @param IoMode - Indicate the type of disk access.
482 @param Offset - The starting byte offset to read from.
483 @param BufferSize - Size of Buffer.
484 @param Buffer - Buffer containing cache data.
485 @param Task point to task instance.
486
487 @retval EFI_SUCCESS - The data was accessed correctly.
488 @retval EFI_MEDIA_CHANGED - The MediaId does not match the current device.
489 @return Others - An error occurred when accessing cache.
490
491**/
492EFI_STATUS
493FatAccessCache (
494 IN FAT_VOLUME *Volume,
495 IN CACHE_DATA_TYPE CacheDataType,
496 IN IO_MODE IoMode,
497 IN UINT64 Offset,
498 IN UINTN BufferSize,
499 IN OUT UINT8 *Buffer,
500 IN FAT_TASK *Task
501 )
502{
503 EFI_STATUS Status;
504 UINTN PageSize;
505 UINTN UnderRun;
506 UINTN OverRun;
507 UINTN AlignedSize;
508 UINTN Length;
509 UINTN PageNo;
510 UINTN AlignedPageCount;
511 UINTN OverRunPageNo;
512 DISK_CACHE *DiskCache;
513 UINT64 EntryPos;
514 UINT8 PageAlignment;
515
516 ASSERT (Volume->CacheBuffer != NULL);
517
518 Status = EFI_SUCCESS;
519 DiskCache = &Volume->DiskCache[CacheDataType];
520 EntryPos = Offset - DiskCache->BaseAddress;
521 PageAlignment = DiskCache->PageAlignment;
522 PageSize = (UINTN)1 << PageAlignment;
523 PageNo = (UINTN)RShiftU64 (EntryPos, PageAlignment);
524 UnderRun = ((UINTN)EntryPos) & (PageSize - 1);
525
526 if (UnderRun > 0) {
527 Length = PageSize - UnderRun;
528 if (Length > BufferSize) {
529 Length = BufferSize;
530 }
531
532 Status = FatAccessUnalignedCachePage (Volume, CacheDataType, IoMode, PageNo, UnderRun, Length, Buffer);
533 if (EFI_ERROR (Status)) {
534 return Status;
535 }
536
537 Buffer += Length;
538 BufferSize -= Length;
539 PageNo++;
540 }
541
542 AlignedPageCount = BufferSize >> PageAlignment;
543 OverRunPageNo = PageNo + AlignedPageCount;
544 //
545 // The access of the Aligned data
546 //
547 if (AlignedPageCount > 0) {
548 //
549 // Accessing fat table cannot have alignment data
550 //
551 ASSERT (CacheDataType == CacheData);
552
553 EntryPos = Volume->RootPos + LShiftU64 (PageNo, PageAlignment);
554 AlignedSize = AlignedPageCount << PageAlignment;
555 Status = FatDiskIo (Volume, IoMode, EntryPos, AlignedSize, Buffer, Task);
556 if (EFI_ERROR (Status)) {
557 return Status;
558 }
559
560 //
561 // If these access data over laps the relative cache range, these cache pages need
562 // to be updated.
563 //
564 FatFlushDataCacheRange (Volume, IoMode, PageNo, OverRunPageNo, Buffer);
565 Buffer += AlignedSize;
566 BufferSize -= AlignedSize;
567 }
568
569 //
570 // The access of the OverRun data
571 //
572 OverRun = BufferSize;
573 if (OverRun > 0) {
574 //
575 // Last read is not a complete page
576 //
577 Status = FatAccessUnalignedCachePage (Volume, CacheDataType, IoMode, OverRunPageNo, 0, OverRun, Buffer);
578 }
579
580 return Status;
581}
582
583/**
584
585 Flush all the dirty cache back, include the FAT cache and the Data cache.
586
587 @param Volume - FAT file system volume.
588 @param Task point to task instance.
589
590 @retval EFI_SUCCESS - Flush all the dirty cache back successfully
591 @return other - An error occurred when writing the data into the disk
592
593**/
594EFI_STATUS
595FatVolumeFlushCache (
596 IN FAT_VOLUME *Volume,
597 IN FAT_TASK *Task
598 )
599{
600 EFI_STATUS Status;
601 CACHE_DATA_TYPE CacheDataType;
602 UINTN GroupIndex;
603 UINTN GroupMask;
604 DISK_CACHE *DiskCache;
605 CACHE_TAG *CacheTag;
606
607 for (CacheDataType = (CACHE_DATA_TYPE)0; CacheDataType < CacheMaxType; CacheDataType++) {
608 DiskCache = &Volume->DiskCache[CacheDataType];
609 if (DiskCache->Dirty) {
610 //
611 // Data cache or fat cache is dirty, write the dirty data back
612 //
613 GroupMask = DiskCache->GroupMask;
614 for (GroupIndex = 0; GroupIndex <= GroupMask; GroupIndex++) {
615 CacheTag = &DiskCache->CacheTag[GroupIndex];
616 if ((CacheTag->RealSize > 0) && CacheTag->Dirty) {
617 //
618 // Write back all Dirty Data Cache Page to disk
619 //
620 Status = FatExchangeCachePage (Volume, CacheDataType, WriteDisk, CacheTag, Task);
621 if (EFI_ERROR (Status)) {
622 return Status;
623 }
624 }
625 }
626
627 DiskCache->Dirty = FALSE;
628 }
629 }
630
631 //
632 // Flush the block device.
633 //
634 Status = Volume->BlockIo->FlushBlocks (Volume->BlockIo);
635 return Status;
636}
637
638/**
639
640 Initialize the disk cache according to Volume's FatType.
641
642 @param Volume - FAT file system volume.
643
644 @retval EFI_SUCCESS - The disk cache is successfully initialized.
645 @retval EFI_OUT_OF_RESOURCES - Not enough memory to allocate disk cache.
646
647**/
648EFI_STATUS
649FatInitializeDiskCache (
650 IN FAT_VOLUME *Volume
651 )
652{
653 DISK_CACHE *DiskCache;
654 UINTN FatCacheGroupCount;
655 UINTN DataCacheSize;
656 UINTN FatCacheSize;
657 UINT8 *CacheBuffer;
658
659 DiskCache = Volume->DiskCache;
660 //
661 // Configure the parameters of disk cache
662 //
663 if (Volume->FatType == Fat12) {
664 FatCacheGroupCount = FAT_FATCACHE_GROUP_MIN_COUNT;
665 DiskCache[CacheFat].PageAlignment = FAT_FATCACHE_PAGE_MIN_ALIGNMENT;
666 DiskCache[CacheData].PageAlignment = FAT_DATACACHE_PAGE_MIN_ALIGNMENT;
667 } else {
668 FatCacheGroupCount = FAT_FATCACHE_GROUP_MAX_COUNT;
669 DiskCache[CacheFat].PageAlignment = FAT_FATCACHE_PAGE_MAX_ALIGNMENT;
670 DiskCache[CacheData].PageAlignment = FAT_DATACACHE_PAGE_MAX_ALIGNMENT;
671 }
672
673 DiskCache[CacheData].GroupMask = FAT_DATACACHE_GROUP_COUNT - 1;
674 DiskCache[CacheData].BaseAddress = Volume->RootPos;
675 DiskCache[CacheData].LimitAddress = Volume->VolumeSize;
676 DiskCache[CacheFat].GroupMask = FatCacheGroupCount - 1;
677 DiskCache[CacheFat].BaseAddress = Volume->FatPos;
678 DiskCache[CacheFat].LimitAddress = Volume->FatPos + Volume->FatSize;
679 FatCacheSize = FatCacheGroupCount << DiskCache[CacheFat].PageAlignment;
680 DataCacheSize = FAT_DATACACHE_GROUP_COUNT << DiskCache[CacheData].PageAlignment;
681 //
682 // Allocate the Fat Cache buffer
683 //
684 CacheBuffer = AllocateZeroPool (FatCacheSize + DataCacheSize);
685 if (CacheBuffer == NULL) {
686 return EFI_OUT_OF_RESOURCES;
687 }
688
689 Volume->CacheBuffer = CacheBuffer;
690 DiskCache[CacheFat].CacheBase = CacheBuffer;
691 DiskCache[CacheData].CacheBase = CacheBuffer + FatCacheSize;
692
693 DiskCache[CacheFat].BlockSize = Volume->BlockIo->Media->BlockSize;
694 DiskCache[CacheData].BlockSize = Volume->BlockIo->Media->BlockSize;
695
696 return EFI_SUCCESS;
697}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette