EFI_STATUS CheckStore ( IN EFI_HANDLE SimpleFileSystemHandle, IN UINT32 VolumeId, OUT EFI_DEVICE_PATH_PROTOCOL **Device ) { #define BLOCK_SIZE 0x200 #define FAT16_VOLUME_ID_OFFSET 39 #define FAT32_VOLUME_ID_OFFSET 67 EFI_STATUS Status; EFI_BLOCK_IO_PROTOCOL *BlkIo; UINT8 BootSector[BLOCK_SIZE]; *Device = NULL; Status = gBS->HandleProtocol ( SimpleFileSystemHandle, &gEfiBlockIoProtocolGuid, // BlockIo should be supported if it supports SimpleFileSystem (VOID*)&BlkIo ); if (EFI_ERROR (Status)) { goto ErrHandle; } if (!BlkIo->Media->MediaPresent) { DEBUG ((EFI_D_ERROR, "FwhMappedFile: Media not present!\n")); Status = EFI_NO_MEDIA; goto ErrHandle; } if (BlkIo->Media->ReadOnly) { DEBUG ((EFI_D_ERROR, "FwhMappedFile: Media is read-only!\n")); Status = EFI_ACCESS_DENIED; goto ErrHandle; } Status = BlkIo->ReadBlocks( BlkIo, BlkIo->Media->MediaId, 0, BLOCK_SIZE, BootSector ); ASSERT_EFI_ERROR (Status); if ((*(UINT32 *) &BootSector[FAT16_VOLUME_ID_OFFSET] != VolumeId) && (*(UINT32 *) &BootSector[FAT32_VOLUME_ID_OFFSET] != VolumeId) ) { Status = EFI_NOT_FOUND; goto ErrHandle; } *Device = DuplicateDevicePath (DevicePathFromHandle (SimpleFileSystemHandle)); ASSERT (*Device != NULL); ErrHandle: return Status; }
EFI_STATUS BootMonFsDiscoverNextImage ( IN BOOTMON_FS_INSTANCE *Instance, IN EFI_LBA *LbaStart, OUT HW_IMAGE_DESCRIPTION *Image ) { EFI_BLOCK_IO_PROTOCOL *Blocks; EFI_LBA CurrentLba; VOID *Out; Blocks = Instance->BlockIo; // Allocate an output buffer Out = AllocatePool (Instance->Media->BlockSize); if (Out == NULL) { return EFI_OUT_OF_RESOURCES; } Blocks->Reset (Blocks, FALSE); CurrentLba = *LbaStart; // Look for images in the rest of this block while (CurrentLba <= Instance->Media->LastBlock) { // Read in the next block Blocks->ReadBlocks (Blocks, Instance->Media->MediaId, CurrentLba, Instance->Media->BlockSize, Out); // Check for an image in the current block if (BootMonFsImageInThisBlock (Out, Instance->Media->BlockSize, (CurrentLba - Instance->Media->LowestAlignedLba), Image)) { DEBUG ((EFI_D_ERROR, "Found image: %a in block %d.\n", &(Image->Footer.Filename), (UINTN)(CurrentLba - Instance->Media->LowestAlignedLba))); FreePool (Out); *LbaStart = Image->BlockEnd + 1; return EFI_SUCCESS; } else { CurrentLba++; } } *LbaStart = CurrentLba; FreePool (Out); return EFI_NOT_FOUND; }
/** Display blocks to the screen. @param[in] DevPath The device path to get the blocks from. @param[in] Lba The Lba number to start from. @param[in] BlockCount How many blocks to display. @retval SHELL_SUCCESS The display was successful. **/ SHELL_STATUS EFIAPI DisplayTheBlocks( IN CONST EFI_DEVICE_PATH_PROTOCOL *DevPath, IN CONST UINT64 Lba, IN CONST UINT8 BlockCount ) { EFI_BLOCK_IO_PROTOCOL *BlockIo; EFI_HANDLE BlockIoHandle; EFI_STATUS Status; SHELL_STATUS ShellStatus; UINT8 *Buffer; UINTN BufferSize; ShellStatus = SHELL_SUCCESS; Status = gBS->LocateDevicePath(&gEfiBlockIoProtocolGuid, (EFI_DEVICE_PATH_PROTOCOL **)&DevPath, &BlockIoHandle); if (EFI_ERROR(Status)) { return (SHELL_NOT_FOUND); } Status = gBS->OpenProtocol(BlockIoHandle, &gEfiBlockIoProtocolGuid, (VOID**)&BlockIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (EFI_ERROR(Status)) { return (SHELL_NOT_FOUND); } BufferSize = BlockIo->Media->BlockSize * BlockCount; if (BufferSize > 0) { Buffer = AllocateZeroPool(BufferSize); } else { ShellPrintEx(-1,-1,L" BlockSize: 0x%08x, BlockCount: 0x%08x\r\n", BlockIo->Media->BlockSize, BlockCount); Buffer = NULL; } Status = BlockIo->ReadBlocks(BlockIo, BlockIo->Media->MediaId, Lba, BufferSize, Buffer); if (!EFI_ERROR(Status) && Buffer != NULL) { ShellPrintHiiEx( -1, -1, NULL, STRING_TOKEN (STR_DBLK_HEADER), gShellDebug1HiiHandle, Lba, BufferSize, BlockIo ); DumpHex(2,0,BufferSize,Buffer); } else { ShellPrintHiiEx(-1, -1, NULL, STRING_TOKEN (STR_READ_FAIL), gShellDebug1HiiHandle, L"BlockIo", Status); ShellStatus = SHELL_DEVICE_ERROR; } if (Buffer != NULL) { FreePool(Buffer); } gBS->CloseProtocol(BlockIoHandle, &gEfiBlockIoProtocolGuid, gImageHandle, NULL); return (ShellStatus); }
/** Read a disk from disk into HBufferImage. @param[in] DeviceName filename to read. @param[in] Offset The offset. @param[in] Size The size. @param[in] Recover if is for recover, no information print. @retval EFI_SUCCESS The operation was successful. @retval EFI_OUT_OF_RESOURCES A memory allocation failed. @retval EFI_LOAD_ERROR A load error occured. @retval EFI_INVALID_PARAMETER A parameter was invalid. **/ EFI_STATUS HDiskImageRead ( IN CONST CHAR16 *DeviceName, IN UINTN Offset, IN UINTN Size, IN BOOLEAN Recover ) { CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath; EFI_DEVICE_PATH_PROTOCOL *DupDevicePath; EFI_DEVICE_PATH_PROTOCOL *DupDevicePathForFree; EFI_HANDLE Handle; EFI_BLOCK_IO_PROTOCOL *BlkIo; EFI_STATUS Status; VOID *Buffer; CHAR16 *Str; UINTN Bytes; HEFI_EDITOR_LINE *Line; UINT64 ByteOffset; EDIT_FILE_TYPE BufferTypeBackup; BufferTypeBackup = HBufferImage.BufferType; HBufferImage.BufferType = FileTypeDiskBuffer; DevicePath = gEfiShellProtocol->GetDevicePathFromMap(DeviceName); if (DevicePath == NULL) { StatusBarSetStatusString (L"Cannot Find Device"); return EFI_INVALID_PARAMETER; } DupDevicePath = DuplicateDevicePath(DevicePath); DupDevicePathForFree = DupDevicePath; // // get blkio interface // Status = gBS->LocateDevicePath(&gEfiBlockIoProtocolGuid,&DupDevicePath,&Handle); FreePool(DupDevicePathForFree); if (EFI_ERROR (Status)) { StatusBarSetStatusString (L"Read Disk Failed"); return Status; } Status = gBS->OpenProtocol(Handle, &gEfiBlockIoProtocolGuid, (VOID**)&BlkIo, gImageHandle, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL); if (EFI_ERROR (Status)) { StatusBarSetStatusString (L"Read Disk Failed"); return Status; } // // if Offset exceeds LastBlock, // return error // if (Offset > BlkIo->Media->LastBlock || Offset + Size > BlkIo->Media->LastBlock) { StatusBarSetStatusString (L"Invalid Offset + Size"); return EFI_LOAD_ERROR; } Bytes = BlkIo->Media->BlockSize * Size; Buffer = AllocateZeroPool (Bytes); if (Buffer == NULL) { StatusBarSetStatusString (L"Read Disk Failed"); return EFI_OUT_OF_RESOURCES; } ByteOffset = MultU64x32 (Offset, BlkIo->Media->BlockSize); // // read from disk // Status = BlkIo->ReadBlocks ( BlkIo, BlkIo->Media->MediaId, Offset, Bytes, Buffer ); if (EFI_ERROR (Status)) { FreePool (Buffer); StatusBarSetStatusString (L"Read Disk Failed"); return EFI_LOAD_ERROR; } HBufferImageFree (); // // convert buffer to line list // Status = HBufferImageBufferToList (Buffer, Bytes); FreePool (Buffer); if (EFI_ERROR (Status)) { StatusBarSetStatusString (L"Read Disk Failed"); return Status; } Status = HDiskImageSetDiskNameOffsetSize (DeviceName, Offset, Size); if (EFI_ERROR (Status)) { StatusBarSetStatusString (L"Read Disk Failed"); return EFI_OUT_OF_RESOURCES; } // // initialize some variables // HDiskImage.BlockSize = BlkIo->Media->BlockSize; HBufferImage.DisplayPosition.Row = 2; HBufferImage.DisplayPosition.Column = 10; HBufferImage.MousePosition.Row = 2; HBufferImage.MousePosition.Column = 10; HBufferImage.LowVisibleRow = 1; HBufferImage.HighBits = TRUE; HBufferImage.BufferPosition.Row = 1; HBufferImage.BufferPosition.Column = 1; if (!Recover) { Str = CatSPrint(NULL, L"%d Lines Read", HBufferImage.NumLines); if (Str == NULL) { StatusBarSetStatusString (L"Read Disk Failed"); return EFI_OUT_OF_RESOURCES; } StatusBarSetStatusString (Str); SHELL_FREE_NON_NULL (Str); HMainEditor.SelectStart = 0; HMainEditor.SelectEnd = 0; } // // has line // if (HBufferImage.Lines != NULL) { HBufferImage.CurrentLine = CR ( HBufferImage.ListHead->ForwardLink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST ); } else { // // create a dummy line // Line = HBufferImageCreateLine (); if (Line == NULL) { StatusBarSetStatusString (L"Read Disk Failed"); return EFI_OUT_OF_RESOURCES; } HBufferImage.CurrentLine = Line; } HBufferImage.Modified = FALSE; HBufferImageNeedRefresh = TRUE; HBufferImageOnlyLineNeedRefresh = FALSE; HBufferImageMouseNeedRefresh = TRUE; return EFI_SUCCESS; }
/** Read data as fast as possible from a block I/O device The ShellCEntryLib library instance wrappers the actual UEFI application entry point and calls this ShellAppMain function. @param ImageHandle The image handle of the UEFI Application. @param SystemTable A pointer to the EFI System Table. @retval 0 The application exited normally. @retval Other An error occurred. **/ INTN EFIAPI ShellAppMain ( IN UINTN Argc, IN CHAR16 **Argv ) { BOOLEAN bBlockIo2; UINT32 BlockIoCount; UINT32 BlockIo2Count; UINT32 BlocksPerRead; UINT32 BlockSize; BOOLEAN bReadComplete; UINT32 BytesPerSecond; UINT32 BytesToRead; UINT64 DataRead; EFI_LBA Lba; EFI_LBA LbaMax; EFI_HANDLE Handle; UINTN HandleCount; UINTN Index; UINT64 MaxMBytes; UINT64 MaxReads; UINT64 MediaBytes; UINT32 MediaId; EFI_BLOCK_IO_PROTOCOL * pBlockIo; EFI_BLOCK_IO2_PROTOCOL * pBlockIo2; EFI_HANDLE * pBlockIoArray; EFI_HANDLE * pBlockIo2Array; EFI_HANDLE * pHandle; EFI_HANDLE * pHandleEnd; EFI_BLOCK_IO_MEDIA * pMedia; EFI_BLOCK_IO2_TOKEN * pToken; EFI_BLOCK_IO2_TOKEN * pTokenEnd; CHAR8 * pUnits; UINT32 Seconds; EFI_STATUS Status; UINT64 Timeout; EFI_EVENT TimeoutEvent; UINT32 TestCount; UINT32 WarmUpBlocks; // // Display the help text // if ( 1 == Argc ) { Print ( L"%s [/2] <handle>\r\n", Argv[ 0 ]); Print ( L"\r\n" ); Print ( L"/2 - Use Block I/O 2 protocol\r\n" ); // // Determine which handles have the block I/O protocol on them // Print ( L"Block I/O Handles\r\n" ); Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &HandleCount, &pBlockIoArray ); if ( !EFI_ERROR ( Status )) { pHandle = pBlockIoArray; BlockIoCount = (UINT32)HandleCount; pHandleEnd = &pHandle[ BlockIoCount ]; while ( pHandleEnd > pHandle ) { Handle = *pHandle++; Status = gBS->OpenProtocol ( Handle, &gEfiBlockIoProtocolGuid, (VOID **)&pBlockIo, NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if ( !EFI_ERROR ( Status )) { if (( NULL != pBlockIo ) && ( NULL != pBlockIo->Media ) && ( pBlockIo->Media->MediaPresent )) { // // Display the handle and device size // pUnits = "Bytes"; MediaBytes = MultU64x32 ( pBlockIo->Media->LastBlock + 1, pBlockIo->Media->BlockSize ); if ( KIBYTE <= MediaBytes ) { pUnits = "KiBytes"; if ( MIBYTE <= MediaBytes ) { pUnits = "MiBytes"; MediaBytes = DivU64x32 ( MediaBytes, 1024 ); if ( MIBYTE <= MediaBytes ) { pUnits = "GiBytes"; MediaBytes = DivU64x32 ( MediaBytes, 1024 ); if ( MIBYTE <= MediaBytes ) { pUnits = "TiBytes"; MediaBytes = DivU64x32 ( MediaBytes, 1024 ); if ( MIBYTE <= MediaBytes ) { pUnits = "PiBytes"; MediaBytes = DivU64x32 ( MediaBytes, 1024 ); } } } } BytesToRead = (UINT32)MediaBytes; Print ( L" 0x%016Lx: %d.%03d %a\r\n", (UINT64)(UINTN)Handle, BytesToRead / 1024, ( BytesToRead % 1024 ) * 1000 / 1024, pUnits ); } else { BytesToRead = (UINT32)MediaBytes; Print ( L" 0x%016Lx: %d %a\r\n", (UINT64)(UINTN)Handle, BytesToRead, pUnits ); } } } } // // Free the handle buffer // gBS->FreePool ( pBlockIoArray ); } else { Print ( L" No block I/O handles found!\r\n" ); } // // Determine which handles have the block I/O 2 protocol on them // Print ( L"Block I/O 2 Handles\r\n" ); Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiBlockIo2ProtocolGuid, NULL, &HandleCount, &pBlockIo2Array ); if ( !EFI_ERROR ( Status )) { pHandle = pBlockIo2Array; BlockIo2Count = (UINT32)HandleCount; pHandleEnd = &pHandle[ BlockIo2Count ]; while ( pHandleEnd > pHandle ) { Handle = *pHandle++; Status = gBS->OpenProtocol ( Handle, &gEfiBlockIoProtocolGuid, (VOID **)&pBlockIo, NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if ( !EFI_ERROR ( Status )) { if (( NULL != pBlockIo ) && ( NULL != pBlockIo->Media ) && ( pBlockIo->Media->MediaPresent )) { // // Display the handle and device size // pUnits = "Bytes"; MediaBytes = MultU64x32 ( pBlockIo->Media->LastBlock + 1, pBlockIo->Media->BlockSize ); if ( KIBYTE <= MediaBytes ) { pUnits = "KiBytes"; if ( MIBYTE <= MediaBytes ) { pUnits = "MiBytes"; MediaBytes = DivU64x32 ( MediaBytes, 1024 ); if ( MIBYTE <= MediaBytes ) { pUnits = "GiBytes"; MediaBytes = DivU64x32 ( MediaBytes, 1024 ); if ( MIBYTE <= MediaBytes ) { pUnits = "TiBytes"; MediaBytes = DivU64x32 ( MediaBytes, 1024 ); if ( MIBYTE <= MediaBytes ) { pUnits = "PiBytes"; MediaBytes = DivU64x32 ( MediaBytes, 1024 ); } } } } BytesToRead = (UINT32)MediaBytes; Print ( L" 0x%016Lx: %d.%03d %a\r\n", (UINT64)(UINTN)Handle, BytesToRead / 1024, ( BytesToRead % 1024 ) * 1000 / 1024, pUnits ); } else { BytesToRead = (UINT32)MediaBytes; Print ( L" 0x%016Lx: %d %a\r\n", (UINT64)(UINTN)Handle, BytesToRead, pUnits ); } } } } // // Free the handle buffer // gBS->FreePool ( pBlockIo2Array ); } else { Print ( L" No block I/O 2 handles found!\r\n" ); } Print ( L"The test reads %d KiByte buffers as fast as it can for a total\r\n", BUFFER_LENGTH_IN_BYTES / 1024 ); Print ( L"of %d seconds. At the end of the time, the performance is computed\r\n", TEST_TIME_IN_SECONDS ); Print ( L"by dividing the number of bytes received prior to the timer expiring\r\n" ); Print ( L"by the test duration. The test reads at most %d MiBytes from the\r\n", MAX_MBYTES ); Print ( L"beginning of the media before wrapping around to the beginning again.\r\n" ); Print ( L"As a warm-up, two buffers worth of data are read from the end of the\r\n" ); Print ( L"%d MiByte region.\r\n", MAX_MBYTES ); return EFI_NOT_STARTED; } // // Determine if the block I/O 2 protocol should be used // bBlockIo2 = FALSE; pToken = &mTokens[ 0 ]; pTokenEnd = &pToken[ DIM ( mTokens )]; if ( 0 == StrCmp ( L"/2", Argv[ 1 ])) { bBlockIo2 = TRUE; } // // Get the handle address // HandleCount = bBlockIo2 ? 2 : 1; Handle = (EFI_HANDLE)StrHexToUintn ( Argv[ HandleCount ]); if ( NULL == Handle ) { Print ( L"ERROR - Invalid handle value\r\n" ); return EFI_INVALID_PARAMETER; } // // Validate the handle // pBlockIo = NULL; pBlockIo2 = NULL; Status = gBS->OpenProtocol ( Handle, bBlockIo2 ? &gEfiBlockIo2ProtocolGuid : &gEfiBlockIoProtocolGuid, bBlockIo2 ? (VOID *)&pBlockIo2 : (VOID *)&pBlockIo, NULL, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL ); if ( EFI_ERROR ( Status )) { Print ( L"ERROR - %r\r\n", Status ); return (( Status & MAX_BIT ) ? 0x80000000 : 0 ) | ( Status & 0x7fffffff ); } // // Create the necessary events // Status = gBS->CreateEvent ( EVT_TIMER | EVT_NOTIFY_SIGNAL, TPL_NOTIFY, TestComplete, NULL, &TimeoutEvent ); if ( EFI_ERROR ( Status )) { Print ( L"ERROR - Failed to create event, Status: %r\r\n", Status ); return (( Status & MAX_BIT ) ? 0x80000000 : 0 ) | ( Status & 0x7fffffff ); } while ( pTokenEnd > pToken ) { Status = gBS->CreateEvent ( 0, TPL_NOTIFY, NULL, NULL, &pToken->Event ); if ( EFI_ERROR ( Status )) { Print ( L"ERROR - Failed to create token event, Status: %r\r\n", Status ); break; } pToken += 1; } if ( !EFI_ERROR ( Status )) { // // Display the media parameters // pMedia = bBlockIo2 ? pBlockIo2->Media : pBlockIo->Media; Print ( L"\r\nMedia Parameters:\r\n" ); Print ( L" BlockSize: %d bytes\r\n", pMedia->BlockSize ); Print ( L" IoAlign: %d bytes\r\n", pMedia->IoAlign ); Print ( L" LastBlock: 0x%Lx\r\n", pMedia->LastBlock ); Print ( L" LogicalBlocksPerPhysicalBlock: %d\r\n", pMedia->LogicalBlocksPerPhysicalBlock ); Print ( L" LogicalPartition: %a\r\n", pMedia->LogicalPartition ? "TRUE" : "FALSE" ); Print ( L" LowestAlignedLba: 0x%Lx\r\n", pMedia->LowestAlignedLba ); Print ( L" MediaId: 0x%08x\r\n", pMedia->MediaId ); Print ( L" MediaPresent: %a\r\n", pMedia->MediaPresent ? "TRUE" : "FALSE" ); #ifdef EFI_BLOCK_IO_PROTOCOL_REVISION3 Print ( L" OptimalTransferLengthGranularity: %d blocks\r\n", pMedia->OptimalTransferLengthGranularity ); #endif // EFI_BLOCK_IO_PROTOCOL_REVISION3 Print ( L" ReadOnly: %a\r\n", pMedia->ReadOnly ? "TRUE" : "FALSE" ); Print ( L" RemovableMedia: %a\r\n", pMedia->RemovableMedia ? "TRUE" : "FALSE" ); Print ( L" WriteCaching: %a\r\n", pMedia->WriteCaching ? "TRUE" : "FALSE" ); Print ( L"\r\n" ); // // Locate the end of the media // BlockSize = pMedia->BlockSize; MediaBytes = pMedia->LastBlock + 1; MediaBytes = MultU64x32 ( MediaBytes, BlockSize ); BlocksPerRead = sizeof ( mBuffer ) / BlockSize; BytesToRead = BlocksPerRead * BlockSize; ASSERT ( 0 < BlocksPerRead ); LbaMax = MAX_MBYTES * 1024L * 1024L; LbaMax = DivU64x32 ( LbaMax, BlocksPerRead ); LbaMax = MultU64x32 ( LbaMax, BlocksPerRead ); LbaMax = DivU64x32 ( LbaMax, BlockSize ); if ( LbaMax > pMedia->LastBlock ) { LbaMax = MultU64x32 ( DivU64x32 ( pMedia->LastBlock + 1, BlocksPerRead ), BlocksPerRead ); } MaxReads = DivU64x32 ( LbaMax, BlocksPerRead ); MaxMBytes = DivU64x32 ( MultU64x32 ( MaxReads, BlocksPerRead * BlockSize ), 1024 * 1024 ); WarmUpBlocks = WARM_UP_READS * BlocksPerRead; if ( LbaMax < WarmUpBlocks ) { WarmUpBlocks = ((UINT32)DivU64x32 ( LbaMax, BlocksPerRead )) * BlocksPerRead; } // // Get the test duration // Seconds = TEST_TIME_IN_SECONDS; // // Display the test parameters // Print ( L"Test Parameters:\r\n" ); Print ( L" Using: BlockIo%sProtocol\r\n", bBlockIo2 ? "2" : "" ); Print ( L" BlockSize: %d bytes\r\n", BlockSize ); Print ( L" Blocks/Read: %d\r\n", BlocksPerRead ); Print ( L" Duration: %d seconds\r\n", Seconds ); Print ( L" LBA max: %Ld\r\n", LbaMax ); Print ( L" Max data: %Ld MiBytes\r\n", MaxMBytes ); Print ( L" Max reads: %Ld\r\n", MaxReads ); if (( 1000 * 1000 * 1000 ) <= MediaBytes ) { UINT32 Remainder; UINT64 GByte; GByte = DivU64x32Remainder ( MediaBytes, 1000 * 1000 * 1000, &Remainder ); Print ( L" Media Size: %d.%03d GiBytes (%d.%03d GBytes)\r\n", (UINT32)( MediaBytes / GIBYTE ), ((UINT32)(( MediaBytes % GIBYTE ) / MIBYTE ) * 1000 ) / KIBYTE, (UINT32)GByte, Remainder / ( 1000 * 1000 )); } else { UINT32 Remainder; UINT64 MByte; MByte = DivU64x32Remainder ( MediaBytes, 1000 * 1000, &Remainder ); Print ( L" Media Size: %d.%03d MiBytes (%d.%03d MBytes)\r\n", (UINT32)DivU64x32 ( MediaBytes, MIBYTE ), ((UINT32)(( MediaBytes % MIBYTE ) / KIBYTE ) * 1000 ) / KIBYTE, (UINT32)MByte, Remainder / 1000 ); } Print ( L" Test Count: %d runs\r\n", TEST_COUNT ); Print ( L" Warm-up reads: %d\r\n", WarmUpBlocks / BlocksPerRead ); Print ( L"\r\n" ); // // Compute the timeout // Timeout = Seconds; Timeout *= 1000L * 1000L * 10L; // // Get the media ID value // MediaId = pMedia->MediaId; // // Warm-up the data path // Lba = LbaMax - WarmUpBlocks; while ( LbaMax > Lba ) { if ( bBlockIo2 ) { Status = pBlockIo2->ReadBlocksEx ( pBlockIo2, MediaId, Lba, NULL, BytesToRead, &mBuffer[ 0 ]); } else { Status = pBlockIo->ReadBlocks ( pBlockIo, MediaId, Lba, BytesToRead, &mBuffer[ 0 ]); } if ( EFI_ERROR ( Status )) { Print ( L"ERROR - Read failure during warm-up, Lba: 0x%016Lx, Status: %r\r\n", Lba, Status ); break; } Lba += BlocksPerRead; } if ( !EFI_ERROR ( Status )) { // // Perform each of the tests // for ( TestCount = 1; TEST_COUNT >= TestCount; TestCount++ ) { // // Initialize the tokens // pToken = &mTokens[ 0 ]; while ( pTokenEnd > pToken ) { gBS->SignalEvent ( pToken->Event ); pToken->TransactionStatus = EFI_SUCCESS; pToken += 1; } pToken = &mTokens[ 0 ]; // // Start the timer // bTestRunning = TRUE; ReadCount = 0; bReadComplete = TRUE; gBS->CheckEvent ( TimeoutEvent ); Status = gBS->SetTimer ( TimeoutEvent, TimerRelative, Timeout ); ASSERT ( EFI_SUCCESS == Status ); if ( bBlockIo2 ) { // // Run the test using Block I/O 2 protocol // do { Lba = 0; while ( bTestRunning && ( LbaMax > Lba )) { // // Wrap the token list if necessary // if ( pTokenEnd <= pToken ) { pToken = &mTokens[ 0 ]; } // // Wait for the next token // gBS->WaitForEvent ( 1, &pToken->Event, &Index ); // // Verify the read status // Status = pToken->TransactionStatus; if ( EFI_ERROR ( Status )) { break; } // // Start the next read // Status = pBlockIo2->ReadBlocksEx ( pBlockIo2, MediaId, Lba, pToken, BytesToRead, &mBuffer[ 0 ]); if ( EFI_ERROR ( Status )) { bReadComplete = FALSE; break; } // // Account for this read // ReadCount += 1; Lba += BlocksPerRead; pToken += 1; } }while ( bTestRunning ); // // Wait for the rest of the reads to complete // pToken = &mTokens[ 0 ]; while ( pTokenEnd > pToken ) { gBS->WaitForEvent ( 1, &pToken->Event, &Index ); pToken += 1; } // // Display any errors // if ( EFI_ERROR ( Status )) { Print ( L"ERROR - Read %afailure, Lba: 0x%016Lx, Status: %r\r\n", bReadComplete ? "" : "queue ", bReadComplete ? Lba - ( DIM ( mTokens ) * BlocksPerRead ) : Lba, Status ); break; } } else { // // Run the test using Block I/O protocol // do { Lba = 0; while ( bTestRunning && ( LbaMax > Lba )) { Status = pBlockIo->ReadBlocks ( pBlockIo, MediaId, Lba, BytesToRead, &mBuffer[ 0 ]); if ( EFI_ERROR ( Status )) { Print ( L"ERROR - Read failure, Lba: 0x%016Lx, Status: %r\r\n", Lba, Status ); return (( Status & MAX_BIT ) ? 0x80000000 : 0 ) | ( Status & 0x7fffffff ); } ReadCount += 1; Lba += BlocksPerRead; } } while ( bTestRunning ); } // // Adjust the read count for the tokens // if ( bBlockIo2 ) { FinalReadCount = ( DIM ( mTokens ) >= FinalReadCount ) ? 0 : FinalReadCount - DIM ( mTokens ); } // // Compute the results // TotalReadCount += FinalReadCount; DataRead = FinalReadCount; DataRead = MultU64x32 ( DataRead, BytesToRead ); BytesPerSecond = (UINT32)DivU64x32 ( DataRead, Seconds ); // // Display the test results // Print ( L"\r\nTest %d Results:\r\n", TestCount ); Print ( L" Reads: %d\r\n", FinalReadCount ); Print ( L" %d.%03d MiBytes/Second (%d.%03d Mbit/Second)\r\n", BytesPerSecond / ( 1024 * 1024 ), ((( BytesPerSecond % ( 1024 * 1024 )) / 1024 ) * 1000 ) / 1024, ( BytesPerSecond * 8 ) / ( 1000 * 1000 ), (( BytesPerSecond * 8 ) % ( 1000 * 1000 )) / 1000 ); } // // Compute the results // DataRead = TotalReadCount; DataRead = MultU64x32 ( DataRead, BytesToRead ); DataRead = DivU64x32 ( DataRead, TEST_COUNT ); BytesPerSecond = (UINT32)DivU64x32 ( DataRead, Seconds ); // // Display the test results // Print ( L"\r\nAverage Test Results:\r\n" ); Print ( L" Total Reads: %d\r\n", TotalReadCount ); Print ( L" %d.%03d MiBytes/Second (%d.%03d Mbit/Second)\r\n", BytesPerSecond / ( 1024 * 1024 ), ((( BytesPerSecond % ( 1024 * 1024 )) / 1024 ) * 1000 ) / 1024, ( BytesPerSecond * 8 ) / ( 1000 * 1000 ), (( BytesPerSecond * 8 ) % ( 1000 * 1000 )) / 1000 ); } } // // Done with the events // gBS->CloseEvent ( TimeoutEvent ); pToken = &mTokens[ 0 ]; while ( pTokenEnd > pToken ) { if ( NULL != pToken->Event ) { gBS->CloseEvent ( pToken->Event ); } pToken += 1; } // // Return the test status // return (( Status & MAX_BIT ) ? 0x80000000 : 0 ) | ( Status & 0x7fffffff ); }
EFI_STATUS HDiskImageRead ( IN CHAR16 *DeviceName, IN UINTN Offset, IN UINTN Size, IN BOOLEAN Recover ) /*++ Routine Description: Read a disk from disk into HBufferImage Arguments: DeviceName - filename to read Offset - The offset Size - The size Recover - if is for recover, no information print Returns: EFI_SUCCESS EFI_LOAD_ERROR EFI_OUT_OF_RESOURCES EFI_INVALID_PARAMETER --*/ { EFI_DEVICE_PATH_PROTOCOL *DevicePath; EFI_BLOCK_IO_PROTOCOL *BlkIo; EFI_STATUS Status; VOID *Buffer; CHAR16 *Str; UINTN Bytes; HEFI_EDITOR_LINE *Line; UINT64 ByteOffset; HEFI_EDITOR_ACTIVE_BUFFER_TYPE BufferTypeBackup; BufferTypeBackup = HBufferImage.BufferType; HBufferImage.BufferType = DISK_BUFFER; DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) ShellGetMap (DeviceName); if (DevicePath == NULL) { HMainStatusBarSetStatusString (L"Cannot Find Device"); return EFI_INVALID_PARAMETER; } // // get blkio interface // Status = LibDevicePathToInterface ( &gEfiBlockIoProtocolGuid, DevicePath, &BlkIo ); if (EFI_ERROR (Status)) { HMainStatusBarSetStatusString (L"Read Disk Failed"); return Status; } // // if Offset exceeds LastBlock, // return error // if (Offset > BlkIo->Media->LastBlock || Offset + Size > BlkIo->Media->LastBlock) { HMainStatusBarSetStatusString (L"Invalid Offset + Size"); return EFI_LOAD_ERROR; } Bytes = BlkIo->Media->BlockSize * Size; Buffer = AllocatePool (Bytes); if (Buffer == NULL) { HMainStatusBarSetStatusString (L"Read Disk Failed"); return EFI_OUT_OF_RESOURCES; } ByteOffset = MultU64x32 (Offset, BlkIo->Media->BlockSize); // // read from disk // Status = BlkIo->ReadBlocks ( BlkIo, BlkIo->Media->MediaId, Offset, Bytes, Buffer ); if (EFI_ERROR (Status)) { FreePool (Buffer); HMainStatusBarSetStatusString (L"Read Disk Failed"); return EFI_LOAD_ERROR; } HBufferImageFree (); // // convert buffer to line list // Status = HBufferImageBufferToList (Buffer, Bytes); FreePool (Buffer); if (EFI_ERROR (Status)) { HMainStatusBarSetStatusString (L"Read Disk Failed"); return Status; } Status = HDiskImageSetDiskNameOffsetSize (DeviceName, Offset, Size); if (EFI_ERROR (Status)) { HMainStatusBarSetStatusString (L"Read Disk Failed"); return EFI_OUT_OF_RESOURCES; } // // initialize some variables // HDiskImage.BlockSize = BlkIo->Media->BlockSize; HBufferImage.DisplayPosition.Row = TEXT_START_ROW; HBufferImage.DisplayPosition.Column = HEX_POSITION; HBufferImage.MousePosition.Row = TEXT_START_ROW; HBufferImage.MousePosition.Column = HEX_POSITION; HBufferImage.LowVisibleRow = 1; HBufferImage.HighBits = TRUE; HBufferImage.BufferPosition.Row = 1; HBufferImage.BufferPosition.Column = 1; if (!Recover) { Str = PoolPrint (L"%d Lines Read", HBufferImage.NumLines); if (Str == NULL) { HMainStatusBarSetStatusString (L"Read Disk Failed"); return EFI_OUT_OF_RESOURCES; } HMainStatusBarSetStatusString (Str); HEditorFreePool (Str); HMainEditor.SelectStart = 0; HMainEditor.SelectEnd = 0; } // // has line // if (HBufferImage.Lines != NULL) { HBufferImage.CurrentLine = CR ( HBufferImage.ListHead->Flink, HEFI_EDITOR_LINE, Link, EFI_EDITOR_LINE_LIST ); } else { // // create a dummy line // Line = HBufferImageCreateLine (); if (Line == NULL) { HMainStatusBarSetStatusString (L"Read Disk Failed"); return EFI_OUT_OF_RESOURCES; } HBufferImage.CurrentLine = Line; } HBufferImage.Modified = FALSE; HBufferImageNeedRefresh = TRUE; HBufferImageOnlyLineNeedRefresh = FALSE; HBufferImageMouseNeedRefresh = TRUE; return EFI_SUCCESS; }
// // TDS 5.5 // EFI_STATUS BBTestMediaIntegrityManualTest ( IN EFI_BB_TEST_PROTOCOL *This, IN VOID *ClientInterface, IN EFI_TEST_LEVEL TestLevel, IN EFI_HANDLE SupportHandle ) { EFI_STANDARD_TEST_LIBRARY_PROTOCOL *StandardLib; EFI_STATUS Status; EFI_BLOCK_IO_PROTOCOL *BlockIo; EFI_TEST_ASSERTION AssertionType; UINT32 MediaId; BOOLEAN RemovableMedia; BOOLEAN MediaPresent; BOOLEAN LogicalPartition; BOOLEAN ReadOnly; BOOLEAN WriteCaching; UINT32 BlockSize; UINT32 IoAlign; EFI_LBA LastBlock; UINTN BufferSize; UINT8 *Buffer; UINT32 BlockNumber; UINTN Index; EFI_DEVICE_PATH_PROTOCOL *DevicePath; CHAR16 *DevicePathStr; // // Get the Standard Library Interface // Status = gtBS->HandleProtocol ( SupportHandle, &gEfiStandardTestLibraryGuid, &StandardLib ); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.HandleProtocol - Handle standard test library", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); return Status; } BlockIo = (EFI_BLOCK_IO_PROTOCOL *)ClientInterface; // // Initialize variable // MediaId = BlockIo->Media->MediaId; RemovableMedia = BlockIo->Media->RemovableMedia; MediaPresent = BlockIo->Media->MediaPresent; LogicalPartition = BlockIo->Media->LogicalPartition; ReadOnly = BlockIo->Media->ReadOnly; WriteCaching = BlockIo->Media->WriteCaching; BlockSize = BlockIo->Media->BlockSize; IoAlign = BlockIo->Media->IoAlign; LastBlock = BlockIo->Media->LastBlock; BlockNumber = (UINT32) MINIMUM(LastBlock, MAX_NUMBER_OF_READ_BLOCK_BUFFER); BufferSize = BlockNumber * BlockSize; if (BufferSize == 0) { BufferSize = 512; } // // allocate buffer // Status = gtBS->AllocatePool (EfiBootServicesData, BufferSize, &Buffer); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.AllocatePool - Allocate buffer for testing", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); return Status; } // // Locate the Handle that the BlockIo interface is bound to // LocateDevicePathFromBlockIo (BlockIo, &DevicePath, StandardLib); DevicePathStr = DevicePathToStr (DevicePath); if (DevicePathStr != NULL) { StandardLib->RecordMessage ( StandardLib, EFI_VERBOSE_LEVEL_DEFAULT, L"Current Device: %s", DevicePathStr ); Status = gtBS->FreePool (DevicePathStr); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.FreePool - Free device path string", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); goto FreeBuffer; } DevicePathStr = NULL; } // // Assertion Point 5.5.2.1 // Media remove of insert of device must affect the MediaPresent field // if (RemovableMedia == TRUE) { // // Insert -> Remove -> Insert or Remove -> Insert -> Remove // for (Index = 0; Index < 2; Index++) { if (MediaPresent == TRUE) { Print (L"Remove media in device "); } else { Print (L"Insert media into device "); } DevicePathStr = DevicePathToStr (DevicePath); if (DevicePathStr != NULL) { Print (DevicePathStr); Status = gtBS->FreePool (DevicePathStr); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.FreePool - Free device path string", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); goto FreeBuffer; } DevicePathStr = NULL; } if (AutoJudge (50, FALSE, L"\r\nReady?\r\n") != TRUE) { goto AssertionPoint2; } // // Call ReadBlocks to force re-install device // Status = BlockIo->ReadBlocks ( BlockIo, MediaId, 0, BlockSize, (VOID*)Buffer ); if (EFI_ERROR(Status)) { // // No Status check here. // } // // Begin to re-locate the BlockIo interface according to the DevicePath // LocateBlockIoFromDevicePath (&BlockIo, DevicePath, StandardLib); if (MediaPresent == BlockIo->Media->MediaPresent) { AssertionType = EFI_TEST_ASSERTION_FAILED; } else { AssertionType = EFI_TEST_ASSERTION_PASSED; } StandardLib->RecordAssertion ( StandardLib, AssertionType, gBlockIoFunctionTestAssertionGuid017, L"EFI_BLOCK_IO_PROTOCOL.Media->MediaPresent,Media remove or insert of device must affect the MediaPresent field", L"%a:%d:Previous MediaPresent=%d, After MediaPresent=%d", __FILE__, __LINE__, MediaPresent, BlockIo->Media->MediaPresent ); // // Restore the envionment // MediaPresent = BlockIo->Media->MediaPresent; } // // Initialize variable // MediaId = BlockIo->Media->MediaId; RemovableMedia = BlockIo->Media->RemovableMedia; MediaPresent = BlockIo->Media->MediaPresent; LogicalPartition = BlockIo->Media->LogicalPartition; ReadOnly = BlockIo->Media->ReadOnly; WriteCaching = BlockIo->Media->WriteCaching; BlockSize = BlockIo->Media->BlockSize; IoAlign = BlockIo->Media->IoAlign; LastBlock = BlockIo->Media->LastBlock; } // // Assertion Point 5.5.2.2 // Media change of device must affect the MediaId field and // may affect the BlockSize and ReadOnly and Logical Partition field. // AssertionPoint2: if (RemovableMedia == TRUE) { if (MediaPresent == TRUE) { Print (L"Change media in device "); } else { Print (L"Insert media into device "); } DevicePathStr = DevicePathToStr (DevicePath); if (DevicePathStr != NULL) { Print (DevicePathStr); Status = gtBS->FreePool (DevicePathStr); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.FreePool - Free device path string", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); goto FreeBuffer; } DevicePathStr = NULL; } if (AutoJudge (50, FALSE, L"\r\nReady?\r\n") != TRUE) { goto FreeBuffer; } // // Call ReadBlocks to force re-install device // Status = BlockIo->ReadBlocks ( BlockIo, MediaId, 0, BlockSize, (VOID*)Buffer ); if (EFI_ERROR(Status)) { // // No Status check here. // } // // Begin to re-locate the BlockIo interface according to the DevicePath // LocateBlockIoFromDevicePath (&BlockIo, DevicePath, StandardLib); // // MediaID verificatoin // if (MediaId == BlockIo->Media->MediaId) { AssertionType = EFI_TEST_ASSERTION_FAILED; } else { AssertionType = EFI_TEST_ASSERTION_PASSED; } StandardLib->RecordAssertion ( StandardLib, AssertionType, gBlockIoFunctionTestAssertionGuid019, L"EFI_BLOCK_IO_PROTOCOL.Media->MediaId,Media remove or insert of device must affect the MediaId field", L"%a:%d:Previous MediaId=%d, After MediaId=%d", __FILE__, __LINE__, MediaId, BlockIo->Media->MediaId ); // // User's view about the current attribute of the media // MediaId = BlockIo->Media->MediaId; RemovableMedia = BlockIo->Media->RemovableMedia; MediaPresent = BlockIo->Media->MediaPresent; LogicalPartition = BlockIo->Media->LogicalPartition; ReadOnly = BlockIo->Media->ReadOnly; WriteCaching = BlockIo->Media->WriteCaching; BlockSize = BlockIo->Media->BlockSize; IoAlign = BlockIo->Media->IoAlign; LastBlock = BlockIo->Media->LastBlock; StandardLib->RecordMessage ( StandardLib, EFI_VERBOSE_LEVEL_DEFAULT, L"Current Media data field:\n" L"MediaId =%d\n" L"RemovableMedia =%d\n" L"MediaPresent =%d\n" L"LogicalPartition=%d\n" L"ReadOnly =%d\n" L"WriteCaching =%d\n" L"BlockSize =%d\n" L"IoAlign =%d\n" L"LastBlock =%lx\n", MediaId, RemovableMedia, MediaPresent, LogicalPartition, ReadOnly, WriteCaching, BlockSize, IoAlign, LastBlock ); // // Output current media data structure // if (AutoJudge (99, TRUE, L"\r\nCorrect?\r\n") != TRUE) { AssertionType = EFI_TEST_ASSERTION_FAILED; } else { AssertionType = EFI_TEST_ASSERTION_PASSED; } StandardLib->RecordAssertion ( StandardLib, AssertionType, gBlockIoFunctionTestAssertionGuid020, L"EFI_BLOCK_IO_PROTOCOL.Media,Media remove or insert of device must affect the MediaId field", L"%a:%d:As user's select", __FILE__, __LINE__ ); // // Restore environment // if (MediaPresent == TRUE) { Print (L"Change media back in device "); } else { Print (L"Remove media from device "); } DevicePathStr = DevicePathToStr (DevicePath); if (DevicePathStr != NULL) { Print (DevicePathStr); Status = gtBS->FreePool (DevicePathStr); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.FreePool - Free device path string", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); goto FreeBuffer; } DevicePathStr = NULL; } if (AutoJudge (50, FALSE, L"\r\nReady?\r\n") != TRUE) { goto FreeBuffer; } // // Call ReadBlocks to force re-install device // Status = BlockIo->ReadBlocks ( BlockIo, MediaId, 0, BlockSize, (VOID*)Buffer ); if (EFI_ERROR(Status)) { // // No Status check here. // } } FreeBuffer: // // Free resources // Status = gtBS->FreePool (Buffer); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.FreePool - Free buffer for testing", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); return Status; } return EFI_SUCCESS; }
// // TDS 5.3 // EFI_STATUS BBTestWriteBlocksFunctionAutoTest ( IN EFI_BB_TEST_PROTOCOL *This, IN VOID *ClientInterface, IN EFI_TEST_LEVEL TestLevel, IN EFI_HANDLE SupportHandle ) { EFI_STANDARD_TEST_LIBRARY_PROTOCOL *StandardLib; EFI_STATUS Status; EFI_BLOCK_IO_PROTOCOL *BlockIo; UINT32 MediaId; BOOLEAN RemovableMedia; BOOLEAN MediaPresent; BOOLEAN LogicalPartition; BOOLEAN ReadOnly; BOOLEAN WriteCaching; UINT32 BlockSize; UINT32 IoAlign; EFI_LBA LastBlock; UINTN BufferSize; UINT8 *Buffer; UINT8 *Buffer2; UINT8 *Buffer3; UINT32 BlockNumber; UINTN IndexI, IndexJ; UINTN NewBufferSize; EFI_LBA NewLba; UINTN Remainder; EFI_DEVICE_PATH_PROTOCOL *DevicePath; CHAR16 *DevicePathStr; EFI_TEST_ASSERTION AssertionTypeRead1; EFI_TEST_ASSERTION AssertionTypeRead2; EFI_TEST_ASSERTION AssertionTypeRead3; EFI_TEST_ASSERTION AssertionTypeWrite1; EFI_TEST_ASSERTION AssertionTypeWrite2; EFI_TEST_ASSERTION AssertionTypeComp1; EFI_TEST_ASSERTION AssertionTypeComp2; EFI_STATUS StatusRead1; EFI_STATUS StatusRead2; EFI_STATUS StatusRead3; EFI_STATUS StatusWrite1; EFI_STATUS StatusWrite2; UINTN CountComp1; UINTN CountComp2; // // Get the Standard Library Interface // Status = gtBS->HandleProtocol ( SupportHandle, &gEfiStandardTestLibraryGuid, &StandardLib ); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.HandleProtocol - Handle standard test library", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); return Status; } BlockIo = (EFI_BLOCK_IO_PROTOCOL *)ClientInterface; // // Locate & record DevicePath for further investigation // LocateDevicePathFromBlockIo (BlockIo, &DevicePath, StandardLib); DevicePathStr = DevicePathToStr (DevicePath); if (DevicePathStr != NULL) { StandardLib->RecordMessage ( StandardLib, EFI_VERBOSE_LEVEL_DEFAULT, L"Current Device: %s", DevicePathStr ); Status = gtBS->FreePool (DevicePathStr); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.FreePool - Free device path string", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); return Status; } DevicePathStr = NULL; } // // Initialize variable // MediaId = BlockIo->Media->MediaId; RemovableMedia = BlockIo->Media->RemovableMedia; MediaPresent = BlockIo->Media->MediaPresent; LogicalPartition = BlockIo->Media->LogicalPartition; ReadOnly = BlockIo->Media->ReadOnly; WriteCaching = BlockIo->Media->WriteCaching; BlockSize = BlockIo->Media->BlockSize; IoAlign = BlockIo->Media->IoAlign; LastBlock = BlockIo->Media->LastBlock; BlockNumber = (UINT32) MINIMUM(LastBlock, MAX_NUMBER_OF_READ_BLOCK_BUFFER); BufferSize = BlockNumber * BlockSize; if (BufferSize == 0) { BufferSize = 512; } // // allocate buffer // Status = gtBS->AllocatePool (EfiBootServicesData, BufferSize, &Buffer); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.AllocatePool - Allocate buffer for testing", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); return Status; } Status = gtBS->AllocatePool (EfiBootServicesData, BufferSize, &Buffer2); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.AllocatePool - Allocate buffer for testing", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); gtBS->FreePool (Buffer); return Status; } Status = gtBS->AllocatePool (EfiBootServicesData, BufferSize, &Buffer3); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.AllocatePool - Allocate buffer for testing", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); gtBS->FreePool (Buffer); gtBS->FreePool (Buffer2); return Status; } // // Assertion Point 5.3.2.1 // ReadBlocks must succeed to read proper data from device with valid parameter // if ((MediaPresent == TRUE) && (ReadOnly == FALSE)) { for (IndexI = 1; IndexI < MAX_DIFFERENT_BUFFERSIZE_FOR_TEST; IndexI++) { // // prepare test data // BufferSize will range from BlockSize to MAX_DIFFERENT_BUFFERSIZE_FOR_TEST*BlockSize // NewBufferSize = IndexI * BlockSize; // //parameter verification on NewBufferSize // if (NewBufferSize > BufferSize) { break; } for (IndexJ = 0; IndexJ < 3 * MAX_DIFFERENT_LBA_FOR_TEST; IndexJ++) { // // prepare test data // if (IndexJ < MAX_DIFFERENT_LBA_FOR_TEST) { // from 1 to MAX_DIFFERENT_LBA_FOR_TEST NewLba = IndexJ; } else if (IndexJ < 2 * MAX_DIFFERENT_LBA_FOR_TEST) { // from (LastBlock - MAX_DIFFERENT_LBA_FOR_TEST - MAX_DIFFERENT_BUFFERSIZE_FOR_TEST) to (LastBlock - MAX_DIFFERENT_BUFFERSIZE_FOR_TEST) NewLba = IndexJ + LastBlock - 2 * MAX_DIFFERENT_LBA_FOR_TEST - MAX_DIFFERENT_BUFFERSIZE_FOR_TEST; } else { // from (LastBlock/2 - MAX_DIFFERENT_LBA_FOR_TEST/2) to (LastBlock/2 + MAX_DIFFERENT_LBA_FOR_TEST/2) NewLba = IndexJ - 2 * MAX_DIFFERENT_LBA_FOR_TEST + (DivU64x32 (LastBlock, 2, &Remainder) - MAX_DIFFERENT_LBA_FOR_TEST / 2); } // //parameter verification on NewLba // if (NewLba + NewBufferSize / BlockSize > LastBlock + 1) { continue; } // // To avoid the LOG information is destroied, the LOG information will // be recorded after the original data is written again. // // // Call ReadBlocks with the specified LBA and BufferSize // StatusRead1 = BlockIo->ReadBlocks ( BlockIo, MediaId, NewLba, NewBufferSize, (VOID*)Buffer ); if (EFI_ERROR(StatusRead1)) { AssertionTypeRead1 = EFI_TEST_ASSERTION_FAILED; } else { AssertionTypeRead1 = EFI_TEST_ASSERTION_PASSED; } // // Write specified buffer2 differ from buffer to the device // StatusWrite1 = BlockIo->WriteBlocks ( BlockIo, MediaId, NewLba, NewBufferSize, (VOID*)Buffer2 ); if (EFI_ERROR(StatusWrite1)) { AssertionTypeWrite1 = EFI_TEST_ASSERTION_FAILED; } else { AssertionTypeWrite1 = EFI_TEST_ASSERTION_PASSED; } // // if write-cached, then flush the data to physical device // if (WriteCaching) { BlockIo->FlushBlocks (BlockIo); } // // Read Block with same LBA and BufferSize again and save data into Buffer3 // StatusRead2 = BlockIo->ReadBlocks ( BlockIo, MediaId, NewLba, NewBufferSize, (VOID*)Buffer3 ); if (EFI_ERROR(StatusRead2)) { AssertionTypeRead2 = EFI_TEST_ASSERTION_FAILED; } else { AssertionTypeRead2 = EFI_TEST_ASSERTION_PASSED; } // // verification on Write and Read blocks on valid media // CountComp1 = VerifyBuffer (Buffer2, Buffer3, NewBufferSize); if (CountComp1 > 0) { AssertionTypeComp1 = EFI_TEST_ASSERTION_FAILED; } else { AssertionTypeComp1 = EFI_TEST_ASSERTION_PASSED; } // // Write buffer read in the first call of ReadBlocks back to the device // StatusWrite2 = BlockIo->WriteBlocks ( BlockIo, MediaId, NewLba, NewBufferSize, (VOID*)Buffer ); if (EFI_ERROR(StatusWrite2)) { AssertionTypeWrite2 = EFI_TEST_ASSERTION_FAILED; } else { AssertionTypeWrite2 = EFI_TEST_ASSERTION_PASSED; } // // if write-cached, then flush the data to physical device // if (WriteCaching) { BlockIo->FlushBlocks (BlockIo); } // // Read Block with same LBA and BufferSize again and save data into Buffer3 // StatusRead3 = BlockIo->ReadBlocks ( BlockIo, MediaId, NewLba, NewBufferSize, (VOID*)Buffer3 ); if (EFI_ERROR(StatusRead3)) { AssertionTypeRead3 = EFI_TEST_ASSERTION_FAILED; } else { AssertionTypeRead3 = EFI_TEST_ASSERTION_PASSED; } // // verification on first and last call of ReadBlocks // CountComp2 = VerifyBuffer (Buffer, Buffer3, NewBufferSize); if (CountComp2 > 0) { AssertionTypeComp2 = EFI_TEST_ASSERTION_FAILED; } else { AssertionTypeComp2 = EFI_TEST_ASSERTION_PASSED; } // // Record test results // StandardLib->RecordAssertion ( StandardLib, AssertionTypeRead1, gTestGenericFailureGuid, L"EFI_BLOCK_IO_PROTOCOL.ReadBlocks - Read Block with proper parameter from valid media", L"%a:%d:BufferSize=%d, Lba=0x%lx, Status=%r", __FILE__, __LINE__, NewBufferSize, NewLba, StatusRead1 ); StandardLib->RecordAssertion ( StandardLib, AssertionTypeWrite1, gBlockIoFunctionTestAssertionGuid009, L"EFI_BLOCK_IO_PROTOCOL.WriteBlocks - Write Block with proper parameter from valid media", L"%a:%d:BufferSize=%d, Lba=0x%lx, Status=%r", __FILE__, __LINE__, NewBufferSize, NewLba, StatusWrite1 ); StandardLib->RecordAssertion ( StandardLib, AssertionTypeRead2, gTestGenericFailureGuid, L"EFI_BLOCK_IO_PROTOCOL.ReadBlocks - Read Block with proper parameter from valid media", L"%a:%d:BufferSize=%d, Lba=0x%lx, Status=%r", __FILE__, __LINE__, NewBufferSize, NewLba, StatusRead2 ); StandardLib->RecordAssertion ( StandardLib, AssertionTypeComp1, gBlockIoFunctionTestAssertionGuid012, L"EFI_BLOCK_IO_PROTOCOL.WriteBlocks - Verification on Write and Read blocks on valid media", L"%a:%d:BufferSize=%d, Lba=0x%lx, DiffCount=%d", __FILE__, __LINE__, NewBufferSize, NewLba, CountComp1 ); StandardLib->RecordAssertion ( StandardLib, AssertionTypeWrite2, gBlockIoFunctionTestAssertionGuid013, L"EFI_BLOCK_IO_PROTOCOL.WriteBlocks - Write Block with proper parameter back to valid media ", L"%a:%d:BufferSize=%d, Lba=0x%lx, Status=%r", __FILE__, __LINE__, NewBufferSize, NewLba, StatusWrite2 ); StandardLib->RecordAssertion ( StandardLib, AssertionTypeRead3, gTestGenericFailureGuid, L"EFI_BLOCK_IO_PROTOCOL.ReadBlocks - Read Block with proper parameter from valid media", L"%a:%d:BufferSize=%d, Lba=0x%lx, Status=%r", __FILE__, __LINE__, NewBufferSize, NewLba, StatusRead3 ); StandardLib->RecordAssertion ( StandardLib, AssertionTypeComp2, gBlockIoFunctionTestAssertionGuid016, L"EFI_BLOCK_IO_PROTOCOL.WriteBlocks - Verification on Write and Read blocks on valid media", L"%a:%d:BufferSize=%d, Lba=0x%lx, DiffCount=%d", __FILE__, __LINE__, NewBufferSize, NewLba, CountComp2 ); }//end of loop of Lba - IndexJ }//end of loop of BufferSize - IndexI } // // Free resources // Status = gtBS->FreePool (Buffer3); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.FreePool - Free buffer for testing", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); return Status; } Status = gtBS->FreePool (Buffer2); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.FreePool - Free buffer for testing", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); return Status; } Status = gtBS->FreePool (Buffer); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.FreePool - Free buffer for testing", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); return Status; } return EFI_SUCCESS; }
// // TDS 5.2 // EFI_STATUS BBTestReadBlocksFunctionAutoTest ( IN EFI_BB_TEST_PROTOCOL *This, IN VOID *ClientInterface, IN EFI_TEST_LEVEL TestLevel, IN EFI_HANDLE SupportHandle ) { EFI_STANDARD_TEST_LIBRARY_PROTOCOL *StandardLib; EFI_STATUS Status; EFI_BLOCK_IO_PROTOCOL *BlockIo; EFI_TEST_ASSERTION AssertionType; UINT32 MediaId; BOOLEAN RemovableMedia; BOOLEAN MediaPresent; BOOLEAN LogicalPartition; BOOLEAN ReadOnly; BOOLEAN WriteCaching; UINT32 BlockSize; UINT32 IoAlign; EFI_LBA LastBlock; UINTN BufferSize; UINT8 *Buffer; UINT32 BlockNumber; UINTN IndexI, IndexJ; UINTN NewBufferSize; EFI_LBA NewLba; UINTN Remainder; EFI_DEVICE_PATH_PROTOCOL *DevicePath; CHAR16 *DevicePathStr; // // Get the Standard Library Interface // Status = gtBS->HandleProtocol ( SupportHandle, &gEfiStandardTestLibraryGuid, &StandardLib ); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.HandleProtocol - Handle standard test library", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); return Status; } BlockIo = (EFI_BLOCK_IO_PROTOCOL *)ClientInterface; // // Locate & record DevicePath for further investigation // LocateDevicePathFromBlockIo (BlockIo, &DevicePath, StandardLib); DevicePathStr = DevicePathToStr (DevicePath); if (DevicePathStr != NULL) { StandardLib->RecordMessage ( StandardLib, EFI_VERBOSE_LEVEL_DEFAULT, L"Current Device: %s", DevicePathStr ); Status = gtBS->FreePool (DevicePathStr); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.FreePool - Free device path string", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); return Status; } DevicePathStr = NULL; } // // Initialize variable // MediaId = BlockIo->Media->MediaId; RemovableMedia = BlockIo->Media->RemovableMedia; MediaPresent = BlockIo->Media->MediaPresent; LogicalPartition = BlockIo->Media->LogicalPartition; ReadOnly = BlockIo->Media->ReadOnly; WriteCaching = BlockIo->Media->WriteCaching; BlockSize = BlockIo->Media->BlockSize; IoAlign = BlockIo->Media->IoAlign; LastBlock = BlockIo->Media->LastBlock; BlockNumber = (UINT32) MINIMUM(LastBlock, MAX_NUMBER_OF_READ_BLOCK_BUFFER); BufferSize = BlockNumber * BlockSize; if (BufferSize == 0) { BufferSize = 512; } // // allocate buffer // Status = gtBS->AllocatePool (EfiBootServicesData, BufferSize, &Buffer); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.AllocatePool - Allocate buffer for testing", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); return Status; } // // Assertion Point 5.2.2.1 // ReadBlocks must succeed to read proper data from device with valid parameter // if (MediaPresent == TRUE) { for (IndexI = 1; IndexI < MAX_DIFFERENT_BUFFERSIZE_FOR_TEST; IndexI++) { // // prepare test data // BufferSize will range from BlockSize to MAX_DIFFERENT_BUFFERSIZE_FOR_TEST*BlockSize // NewBufferSize = IndexI * BlockSize; // //parameter verification on NewBufferSize // if (NewBufferSize > BufferSize) { break; } for (IndexJ = 0; IndexJ < 3 * MAX_DIFFERENT_LBA_FOR_TEST; IndexJ++) { // // prepare test data // if (IndexJ < MAX_DIFFERENT_LBA_FOR_TEST) { // from 1 to MAX_DIFFERENT_LBA_FOR_TEST NewLba = IndexJ; } else if (IndexJ < 2 * MAX_DIFFERENT_LBA_FOR_TEST) { // from (LastBlock - MAX_DIFFERENT_LBA_FOR_TEST - MAX_DIFFERENT_BUFFERSIZE_FOR_TEST) to (LastBlock - MAX_DIFFERENT_BUFFERSIZE_FOR_TEST) NewLba = IndexJ + LastBlock - 2 * MAX_DIFFERENT_LBA_FOR_TEST - MAX_DIFFERENT_BUFFERSIZE_FOR_TEST; } else { // from (LastBlock/2 - MAX_DIFFERENT_LBA_FOR_TEST/2) to (LastBlock/2 + MAX_DIFFERENT_LBA_FOR_TEST/2) NewLba = IndexJ - 2 * MAX_DIFFERENT_LBA_FOR_TEST + (DivU64x32 (LastBlock, 2, &Remainder) - MAX_DIFFERENT_LBA_FOR_TEST / 2); } // //parameter verification on NewLba // if (NewLba + NewBufferSize / BlockSize > LastBlock + 1) { continue; } // // Call ReadBlocks with the specified LBA and BufferSize // Status = BlockIo->ReadBlocks ( BlockIo, MediaId, NewLba, NewBufferSize, (VOID*)Buffer ); if (EFI_ERROR(Status)) { AssertionType = EFI_TEST_ASSERTION_FAILED; } else { AssertionType = EFI_TEST_ASSERTION_PASSED; } StandardLib->RecordAssertion ( StandardLib, AssertionType, gBlockIoFunctionTestAssertionGuid003, L"EFI_BLOCK_IO_PROTOCOL.ReadBlocks - Read Block with proper parameter from valid media", L"%a:%d:BufferSize=%d, Lba=0x%lx, Status=%r", __FILE__, __LINE__, NewBufferSize, NewLba, Status ); if (EFI_ERROR(Status)) { continue; } }//end of loop of Lba - IndexJ }//end of loop of BufferSize - IndexI } // // Free resources // Status = gtBS->FreePool (Buffer); if (EFI_ERROR(Status)) { StandardLib->RecordAssertion ( StandardLib, EFI_TEST_ASSERTION_FAILED, gTestGenericFailureGuid, L"BS.FreePool - Free buffer for testing", L"%a:%d:Status - %r", __FILE__, __LINE__, Status ); return Status; } return EFI_SUCCESS; }
VOID EFIAPI SEnvBlkIo ( IN EFI_HANDLE h, IN VOID *Interface ) /*++ Routine Description: Arguments: h - An EFI handle Interface - The interface Returns: --*/ { EFI_BLOCK_IO_PROTOCOL *BlkIo; EFI_BLOCK_IO_MEDIA *BlkMedia; VOID *Buffer; BlkIo = Interface; BlkMedia = BlkIo->Media; // // Issue a dummy read to the device to check for media change // Buffer = AllocatePool (BlkMedia->BlockSize); if (Buffer) { BlkIo->ReadBlocks ( BlkIo, BlkMedia->MediaId, 0, BlkMedia->BlockSize, Buffer ); FreePool (Buffer); } // // Dump BlkIo Info // PrintToken ( STRING_TOKEN (STR_SHELLENV_DPROT_MID), HiiEnvHandle, BlkMedia->RemovableMedia ? L"Removable " : L"Fixed ", BlkMedia->MediaPresent ? L"" : L"not-present ", BlkMedia->MediaId ); PrintToken ( STRING_TOKEN (STR_SHELLENV_DPROT_BSIZE_LBLOCK), HiiEnvHandle, BlkMedia->BlockSize, BlkMedia->LastBlock, MultU64x32 (BlkMedia->LastBlock + 1, BlkMedia->BlockSize), BlkMedia->LogicalPartition ? L"partition" : L"raw", BlkMedia->ReadOnly ? L"ro" : L"rw", BlkMedia->WriteCaching ? L"cached" : L"!cached" ); }
EFI_STATUS BOpt_FindFileSystem ( IN BMM_CALLBACK_DATA *CallbackData ) /*++ Routine Description Find file systems for current Extensible Firmware Including Handles that support Simple File System protocol, Load File protocol. Building up the FileSystem Menu for user selection All file system will be stored in FsOptionMenu for future use. Arguments: CallbackData - BMM context data Returns: EFI_SUCCESS - Success find the file system EFI_OUT_OF_RESOURCES - Can not create menu entry --*/ { UINTN NoBlkIoHandles; UINTN NoSimpleFsHandles; UINTN NoLoadFileHandles; EFI_HANDLE *BlkIoHandle; EFI_HANDLE *SimpleFsHandle; EFI_HANDLE *LoadFileHandle; UINT16 *VolumeLabel; EFI_BLOCK_IO_PROTOCOL *BlkIo; UINTN Index; EFI_STATUS Status; BM_MENU_ENTRY *MenuEntry; BM_FILE_CONTEXT *FileContext; UINT16 *TempStr; UINTN OptionNumber; VOID *Buffer; EFI_LEGACY_BIOS_PROTOCOL *LegacyBios; UINT16 DeviceType; BBS_BBS_DEVICE_PATH BbsDevicePathNode; EFI_DEVICE_PATH_PROTOCOL *DevicePath; BOOLEAN RemovableMedia; NoSimpleFsHandles = 0; NoLoadFileHandles = 0; OptionNumber = 0; InitializeListHead (&FsOptionMenu.Head); // // Locate Handles that support BlockIo protocol // Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &NoBlkIoHandles, &BlkIoHandle ); if (!EFI_ERROR (Status)) { for (Index = 0; Index < NoBlkIoHandles; Index++) { Status = gBS->HandleProtocol ( BlkIoHandle[Index], &gEfiBlockIoProtocolGuid, &BlkIo ); if (EFI_ERROR (Status)) { continue; } // // Issue a dummy read to trigger reinstall of BlockIo protocol for removable media // if (BlkIo->Media->RemovableMedia) { Buffer = EfiAllocateZeroPool (BlkIo->Media->BlockSize); if (NULL == Buffer) { SafeFreePool (BlkIoHandle); return EFI_OUT_OF_RESOURCES; } BlkIo->ReadBlocks ( BlkIo, BlkIo->Media->MediaId, 0, BlkIo->Media->BlockSize, Buffer ); SafeFreePool (Buffer); } } SafeFreePool (BlkIoHandle); } // // Locate Handles that support Simple File System protocol // Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &NoSimpleFsHandles, &SimpleFsHandle ); if (!EFI_ERROR (Status)) { // // Find all the instances of the File System prototocol // for (Index = 0; Index < NoSimpleFsHandles; Index++) { Status = gBS->HandleProtocol ( SimpleFsHandle[Index], &gEfiBlockIoProtocolGuid, &BlkIo ); if (EFI_ERROR (Status)) { // // If no block IO exists assume it's NOT a removable media // RemovableMedia = FALSE; } else { // // If block IO exists check to see if it's remobable media // RemovableMedia = BlkIo->Media->RemovableMedia; } // // Allocate pool for this load option // MenuEntry = BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT); if (NULL == MenuEntry) { SafeFreePool (SimpleFsHandle); return EFI_OUT_OF_RESOURCES; } FileContext = (BM_FILE_CONTEXT *) MenuEntry->VariableContext; FileContext->Handle = SimpleFsHandle[Index]; MenuEntry->OptionNumber = Index; FileContext->FHandle = EfiLibOpenRoot (FileContext->Handle); if (!FileContext->FHandle) { BOpt_DestroyMenuEntry (MenuEntry); continue; } MenuEntry->HelpString = DevicePathToStr (EfiDevicePathFromHandle (FileContext->Handle)); FileContext->Info = EfiLibFileSystemVolumeLabelInfo (FileContext->FHandle); FileContext->FileName = EfiStrDuplicate (L"\\"); FileContext->DevicePath = EfiFileDevicePath ( FileContext->Handle, FileContext->FileName ); FileContext->IsDir = TRUE; FileContext->IsRoot = TRUE; FileContext->IsRemovableMedia = FALSE; FileContext->IsLoadFile = FALSE; // // Get current file system's Volume Label // if (FileContext->Info == NULL) { VolumeLabel = L"NO FILE SYSTEM INFO"; } else { if (FileContext->Info->VolumeLabel == NULL) { VolumeLabel = L"NULL VOLUME LABEL"; } else { VolumeLabel = FileContext->Info->VolumeLabel; if (*VolumeLabel == 0x0000) { VolumeLabel = L"NO VOLUME LABEL"; } } } TempStr = MenuEntry->HelpString; MenuEntry->DisplayString = EfiAllocateZeroPool (MAX_CHAR); ASSERT (MenuEntry->DisplayString != NULL); SPrint ( MenuEntry->DisplayString, MAX_CHAR, L"%s, [%s]", VolumeLabel, TempStr ); OptionNumber++; InsertTailList (&FsOptionMenu.Head, &MenuEntry->Link); } } if (NoSimpleFsHandles != 0) { SafeFreePool (SimpleFsHandle); } // // Searching for handles that support Load File protocol // Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiLoadFileProtocolGuid, NULL, &NoLoadFileHandles, &LoadFileHandle ); if (!EFI_ERROR (Status)) { for (Index = 0; Index < NoLoadFileHandles; Index++) { MenuEntry = BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT); if (NULL == MenuEntry) { SafeFreePool (LoadFileHandle); return EFI_OUT_OF_RESOURCES; } FileContext = (BM_FILE_CONTEXT *) MenuEntry->VariableContext; FileContext->IsRemovableMedia = FALSE; FileContext->IsLoadFile = TRUE; FileContext->Handle = LoadFileHandle[Index]; FileContext->IsRoot = TRUE; FileContext->DevicePath = EfiDevicePathFromHandle (FileContext->Handle); MenuEntry->HelpString = DevicePathToStr (FileContext->DevicePath); TempStr = MenuEntry->HelpString; MenuEntry->DisplayString = EfiAllocateZeroPool (MAX_CHAR); ASSERT (MenuEntry->DisplayString != NULL); SPrint ( MenuEntry->DisplayString, MAX_CHAR, L"Load File [%s]", TempStr ); MenuEntry->OptionNumber = OptionNumber; OptionNumber++; InsertTailList (&FsOptionMenu.Head, &MenuEntry->Link); } } if (NoLoadFileHandles != 0) { SafeFreePool (LoadFileHandle); } // // Add Legacy Boot Option Support Here // Status = gBS->LocateProtocol ( &gEfiLegacyBiosProtocolGuid, NULL, &LegacyBios ); if (!EFI_ERROR (Status)) { for (Index = BBS_TYPE_FLOPPY; Index <= BBS_TYPE_EMBEDDED_NETWORK; Index++) { MenuEntry = BOpt_CreateMenuEntry (BM_FILE_CONTEXT_SELECT); if (NULL == MenuEntry) { return EFI_OUT_OF_RESOURCES; } FileContext = (BM_FILE_CONTEXT *) MenuEntry->VariableContext; FileContext->IsRemovableMedia = FALSE; FileContext->IsLoadFile = TRUE; FileContext->IsBootLegacy = TRUE; DeviceType = (UINT16) Index; BbsDevicePathNode.Header.Type = BBS_DEVICE_PATH; BbsDevicePathNode.Header.SubType = BBS_BBS_DP; SetDevicePathNodeLength ( &BbsDevicePathNode.Header, sizeof (BBS_BBS_DEVICE_PATH) ); BbsDevicePathNode.DeviceType = DeviceType; BbsDevicePathNode.StatusFlag = 0; BbsDevicePathNode.String[0] = 0; DevicePath = EfiAppendDevicePathNode ( EndDevicePath, (EFI_DEVICE_PATH_PROTOCOL *) &BbsDevicePathNode ); FileContext->DevicePath = DevicePath; MenuEntry->HelpString = DevicePathToStr (FileContext->DevicePath); TempStr = MenuEntry->HelpString; MenuEntry->DisplayString = EfiAllocateZeroPool (MAX_CHAR); ASSERT (MenuEntry->DisplayString != NULL); SPrint ( MenuEntry->DisplayString, MAX_CHAR, L"Boot Legacy [%s]", TempStr ); MenuEntry->OptionNumber = OptionNumber; OptionNumber++; InsertTailList (&FsOptionMenu.Head, &MenuEntry->Link); } } // // Remember how many file system options are here // FsOptionMenu.MenuNumber = OptionNumber; return EFI_SUCCESS; }
/** This function builds the FsOptionMenu list which records all available file system in the system. They include all instances of EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, all instances of EFI_LOAD_FILE_SYSTEM and all type of legacy boot device. @retval EFI_SUCCESS Success find the file system @retval EFI_OUT_OF_RESOURCES Can not create menu entry **/ EFI_STATUS FindFileSystem ( VOID ) { UINTN NoBlkIoHandles; UINTN NoSimpleFsHandles; EFI_HANDLE *BlkIoHandle; EFI_HANDLE *SimpleFsHandle; UINT16 *VolumeLabel; EFI_BLOCK_IO_PROTOCOL *BlkIo; UINTN Index; EFI_STATUS Status; SECUREBOOT_MENU_ENTRY *MenuEntry; SECUREBOOT_FILE_CONTEXT *FileContext; UINT16 *TempStr; UINTN OptionNumber; VOID *Buffer; BOOLEAN RemovableMedia; NoSimpleFsHandles = 0; OptionNumber = 0; InitializeListHead (&FsOptionMenu.Head); // // Locate Handles that support BlockIo protocol // Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiBlockIoProtocolGuid, NULL, &NoBlkIoHandles, &BlkIoHandle ); if (!EFI_ERROR (Status)) { for (Index = 0; Index < NoBlkIoHandles; Index++) { Status = gBS->HandleProtocol ( BlkIoHandle[Index], &gEfiBlockIoProtocolGuid, (VOID **) &BlkIo ); if (EFI_ERROR (Status)) { continue; } // // Issue a dummy read to trigger reinstall of BlockIo protocol for removable media // if (BlkIo->Media->RemovableMedia) { Buffer = AllocateZeroPool (BlkIo->Media->BlockSize); if (NULL == Buffer) { FreePool (BlkIoHandle); return EFI_OUT_OF_RESOURCES; } BlkIo->ReadBlocks ( BlkIo, BlkIo->Media->MediaId, 0, BlkIo->Media->BlockSize, Buffer ); FreePool (Buffer); } } FreePool (BlkIoHandle); } // // Locate Handles that support Simple File System protocol // Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiSimpleFileSystemProtocolGuid, NULL, &NoSimpleFsHandles, &SimpleFsHandle ); if (!EFI_ERROR (Status)) { // // Find all the instances of the File System prototocol // for (Index = 0; Index < NoSimpleFsHandles; Index++) { Status = gBS->HandleProtocol ( SimpleFsHandle[Index], &gEfiBlockIoProtocolGuid, (VOID **) &BlkIo ); if (EFI_ERROR (Status)) { // // If no block IO exists assume it's NOT a removable media // RemovableMedia = FALSE; } else { // // If block IO exists check to see if it's remobable media // RemovableMedia = BlkIo->Media->RemovableMedia; } // // Allocate pool for this instance. // MenuEntry = CreateMenuEntry (); if (NULL == MenuEntry) { FreePool (SimpleFsHandle); return EFI_OUT_OF_RESOURCES; } FileContext = (SECUREBOOT_FILE_CONTEXT *) MenuEntry->FileContext; FileContext->Handle = SimpleFsHandle[Index]; MenuEntry->OptionNumber = Index; FileContext->FHandle = OpenRoot (FileContext->Handle); if (FileContext->FHandle == NULL) { DestroyMenuEntry (MenuEntry); continue; } MenuEntry->HelpString = DevicePathToStr (DevicePathFromHandle (FileContext->Handle)); FileContext->Info = FileSystemVolumeLabelInfo (FileContext->FHandle); FileContext->FileName = StrDuplicate (L"\\"); FileContext->DevicePath = FileDevicePath ( FileContext->Handle, FileContext->FileName ); FileContext->IsDir = TRUE; FileContext->IsRoot = TRUE; FileContext->IsRemovableMedia = RemovableMedia; FileContext->IsLoadFile = FALSE; // // Get current file system's Volume Label // if (FileContext->Info == NULL) { VolumeLabel = L"NO FILE SYSTEM INFO"; } else { if (FileContext->Info->VolumeLabel == NULL) { VolumeLabel = L"NULL VOLUME LABEL"; } else { VolumeLabel = FileContext->Info->VolumeLabel; if (*VolumeLabel == 0x0000) { VolumeLabel = L"NO VOLUME LABEL"; } } } TempStr = MenuEntry->HelpString; MenuEntry->DisplayString = AllocateZeroPool (MAX_CHAR); ASSERT (MenuEntry->DisplayString != NULL); UnicodeSPrint ( MenuEntry->DisplayString, MAX_CHAR, L"%s, [%s]", VolumeLabel, TempStr ); OptionNumber++; InsertTailList (&FsOptionMenu.Head, &MenuEntry->Link); } } if (NoSimpleFsHandles != 0) { FreePool (SimpleFsHandle); } // // Remember how many file system options are here // FsOptionMenu.MenuNumber = OptionNumber; return EFI_SUCCESS; }