summaryrefslogtreecommitdiff
path: root/FatPkg/EnhancedFatDxe/DiskCache.c
diff options
context:
space:
mode:
Diffstat (limited to 'FatPkg/EnhancedFatDxe/DiskCache.c')
-rw-r--r--FatPkg/EnhancedFatDxe/DiskCache.c495
1 files changed, 0 insertions, 495 deletions
diff --git a/FatPkg/EnhancedFatDxe/DiskCache.c b/FatPkg/EnhancedFatDxe/DiskCache.c
deleted file mode 100644
index 63f9c007d6..0000000000
--- a/FatPkg/EnhancedFatDxe/DiskCache.c
+++ /dev/null
@@ -1,495 +0,0 @@
-/** @file
- Cache implementation for EFI FAT File system driver.
-
-Copyright (c) 2005 - 2013, Intel Corporation. All rights reserved.<BR>
-This program and the accompanying materials are licensed and made available
-under the terms and conditions of the BSD License which accompanies this
-distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#include "Fat.h"
-
-/**
-
- This function is used by the Data Cache.
-
- When this function is called by write command, all entries in this range
- are older than the contents in disk, so they are invalid; just mark them invalid.
-
- When this function is called by read command, if any entry in this range
- is dirty, it means that the relative info directly readed from media is older than
- than the info in the cache; So need to update the relative info in the Buffer.
-
- @param Volume - FAT file system volume.
- @param IoMode - This function is called by read command or write command
- @param StartPageNo - First PageNo to be checked in the cache.
- @param EndPageNo - Last PageNo to be checked in the cache.
- @param Buffer - The user buffer need to update. Only when doing the read command
- and there is dirty cache in the cache range, this parameter will be used.
-
-**/
-STATIC
-VOID
-FatFlushDataCacheRange (
- IN FAT_VOLUME *Volume,
- IN IO_MODE IoMode,
- IN UINTN StartPageNo,
- IN UINTN EndPageNo,
- OUT UINT8 *Buffer
- )
-{
- UINTN PageNo;
- UINTN GroupNo;
- UINTN GroupMask;
- UINTN PageSize;
- UINT8 PageAlignment;
- DISK_CACHE *DiskCache;
- CACHE_TAG *CacheTag;
- UINT8 *BaseAddress;
-
- DiskCache = &Volume->DiskCache[CacheData];
- BaseAddress = DiskCache->CacheBase;
- GroupMask = DiskCache->GroupMask;
- PageAlignment = DiskCache->PageAlignment;
- PageSize = (UINTN)1 << PageAlignment;
-
- for (PageNo = StartPageNo; PageNo < EndPageNo; PageNo++) {
- GroupNo = PageNo & GroupMask;
- CacheTag = &DiskCache->CacheTag[GroupNo];
- if (CacheTag->RealSize > 0 && CacheTag->PageNo == PageNo) {
- //
- // When reading data form disk directly, if some dirty data
- // in cache is in this rang, this data in the Buffer need to
- // be updated with the cache's dirty data.
- //
- if (IoMode == ReadDisk) {
- if (CacheTag->Dirty) {
- CopyMem (
- Buffer + ((PageNo - StartPageNo) << PageAlignment),
- BaseAddress + (GroupNo << PageAlignment),
- PageSize
- );
- }
- } else {
- //
- // Make all valid entries in this range invalid.
- //
- CacheTag->RealSize = 0;
- }
- }
- }
-}
-
-/**
-
- Exchange the cache page with the image on the disk
-
- @param Volume - FAT file system volume.
- @param DataType - Indicate the cache type.
- @param IoMode - Indicate whether to load this page from disk or store this page to disk.
- @param CacheTag - The Cache Tag for the current cache page.
- @param Task point to task instance.
-
- @retval EFI_SUCCESS - Cache page exchanged successfully.
- @return Others - An error occurred when exchanging cache page.
-
-**/
-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
- )
-{
- EFI_STATUS Status;
- UINTN GroupNo;
- UINTN PageNo;
- UINTN WriteCount;
- UINTN RealSize;
- UINT64 EntryPos;
- UINT64 MaxSize;
- DISK_CACHE *DiskCache;
- VOID *PageAddress;
- UINT8 PageAlignment;
-
- DiskCache = &Volume->DiskCache[DataType];
- PageNo = CacheTag->PageNo;
- GroupNo = PageNo & DiskCache->GroupMask;
- PageAlignment = DiskCache->PageAlignment;
- PageAddress = DiskCache->CacheBase + (GroupNo << PageAlignment);
- EntryPos = DiskCache->BaseAddress + LShiftU64 (PageNo, PageAlignment);
- RealSize = CacheTag->RealSize;
- if (IoMode == ReadDisk) {
- RealSize = (UINTN)1 << PageAlignment;
- MaxSize = DiskCache->LimitAddress - EntryPos;
- if (MaxSize < RealSize) {
- DEBUG ((EFI_D_INFO, "FatDiskIo: Cache Page OutBound occurred! \n"));
- RealSize = (UINTN) MaxSize;
- }
- }
-
- WriteCount = 1;
- if (DataType == CacheFat && IoMode == WriteDisk) {
- WriteCount = Volume->NumFats;
- }
-
- do {
- //
- // Only fat table writing will execute more than once
- //
- Status = FatDiskIo (Volume, IoMode, EntryPos, RealSize, PageAddress, Task);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- EntryPos += Volume->FatSize;
- } while (--WriteCount > 0);
-
- CacheTag->Dirty = FALSE;
- CacheTag->RealSize = RealSize;
- return EFI_SUCCESS;
-}
-
-/**
-
- Get one cache page by specified PageNo.
-
- @param Volume - FAT file system volume.
- @param CacheDataType - The cache type: CACHE_FAT or CACHE_DATA.
- @param PageNo - PageNo to match with the cache.
- @param CacheTag - The Cache Tag for the current cache page.
-
- @retval EFI_SUCCESS - Get the cache page successfully.
- @return other - An error occurred when accessing data.
-
-**/
-STATIC
-EFI_STATUS
-FatGetCachePage (
- IN FAT_VOLUME *Volume,
- IN CACHE_DATA_TYPE CacheDataType,
- IN UINTN PageNo,
- IN CACHE_TAG *CacheTag
- )
-{
- EFI_STATUS Status;
- UINTN OldPageNo;
-
- OldPageNo = CacheTag->PageNo;
- if (CacheTag->RealSize > 0 && OldPageNo == PageNo) {
- //
- // Cache Hit occurred
- //
- return EFI_SUCCESS;
- }
-
- //
- // Write dirty cache page back to disk
- //
- if (CacheTag->RealSize > 0 && CacheTag->Dirty) {
- Status = FatExchangeCachePage (Volume, CacheDataType, WriteDisk, CacheTag, NULL);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- }
- //
- // Load new data from disk;
- //
- CacheTag->PageNo = PageNo;
- Status = FatExchangeCachePage (Volume, CacheDataType, ReadDisk, CacheTag, NULL);
-
- return Status;
-}
-
-/**
-
- Read Length bytes from the position of Offset into Buffer, or
- write Length bytes from Buffer into the position of Offset.
-
- @param Volume - FAT file system volume.
- @param CacheDataType - The type of cache: CACHE_DATA or CACHE_FAT.
- @param IoMode - Indicate the type of disk access.
- @param PageNo - The number of unaligned cache page.
- @param Offset - The starting byte of cache page.
- @param Length - The number of bytes that is read or written
- @param Buffer - Buffer containing cache data.
-
- @retval EFI_SUCCESS - The data was accessed correctly.
- @return Others - An error occurred when accessing unaligned cache page.
-
-**/
-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
- )
-{
- EFI_STATUS Status;
- VOID *Source;
- VOID *Destination;
- DISK_CACHE *DiskCache;
- CACHE_TAG *CacheTag;
- UINTN GroupNo;
-
- DiskCache = &Volume->DiskCache[CacheDataType];
- GroupNo = PageNo & DiskCache->GroupMask;
- CacheTag = &DiskCache->CacheTag[GroupNo];
- Status = FatGetCachePage (Volume, CacheDataType, PageNo, CacheTag);
- if (!EFI_ERROR (Status)) {
- Source = DiskCache->CacheBase + (GroupNo << DiskCache->PageAlignment) + Offset;
- Destination = Buffer;
- if (IoMode != ReadDisk) {
- CacheTag->Dirty = TRUE;
- DiskCache->Dirty = TRUE;
- Destination = Source;
- Source = Buffer;
- }
-
- CopyMem (Destination, Source, Length);
- }
-
- return Status;
-}
-
-/**
-
- Read BufferSize bytes from the position of Offset into Buffer,
- or write BufferSize bytes from Buffer into the position of Offset.
-
- Base on the parameter of CACHE_DATA_TYPE, the data access will be divided into
- the access of FAT cache (CACHE_FAT) and the access of Data cache (CACHE_DATA):
-
- 1. Access of FAT cache (CACHE_FAT): Access the data in the FAT cache, if there is cache
- page hit, just return the cache page; else update the related cache page and return
- the right cache page.
- 2. Access of Data cache (CACHE_DATA):
- The access data will be divided into UnderRun data, Aligned data and OverRun data;
- The UnderRun data and OverRun data will be accessed by the Data cache,
- but the Aligned data will be accessed with disk directly.
-
- @param Volume - FAT file system volume.
- @param CacheDataType - The type of cache: CACHE_DATA or CACHE_FAT.
- @param IoMode - Indicate the type of disk access.
- @param Offset - The starting byte offset to read from.
- @param BufferSize - Size of Buffer.
- @param Buffer - Buffer containing cache data.
- @param Task point to task instance.
-
- @retval EFI_SUCCESS - The data was accessed correctly.
- @retval EFI_MEDIA_CHANGED - The MediaId does not match the current device.
- @return Others - An error occurred when accessing cache.
-
-**/
-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
- )
-{
- EFI_STATUS Status;
- UINTN PageSize;
- UINTN UnderRun;
- UINTN OverRun;
- UINTN AlignedSize;
- UINTN Length;
- UINTN PageNo;
- UINTN AlignedPageCount;
- UINTN OverRunPageNo;
- DISK_CACHE *DiskCache;
- UINT64 EntryPos;
- UINT8 PageAlignment;
-
- ASSERT (Volume->CacheBuffer != NULL);
-
- Status = EFI_SUCCESS;
- DiskCache = &Volume->DiskCache[CacheDataType];
- EntryPos = Offset - DiskCache->BaseAddress;
- PageAlignment = DiskCache->PageAlignment;
- PageSize = (UINTN)1 << PageAlignment;
- PageNo = (UINTN) RShiftU64 (EntryPos, PageAlignment);
- UnderRun = ((UINTN) EntryPos) & (PageSize - 1);
-
- if (UnderRun > 0) {
- Length = PageSize - UnderRun;
- if (Length > BufferSize) {
- Length = BufferSize;
- }
-
- Status = FatAccessUnalignedCachePage (Volume, CacheDataType, IoMode, PageNo, UnderRun, Length, Buffer);
- if (EFI_ERROR (Status)) {
- return Status;
- }
-
- Buffer += Length;
- BufferSize -= Length;
- PageNo++;
- }
-
- AlignedPageCount = BufferSize >> PageAlignment;
- OverRunPageNo = PageNo + AlignedPageCount;
- //
- // The access of the Aligned data
- //
- if (AlignedPageCount > 0) {
- //
- // Accessing fat table cannot have alignment data
- //
- ASSERT (CacheDataType == CacheData);
-
- EntryPos = Volume->RootPos + LShiftU64 (PageNo, PageAlignment);
- AlignedSize = AlignedPageCount << PageAlignment;
- Status = FatDiskIo (Volume, IoMode, EntryPos, AlignedSize, Buffer, Task);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // If these access data over laps the relative cache range, these cache pages need
- // to be updated.
- //
- FatFlushDataCacheRange (Volume, IoMode, PageNo, OverRunPageNo, Buffer);
- Buffer += AlignedSize;
- BufferSize -= AlignedSize;
- }
- //
- // The access of the OverRun data
- //
- OverRun = BufferSize;
- if (OverRun > 0) {
- //
- // Last read is not a complete page
- //
- Status = FatAccessUnalignedCachePage (Volume, CacheDataType, IoMode, OverRunPageNo, 0, OverRun, Buffer);
- }
-
- return Status;
-}
-
-/**
-
- Flush all the dirty cache back, include the FAT cache and the Data cache.
-
- @param Volume - FAT file system volume.
- @param Task point to task instance.
-
- @retval EFI_SUCCESS - Flush all the dirty cache back successfully
- @return other - An error occurred when writing the data into the disk
-
-**/
-EFI_STATUS
-FatVolumeFlushCache (
- IN FAT_VOLUME *Volume,
- IN FAT_TASK *Task
- )
-{
- EFI_STATUS Status;
- CACHE_DATA_TYPE CacheDataType;
- UINTN GroupIndex;
- UINTN GroupMask;
- DISK_CACHE *DiskCache;
- CACHE_TAG *CacheTag;
-
- for (CacheDataType = (CACHE_DATA_TYPE) 0; CacheDataType < CacheMaxType; CacheDataType++) {
- DiskCache = &Volume->DiskCache[CacheDataType];
- if (DiskCache->Dirty) {
- //
- // Data cache or fat cache is dirty, write the dirty data back
- //
- GroupMask = DiskCache->GroupMask;
- for (GroupIndex = 0; GroupIndex <= GroupMask; GroupIndex++) {
- CacheTag = &DiskCache->CacheTag[GroupIndex];
- if (CacheTag->RealSize > 0 && CacheTag->Dirty) {
- //
- // Write back all Dirty Data Cache Page to disk
- //
- Status = FatExchangeCachePage (Volume, CacheDataType, WriteDisk, CacheTag, Task);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- }
- }
-
- DiskCache->Dirty = FALSE;
- }
- }
- //
- // Flush the block device.
- //
- Status = Volume->BlockIo->FlushBlocks (Volume->BlockIo);
- return Status;
-}
-
-/**
-
- Initialize the disk cache according to Volume's FatType.
-
- @param Volume - FAT file system volume.
-
- @retval EFI_SUCCESS - The disk cache is successfully initialized.
- @retval EFI_OUT_OF_RESOURCES - Not enough memory to allocate disk cache.
-
-**/
-EFI_STATUS
-FatInitializeDiskCache (
- IN FAT_VOLUME *Volume
- )
-{
- DISK_CACHE *DiskCache;
- UINTN FatCacheGroupCount;
- UINTN DataCacheSize;
- UINTN FatCacheSize;
- UINT8 *CacheBuffer;
-
- DiskCache = Volume->DiskCache;
- //
- // Configure the parameters of disk cache
- //
- if (Volume->FatType == Fat12) {
- FatCacheGroupCount = FAT_FATCACHE_GROUP_MIN_COUNT;
- DiskCache[CacheFat].PageAlignment = FAT_FATCACHE_PAGE_MIN_ALIGNMENT;
- DiskCache[CacheData].PageAlignment = FAT_DATACACHE_PAGE_MIN_ALIGNMENT;
- } else {
- FatCacheGroupCount = FAT_FATCACHE_GROUP_MAX_COUNT;
- DiskCache[CacheFat].PageAlignment = FAT_FATCACHE_PAGE_MAX_ALIGNMENT;
- DiskCache[CacheData].PageAlignment = FAT_DATACACHE_PAGE_MAX_ALIGNMENT;
- }
-
- DiskCache[CacheData].GroupMask = FAT_DATACACHE_GROUP_COUNT - 1;
- DiskCache[CacheData].BaseAddress = Volume->RootPos;
- DiskCache[CacheData].LimitAddress = Volume->VolumeSize;
- DiskCache[CacheFat].GroupMask = FatCacheGroupCount - 1;
- DiskCache[CacheFat].BaseAddress = Volume->FatPos;
- DiskCache[CacheFat].LimitAddress = Volume->FatPos + Volume->FatSize;
- FatCacheSize = FatCacheGroupCount << DiskCache[CacheFat].PageAlignment;
- DataCacheSize = FAT_DATACACHE_GROUP_COUNT << DiskCache[CacheData].PageAlignment;
- //
- // Allocate the Fat Cache buffer
- //
- CacheBuffer = AllocateZeroPool (FatCacheSize + DataCacheSize);
- if (CacheBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Volume->CacheBuffer = CacheBuffer;
- DiskCache[CacheFat].CacheBase = CacheBuffer;
- DiskCache[CacheData].CacheBase = CacheBuffer + FatCacheSize;
- return EFI_SUCCESS;
-}