23 if (CacheTag ==
NULL) {
24 ASSERT (CacheTag !=
NULL);
28 ZeroMem (CacheTag->DirtyBlocks, sizeof (CacheTag->DirtyBlocks));
29 CacheTag->Dirty =
FALSE;
44 IN DIRTY_BLOCKS *DirtyBlocks
54 ASSERT (BitNumber < DIRTY_BITS);
56 BlockIndex = BitNumber / DIRTY_BITS_PER_BLOCK;
57 BitIndex = BitNumber % DIRTY_BITS_PER_BLOCK;
58 DirtyBlocks[BlockIndex] |=
LShiftU64 (1ull, BitIndex);
73 IN DIRTY_BLOCKS *DirtyBlocks
79 ASSERT (BitNumber < DIRTY_BITS);
81 BlockIndex = BitNumber / DIRTY_BITS_PER_BLOCK;
82 BitIndex = BitNumber % DIRTY_BITS_PER_BLOCK;
83 return (DirtyBlocks[BlockIndex] &
LShiftU64 (1ull, BitIndex)) != 0;
108 Bit = Offset / DiskCache->BlockSize;
109 LastBit = (Offset + Length - 1) / DiskCache->BlockSize;
111 ASSERT (Bit <= LastBit);
112 ASSERT (LastBit <= DIRTY_BITS);
116 }
while (++Bit <= LastBit);
118 CacheTag->Dirty =
TRUE;
148 IN CACHE_DATA_TYPE DataType,
158 UINTN BlockIndexInTag;
166 if ((IoMode == WriteDisk) && (CacheTag->RealSize != 0)) {
167 DiskCache = &Volume->DiskCache[DataType];
168 WriteBuffer = Buffer;
169 LastBit = (CacheTag->RealSize - 1) / DiskCache->BlockSize;
177 WriteSize += DiskCache->BlockSize;
179 if (BlockIndexInTag > LastBit) {
184 Status =
FatDiskIo (Volume, IoMode, StartPos, WriteSize, WriteBuffer, Task);
185 if (EFI_ERROR (Status)) {
189 StartPos += WriteSize + DiskCache->BlockSize;
190 WriteBuffer = (VOID *)((
UINTN)WriteBuffer + WriteSize + DiskCache->BlockSize);
194 StartPos += DiskCache->BlockSize;
195 WriteBuffer = (VOID *)((
UINTN)WriteBuffer + DiskCache->BlockSize);
198 }
while (BlockIndexInTag <= LastBit);
200 ASSERT (WriteSize == 0);
202 Status =
FatDiskIo (Volume, IoMode, Offset, BufferSize, Buffer, Task);
203 if (EFI_ERROR (Status)) {
249 DiskCache = &Volume->DiskCache[CacheData];
250 BaseAddress = DiskCache->CacheBase;
251 GroupMask = DiskCache->GroupMask;
252 PageAlignment = DiskCache->PageAlignment;
253 PageSize = (
UINTN)1 << PageAlignment;
255 for (PageNo = StartPageNo; PageNo < EndPageNo; PageNo++) {
256 GroupNo = PageNo & GroupMask;
257 CacheTag = &DiskCache->CacheTag[GroupNo];
258 if ((CacheTag->RealSize > 0) && (CacheTag->PageNo == PageNo)) {
264 if (IoMode == ReadDisk) {
265 if (CacheTag->Dirty) {
267 Buffer + ((PageNo - StartPageNo) << PageAlignment),
268 BaseAddress + (GroupNo << PageAlignment),
276 CacheTag->RealSize = 0;
300 IN CACHE_DATA_TYPE DataType,
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;
334 if ((DataType == CacheFat) && (IoMode == WriteDisk)) {
335 WriteCount = Volume->NumFats;
342 Status =
CacheFatDiskIo (CacheTag, DataType, Volume, IoMode, EntryPos, RealSize, PageAddress, Task);
343 if (EFI_ERROR (Status)) {
347 EntryPos += Volume->FatSize;
348 }
while (--WriteCount > 0);
351 CacheTag->RealSize = RealSize;
372 IN CACHE_DATA_TYPE CacheDataType,
380 OldPageNo = CacheTag->PageNo;
381 if ((CacheTag->RealSize > 0) && (OldPageNo == PageNo)) {
391 if ((CacheTag->RealSize > 0) && CacheTag->Dirty) {
393 if (EFI_ERROR (Status)) {
401 CacheTag->PageNo = PageNo;
428 IN CACHE_DATA_TYPE CacheDataType,
443 DiskCache = &Volume->DiskCache[CacheDataType];
444 GroupNo = PageNo & DiskCache->GroupMask;
445 CacheTag = &DiskCache->CacheTag[GroupNo];
447 if (!EFI_ERROR (Status)) {
448 Source = DiskCache->CacheBase + (GroupNo << DiskCache->PageAlignment) + Offset;
449 Destination = Buffer;
450 if (IoMode != ReadDisk) {
452 DiskCache->Dirty =
TRUE;
453 Destination = Source;
457 CopyMem (Destination, Source, Length);
495 IN CACHE_DATA_TYPE CacheDataType,
499 IN OUT UINT8 *Buffer,
510 UINTN AlignedPageCount;
516 ASSERT (Volume->CacheBuffer !=
NULL);
519 DiskCache = &Volume->DiskCache[CacheDataType];
520 EntryPos = Offset - DiskCache->BaseAddress;
521 PageAlignment = DiskCache->PageAlignment;
522 PageSize = (
UINTN)1 << PageAlignment;
524 UnderRun = ((
UINTN)EntryPos) & (PageSize - 1);
527 Length = PageSize - UnderRun;
528 if (Length > BufferSize) {
533 if (EFI_ERROR (Status)) {
538 BufferSize -= Length;
542 AlignedPageCount = BufferSize >> PageAlignment;
543 OverRunPageNo = PageNo + AlignedPageCount;
547 if (AlignedPageCount > 0) {
551 ASSERT (CacheDataType == CacheData);
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)) {
565 Buffer += AlignedSize;
566 BufferSize -= AlignedSize;
572 OverRun = BufferSize;
601 CACHE_DATA_TYPE CacheDataType;
607 for (CacheDataType = (CACHE_DATA_TYPE)0; CacheDataType < CacheMaxType; CacheDataType++) {
608 DiskCache = &Volume->DiskCache[CacheDataType];
609 if (DiskCache->Dirty) {
613 GroupMask = DiskCache->GroupMask;
614 for (GroupIndex = 0; GroupIndex <= GroupMask; GroupIndex++) {
615 CacheTag = &DiskCache->CacheTag[GroupIndex];
616 if ((CacheTag->RealSize > 0) && CacheTag->Dirty) {
621 if (EFI_ERROR (Status)) {
627 DiskCache->Dirty =
FALSE;
634 Status = Volume->BlockIo->FlushBlocks (Volume->BlockIo);
654 UINTN FatCacheGroupCount;
659 DiskCache = Volume->DiskCache;
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;
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;
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;
685 if (CacheBuffer ==
NULL) {
686 return EFI_OUT_OF_RESOURCES;
689 Volume->CacheBuffer = CacheBuffer;
690 DiskCache[CacheFat].CacheBase = CacheBuffer;
691 DiskCache[CacheData].CacheBase = CacheBuffer + FatCacheSize;
693 DiskCache[CacheFat].BlockSize = Volume->BlockIo->Media->BlockSize;
694 DiskCache[CacheData].BlockSize = Volume->BlockIo->Media->BlockSize;
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS FatInitializeDiskCache(IN FAT_VOLUME *Volume)
STATIC VOID SetCacheTagDirty(IN DISK_CACHE *DiskCache, IN CACHE_TAG *CacheTag, IN UINTN Offset, IN UINTN Length)
STATIC VOID ClearCacheTagDirtyState(IN CACHE_TAG *CacheTag)
EFI_STATUS FatVolumeFlushCache(IN FAT_VOLUME *Volume, IN FAT_TASK *Task)
STATIC VOID FatFlushDataCacheRange(IN FAT_VOLUME *Volume, IN IO_MODE IoMode, IN UINTN StartPageNo, IN UINTN EndPageNo, OUT UINT8 *Buffer)
STATIC EFI_STATUS FatAccessUnalignedCachePage(IN FAT_VOLUME *Volume, IN CACHE_DATA_TYPE CacheDataType, IN IO_MODE IoMode, IN UINTN PageNo, IN UINTN Offset, IN UINTN Length, IN OUT VOID *Buffer)
STATIC VOID SetBitInDirtyBlock(IN UINTN BitNumber, IN DIRTY_BLOCKS *DirtyBlocks)
STATIC EFI_STATUS FatGetCachePage(IN FAT_VOLUME *Volume, IN CACHE_DATA_TYPE CacheDataType, IN UINTN PageNo, IN CACHE_TAG *CacheTag)
STATIC EFI_STATUS CacheFatDiskIo(IN CACHE_TAG *CacheTag, IN CACHE_DATA_TYPE DataType, IN FAT_VOLUME *Volume, IN IO_MODE IoMode, IN UINT64 Offset, IN UINTN BufferSize, IN OUT VOID *Buffer, IN FAT_TASK *Task)
STATIC EFI_STATUS FatExchangeCachePage(IN FAT_VOLUME *Volume, IN CACHE_DATA_TYPE DataType, IN IO_MODE IoMode, IN CACHE_TAG *CacheTag, IN FAT_TASK *Task)
STATIC BOOLEAN IsBitInBlockDirty(IN UINTN BitNumber, IN DIRTY_BLOCKS *DirtyBlocks)
EFI_STATUS FatAccessCache(IN FAT_VOLUME *Volume, IN CACHE_DATA_TYPE CacheDataType, IN IO_MODE IoMode, IN UINT64 Offset, IN UINTN BufferSize, IN OUT UINT8 *Buffer, IN FAT_TASK *Task)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
EFI_STATUS FatDiskIo(IN FAT_VOLUME *Volume, IN IO_MODE IoMode, IN UINT64 Offset, IN UINTN BufferSize, IN OUT VOID *Buffer, IN FAT_TASK *Task)
#define DEBUG(Expression)