From b7c51c9cf4864df6aabb99a1ae843becd577237c Mon Sep 17 00:00:00 2001 From: raywu Date: Fri, 15 Jun 2018 00:00:50 +0800 Subject: init. 1AQQW051 --- Core/EM/FloppyCtrl/FloppyCtrl.c | 2792 ++++++++++++++++++++++++++++++++++ Core/EM/FloppyCtrl/FloppyCtrl.cif | 13 + Core/EM/FloppyCtrl/FloppyCtrl.h | 441 ++++++ Core/EM/FloppyCtrl/FloppyCtrl.mak | 94 ++ Core/EM/FloppyCtrl/FloppyCtrl.sdl | 40 + Core/EM/FloppyCtrl/FloppyCtrlPei.dxs | 70 + Core/EM/FloppyCtrl/Names.c | 240 +++ 7 files changed, 3690 insertions(+) create mode 100644 Core/EM/FloppyCtrl/FloppyCtrl.c create mode 100644 Core/EM/FloppyCtrl/FloppyCtrl.cif create mode 100644 Core/EM/FloppyCtrl/FloppyCtrl.h create mode 100644 Core/EM/FloppyCtrl/FloppyCtrl.mak create mode 100644 Core/EM/FloppyCtrl/FloppyCtrl.sdl create mode 100644 Core/EM/FloppyCtrl/FloppyCtrlPei.dxs create mode 100644 Core/EM/FloppyCtrl/Names.c (limited to 'Core/EM/FloppyCtrl') diff --git a/Core/EM/FloppyCtrl/FloppyCtrl.c b/Core/EM/FloppyCtrl/FloppyCtrl.c new file mode 100644 index 0000000..e096e72 --- /dev/null +++ b/Core/EM/FloppyCtrl/FloppyCtrl.c @@ -0,0 +1,2792 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Core/CORE_DXE/FloppyCtrl/FloppyCtrl.c 47 11/03/11 6:13a Rajeshms $ +// +// $Revision: 47 $ +// +// $Date: 11/03/11 6:13a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Core/CORE_DXE/FloppyCtrl/FloppyCtrl.c $ +// +// 47 11/03/11 6:13a Rajeshms +// [TAG] EIP73253 +// [Category] Improvement +// [Description] Floppy Driver Follow the UEFI Driver Model as per the +// UEFI Spec. +// [Files] FloppyCtrl.c +// +// 46 10/27/09 12:24p Pats +// EIP21981: enable RAID module hangs on checkpoint 99 +// Solution: Small delay in DMAChInit() +// +// 45 8/28/09 10:29a Felixp +// Component Name protocol implementation is upadted to support both +// ComponentName and ComponentName2 protocols +// (based on value of the EFI_SPECIFICATION_VERSION SDL token). +// +// 44 7/02/09 12:40p Yul +// Syns to coding standards +// +// 43 7/02/09 10:14a Yul +// Update Header and Tailer and syns with coding standards +// +// 42 6/24/09 11:12a Yul +// Fix for the EIP 14848 AMIDIAG issue. +// Instead of reading flag directly, check drive status and update the +// flag. +// +// 41 4/13/07 1:37p Ambikas +// Coding standards changes: added a couple of AMI_PHDRs; moved mPpiList +// before FDCPeimEntryPoint declaration. +// +// 40 4/13/07 12:02p Ambikas +// +// 39 4/13/07 11:57a Ambikas +// Coding standard changes: updated year in AMI copyright header and +// footer; removed commented out function GetFloppyModel. +// +// 38 4/10/07 10:01a Felixp +// LookupHID routine renamed to LookupFloppyHid to avoid linking issue +// when linking with PS2CTRL module +// +// 37 3/29/07 2:53p Yakovlevs +// Excluded GetFloppy_DP from PEI build path +// +// 36 3/29/07 2:09p Yakovlevs +// Replaced Device Path manipulation with Lib function call. +// +// 35 1/19/07 1:04p Yakovlevs +// Fixes for Legacy Free system EIP issue 8888 +// +// 34 10/04/06 12:24p Markw +// Add x64 support. +// +// 33 6/04/06 10:43p Ambikas +// +// 32 5/23/06 4:12a Felixp +// Bug fix: missing CloseProtocol calls added +// +// 31 5/20/06 9:30p Felixp +// minor bug fix: parameter was missing in ASSERT_PEI_ERROR +// +// 30 5/19/06 10:33p Felixp +// Device Path code updated to use NEXT_NODE/NODE_LENGTH macros to remove +// direct access to the Length field +// +// 29 5/05/06 5:21p Ambikas +// +// 28 4/03/06 3:55p Felixp +// Converted to support new Super I/O infrastructure +// +// 27 3/13/06 2:22a Felixp +// +// 26 12/21/05 11:42a Ambikas +// BIOS Recovery using floppy didn't work. The Fix: +// -Added function CheckMRQBit_NoDelay. +// -FddReadWriteFn: After initializing DMA registers and sending command +// packet, we wait for the result packet. Instead of calling CheckMRQBit, +// we call CheckMRQBit_NoDelay. Comment in that spot explains the reason +// why. +// +// 25 12/20/05 10:50p Ambikas +// Edited Revision History header part 24. +// +// 24 12/20/05 10:47p Ambikas +// Minor changes: +// -Added gPeiStall. Delay(): no longer use Locate Ppi every time for Stall Ppi. +// -Got rid of unused bit defs for FloppyInterface->FdcFlag and consolidated remaining bit defs with bit defs for global var FdcFlag. +// Eliminated FdcFlag. Added global var gPeiToDxeFloppyDrive0Status, which will pass state of floppy at end of pei to dxe, as FdcFlag did. +// Replaced constants (e.g. BIT00) with names. +// -UINT8 MediaType replaced with FLOPPY_DISK_FORMAT FloppyDiskFormat. -Added InitFloppyBlockIOLastBlockAndMaxSectors(). +// -FddReadWriteFn: For command packet, only check MRQ bit; don't check DIO bit. Got rid of other unnnessary checking of DIO/MRQ bits. Changed error message. +// -DmaInitTable: got rid of lines writing nonexistent registers 9 and 0xd2. (This is Ich7). +// -DmaInitForFloppy: write the clear byte register (DMA1_RESET_REG) before writing the count value. +// -SetDataRate: Configuration Control Register is 0x3f7, not 0x3f4. +// +// 23 11/23/05 11:30a Felixp +// When floppy driver is not connected, stop SIO driver +// +// 21 9/30/05 4:03p Felixp +// VC7.1 warnings removed +// +// 20 9/28/05 12:00p Felixp +// bug fix in UpdateIOST +// +// 19 8/22/05 5:32p Felixp +// Disable Floppy when controller is not detected +// (update vIOST variable) +// +// 18 8/10/05 1:06p Mandal +// FDCReset function - Considering the return status of FloopyDriveInit +// function. +// +// 17 5/14/05 5:13p Eswark +// +// 16 5/14/05 5:07p Eswark +// MotorOff function included in FdcReset Function. +// +// 15 7/18/05 3:51p Felixp +// +// 14 4/01/05 4:13p Eswark +// +// 13 4/01/05 11:54a Eswark +// Interface structure is getting the proper media change value from +// "CheckMediaChange" function. +// +// 12 3/25/05 6:39p Felixp +// +// 11 3/25/05 6:09p Eswark +// Moved code from "FDCPeimEntryPoint" to "GetBlockDeviceMediaInfo". +// +// 9 3/25/05 8:27a Felixp +// +// 8 3/25/05 7:58a Felixp +// +// 7 3/24/05 6:28p Felixp +// +// 6 3/24/05 11:51a Eswark +// Added Floppy peim code based on recovery specifixcation. +// +// 4 3/22/05 4:47p Eswark +// Added pei support. +// +// 3 3/04/05 11:28a Mandal +// +// 2 2/07/05 4:03p Yakovlevs +// +// 1 2/01/05 1:12a Felixp +// +// 7 2/01/05 12:30a Felixp +// +// 6 1/22/05 12:41p Felixp +// Bug fix: +// Last parameter to AllocatePages was UINT8* instead of +// EFI_PHYSICAL_ADDRESS*, which +// resulted in a stack corruption. +// +// 5 1/18/05 3:22p Felixp +// PrintDebugMessage renamed to Trace +// +// 4 1/04/05 11:20a Felixp +// +// 1 12/22/04 6:19p Admin +// +// 1 12/22/04 6:18p Admin +// +// 8 12/17/04 7:38p Olegi +// +// 7 12/17/04 6:59p Felixp +// DEBUG_MSG renamed to TRACE +// +// 6 12/17/04 9:39a Olegi +// +// 5 12/16/04 10:38a Eswark +// Added header for the floppy driver. +//********************************************************************** + + +//********************************************************************** +// +// +// Name: FloppyCtrl.c - Floppy Controller DXE driver +// +// Description: +// This driver initializes floppy controller and produces block IO protocol +// for floppy read and write access. +// +// +//********************************************************************** + +//====================================================================== +// Module specific Includes +#include "FloppyCtrl.h" +#include + +//====================================================================== +// GUID Definitions +static EFI_GUID gEfiBlockIoProtocolGuid = EFI_BLOCK_IO_PROTOCOL_GUID; +static EFI_GUID gEfiAmiSioProtocolGuid = EFI_AMI_SIO_PROTOCOL_GUID; +static EFI_GUID gDriverBindingProtocolGuid = EFI_DRIVER_BINDING_PROTOCOL_GUID; +static EFI_GUID gDevicePathProtocolGuid = EFI_DEVICE_PATH_PROTOCOL_GUID; +static EFI_GUID gEfiPeiStallPpiGuid = EFI_PEI_STALL_PPI_GUID; +#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID //old Core +static EFI_GUID gComponentNameProtocolGuid = EFI_COMPONENT_NAME_PROTOCOL_GUID; +#else +static EFI_GUID gComponentNameProtocolGuid = EFI_COMPONENT_NAME2_PROTOCOL_GUID; +#endif +static EFI_GUID gPciIoProtocolGuid = EFI_PCI_IO_PROTOCOL_GUID; + +extern EFI_COMPONENT_NAME_PROTOCOL gFloppyCtlDriverName; + +static EFI_SYSTEM_TABLE *gSysTable = NULL; +static EFI_PEI_SERVICES **PeiServices = NULL; + +EFI_PEI_STALL_PPI *gPeiStall = NULL; + +// gPeiToDxeFloppyDrive0Status: +// The last thing Pei Recovery function GetBlockDeviceMediaInfo does is to +// set gPeiToDxeFloppyDrive0Status to the current value of +// FloppyInterface->FdcFlag +// The dxe entry point FloppyCtrlStart copies gPeiToDxeFloppyDrive0Status +// to its FloppyInterface->FdcFlag for floppy drive 0. +// This way, FloppyCtrlStart can check if floppy drive0 has been initialized +// in pei and if so, can bypass initialization in dxe. +// +UINT8 gPeiToDxeFloppyDrive0Status = FDC_FLAG_NOT_INTIALIZED; + +// PEIM specific code start +static EFI_GUID guidBlockIo = EFI_PEI_VIRTUAL_BLOCK_IO_PPI; + +// PPI that are installed +static EFI_PEI_PPI_DESCRIPTOR mPpiList[] = { + EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, + &guidBlockIo, + NULL +}; //initialized by the entry point + +//********************************************************************** +// +// +// Procedure: FDCPeimEntryPoint +// +// Description: +// This is the entry point of PEIM FDC +// +// Input: +// IN EFI_FFS_FILE_HEADER *FfsHeader, +// IN EFI_PEI_SERVICES **PeiServices +// +// Output: +// EFI_STATUS +// +// Modified: +// +// Referrals: InitAmiLib InstallMultipleProtocolInterfaces +// +// Notes: +// Here is the control flow of this function: +// 1. Initialize Ami Lib. +// 2. Install Driver Binding Protocol +// 3. Return EFI_SUCCESS. +// +// +//********************************************************************** + +#ifdef PEI_FLOPPY_CTRL +EFI_STATUS FDCPeimEntryPoint( + IN EFI_FFS_FILE_HEADER *FfsHeader, + IN EFI_PEI_SERVICES **pPeiServices ) +{ + EFI_STATUS Status = EFI_SUCCESS; + FLOPPY_CTRL_PROTOCOL *FloppyInterface; + + PeiServices = pPeiServices; + + //Allocate Storage for FLOPPY_CTRL_PROTOCOL; + Status = (**PeiServices).AllocatePool( PeiServices, \ + sizeof(FLOPPY_CTRL_PROTOCOL), (VOID**)&FloppyInterface ); + ASSERT_PEI_ERROR( PeiServices, Status ); + //Clear data + MemSet((void*)FloppyInterface, sizeof(FLOPPY_CTRL_PROTOCOL), 0 ); + + FloppyInterface->PeimRecBlk.GetNumberOfBlockDevices + = GetNumberOfBlockDevices; + FloppyInterface->PeimRecBlk.GetBlockDeviceMediaInfo + = GetBlockDeviceMediaInfo; + FloppyInterface->PeimRecBlk.ReadBlocks = PeimReadBlocks; + + mPpiList[0].Ppi = &FloppyInterface->PeimRecBlk; + Status = (*PeiServices)->InstallPpi( PeiServices, &mPpiList[0] ); + ASSERT_PEI_ERROR( PeiServices, Status ); + + Status = (*PeiServices)->LocatePpi( PeiServices, &gEfiPeiStallPpiGuid, \ + 0, NULL, &gPeiStall ); + ASSERT_PEI_ERROR( PeiServices, Status ); + + return Status; +} + +#endif + +//********************************************************************** +// +// +// Procedure: GetNumberOfBlockDevices +// +// Description: +// This is the function to get the number of Block Devices +// +// Input: +// IN EFI_PEI_SERVICES **PeiServices, +// IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This +// +// Output: +// OUT UINTN *NumberBlockDevices +// EFI_STATUS +// +// +//********************************************************************** + +EFI_STATUS GetNumberOfBlockDevices( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, + OUT UINTN *NumberBlockDevices ) +{ + *NumberBlockDevices = 01; + return EFI_SUCCESS; +} + +//********************************************************************** +// +// +// Procedure: GetBlockDeviceMediaInfo +// +// Description: +// This is the function to get the Media information of Block Devices +// +// Input: +// IN EFI_PEI_SERVICES **PeiServices, +// IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, +// IN UINTN DeviceIndex +// +// Output: +// OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo +// EFI_STATUS +// +// +//********************************************************************** + +EFI_STATUS GetBlockDeviceMediaInfo( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, + IN UINTN DeviceIndex, + OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo ) +{ + FLOPPY_CTRL_PROTOCOL *FloppyInterface \ + = OUTTER( This, PeimRecBlk, FLOPPY_CTRL_PROTOCOL ); + EFI_STATUS Status = EFI_SUCCESS; + + if ( FloppyInterface->FdcFlag & FDC_FLAG_DRIVE_INIT_ERROR ) { + Status = EFI_DEVICE_ERROR; + } + else if ((FloppyInterface->FdcFlag & FDC_FLAG_DRIVE_INIT_SUCCESS) \ + || (FloppyInterface->FdcFlag == FDC_FLAG_NOT_INTIALIZED)) + { + FloppyInterface->BlkIo.Media = &(FloppyInterface->BlkIoMedia); + MediaInfo->DeviceType = LegacyFloppy; // Legacy Floppy + MediaInfo->BlockSize = 512; // SECTOR_SIZE + FloppyInterface->DriveNum = 00; + FloppyInterface->BaseAddr = 0x3F0; + FloppyInterface->FloppyDiskFormat = HighDensity1_44Mb; + + InitFloppyBlockIOLastBlockAndMaxSectors( FloppyInterface ); + + // Initilize DMA channels + if ( FloppyInterface->FdcFlag == FDC_FLAG_NOT_INTIALIZED ) { + DMAChInit( ); + } + + // Initilize floppy controller + Status = FloppyDriveInit( FloppyInterface ); + + MediaInfo->MediaPresent = FloppyInterface->BlkIoMedia.MediaPresent; + + if ( !(EFI_ERROR( Status ))) { + FloppyInterface->FdcFlag = FDC_FLAG_DRIVE_INIT_SUCCESS; + FloppyInterface->BlkIoMedia.BlockSize = 512; + + // FloppyInterface->DMABuffer: + // We don't allocate a buffer because we can't get memory at + // an address which meets the DMA requirement of being 24 bits + // or less in length. Instead, we set the DMA buffer + // to address 0x0 as nothing is there currently. + + FloppyInterface->DMABuffer = 0; + } + else { + FloppyInterface->TimerFlag = 01; + MotorOff( FloppyInterface->Event, FloppyInterface ); + FloppyInterface->FdcFlag |= FDC_FLAG_DRIVE_INIT_ERROR; + } + } + + gPeiToDxeFloppyDrive0Status = FloppyInterface->FdcFlag; + return Status; +} + +//********************************************************************** +// +// +// Procedure: PeimReadBlocks +// +// Description: +// This is the function to Read Blocks in PEIM +// +// Input: +// IN EFI_PEI_SERVICES **PeiServices, +// IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, +// IN UINTN DeviceIndex, +// IN EFI_PEI_LBA StartLBA, +// IN UINTN BufferSize +// +// Output: +// OUT VOID *Buffer +// EFI_STATUS +// +// +//********************************************************************** + +EFI_STATUS PeimReadBlocks( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, + IN UINTN DeviceIndex, + IN EFI_PEI_LBA StartLBA, + IN UINTN BufferSize, + OUT VOID *Buffer ) +{ + FLOPPY_CTRL_PROTOCOL *pFloppyInterface = OUTTER( This, PeimRecBlk, \ + FLOPPY_CTRL_PROTOCOL ); + + return FdcBlkRead((EFI_BLOCK_IO_PROTOCOL*)pFloppyInterface, \ + (UINT32)DeviceIndex, StartLBA, BufferSize, Buffer ); +} + +// PEIM specific code end +//================================================================================== + +//================================================================================== +// Function Prototypes for Driver Binding Protocol Interface +//================================================================================== +#ifdef DXE_FLOPPY_CTRL + +EFI_STATUS +EFIAPI FloppyCtrlSupported ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ); + +EFI_STATUS +EFIAPI FloppyCtrlStart ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ); + +EFI_STATUS +EFIAPI FloppyCtrlStop ( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer ); + +//================================================================================== +// Driver binding protocol instance for Floppy Controller Driver +//================================================================================== +EFI_DRIVER_BINDING_PROTOCOL gFloppyCtrlDriverBindingProtocol = { + FloppyCtrlSupported, + FloppyCtrlStart, + FloppyCtrlStop, + 0x10, + NULL, + NULL +}; +#endif + +//********************************************************************** +// +// +// Procedure: IsPei +// +// Description: +// This is the function to check whether in PEI phase +// +// Input: +// IN VOID **PeiServices, +// IN VOID *FfsHeader +// +// Output: +// OUT BOOLEAN +// +// +//********************************************************************** +BOOLEAN IsPei( + VOID *FfsHeader, + IN VOID *PeiServices ) +{ + if ( !FfsHeader ) { + return TRUE; + } + + if ( FfsHeader <= (VOID*)IsPei + || ((EFI_FFS_FILE_HEADER*)FfsHeader)->Type != \ + EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER + ) { + return FALSE; + } + + if ( *(UINT64*)PeiServices == EFI_SYSTEM_TABLE_SIGNATURE ) { + return FALSE; + } + return TRUE; +} + +//********************************************************************** +// +// +// Procedure: FloppyCtrlEntryPoint +// +// Description: Installs gIdeBusDriverBinding protocol +// +// Input: +// IN EFI_HANDLE ImageHandle, +// IN EFI_SYSTEM_TABLE *SystemTable +// +// Output: +// EFI_STATUS +// +// Modified: +// +// Referrals: InitAmiLib InstallMultipleProtocolInterfaces +// +// Notes: +// Here is the control flow of this function: +// 1. Initialize Ami Lib. +// 2. Install Driver Binding Protocol +// 3. Return EFI_SUCCESS. +// +// +//********************************************************************** + +EFI_STATUS FloppyCtrlEntryPoint( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) +{ + EFI_STATUS Status = EFI_SUCCESS; + + #ifdef PEI_FLOPPY_CTRL + + if ( IsPei( ImageHandle, SystemTable )) { + return FDCPeimEntryPoint((VOID*)ImageHandle, (VOID*)SystemTable ); + } + #endif + + #ifdef DXE_FLOPPY_CTRL + InitAmiLib( ImageHandle, SystemTable ); + + // Initialize global variable for use in this driver + gSysTable = SystemTable; + + // initiaize the ImageHandle and DriverBindingHandle + gFloppyCtrlDriverBindingProtocol.DriverBindingHandle = NULL; + gFloppyCtrlDriverBindingProtocol.ImageHandle = ImageHandle; + + Status = pBS->InstallMultipleProtocolInterfaces( + &gFloppyCtrlDriverBindingProtocol.DriverBindingHandle, + &gDriverBindingProtocolGuid, + &gFloppyCtrlDriverBindingProtocol, + &gComponentNameProtocolGuid, &gFloppyCtlDriverName, + NULL ); + #endif + return Status; +} + +#ifdef DXE_FLOPPY_CTRL +//********************************************************************** +// +// +// Procedure: FloppyCtrlSupported +// +// Description: Floppy Controller Driver Supported function +// This function is a part of DriverBinfing protocol +// +// Input: +// IN EFI_DRIVER_BINDING_PROTOCOL *This, +// IN EFI_HANDLE ControllerHandle, +// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath +// +// Output: +// EFI_STATUS +// +// +//********************************************************************** + +EFI_STATUS +EFIAPI FloppyCtrlSupported( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) +{ + ACPI_HID_DEVICE_PATH * acpiDP; + EFI_STATUS Status; + + if ( !EFI_ERROR( Status = GetFloppy_DP( This, ControllerHandle, \ + &acpiDP, EFI_OPEN_PROTOCOL_BY_DRIVER, TRUE )) + && LookupFloppyHid( acpiDP->HID, acpiDP->UID )) { + return EFI_SUCCESS; + } + + return Status; +} + +//********************************************************************** +// +// +// Procedure: FloppyCtrlStart +// +// Description: Floppy Controller Driver Start function +// This function initializes floppy controller and installs +// Floppy BlkIO protocol. +// +// Input: +// IN EFI_DRIVER_BINDING_PROTOCOL *This, +// IN EFI_HANDLE ControllerHandle, +// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath +// +// Output: +// EFI_STATUS +// +// +//********************************************************************** + +EFI_STATUS +EFIAPI FloppyCtrlStart( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath ) +{ + EFI_STATUS Status; + UINT16 BaseAddr = 0; + ACPI_HID_DEVICE_PATH *acpiDP; + FLOPPY_CTRL_PROTOCOL *FloppyInterface; + AMI_SIO_PROTOCOL *AmiSio; + T_ITEM_LIST *ResList; + UINT16 FdcBase = 0; + UINT8 FdcDma = 0; + UINTN i; + ASLRF_S_HDR *hdr; + EFI_DEVICE_PATH_PROTOCOL *FloppyDevPath; + EFI_PHYSICAL_ADDRESS Address; + + if ( !EFI_ERROR( GetFloppy_DP( This, ControllerHandle, &acpiDP, \ + EFI_OPEN_PROTOCOL_BY_DRIVER, TRUE )) + && LookupFloppyHid( acpiDP->HID, acpiDP->UID )) + { + if ( acpiDP->UID == 00 ) + { + if ( gPeiToDxeFloppyDrive0Status & FDC_FLAG_DRIVE_INIT_SUCCESS ) { + return EFI_SUCCESS; + } + + if ( gPeiToDxeFloppyDrive0Status & FDC_FLAG_DRIVE_INIT_ERROR ) { + return EFI_DEVICE_ERROR; + } + } + + Status = pBS->OpenProtocol( ControllerHandle, + &gEfiAmiSioProtocolGuid, + (VOID**)&AmiSio, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_BY_DRIVER ); + + if ( !(EFI_ERROR( Status ))) + { + Status = AmiSio->CurrentRes( AmiSio, 00, &ResList ); + + if ( ResList != NULL ) + { + //FDC uses 8 io ports but ports 3F6 or 376 are reserved + //in FDC and been used by Legacy IDE mode to avoid resource + //collision ASL code has 2 IO resource descriptors there + // + BOOLEAN ioset = FALSE; + + //---------------- + for ( i = 0; i < ResList->ItemCount; i++ ) + { + // We need only DMA chnl and Base Addr + hdr = (ASLRF_S_HDR*)ResList->Items[i]; + + switch ( hdr->Name ) + { + case ASLV_RT_FixedIO: + + if ( !ioset ) { + FdcBase = ((ASLR_FixedIO*)hdr)->_BAS; + ioset = TRUE; + } + break; + case ASLV_RT_DMA: + FdcDma = ((ASLR_DMA*)hdr)->_DMA; + break; + case ASLV_RT_IO: + + if ( !ioset ) { + FdcBase = ((ASLR_IO*)hdr)->_MIN; + ioset = TRUE; + } + break; + } + } + BaseAddr = FdcBase; + } + else { + Status = EFI_DEVICE_ERROR; + goto Error; + } + } + else { + return EFI_DEVICE_ERROR; + } + + // added code for DMA controller reset + //dma init only needs to be done once; so even if this is drive 1, + // we can look at gPeiToDxeFloppyDrive0Status + if ( gPeiToDxeFloppyDrive0Status == FDC_FLAG_NOT_INTIALIZED ) { + DMAChInit( ); + } + + // Allocate memory for FLOPPY_CTRL_PROTOCOL + FloppyInterface = MallocZ( sizeof(FLOPPY_CTRL_PROTOCOL)); + + if ( !FloppyInterface ) { + Status = EFI_OUT_OF_RESOURCES; + goto Error; + } + + FloppyInterface->DriveNum = acpiDP->UID; + + if ( BaseAddr == 00 ) + { + if ( FloppyInterface->DriveNum == 00 ) { + BaseAddr = 0x3F0; + } + else if ( FloppyInterface->DriveNum == 01 ) + { + BaseAddr = 0x3f0; + } + else { + Status = EFI_UNSUPPORTED; + goto Error; + } + } + FloppyInterface->BaseAddr = BaseAddr; + FloppyInterface->FloppyDiskFormat = HighDensity1_44Mb; + + if ( FloppyInterface->DriveNum == 0 ) { + FloppyInterface->FdcFlag = gPeiToDxeFloppyDrive0Status; + } + else { + FloppyInterface->FdcFlag = FDC_FLAG_NOT_INTIALIZED; + } + + // Do Floppy drive initlization (includes controller reset also.) + + // Initilize floppy controller + Status = FloppyDriveInit( FloppyInterface ); + + if ( Status != EFI_DEVICE_ERROR ) + { + InitFloppyBlockIO( FloppyInterface ); + Address = DMA_MAX_ADDR_LIMIT; + // Allocate memory for DMA buffer + Status = pBS->AllocatePages( AllocateMaxAddress, \ + EfiBootServicesData, NUM_PAGES, &Address ); + + // adjust memory. + if ( !EFI_ERROR( Status )) + { + FloppyInterface->DmaFlag = BIT00; + + if (((Address + FloppyInterface->MaxSectors * SECTOR_SIZE) \ + & 0xff0000) != (Address & 0xff0000)) + { + pBS->FreePages( Address, (UINTN)NUM_PAGES ); + Address = DMA_MAX_ADDR_LIMIT; + Status = pBS->AllocatePages( AllocateMaxAddress, \ + EfiBootServicesData, NUM_PAGES * 2, &Address ); + + if ( EFI_ERROR( Status )) { + Status = pBS->FreePages( Address, NUM_PAGES * 2 ); + } + else { + FloppyInterface->DmaFlag |= BIT01; + + if (((Address + FloppyInterface->MaxSectors \ + * SECTOR_SIZE) & 0xff0000) != (Address & 0xff0000)) { + Address = Address & 0xff0000; + } + } + } + } + FloppyInterface->DMABuffer = (UINT8*)Address; + } + + FloppyInterface->TimerFlag = 01; + MotorOff( FloppyInterface->Event, FloppyInterface ); + + if ( EFI_ERROR( Status )) + { + pBS->FreePool( FloppyInterface ); + FloppyInterface->FdcFlag |= FDC_FLAG_DRIVE_INIT_ERROR; + TRACE((-1, "FDC :Floppy driver start function - Drive initialization error\n")); + Status = pBS->HandleProtocol( ControllerHandle, \ + &gDevicePathProtocolGuid, &FloppyDevPath ); + + if ( !EFI_ERROR( Status )) + { + //TODO: Intel DxeMain does not like this trick + //Let's comments it out temporary + // + //EFI_HANDLE Handle; + //Status=pBS->LocateDevicePath(&gPciIoProtocolGuid, &FloppyDevPath,&Handle); + //if (!EFI_ERROR(Status)) pBS->DisconnectController(Handle,NULL,ControllerHandle); + } + Status = EFI_DEVICE_ERROR; + goto Error; + } + + Status = pBS->CreateEvent( + EVT_TIMER | EVT_NOTIFY_SIGNAL, + TPL_NOTIFY, + (EFI_EVENT_NOTIFY)MotorOff, + (void*)FloppyInterface, + &(FloppyInterface->Event)); + + if ( EFI_ERROR( Status )) { + goto Error; + } + + //Status = pBS->OpenProtocol(ControllerHandle, &gDevicePathProtocolGuid, + // (void **)&FloppyDevPath, + // This->DriverBindingHandle, + // ControllerHandle, + // EFI_OPEN_PROTOCOL_BY_DRIVER); + + //if(EFI_ERROR(Status)) return Status; + + // Install Block IO protocol for floppy controller + Status = pBS->InstallMultipleProtocolInterfaces( &ControllerHandle, + &gEfiBlockIoProtocolGuid, + &(FloppyInterface->BlkIo), + NULL ); + + if ( EFI_ERROR( Status )) + { + TRACE((-1, "FDC :Floppy driver start function - Out of Resources for Block IO protocol\n")); + goto Error; + } + + if ( gSysTable ) { + pBS->SetTimer( FloppyInterface->Event, TimerRelative, 20000000 ); + } + return EFI_SUCCESS; + } + Status = EFI_UNSUPPORTED; + goto Error; + +Error: + pBS->CloseProtocol( ControllerHandle, + &gEfiAmiSioProtocolGuid, + This->DriverBindingHandle, + ControllerHandle ); + if( Status == EFI_OUT_OF_RESOURCES ) { + return EFI_OUT_OF_RESOURCES; + } + return EFI_DEVICE_ERROR; +} + +//********************************************************************** +// +// +// Procedure: FloppyCtrlStop +// +// Description: Floppy Controller Driver Stop function +// This functiuon uninstalls Floppy BlkIO protocol and driver +// binding protocol. +// +// Input: +// IN EFI_DRIVER_BINDING_PROTOCOL *This, +// IN EFI_HANDLE ControllerHandle, +// IN UINTN NumberOfChildren, +// IN EFI_HANDLE *ChildHandleBuffer +// +// Output: +// EFI_STATUS +// +// +//********************************************************************** + +EFI_STATUS +EFIAPI FloppyCtrlStop( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN UINTN NumberOfChildren, + IN EFI_HANDLE *ChildHandleBuffer ) +{ + EFI_STATUS Status; + FLOPPY_CTRL_PROTOCOL *FloppyInterface; + + if(NumberOfChildren) { + return EFI_DEVICE_ERROR; + } + + Status = pBS->OpenProtocol( ControllerHandle, + &gEfiBlockIoProtocolGuid, + (VOID**)&FloppyInterface, + This->DriverBindingHandle, + ControllerHandle, + EFI_OPEN_PROTOCOL_GET_PROTOCOL ); + + if ( EFI_ERROR( Status )) { + return EFI_DEVICE_ERROR; + } + + // uninstall block io protocol + Status = pBS->UninstallMultipleProtocolInterfaces( &ControllerHandle, + &gEfiBlockIoProtocolGuid, &(FloppyInterface->BlkIo), + NULL ); + + if ( EFI_ERROR( Status )) { + return EFI_DEVICE_ERROR; + } + + pBS->CloseProtocol( ControllerHandle, + &gEfiAmiSioProtocolGuid, + This->DriverBindingHandle, + ControllerHandle ); + pBS->CloseProtocol( ControllerHandle,&gDevicePathProtocolGuid, + This->DriverBindingHandle,ControllerHandle); + + // deallocate DMA buffer + if ( FloppyInterface->DmaFlag & BIT01 ) { + pBS->FreePages((EFI_PHYSICAL_ADDRESS)( FloppyInterface->DMABuffer ), \ + (UINTN)NUM_PAGES * 2 ); + } + pBS-> FreePages((EFI_PHYSICAL_ADDRESS)( FloppyInterface->DMABuffer ), \ + (UINTN)NUM_PAGES ); + + // reset the status flag + FloppyInterface->FdcFlag = FDC_FLAG_NOT_INTIALIZED; + + pBS->CloseEvent(FloppyInterface->Event); + + // Free memory pool used by floppy interface structure + pBS->FreePool( FloppyInterface ); + + // uninstall driver binding protocol + //###DEBUGThis needs to be done in the Unload routine + //Status = pBS->UninstallMultipleProtocolInterfaces( + // &gFloppyCtrlDriverBindingProtocol.DriverBindingHandle, + // &gDriverBindingProtocolGuid, &gFloppyCtrlDriverBindingProtocol, + // &gComponentNameProtocolGuid, &gFloppyCtlDriverName, + // NULL); + //DEBUG END + return EFI_SUCCESS; +} + +#endif + + +//********************************************************************** +// +// +// Procedure: FloppyDriveInit +// +// Description: This function initializes the floppy driver +// Do FDC reset, turn on the motor and checks for media change +// +// Input: +// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface +// +// Output: +// EFI_STATUS +// +// +//********************************************************************** + +EFI_STATUS FloppyDriveInit( + IN FLOPPY_CTRL_PROTOCOL *FloppyInterface ) +{ + EFI_STATUS Status = EFI_SUCCESS; + UINT16 BaseAddr; + UINT16 DataReg; + + FloppyInterface->FdcFlag = FDC_FLAG_NOT_INTIALIZED; + FloppyInterface->PrCyl = 0x0F0; + BaseAddr = FloppyInterface->BaseAddr; + DataReg = FloppyInterface->BaseAddr + 05; + + CtrlReset( FloppyInterface ); + SetDataRate( FloppyInterface ); + + if ( EFI_ERROR( MotorOn( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + + if ( EFI_ERROR( Specify( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + + FloppyInterface->BlkIoMedia.MediaPresent = TRUE; + + if ( CheckMediaChange( FloppyInterface ) == EFI_MEDIA_CHANGED ) { + Status = EFI_MEDIA_CHANGED; + } + + if ( EFI_ERROR( Calibrate( FloppyInterface ))) + { + Delay( 10000 ); + + if ( EFI_ERROR( Calibrate( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + } + FloppyInterface->PrCyl = 00; + + if ( Status == EFI_MEDIA_CHANGED ) + { + Status = EFI_SUCCESS; + + if ( EFI_ERROR( Seek( FloppyInterface, 00, 01 ))) + { + Delay( 5000 ); + + if ( EFI_ERROR( Seek( FloppyInterface, 00, 01 ))) { + return EFI_DEVICE_ERROR; + } + } + FloppyInterface->PrCyl = 01; + + if ( CheckMediaChange( FloppyInterface ) == EFI_MEDIA_CHANGED ) + { + FloppyInterface->BlkIoMedia.MediaPresent = FALSE; + Status = EFI_NO_MEDIA; + } + } + + FloppyInterface->FdcFlag |= FDC_FLAG_DRIVE_INIT_SUCCESS; + + return Status; +} + +//********************************************************************** +// +// +// Procedure: InitFloppyBlockIO +// +// Description: Initilizes the data required for floppy block IO protocol +// +// Input: +// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface +// +// Output: +// EFI_STATUS +// +// Refferals: EFI 1.1 specification, Chapter 11.6. +// +// +//********************************************************************** + +EFI_STATUS InitFloppyBlockIO( + IN FLOPPY_CTRL_PROTOCOL *FloppyInterface ) +{ + EFI_STATUS Status = EFI_SUCCESS; + + FloppyInterface->BlkIo.Revision = 01; + FloppyInterface->BlkIo.Reset = FdcReset; + FloppyInterface->BlkIo.ReadBlocks = FdcBlkRead; + FloppyInterface->BlkIo.WriteBlocks = FdcBlkWrite; + FloppyInterface->BlkIo.FlushBlocks = FdcBlkFlush; + + FloppyInterface->BlkIo.Media = &(FloppyInterface->BlkIoMedia); + FloppyInterface->BlkIoMedia.MediaId = FloppyInterface->DriveNum; + FloppyInterface->BlkIoMedia.RemovableMedia = TRUE; + FloppyInterface->BlkIoMedia.LogicalPartition = FALSE; + FloppyInterface->BlkIoMedia.ReadOnly = FALSE; + FloppyInterface->BlkIoMedia.WriteCaching = FALSE; + FloppyInterface->BlkIoMedia.BlockSize = 512; + + InitFloppyBlockIOLastBlockAndMaxSectors( FloppyInterface ); + + FloppyInterface->BlkIoMedia.IoAlign = 0; + return Status; +} + +VOID InitFloppyBlockIOLastBlockAndMaxSectors( + FLOPPY_CTRL_PROTOCOL *FloppyInterface ) +{ + // parameters change based on floppy type + // LastBlock = 2 heads * MaxSectors * NumTracks - 1 + // corresponding to 720KB drive + if ( FloppyInterface->FloppyDiskFormat == DoubleDensity720Kb ) + { + FloppyInterface->BlkIoMedia.LastBlock = 1339; //(2*9*80-1) + FloppyInterface->MaxSectors = 0x09; + } + // corresponding to 1.44 MB drive + else if ( FloppyInterface->FloppyDiskFormat == HighDensity1_44Mb ) + { + FloppyInterface->BlkIoMedia.LastBlock = 2779; //(2 * 18 * 80 -1) + FloppyInterface->MaxSectors = 18; + } + // corresponding to 2.88 MB drive + else { + FloppyInterface->BlkIoMedia.LastBlock = 5759; //(2 * 36 * 80 -1) + FloppyInterface->MaxSectors = 36; + } +} + +//********************************************************************** +// +// +// Procedure: FdcReset +// +// Description: FDC reset function. +// +// Input: +// IN EFI_BLOCK_IO_PROTOCOL *This, +// IN BOOLEAN ExtendedVerification +// +// Output: +// EFI_STATUS +// +// +//********************************************************************** +EFI_STATUS FdcReset( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN BOOLEAN ExtendedVerification ) +{ + #ifdef DXE_FLOPPY_CTRL + FLOPPY_CTRL_PROTOCOL *FloppyInterface = (FLOPPY_CTRL_PROTOCOL*)This; + BOOLEAN ErrorFlag = TRUE; + + if ( EFI_ERROR( FloppyDriveInit((FLOPPY_CTRL_PROTOCOL*)This )) == \ + EFI_DEVICE_ERROR ) { + ErrorFlag = FALSE; + } + pBS->SetTimer(((FLOPPY_CTRL_PROTOCOL*)This)->Event, TimerRelative, \ + 20000000 ); + + // MotorOff(((FLOPPY_CTRL_PROTOCOL *)This)->Event, FloppyInterface); + if ( ErrorFlag == FALSE ) { + return EFI_DEVICE_ERROR; + } + return EFI_SUCCESS; + #else + return EFI_UNSUPPORTED; + #endif +} + +//********************************************************************** +// +// +// Procedure: FdcBlkRead +// +// Description: The ReadBlocks() function reads the requested number of +// blocks from the device. All the blocks are read, or an +// error is returned. +// +// Input: +// IN EFI_BLOCK_IO_PROTOCOL *This, +// IN UINT32 MediaId, +// IN EFI_LBA LBA, +// IN UINTN BufferSize, +// +// Output: +// OUT VOID *Buffer +// EFI_STATUS - +// EFI_SUCCESS- The data was read correctly from the device. +// EFI_DEVICE_ERROR- The device reported an error while attempting to +// perform the read operation. +// EFI_NO_MEDIA- There is no media in the device. +// EFI_MEDIA_CHANGED- The MediaId is not for the current media. +// EFI_BAD_BUFFER_SIZE- The BufferSize parameter is not a multiple +// of the intrinsic block size of the device. +// EFI_INVALID_PARAMETER- The read request contains LBAs that are not valid, +// or the buffer is not on proper alignment. +// +// +//********************************************************************** + +EFI_STATUS FdcBlkRead( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN UINTN BufferSize, + OUT VOID *Buffer ) +{ + UINT8 RWFlag = READ_OPERATION; + EFI_STATUS Status; + + Status = FddReadWriteFn( This, MediaId, LBA, BufferSize, RWFlag, Buffer ); + + if ( Status == EFI_DEVICE_ERROR ) + { + if ( EFI_ERROR( FloppyDriveInit((FLOPPY_CTRL_PROTOCOL*)This ))) { + Status = EFI_DEVICE_ERROR; + } + else { + Status = FddReadWriteFn( This, MediaId, LBA, BufferSize, \ + RWFlag, Buffer ); + } + } + ((FLOPPY_CTRL_PROTOCOL*)This)->TimerFlag = 01; + #ifdef DXE_FLOPPY_CTRL + + if ( gSysTable ) { + pBS->SetTimer(((FLOPPY_CTRL_PROTOCOL*)This)->Event, TimerRelative, \ + 20000000 ); + } + #endif + + return Status; +} + +//********************************************************************** +// +// +// Procedure: FdcBlkWrite +// +// Description: The WriteBlocks() function reads the requested number of +// blocks from the device. All the blocks are read, or an +// error is returned. +// Input: +// IN EFI_BLOCK_IO_PROTOCOL *This, +// IN UINT32 MediaId, +// IN EFI_LBA LBA, +// IN UINTN BufferSize, +// +// Output: +// OUT VOID *Buffer +// EFI_STATUS - +// EFI_SUCCESS- The data was read correctly from the device. +// EFI_DEVICE_ERROR- The device reported an error while attempting to +// perform the read operation. +// EFI_NO_MEDIA- There is no media in the device. +// EFI_MEDIA_CHANGED- The MediaId is not for the current media. +// EFI_BAD_BUFFER_SIZE- The BufferSize parameter is not a multiple +// of the intrinsic block size of the device. +// EFI_INVALID_PARAMETER- The read request contains LBAs that are not valid, +// or the buffer is not on proper alignment. +// +// +//********************************************************************** + +EFI_STATUS FdcBlkWrite( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN UINTN BufferSize, + OUT VOID *Buffer ) +{ + UINT8 RWFlag = WRITE_OPERATION; + EFI_STATUS Status; + + Status = FddReadWriteFn( This, MediaId, LBA, BufferSize, RWFlag, Buffer ); + + if ( Status == EFI_DEVICE_ERROR ) + { + if ( EFI_ERROR( FloppyDriveInit((FLOPPY_CTRL_PROTOCOL*)This ))) { + Status = EFI_DEVICE_ERROR; + } + else { + Status = FddReadWriteFn( This, MediaId, LBA, BufferSize, RWFlag, Buffer ); + } + } + ((FLOPPY_CTRL_PROTOCOL*)This)->TimerFlag = 01; + #ifdef DXE_FLOPPY_CTRL + + if ( gSysTable ) { + pBS->SetTimer(((FLOPPY_CTRL_PROTOCOL*)This)->Event, TimerRelative, \ + 20000000 ); + } + #endif + + return Status; +} + +//********************************************************************** +// +// +// Procedure: FdcBlkFlush +// +// Description: The FlushBlocks() function flushes all modified data to +// the physical block device. +// +// Input: +// IN EFI_BLOCK_IO_PROTOCOL *This, +// +// Output: +// EFI_STATUS +// +// +//********************************************************************** + +EFI_STATUS FdcBlkFlush( + IN EFI_BLOCK_IO_PROTOCOL *This ) +{ + return EFI_SUCCESS; +} + +//********************************************************************** +// +// +// Procedure: FdcBlkWrite +// +// Description: The WriteBlocks() function reads the requested number of +// blocks from the device. All the blocks are read, or an +// error is returned. +// Input: +// IN EFI_BLOCK_IO_PROTOCOL *This, +// IN UINT32 MediaId, +// IN EFI_LBA LBA, +// IN UINTN BufferSize, +// IN UINT8 RWFlag +// +// Output: +// OUT VOID *Buffer +// EFI_STATUS - +// EFI_SUCCESS- The data was read correctly from the device. +// EFI_DEVICE_ERROR- The device reported an error while attempting to +// perform the read operation. +// EFI_NO_MEDIA- There is no media in the device. +// EFI_MEDIA_CHANGED- The MediaId is not for the current media. +// EFI_BAD_BUFFER_SIZE- The BufferSize parameter is not a multiple +// of the intrinsic block size of the device. +// EFI_INVALID_PARAMETER- The read request contains LBAs that are not valid, +// or the buffer is not on proper alignment. +// +// +//********************************************************************** + +EFI_STATUS FddReadWriteFn( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN UINTN BufferSize, + IN UINT8 RWFlag, + OUT VOID *Buffer ) +{ + UINT8 Offset; + UINT8 Head; + UINT8 Cylinder; + UINT8 Sector; + UINT8 MaxSectors; + UINT8 *LocalBuffer; + UINT8 *SavedBuffer = Buffer; + UINT8 St2 = 0xff; + UINT16 DataReg; + UINTN Remainder; + UINT64 Result; + UINTN TrackLength; + UINTN NumBlks; + EFI_LBA LocalLBA = LBA; + EFI_BLOCK_IO_MEDIA *BlkMedia = This->Media; + FLOPPY_CTRL_PROTOCOL *FloppyInterface = (FLOPPY_CTRL_PROTOCOL*)This; + FDD_CMD_PKT *FdcRWCmdPkt = &(FloppyInterface->CmdRdWrSect); + UINT8 *ResultPacket = (UINT8*)(&FloppyInterface->ResultPacket); + UINTN CommandPacketSize = sizeof(FDD_CMD_PKT); + UINTN ResultPacketSize = sizeof(FDD_RESULT_PACKET); + + FloppyInterface->TimerFlag = 00; + #ifdef DXE_FLOPPY_CTRL + + if ( gSysTable ) { + pBS->SetTimer( FloppyInterface->Event, TimerCancel, 00 ); + } + #endif + + DataReg = FloppyInterface->BaseAddr + 05; + + // 1. Check the correctness of the input before r/w operation + if ( gSysTable ) + { + if ( MediaId != FloppyInterface->BlkIoMedia.MediaId ) { + return EFI_MEDIA_CHANGED; + } + } + + if ( BufferSize == 0 ) { + return EFI_SUCCESS; + } + + if ( Buffer == NULL ) { + return EFI_INVALID_PARAMETER; + } + + if ((BufferSize % BlkMedia->BlockSize) != 0 ) { + return EFI_BAD_BUFFER_SIZE; + } + + if ((((BufferSize / BlkMedia->BlockSize) + LBA - 1) > BlkMedia->LastBlock) + || (LBA > BlkMedia->LastBlock)) { + return EFI_INVALID_PARAMETER; + } + + //2. Check Motor is ON or OFF + if ( !(FloppyInterface->FdcFlag & FDC_FLAG_MOTOR_ON)) + { + SetDataRate( FloppyInterface ); + + // Turn on the motor + if ( EFI_ERROR( MotorOn( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + + if ( EFI_ERROR( Specify( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + } + + // 3. check for media change + if ( CheckMediaChange( FloppyInterface ) == EFI_MEDIA_CHANGED ) + { + FloppyInterface->FdcFlag = FDC_FLAG_NOT_INTIALIZED; + + if ( EFI_ERROR( Seek( FloppyInterface, 00, 01 ))) + { + Delay( 5000 ); + + if ( EFI_ERROR( Seek( FloppyInterface, 00, 01 ))) { + return EFI_DEVICE_ERROR; + } + } + + if ( EFI_ERROR( Seek( FloppyInterface, 00, 00 ))) + { + Delay( 5000 ); + + if ( EFI_ERROR( Seek( FloppyInterface, 00, 00 ))) { + return EFI_DEVICE_ERROR; + } + } + FloppyInterface->PrCyl = 00; + + if ( CheckMediaChange( FloppyInterface ) == EFI_MEDIA_CHANGED ) + { + FloppyInterface->BlkIoMedia.MediaPresent = FALSE; + return EFI_NO_MEDIA; + } + FloppyInterface->BlkIoMedia.MediaPresent = TRUE; + (FloppyInterface->BlkIoMedia.MediaId)++; + FloppyInterface->BlkIoMedia.ReadOnly = FALSE; + } + + if ( FloppyInterface->BlkIoMedia.MediaPresent == TRUE ) + { + NumBlks = BufferSize / (BlkMedia->BlockSize); + + if ( RWFlag == WRITE_OPERATION ) + { + if ( ChkDrSts( FloppyInterface, 00 ) != EFI_WRITE_PROTECTED ) + { + // Corresponds to write operation + if ( EFI_ERROR( ChkDrSts( FloppyInterface, 00 )) == \ + EFI_WRITE_PROTECTED ) + { + FloppyInterface->BlkIoMedia.ReadOnly = TRUE; + return EFI_WRITE_PROTECTED; + } + } + else { + FloppyInterface->BlkIoMedia.ReadOnly = TRUE; + return EFI_WRITE_PROTECTED; + } + } + + for (; NumBlks > 0;) + { + //7. Prepare Read or Write packet + FdcRWCmdPkt = &(FloppyInterface->CmdRdWrSect); + + if ( RWFlag == READ_OPERATION ) { + FdcRWCmdPkt->CommandCode = RD_SECTOR_CMD \ + + M_COMMAND_BIT_MULTITRACK_OPERATION \ + + F_COMMAND_BIT_MFM_RECORDING_METHOD \ + + S_COMMAND_BIT_SKIP_MODE; + } + else { + FdcRWCmdPkt->CommandCode = WR_SECTOR_CMD \ + + F_COMMAND_BIT_MFM_RECORDING_METHOD; + } + + MaxSectors = FloppyInterface->MaxSectors; + Result = Div64( LocalLBA, (UINT32)MaxSectors, &Remainder ); + Head = (UINT8)( Result ) % 02; + Sector = (UINT8)Remainder + 01; + Cylinder = (UINT8)Div64( LocalLBA, (UINT32)( MaxSectors * 2 ), NULL ); + + //7a. Seek to the perticular cylinder + // Delay(4000); + // Standard delay =3MilliSec for Track to track change + if ((FloppyInterface->PrCyl != Cylinder) || (St2 == 0xFF)) + { + if ( EFI_ERROR( Seek( FloppyInterface, Head, Cylinder ))) + { + // Standard delay =3MilliSec for Track to track change + Delay( 4000 ); + + if ( EFI_ERROR( Seek( FloppyInterface, Head, Cylinder ))) { + return EFI_DEVICE_ERROR; + } + } + St2 = 00; + FloppyInterface->PrCyl = Cylinder; + } + + FdcRWCmdPkt->HeadDdrSel = (UINT8)( Head << 02 ) \ + + FloppyInterface->DriveNum; + FdcRWCmdPkt->Cylinder = Cylinder; + FdcRWCmdPkt->Head = Head; + FdcRWCmdPkt->Sector = Sector; + // Sector size: 00-128Bytes, 01-256Bytes, 02-512Bytes ...07-16Kbytes + FdcRWCmdPkt->Size = 02; + FdcRWCmdPkt->TrackLength = MaxSectors; + + if ((Sector + NumBlks - 1) <= MaxSectors ) + { + TrackLength = NumBlks; + NumBlks = 00; + } + //###DEBUG + //else if((Head == 0 ) && (Sector == 1) && (NumBlks >= (UINTN)MaxSectors *2)) + //{ + // LocalLBA += (MaxSectors * 2) ; + // NumBlks -= (MaxSectors * 2) ; + // TrackLength = MaxSectors * 2; + // FdcRWCmdPkt->TrackLength = MaxSectors * 2; + //} + //DEBUG END + else if ((Sector == 1) && (NumBlks >= (UINTN)MaxSectors)) + { + LocalLBA += MaxSectors; + NumBlks -= MaxSectors; + TrackLength = MaxSectors; + //if(RWFlag == READ_OPERATION) + //FdcRWCmdPkt->CommandCode= RD_TRACK_CMD + BIT06 + BIT05; + } + else { + LocalLBA += (MaxSectors - Sector + 1); + NumBlks -= (MaxSectors - Sector + 1); + //FdcRWCmdPkt->TrackLength = MaxSectors - Sector +1; + TrackLength = MaxSectors - Sector + 1; + } + // TRACE((-1,"FDC RWFunction: RWFlag:%x, Head :%x,Track :%x,Sector :%x,NBlks :%x\n",(UINT16)RWFlag, (UINT16)Head, (UINT16)Cylender, (UINT16)Sector, (UINT16)TrackLength)); + // Standard value = 27 - 3 1/2Floppy, = 42 - 5 1/4 Floppy; + FdcRWCmdPkt->GapLength = 0x1b; + // = FF if sector size not equal to 00; + FdcRWCmdPkt->DataLength = 0Xff; + + if ((((EFI_PHYSICAL_ADDRESS)SavedBuffer \ + + (EFI_PHYSICAL_ADDRESS)( TrackLength * SECTOR_SIZE )) + > (EFI_PHYSICAL_ADDRESS)DMA_BUFFER_LIMIT) + || ((((EFI_PHYSICAL_ADDRESS)SavedBuffer \ + + (EFI_PHYSICAL_ADDRESS)( TrackLength * SECTOR_SIZE )) & 0xff0000) + != ((EFI_PHYSICAL_ADDRESS)SavedBuffer & 0xff0000))) + { + LocalBuffer = FloppyInterface->DMABuffer; + + if ( RWFlag == WRITE_OPERATION ) { + CopyBuffer( SavedBuffer, LocalBuffer, TrackLength \ + * SECTOR_SIZE ); + } + } + else { + LocalBuffer = (UINT8*)SavedBuffer; + } + + // 7b. Set DMA cotroller + DMAInitForFloppy( LocalBuffer, TrackLength, RWFlag ); + + // 7c. send R/W command + for ( Offset = 0; Offset < CommandPacketSize; Offset++ ) + { + if ( EFI_ERROR( CheckMRQBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + IoWrite8( DataReg, ((UINT8*)FdcRWCmdPkt)[Offset] ); + } + + //7d. Get the R/W command result packet + for ( Offset = 0; Offset < ResultPacketSize; Offset++ ) + { + // We have initialized the DMA registers and sent the command packet. + // Now, we wait for the result packet. We use CheckMRQBit_NoDelay instead + // of CheckMRQBit. This is because of the following problem, observed on + // the Lakeport board with South Bridge Ich7: CheckMRQBit has a loop in + // which it checks the MRQ bit and if it isn't set calls Delay() with a + // certain amount of time. CheckMRQBit_NoDelay just checks the MRQ bit + // continuously until it is set. The Delay function isn't used. The Delay + // function uses the Stall Ppi, which is in ROM. When this Stall Ppi + // is used while waiting for the result packet, the floppy controller + // always returns a DMA timeout error. That is, the floppy controller + // doesn't receive certain signals from the DMA controller within a required + // time period. The DMA transaction doesn't get started. This problem doesn't + // occur if we don't use the Delay function. Alternately, the problem also + // doesn't occur if the Stall Ppi is re-installed in RAM. + + if ( EFI_ERROR( CheckMRQBit_NoDelay( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + + ResultPacket[Offset] = IoRead8( DataReg ); + } + + //7d. Check for error condition + if ( !((*ResultPacket) & (IC1_STATUS0_BIT_INTERRUPT_CODE \ + + IC0_STATUS0_BIT_INTERRUPT_CODE))) + { + // Read Write success + if ( RWFlag == READ_OPERATION ) + { // Copy Buffer + if ((((EFI_PHYSICAL_ADDRESS)SavedBuffer \ + + (EFI_PHYSICAL_ADDRESS)( TrackLength * SECTOR_SIZE )) + > (EFI_PHYSICAL_ADDRESS)DMA_BUFFER_LIMIT) + || ((((EFI_PHYSICAL_ADDRESS)SavedBuffer \ + + (EFI_PHYSICAL_ADDRESS)( TrackLength * SECTOR_SIZE )) \ + & 0xff0000) + != ((EFI_PHYSICAL_ADDRESS)SavedBuffer & 0xff0000))) { + CopyBuffer( LocalBuffer, SavedBuffer, TrackLength \ + * SECTOR_SIZE ); + } + } + SavedBuffer = (UINT8*)((EFI_PHYSICAL_ADDRESS)SavedBuffer \ + + (EFI_PHYSICAL_ADDRESS)( TrackLength * SECTOR_SIZE )); + } + else { + #ifdef EFI_DEBUG + + if ( gSysTable ) { + #ifdef DXE_FLOPPY_CTRL + TRACE((-1, "FddReadWriteFn Error: \n")); + TRACE((-1, "ST0: %x, ST1: %x, ST2: %x\n", FloppyInterface->ResultPacket.Status0, FloppyInterface->ResultPacket.Status1, FloppyInterface->ResultPacket.Status2)); + TRACE((-1, "Cylinder: %x, Head: %x, Sector Number: %x, Sector Size: %x\n", FloppyInterface->ResultPacket.Cylinder, FloppyInterface->ResultPacket.Head, FloppyInterface->ResultPacket.SectorNumber, FloppyInterface->ResultPacket.SectorSize)); + #endif + } + else { + #ifdef PEI_FLOPPY_CTRL + PEI_TRACE((-1, PeiServices, "FddReadWriteFn: \n")); + PEI_TRACE((-1, PeiServices, "ST0: %x, ST1: %x, ST2: %x\n", FloppyInterface->ResultPacket.Status0, FloppyInterface->ResultPacket.Status1, FloppyInterface->ResultPacket.Status2)); + PEI_TRACE((-1, PeiServices, "Cylinder: %x, Head: %x, Sector Number: %x, Sector Size: %x\n", FloppyInterface->ResultPacket.Cylinder, FloppyInterface->ResultPacket.Head, FloppyInterface->ResultPacket.SectorNumber, FloppyInterface->ResultPacket.SectorSize)); + #endif + } + #endif + return EFI_DEVICE_ERROR; + } + } // Read command end + return EFI_SUCCESS; + } + return EFI_NO_MEDIA; +} + +//********************************************************************** +// +// +// Procedure: CopyBuffer +// +// Description: Copie source to destination of required size +// +// Input: +// IN VOID *InBuffer, +// IN VOID *OutBuffer, +// IN UINTN Count +// +// Output: +// VOID +// +// +//********************************************************************** + +void CopyBuffer( + IN VOID *InBuffer, + IN VOID *OutBuffer, + IN UINTN Count ) +{ + UINT32 *SrcBuffer = (UINT32*)InBuffer; + UINT32 *DestBuffer = (UINT32*)OutBuffer; + UINTN i = 0; + UINTN size = Count / 4; + + for ( i = 0; i < size; i++ ) + { + DestBuffer[i] = SrcBuffer[i]; + } +} + +static DMA_INIT DmaInitTable [] = { + // Core8 DMAC.ASM file (Fn-init_8237) + 0x00C, 0x000, // Reset DMA Controller 1 + 0x008, 0x000, // Enable DMA controller 1 + + 0x0D8, 0x000, // Reset DMA Controller 2 + 0x0D0, 0x000, // Enable DMA controller 2 + + 0x00B, 0x040, // DMA contr. 1 Ch0 single mode, addr. increment, disable auto init. + 0x00A, 0x000, // Enable DREQs for channel + + 0x00B, 0x041, // DMA contr. 1 Ch1 single mode, addr. increment, disable auto init. + 0x00A, 0x001, // Enable DREQs for channel + + 0x00B, 0x042, // DMA contr. 1 Ch2 single mode, addr. increment, disable auto init. + 0x00A, 0x002, // Enable DREQs for channel + + 0x00B, 0x043, // DMA contr. 1 CH3 single mode, addr. increment, disable auto init. + 0x00A, 0x003, // Enable DREQs for channel + + 0x0D6, 0x0c0, // DMA contr. 2 Ch4 Cascade mode, addr. increment, disable auto init. + 0x0d4, 0x000, // Enable DREQs for channel + + 0x0D6, 0x041, // DMA contr. 2 Ch5 single mode, addr. increment, disable auto init. + 0x0D4, 0x001, // Enable DREQs for channel + + 0x0D6, 0x042, // DMA contr. 2 Ch6 single mode, addr. increment, disable auto init. + 0x0D4, 0x002, // Enable DREQs for channel + + 0x0D6, 0x043, // DMA contr. 2 Ch7 single mode, addr. increment, disable auto init. + 0x0D4, 0x003 // Enable DREQs for channel +}; + +//********************************************************************** +// +// +// Procedure: DMAChInit +// +// Description: DMA controller reset function +// +// Input: +// VOID +// +// Output: +// VOID +// +// +//********************************************************************** + +void DMAChInit( ) +{ + UINTN Index; + + // DMA controller initialize + for ( Index = 0; Index < (sizeof(DmaInitTable) / sizeof(DMA_INIT)); Index++ ) + { + IoWrite8( DmaInitTable[Index].PortAddr, DmaInitTable[Index].Value ); + Delay(10); // Delay 10us + } +} + +//********************************************************************** +// +// +// Procedure: DMAInitForFloppy +// +// Description: This function program sthe DMA-1 channel-2 for floppy read +// and write operations +// +// Input: +// IN VOID *Buffer, +// IN UINTN NumBlks, +// IN BOOLEAN RWFlag +// +// Output: +// VOID +// +// +//********************************************************************** + +void DMAInitForFloppy( + IN VOID *Buffer, + IN UINTN NumBlks, + IN BOOLEAN RWFlag ) +{ + UINTN Count; + + IoWrite8( DMA1_CH_MASK_REG, 0x06 ); + + // set mode + if ( RWFlag == READ_OPERATION ) { + IoWrite8( DMA1_MODE_REG, 0x46 ); + } + else { + IoWrite8( DMA1_MODE_REG, 0x4a ); + } + + // set base address and page register + IoWrite8( DMA1_RESET_REG, 0x00 ); + IoWrite8( DMA1_ADDR_REG, (UINT8)( UINTN ) Buffer ); + IoWrite8( DMA1_ADDR_REG, (UINT8)((UINTN)Buffer >> 8 )); + IoWrite8( DMA1_PAGE_REG, (UINT8)((UINTN)Buffer >> 16 )); + + // set count register + IoWrite8( DMA1_RESET_REG, 0x00 ); + Count = SECTOR_SIZE * NumBlks - 1; + IoWrite8( DMA1_COUNT_REG, (UINT8)Count ); + Count >>= 8; + IoWrite8( DMA1_COUNT_REG, (UINT8)Count ); + + // clear channel 2 mask + IoWrite8( DMA1_CH_MASK_REG, 0x02 ); +} + +////////////////////////////////////////////////////////////////////////////// +// FLOPPY COMMANDS // +////////////////////////////////////////////////////////////////////////////// + +//********************************************************************** +// +// +// Procedure: ChkDrSts +// +// Description: This function in the result phase provides the status +// information concerning the connected drives +// +// Input: +// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface, +// IN UINT8 HeadNum +// +// Output: +// EFI_STATUS +// +// +//********************************************************************** + +EFI_STATUS ChkDrSts( + IN FLOPPY_CTRL_PROTOCOL *FloppyInterface, + IN UINT8 HeadNum ) +{ + EFI_STATUS Status3; + UINT16 DataReg; + + DataReg = FloppyInterface->BaseAddr + 05; + + // Command phase + if ( EFI_ERROR( CheckBusyBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + + if ( EFI_ERROR( CheckMSRDOBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + IoWrite8( DataReg, CHECK_DRV_STATUS_CMD ); + + if ( EFI_ERROR( CheckMSRDOBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + IoWrite8( DataReg, (UINT8)((HeadNum << (UINT8)02) \ + + FloppyInterface->DriveNum )); + + // Result phase + if ( EFI_ERROR( CheckMSRDIBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + Status3 = IoRead8( DataReg ); + + if ( Status3 & BIT06 ) + { + FloppyInterface->FdcFlag |= FDC_FLAG_WRITE_PROTECTED; + return EFI_WRITE_PROTECTED; + } + + if ( EFI_ERROR( CheckBusyBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + return EFI_SUCCESS; +} + +//********************************************************************** +// +// +// Procedure: Specify +// +// Description: This function passes the controller mechanical control +// of the data of the connected drives. +// +// Input: +// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface, +// +// Output: +// EFI_STATUS +// +// +//********************************************************************** + +EFI_STATUS Specify( + IN FLOPPY_CTRL_PROTOCOL *FloppyInterface ) +{ + FDD_SPECIFY_CMD *FdcSpecifyCmd; + UINT8 Offset; + UINT16 DataReg; + + DataReg = FloppyInterface->BaseAddr + 05; + FdcSpecifyCmd = &(FloppyInterface->CmdSpecify); + + FdcSpecifyCmd->CommandCode = SPECIFY_CMD; + + // corresponding to 720KB drive + if ( FloppyInterface->FloppyDiskFormat == DoubleDensity720Kb ) + { + FdcSpecifyCmd->Ctrldata1 = 0xaF; + FdcSpecifyCmd->Ctrldata2 = 02; + } + // corresponding to 1.44 MB drive + else if ( FloppyInterface->FloppyDiskFormat == HighDensity1_44Mb ) + { + //FdcSpecifyCmd->Ctrldata1 = 0xbF; + FdcSpecifyCmd->Ctrldata1 = 0xDF; + FdcSpecifyCmd->Ctrldata2 = 02; + } + else { // corresponding to 2.88 MB drive + FdcSpecifyCmd->Ctrldata1 = 0xDF; + FdcSpecifyCmd->Ctrldata2 = 02; + } + + if ( EFI_ERROR( CheckBusyBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + + for ( Offset = 0; Offset < sizeof (FDD_SPECIFY_CMD); Offset++ ) + { + if ( EFI_ERROR( CheckMSRDOBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + IoWrite8( DataReg, *(((UINT8*)FdcSpecifyCmd)++)); + } + + if ( EFI_ERROR( CheckBusyBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + return EFI_SUCCESS; +} + +//********************************************************************** +// +// +// Procedure: Calibrate +// +// Description: This function moves the read/write head to cylinder 0. +// +// Input: +// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface, +// +// Output: +// EFI_STATUS +// +// +//********************************************************************** + +EFI_STATUS Calibrate( + IN FLOPPY_CTRL_PROTOCOL *FloppyInterface ) +{ + EFI_STATUS Status; + FDD_CALIBRATE_CMD *FdcCalibrateCmd; + UINT8 Offset; + UINT8 DriveNum; + UINT16 DataReg; + + DriveNum = FloppyInterface->DriveNum; + DataReg = FloppyInterface->BaseAddr + 05; + FdcCalibrateCmd = &(FloppyInterface->CmdCalibrate); + + FdcCalibrateCmd->CommandCode = CALIBRATE_CMD; + FdcCalibrateCmd->HeadDdrSel = DriveNum; + + if ( EFI_ERROR( CheckBusyBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + + for ( Offset = 0; Offset < sizeof (FDD_CALIBRATE_CMD); Offset++ ) + { + if ( EFI_ERROR( CheckMSRDOBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + IoWrite8( DataReg, *(((UINT8*)FdcCalibrateCmd)++)); + } + Delay( 200000 ); + + // Send CHECK_INT_STATUS command + if ( EFI_ERROR( CheckMSRDOBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + IoWrite8( DataReg, (UINT8)CHECK_INT_STATUS_CMD ); + + if ( EFI_ERROR( CheckMSRDIBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + Status = IoRead8( DataReg ); + + if ( EFI_ERROR( CheckMRQBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + IoRead8( DataReg ); + + if ((Status & 0xf0) == 0x20 ) + { + if ( EFI_ERROR( CheckBusyBit( FloppyInterface ))) + { + #ifdef EFI_DEBUG + + if ( gSysTable ) { + #ifdef DXE_FLOPPY_CTRL + TRACE((-1, "FDC: CalibrateFn1 Status: %x\n", Status)); + #endif + } + else { + #ifdef PEI_FLOPPY_CTRL + PEI_TRACE((-1, PeiServices, "FDC: CalibrateFn1 Status: %x\n", Status)); + #endif + } + #endif + return EFI_DEVICE_ERROR; + } + return EFI_SUCCESS; + } + + #ifdef EFI_DEBUG + + if ( gSysTable ) { + #ifdef DXE_FLOPPY_CTRL + TRACE((-1, "FDC: CalibrateFn2 Status: %x\n", Status)); + #endif + } + else { + #ifdef PEI_FLOPPY_CTRL + PEI_TRACE((-1, PeiServices, "FDC: CalibrateFn2 Status: %x\n", Status)); + #endif + } + #endif + return EFI_DEVICE_ERROR; +} + +//********************************************************************** +// +// +// Procedure: Seek +// +// Description: This function moves the read/write head to the park cylinder. +// +// Input: +// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface, +// IN UINT8 HeadNum, +// IN UINT8 CylNum +// +// Output: +// EFI_STATUS +// +// +//********************************************************************** + +EFI_STATUS Seek( + IN FLOPPY_CTRL_PROTOCOL *FloppyInterface, + IN UINT8 HeadNum, + IN UINT8 CylNum ) +{ + EFI_STATUS Status; + FDD_SEEK_CMD *FdcSeekCmd; + UINT8 Offset; + UINT8 DriveNum; + UINT16 DataReg; + + DriveNum = FloppyInterface->DriveNum; + DataReg = FloppyInterface->BaseAddr + 05; + FdcSeekCmd = &(FloppyInterface->CmdSeek); + + FdcSeekCmd->CommandCode = SEEK_CMD; + FdcSeekCmd->DiskHeadSel = (HeadNum << 02) + DriveNum; + FdcSeekCmd->NewCylinder = CylNum; + + if ( EFI_ERROR( CheckBusyBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + + for ( Offset = 0; Offset < sizeof (FDD_SEEK_CMD); Offset++ ) + { + if ( EFI_ERROR( CheckMSRDOBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + IoWrite8( DataReg, *(((UINT8*)FdcSeekCmd)++)); + } + + if ( FloppyInterface->PrCyl > CylNum ) { + Delay((FloppyInterface->PrCyl - CylNum + 1) * 4000 ); + } + else { + Delay((CylNum - FloppyInterface->PrCyl + 1) * 4000 ); + } + + // Send CHECK_INT_STATUS command + if ( EFI_ERROR( CheckMSRDOBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + IoWrite8( DataReg, (UINT8)CHECK_INT_STATUS_CMD ); + + if ( EFI_ERROR( CheckMSRDIBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + // Delay(5000); + Status = IoRead8( DataReg ); + + //EK1123 if(EFI_ERROR(CheckMRQBit(FloppyInterface))) + //EK1123 return EFI_DEVICE_ERROR; + //EK1123 START + if ( EFI_ERROR( CheckMSRDIBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + //EK1123 END + IoRead8( DataReg ); + + if ((Status & 0xf0) == 0x20 ) { + return EFI_SUCCESS; + } + #ifdef EFI_DEBUG + + if ( gSysTable ) { + #ifdef DXE_FLOPPY_CTRL + TRACE((-1, "FDC: SeekFn2 Status: %x\n", Status)); + #endif + } + else { + #ifdef PEI_FLOPPY_CTRL + PEI_TRACE((-1, PeiServices, "FDC: SeekFn2 Status: %x\n", Status)); + #endif + } + #endif + return EFI_DEVICE_ERROR; +} + +//********************************************************************** +// +// +// Procedure: Delay +// +// Description: This function introduce delay. +// +// Input: +// IN UINT32 MicroSec +// +// Output: +// VOID +// +// +//********************************************************************** + +static void Delay( + IN UINT32 MicroSec ) +{ + if ( gSysTable ) { + gSysTable->BootServices->Stall( MicroSec ); + } + else { + gPeiStall-> Stall( PeiServices, gPeiStall, MicroSec ); + } +} + +////////////////////////////////////////////////////////////////////////////// +// MOTOR ON/OFF FUNCTIONS // +////////////////////////////////////////////////////////////////////////////// + +//********************************************************************** +// +// +// Procedure: MotorOn +// +// Description: This function turns the motor on, selects a perticular drive +// and enables the DMA controller +// +// Input: +// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface +// +// Output: +// EFI_STATUS +// +// +//********************************************************************** + +EFI_STATUS MotorOn( + IN FLOPPY_CTRL_PROTOCOL *FloppyInterface ) +{ + UINT8 Data; + UINT16 DOR; + UINT8 DriveNum; + + DriveNum = FloppyInterface->DriveNum; + DOR = FloppyInterface->BaseAddr + 02; + + if ( EFI_ERROR( CheckBusyBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + // Check motor is alredy on + Data = IoRead8( DOR ); + + if ( Data & (MOTORA_START_BIT << DriveNum)) { + return EFI_SUCCESS; + } + + // Select drive and enable controller + Data = CTRL_EN_BIT | DMA_IRQEN_BIT; + + IoWrite8( DOR, Data ); + Delay( 10000 ); + + // Turn on the motor + if ( DriveNum == 00 ) + { + Data |= DriveNum | MOTORA_START_BIT; + } + else { + Data |= DriveNum | MOTORB_START_BIT; + } + IoWrite8( DOR, Data ); + + if ( EFI_ERROR( CheckBusyBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + + if ( EFI_ERROR( CheckMRQBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + FloppyInterface->FdcFlag |= FDC_FLAG_MOTOR_ON; + Delay( 20000 ); + + if ( EFI_ERROR( CheckBusyBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + return EFI_SUCCESS; +} + +//********************************************************************** +// +// +// Procedure: MotorOff +// +// Description: This function turns off the motor. +// +// Input: +// IN EFI_EVENT Event, +// IN VOID *Context +// +// Output: +// EFI_STATUS +// +// +//********************************************************************** + +EFI_STATUS MotorOff( + IN EFI_EVENT Event, + IN VOID *Context ) +{ + UINT8 Data; + UINT16 DOR; + UINT8 DriveNum; + + FLOPPY_CTRL_PROTOCOL *FloppyInterface = Context; + + // create timer event + if ( FloppyInterface->TimerFlag != 01 ) { + return EFI_SUCCESS; + } + + DriveNum = FloppyInterface->DriveNum; + DOR = FloppyInterface->BaseAddr + 02; + // Check motor is alredy on + //###DEBUG if(EFI_ERROR(CheckBusyBit(FloppyInterface))) + // return EFI_DEVICE_ERROR; + //if(EFI_ERROR(CheckMRQBit(FloppyInterface))) + // return EFI_DEVICE_ERROR; + //Data = IoRead8(DOR); + //###DEBUG END + // Turn OFF the motor + + if ( EFI_ERROR( CheckBusyBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + + if ( EFI_ERROR( CheckMRQBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + Data = IoRead8( DOR ); + + if ( Data & (MOTORA_START_BIT << DriveNum)) + { + if ( DriveNum == 00 ) + { + Data &= 0xEF; + IoWrite8( DOR, Data ); + } + + if ( DriveNum == 01 ) + { + Data &= 0xDF; + IoWrite8( DOR, Data ); + } + Delay( 20000 ); + } + FloppyInterface->FdcFlag &= ~(FDC_FLAG_MOTOR_ON); + return EFI_SUCCESS; +} + +//********************************************************************** +// +// +// Procedure: CtrlReset +// +// Description: This function resets the controller and enables the +// Floppy disk controller and DMA controller. +// +// Input: +// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface +// +// Output: +// EFI_STATUS +// +// +//********************************************************************** + +EFI_STATUS CtrlReset( + IN FLOPPY_CTRL_PROTOCOL *FloppyInterface ) +{ + UINT8 Data; + UINT16 DOR; + UINT8 DriveNum; + + DriveNum = FloppyInterface->DriveNum; + DOR = FloppyInterface->BaseAddr + 02; + + Data = 00 + DriveNum; + + IoWrite8( DOR, Data ); + Delay( 1000 ); + Data = CTRL_EN_BIT | DMA_IRQEN_BIT | DriveNum; + IoWrite8( DOR, Data ); + Delay( 1000 ); + return EFI_SUCCESS; +} + +////////////////////////////////////////////////////////////////////////////// +// FLOPPY DRIVE PARAMETERS // +// & // +// TESTING FUNCTONS // +////////////////////////////////////////////////////////////////////////////// + +//********************************************************************** +// +// +// Procedure: SetDataRate +// +// Description: This function programs the data transmit rate for +// the floppy controller. +// +// Input: +// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface +// +// Output: +// VOID +// +// +//********************************************************************** + +void SetDataRate( + IN FLOPPY_CTRL_PROTOCOL *FloppyInterface ) +{ + UINT8 Data; + UINT16 CCR; + + //CCR: Configuration Control Register + CCR = FloppyInterface->BaseAddr + 07; + + if ( FloppyInterface->FloppyDiskFormat == DoubleDensity720Kb ) { + Data = 10; // 01 -720kbps/s-720KByte floppy in 1.44MB drive + } + else if ( FloppyInterface->FloppyDiskFormat == HighDensity1_44Mb ) + { + Data = 00; // 00 -500kbits/s-1.44MB floppy in 1.44MB drive + } + else { + Data = 00; + } + IoWrite8( CCR, Data ); +} + +//********************************************************************** +// +// +// Procedure: CheckBusyBit +// +// Description: This function checks the main status register BIT04 +// to find whether controller is cutrrently is executing a +// command or not? +// +// Input: +// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface +// +// Output: +// EFI_STATUS +// +// +//********************************************************************** + +EFI_STATUS CheckBusyBit( + IN FLOPPY_CTRL_PROTOCOL *FloppyInterface ) +{ + UINT8 Status; + UINT16 Count = 30000; + UINT16 MSR; + + MSR = FloppyInterface->BaseAddr + 04; + + while ( Count-- ) + { + Status = IoRead8( MSR ); + + if ( !(Status & BUSY_BIT)) { + return EFI_SUCCESS; + } + Delay( 100 ); + } + return EFI_TIMEOUT; +} + +//********************************************************************** +// +// +// Procedure: CheckMRQBit +// +// Description: This function checks the main status register BIT04 to find +// whether data register is free to receive or provide commands. +// +// Input: +// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface +// +// Output: +// EFI_STATUS +// +// +//********************************************************************** + +EFI_STATUS CheckMRQBit( + IN FLOPPY_CTRL_PROTOCOL *FloppyInterface ) +{ + UINT8 Status; + UINT16 Count = 30000; + UINT16 MSR; + + MSR = FloppyInterface->BaseAddr + 04; + + while ( Count-- ) + { + Status = IoRead8( MSR ); + + if ( Status & MRQ_BIT ) { + return EFI_SUCCESS; + } + Delay( 100 ); + } + return EFI_TIMEOUT; +} + +//********************************************************************** +// +// +// Procedure: CheckMRQBit_NoDelay +// +// Description: This function checks the main status register BIT04 to find +// whether data register is free to receive or provide commands. +// It does not use the Delay function. +// +// Input: +// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface +// +// Output: +// EFI_STATUS +// +// +//********************************************************************** + +EFI_STATUS CheckMRQBit_NoDelay( + IN FLOPPY_CTRL_PROTOCOL *FloppyInterface ) +{ + UINT8 Status; + UINT32 Count = 500000; + UINT16 MSR; + + MSR = FloppyInterface->BaseAddr + 04; + + while ( Count-- ) + { + Status = IoRead8( MSR ); + + if ( Status & MRQ_BIT ) { + return EFI_SUCCESS; + } + } + return EFI_TIMEOUT; +} + +//********************************************************************** +// +// +// Procedure: CheckMSRDIBit +// +// Description: This function checks the main status register DIO bit6. +// Using DIO the controller indicates whether it expects data +// from the CPU or it wants to handover staus information to it. +// +// Input: +// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface +// +// Output: +// EFI_STATUS +// +// +//********************************************************************** + +EFI_STATUS CheckMSRDIBit( + IN FLOPPY_CTRL_PROTOCOL *FloppyInterface ) +{ + EFI_STATUS Status; + UINT16 Count = 20000; + UINT16 MSR; + + MSR = FloppyInterface->BaseAddr + 04; + + while ( Count-- ) + { + Status = IoRead8( MSR ); + + if ( Status & BIT06 ) + { + Count = 20000; + while ( Count-- ) + { + Status = IoRead8( MSR ); + + if ( Status & MRQ_BIT ) { + return EFI_SUCCESS; + } + Delay( 100 ); + } + return EFI_SUCCESS; + } + Delay( 100 ); + } + return EFI_TIMEOUT; +} + +//********************************************************************** +// +// +// Procedure: CheckMSRDOBit +// +// Description: This function checks the main status register DIO bit6. +// Using DIO the controller indicates whether it expects data +// from the CPU or it wants to handover staus information to it. +// +// Input: +// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface +// +// Output: +// EFI_STATUS +// +// +//********************************************************************** +EFI_STATUS CheckMSRDOBit( + IN FLOPPY_CTRL_PROTOCOL *FloppyInterface ) +{ + EFI_STATUS Status; + UINT16 Count = 20000; + UINT16 MSR; + + MSR = FloppyInterface->BaseAddr + 04; + + while ( Count-- ) + { + Status = IoRead8( MSR ); + + if ( !(Status & BIT06)) + { + Count = 20000; + while ( Count-- ) + { + Status = IoRead8( MSR ); + + if ( Status & MRQ_BIT ) { + return EFI_SUCCESS; + } + Delay( 100 ); + } + return EFI_SUCCESS; + } + Delay( 100 ); + } + return EFI_TIMEOUT; +} + +//********************************************************************** +// +// +// Procedure: CheckMediaChange +// +// Description: This function reads the DIR register to determine the +// Disk change. +// +// Input: +// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface +// +// Output: +// EFI_STATUS +// +// +//********************************************************************** +EFI_STATUS CheckMediaChange( + IN FLOPPY_CTRL_PROTOCOL *FloppyInterface ) +{ + UINT8 Data; + UINT16 DIR; + + DIR = FloppyInterface->BaseAddr + 07; + + if ( EFI_ERROR( CheckBusyBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + + if ( EFI_ERROR( CheckMRQBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + Data = IoRead8( DIR ); + + if ( EFI_ERROR( CheckBusyBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + + if ( EFI_ERROR( CheckMRQBit( FloppyInterface ))) { + return EFI_DEVICE_ERROR; + } + + if ( !(Data & DISK_CHG_STS_BIT)) + { + FloppyInterface->BlkIoMedia.MediaPresent = TRUE; + return EFI_SUCCESS; + } + + // if(gSysTable) + // FloppyInterface->BlkIoMedia.MediaPresent = FALSE; + // else + // FloppyInterface->PeimBlkIo.MediaPresent = FALSE; + return EFI_MEDIA_CHANGED; +} + +//********************************************************************** +// +// +// Procedure: LookupFloppyHid +// +// Description: This fuction searches the Floppy device in table that +// matches given HID and UID +// +// Input: +// UINT32 hid - HID to look for +// UINT32 uid - UID to look for +// +// Output: +// TRUE if match is found, FALSE otherwise +// +// +//********************************************************************** +BOOLEAN LookupFloppyHid( + IN UINT32 hid, + IN UINT32 uid ) +{ + UINT8 FloppyUid; + + for ( FloppyUid = 0; FloppyUid <= 3; FloppyUid++ ) + { + if ( hid == EISA_PNP_ID( 0x604 ) && uid == FloppyUid ) { + return TRUE; + } + } + return FALSE; +} + +#ifdef DXE_FLOPPY_CTRL +//********************************************************************** +// +// +// Procedure: GetFloppy_DP +// +// Description: This fuction returns the last node in the device +// path for the given controller. +// +// Input: +// IN EFI_DRIVER_BINDING_PROTOCOL *This, +// IN EFI_HANDLE Controller, +// IN ACPI_HID_DEVICE_PATH** Floppydp, +// IN UINT32 Attributes, +// IN BOOLEAN Close +// +// Output: +// EFI_SUCCESS or EFI_UNSUPPORTED +// +// +//********************************************************************** +EFI_STATUS GetFloppy_DP( + IN EFI_DRIVER_BINDING_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN ACPI_HID_DEVICE_PATH ** Floppydp, + IN UINT32 Attributes, + IN BOOLEAN Close ) +{ + EFI_STATUS Status; + ACPI_HID_DEVICE_PATH *acpiDP; + EFI_DEVICE_PATH_PROTOCOL * FloppyDevPath; + + // Get device path from Controller handle. + Status = pBS->OpenProtocol( Controller, &gDevicePathProtocolGuid, + (void**)&FloppyDevPath, This->DriverBindingHandle, Controller, Attributes ); + + if ( EFI_ERROR( Status )) { + if( Status == (EFI_ALREADY_STARTED || EFI_ACCESS_DENIED)){ + return Status; + } + return EFI_UNSUPPORTED; + } + + // FloppyDevPath is now the last node + acpiDP = *Floppydp = (ACPI_HID_DEVICE_PATH*)DPGetLastNode( FloppyDevPath ); + + Status = (acpiDP->Header.Type == ACPI_DEVICE_PATH + && acpiDP->Header.SubType == ACPI_DP) ? EFI_SUCCESS : EFI_UNSUPPORTED; + + if ( Close ) { + pBS->CloseProtocol( Controller, &gDevicePathProtocolGuid, + This->DriverBindingHandle, Controller ); + } + + return Status; +} + +#endif +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/FloppyCtrl/FloppyCtrl.cif b/Core/EM/FloppyCtrl/FloppyCtrl.cif new file mode 100644 index 0000000..fc3ca4f --- /dev/null +++ b/Core/EM/FloppyCtrl/FloppyCtrl.cif @@ -0,0 +1,13 @@ + + name = "FloppyCtrl" + category = ModulePart + LocalRoot = "Core\EM\FloppyCtrl\" + RefName = "FloppyCtrl" +[files] +"FloppyCtrl.sdl" +"FloppyCtrl.mak" +"FloppyCtrl.h" +"FloppyCtrl.c" +"Names.c" +"FloppyCtrlPei.dxs" + diff --git a/Core/EM/FloppyCtrl/FloppyCtrl.h b/Core/EM/FloppyCtrl/FloppyCtrl.h new file mode 100644 index 0000000..bf99e16 --- /dev/null +++ b/Core/EM/FloppyCtrl/FloppyCtrl.h @@ -0,0 +1,441 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Core/CORE_DXE/FloppyCtrl/FloppyCtrl.h 17 7/02/09 12:54p Yul $ +// +// $Revision: 17 $ +// +// $Date: 7/02/09 12:54p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Core/CORE_DXE/FloppyCtrl/FloppyCtrl.h $ +// +// 17 7/02/09 12:54p Yul +// Syns to coding standards +// +// 16 7/02/09 10:14a Yul +// Update Header and Tailer and syns with coding standards +// +// 15 4/13/07 1:37p Ambikas +// Coding standards changes: changed spaces, dashes, etc. +// +// 14 4/13/07 11:58a Ambikas +// +// 13 4/13/07 11:56a Ambikas +// Coding standard changes: updated the year in the AMI copyright header and footer; +// removed two commented out function headers (MotorOff, GetFloppyModel). +// +// 12 4/10/07 10:01a Felixp +// LookupHID routine renamed to LookupFloppyHid to avoid linking issue +// when linking with PS2CTRL module +// +// 11 9/13/06 10:08a Felixp +// +// 10 3/13/06 2:22a Felixp +// +// 9 12/21/05 11:39a Ambikas +// Added function prototype CheckMRQBit_NoDelay. +// +// 8 12/20/05 10:27p Ambikas +// Minor changes: Added new bit definitions for FLOPP_CTRL_PROTOCOL field +// UINT8 FdcFlag. FLOPPY_CTRL_PROTOCOL: FLOPPY_DISK_FORMAT +// FloppyDiskFormat replaces field UINT8 MediaType. Added various bit +// other definitions. +// +// 7 3/25/05 6:20p Felixp +// +// 6 3/25/05 7:58a Felixp +// +// 5 3/24/05 6:29p Felixp +// Included stall.h file. +// +// 4 3/24/05 11:52a Eswark +// Added Floppy peim code based on recovery specifixcation. +// +// 3 3/22/05 4:47p Eswark +// Added Pei support. +// +// 2 3/04/05 11:27a Mandal +// +//********************************************************************** + + +// +//---------------------------------------------------------------------- +// +// Name: FloppyCtrl.h +// +// Description: FloppyCtrl deader file - +// function delcarations, structs, constants +// +//---------------------------------------------------------------------- +// + + +#ifndef __FLOPPY_CTRL_H__ +#define __FLOPPY_CTRL_H__ + +#if !defined(PEI_FLOPPY_CTRL) && !defined(DXE_FLOPPY_CTRL) + #define PEI_FLOPPY_CTRL + #define DXE_FLOPPY_CTRL +#endif + +//---------------------------------------------------------------------- + +#include +#include +#include +#include +#include +#include +#include +#include +#include "ppi\DeviceRecoveryBlockIo.h" +#include +#include "protocol\BlockIo.h" +#include "protocol\AmiSio.h" +#include +#include +#include +#include "pei.h" + +//---------------------------------------------------------------------- + +#define EFI_FLOPPY_CTRL_INTERFACE_REVISION 0x00010000 +extern EFI_SYSTEM_TABLE *gSysTable; + +//---------------------------------------------------------------------- + +// PEIM specific code start + +EFI_STATUS +EFIAPI FdcBlkRead ( + IN EFI_BLOCK_IO_PROTOCOL *This, + IN UINT32 MediaId, + IN EFI_LBA LBA, + IN UINTN BufferSize, + OUT VOID *Buffer ); + +typedef +EFI_STATUS +(EFIAPI * PEI_FDC_BLK_RESET)( + IN EFI_BLOCK_IO_PROTOCOL *This + ); + + +EFI_STATUS PeimReadBlocks ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, + IN UINTN DeviceIndex, + IN EFI_PEI_LBA StartLBA, + IN UINTN BufferSize, + OUT VOID *Buffer ); + +EFI_STATUS GetNumberOfBlockDevices ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, + OUT UINTN *NumberBlockDevices ); + +EFI_STATUS GetBlockDeviceMediaInfo ( + IN EFI_PEI_SERVICES **PeiServices, + IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This, + IN UINTN DeviceIndex, + OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo ); + +// PEIM specific code end +//---------------------------------------------------------------------- + +// Floppy Disk Controller Commands +typedef struct FDD_CMD_PKT_tag +{ + UINT8 CommandCode; + UINT8 HeadDdrSel; + UINT8 Cylinder; + UINT8 Head; + UINT8 Sector; + UINT8 Size; + UINT8 TrackLength; + UINT8 GapLength; + UINT8 DataLength; +} FDD_CMD_PKT; + +typedef struct +{ + UINT8 CommandCode; + UINT8 HeadDdrSel; +} FDD_CALIBRATE_CMD; + +typedef struct +{ + UINT8 CommandCode; + UINT8 Ctrldata1; + UINT8 Ctrldata2; +} FDD_SPECIFY_CMD; + +typedef struct +{ + UINT8 CommandCode; + UINT8 DiskHeadSel; + UINT8 NewCylinder; +} FDD_SEEK_CMD; + +typedef struct +{ + UINT8 CommandCode; + UINT8 DiskHeadSel; + UINT8 Cylinder; + UINT8 Head; + UINT8 Sector; + UINT8 EndOfTrack; + UINT8 GapLength; + UINT8 ScanTestPause; +} FDD_SCAN_CMD; + +typedef struct +{ + UINT8 Status0; + UINT8 Status1; + UINT8 Status2; + UINT8 Cylinder; + UINT8 Head; + UINT8 SectorNumber; + UINT8 SectorSize; +} FDD_RESULT_PACKET; + +typedef enum +{ + DoubleDensity720Kb, + HighDensity1_44Mb, + ExtraHighDensity2_88Mb +} FLOPPY_DISK_FORMAT; + +typedef struct FLOPPY_CTRL_PROTOCOL_tag +{ + //Don't add any member of this structure before this place add it at the end + EFI_BLOCK_IO_PROTOCOL BlkIo; + EFI_BLOCK_IO_MEDIA BlkIoMedia; + EFI_PEI_RECOVERY_BLOCK_IO_PPI PeimRecBlk; + FDD_CMD_PKT CmdRdWrSect; + FDD_SEEK_CMD CmdSeek; + FDD_CALIBRATE_CMD CmdCalibrate; + FDD_SPECIFY_CMD CmdSpecify; + FDD_RESULT_PACKET ResultPacket; + UINT8 FdcFlag; + //Bit0 Drive initilization success + //Bit1 Drive initilization failure + //Bit2 Drive motor on + //Bit3 Drive write protected + UINT8 PrCyl; //ek1123 + UINT8 TimerFlag; //ek1122 + EFI_EVENT Event; //ek1122 + UINT8 DmaFlag; + UINT8 DriveNum; + UINT8 FloppyType; + UINT16 BaseAddr; + FLOPPY_DISK_FORMAT FloppyDiskFormat; + UINT8 MaxSectors; + UINT8 *DMABuffer; + UINT8 *TempBuffer; +} FLOPPY_CTRL_PROTOCOL; + +typedef struct DMA_INIT_tag +{ + UINT8 PortAddr; + UINT8 Value; +} DMA_INIT; + +//FLOPPY_CTRL_PROTOCOL FdcFlag bit definitions +#define FDC_FLAG_NOT_INTIALIZED 0 +#define FDC_FLAG_DRIVE_INIT_SUCCESS BIT00 +#define FDC_FLAG_DRIVE_INIT_ERROR BIT01 +#define FDC_FLAG_MOTOR_ON BIT02 +#define FDC_FLAG_WRITE_PROTECTED BIT03 + +#define DXE_FLAG 0xAB +#define PEI_FLAG 0xCD + +#define FLOPPY_DMA_CHANNAL 0x02 +#define FLOPPY_IRQ 0x06 +#define START_MOTOR 0x01 +#define STOP_MOTOR 0x00 +#define DMA_IRQ_CHAN_EN 0x01 +#define DMA_IRQ_CHAN_DIS 0x00 +#define FLOPPY_INTR 0x0e + +// Digital output register bits +#define DRVA_SEL 00 // 00 =Drive0(A) +#define DRVB_SEL 01 // 01 =Drive0(B) +#define DRVC_SEL 02 // 02 =Drive0(C) +#define DRVD_SEL 03 // 03 =Drive0(D) +#define CTRL_EN_BIT BIT02 +#define DMA_IRQEN_BIT BIT03 +#define MOTORA_START_BIT BIT04 +#define MOTORB_START_BIT BIT05 +#define MOTORC_START_BIT BIT06 +#define MOTORD_START_BIT BIT07 + +// Main Status register bits +#define DRVA_ACT 00 // DriveA in positioning mode +#define DRVB_ACT 01 // DriveB in positioning mode +#define DRVC_ACT 02 // DriveC in positioning mode +#define DRVD_ACT 03 // DriveD in positioning mode +#define BUSY_BIT BIT04 +#define NDMA_BIT BIT05 +#define DIO_BIT BIT06 +#define MRQ_BIT BIT07 + +// Digital Input Register bits +#define DISK_CHG_STS_BIT BIT07 + +// FDC Data Transfer commands +#define RD_SECTOR_CMD 0x06 +#define RD_TRACK_CMD 0x02 +#define WR_SECTOR_CMD 0x05 +#define WR_DEL_SECTOR_CMD 0x09 +#define RD_DEL_SECTOR_CMD 0x0C +#define RD_TRACK_CMD 0x02 +#define FORMAT_TRACK_CMD 0x0D + +//Bits for Read/Write Sector Command +#define M_COMMAND_BIT_MULTITRACK_OPERATION BIT07 +#define F_COMMAND_BIT_MFM_RECORDING_METHOD BIT06 +#define S_COMMAND_BIT_SKIP_MODE BIT05 + +//Bits for Result Status 0 +#define IC1_STATUS0_BIT_INTERRUPT_CODE BIT07 +#define IC0_STATUS0_BIT_INTERRUPT_CODE BIT06 + +// ControlCommands +#define RD_SECTOR_ID 0x0A +#define CALIBRATE_CMD 0x07 +#define SPECIFY_CMD 0x03 +#define FIX_DRIVE_DATA_CMD 0x03 +#define CHECK_INT_STATUS_CMD 0x08 +#define CHECK_DRV_STATUS_CMD 0x04 +#define SEEK_CMD 0x0F +#define PARK_RW_HEAD_CMD 0x0F +#define INVALID_CMD 0x00 + +// Extended commands +#define VERIFY_COMMAND 0x16 + +// temp remove +#define SCAN_EQU_CMD 0x11 +#define SCAN_LOW_EQU_CMD 0x19 +#define SCAN_HIGH_EQU_CMD 0x1D + +// DMA registers + +#define DMA1_ADDR_REG 0x04 +#define DMA1_COUNT_REG 0x05 +#define DMA1_STS_REG 0x08 +#define DMA1_CMD_REG 0x08 +#define DMA1_REQ_REG 0x09 +#define DMA1_CH_MASK_REG 0x0A +#define DMA1_MODE_REG 0x0B +#define DMA1_RESET_REG 0x0C +#define DMA1_INTER_REG 0x0D +#define DMA1_MASK_REG 0x0F +#define DMA1_PAGE_REG 0x81 + + +#define DMA_MAX_ADDR_LIMIT 0xFB0000 +#define DMA_BUFFER_LIMIT 0xFFFFFF +#define READ_OPERATION 0x0F +#define WRITE_OPERATION 0x00 +#define SECTOR_SIZE 512 +#define NUM_PAGES 05 + +// Function declarations +BOOLEAN LookupFloppyHid( UINT32, UINT32 ); +EFI_STATUS GetFloppy_DP( EFI_DRIVER_BINDING_PROTOCOL *, EFI_HANDLE, ACPI_HID_DEVICE_PATH * *, UINT32, BOOLEAN ); +EFI_STATUS FloppyDriveInit ( + FLOPPY_CTRL_PROTOCOL* ); +void DriveReady ( + FLOPPY_CTRL_PROTOCOL* ); +EFI_STATUS CheckBusyBit ( + FLOPPY_CTRL_PROTOCOL* ); +EFI_STATUS CheckMRQBit ( + FLOPPY_CTRL_PROTOCOL* ); +EFI_STATUS CheckMRQBit_NoDelay ( + FLOPPY_CTRL_PROTOCOL *FloppyInterface ); +void DMAInitForFloppy ( + IN VOID*, + IN UINTN, + IN BOOLEAN ); +EFI_STATUS InitFloppyBlockIO ( ); +VOID InitFloppyBlockIOLastBlockAndMaxSectors ( + FLOPPY_CTRL_PROTOCOL *FloppyInterface ); +EFI_STATUS MotorOn ( + FLOPPY_CTRL_PROTOCOL* ); +void SetDataRate ( + FLOPPY_CTRL_PROTOCOL* ); +EFI_STATUS CheckMediaChange ( + FLOPPY_CTRL_PROTOCOL* ); +void Delay( UINT32 ); +EFI_STATUS Specify ( + FLOPPY_CTRL_PROTOCOL* ); +EFI_STATUS Calibrate ( + FLOPPY_CTRL_PROTOCOL* ); +EFI_STATUS MotorOff( EFI_EVENT, VOID* ); +EFI_STATUS FdcBlkRead ( + IN EFI_BLOCK_IO_PROTOCOL*, + IN UINT32, + IN EFI_LBA, + IN UINTN, + OUT VOID* ); +EFI_STATUS FdcBlkWrite ( + IN EFI_BLOCK_IO_PROTOCOL*, + IN UINT32, + IN EFI_LBA, + IN UINTN, + OUT VOID* ); +EFI_STATUS Seek( FLOPPY_CTRL_PROTOCOL *, UINT8, UINT8 ); +EFI_STATUS FddReadWriteFn ( + IN EFI_BLOCK_IO_PROTOCOL*, + IN UINT32, + IN EFI_LBA, + IN UINTN, + IN UINT8, + OUT VOID* ); +EFI_STATUS FdcReset ( + IN EFI_BLOCK_IO_PROTOCOL*, + IN BOOLEAN ); +EFI_STATUS FdcBlkFlush ( + IN EFI_BLOCK_IO_PROTOCOL* ); +EFI_STATUS CtrlReset ( + FLOPPY_CTRL_PROTOCOL* ); +EFI_STATUS ChkDrSts( FLOPPY_CTRL_PROTOCOL *, UINT8 ); +void CopyBuffer( VOID *, VOID *, UINTN ); +EFI_STATUS CheckMSRDOBit ( + FLOPPY_CTRL_PROTOCOL* ); +EFI_STATUS CheckMSRDIBit ( + FLOPPY_CTRL_PROTOCOL* ); +void DMAChInit ( ); +#endif // __FLOPPY_CTRL_H__ + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** diff --git a/Core/EM/FloppyCtrl/FloppyCtrl.mak b/Core/EM/FloppyCtrl/FloppyCtrl.mak new file mode 100644 index 0000000..e093097 --- /dev/null +++ b/Core/EM/FloppyCtrl/FloppyCtrl.mak @@ -0,0 +1,94 @@ +#********************************************************************** +#** ** +#** (C)Copyright 1985-2007, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 6145-F Northbelt Pkwy, Norcross, GA 30071 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#********************************************************************** +#********************************************************************** +# $Header: /Alaska/SOURCE/Core/CORE_DXE/FloppyCtrl/FloppyCtrl.mak 6 4/13/07 1:36p Ambikas $ +# +# $Revision: 6 $ +# +# $Date: 4/13/07 1:36p $ +#********************************************************************** +# Revision History +# ---------------- +# $Log: /Alaska/SOURCE/Core/CORE_DXE/FloppyCtrl/FloppyCtrl.mak $ +# +# 6 4/13/07 1:36p Ambikas +# Coding standards changes: Updated year in AMI copyright header and +# footer; +# +# changed AMI_FHDR a bit. +# +# 5 10/13/06 4:40p Felixp +# +# 4 9/13/06 10:08a Felixp +# x64 support +# +#********************************************************************** + + +# +#---------------------------------------------------------------------- +# +# Name: FloppyCtrl.mak +# +# Description: Floppy Controller component make file +# +#---------------------------------------------------------------------- +# + + +all : FloppyCtrl + +FloppyCtrl : $(BUILD_DIR)\FloppyCtrl.mak FloppyCtrlBin + +$(BUILD_DIR)\FloppyCtrl.mak : $(FLOPPY_CTRL_DIR)\$(@B).cif $(FLOPPY_CTRL_DIR)\$(@B).mak $(BUILD_RULES) + $(CIF2MAK) $(FLOPPY_CTRL_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) + +!IF "$(x64_BUILD)"!="1" +FloppyCtrlBin : $(AMIDXELIB) $(AMIPEILIB) + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\FloppyCtrl.mak all\ + GUID=8B9D3EE0-4BA4-433b-9C48-4E830B3B40FD\ + ENTRY_POINT=FloppyCtrlEntryPoint\ + DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX\ + TYPE=COMBINED COMPRESS=1\ +!ELSE + +RecoverySrcPeiBin : $(BUILD_DIR)\FloppyCtrlPei.lib +CORE_DXE_LIBBin : $(BUILD_DIR)\FloppyCtrlDxe.lib + +$(BUILD_DIR)\FloppyCtrlPei.lib $(BUILD_DIR)\FloppyCtrlDxe.lib : FloppyCtrl + +FloppyCtrlBin : + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\FloppyCtrl.mak all\ + BUILD_DIR=$(BUILD_DIR)\IA32\ + "CFLAGS=$(CFLAGS) /DPEI_FLOPPY_CTRL"\ + TYPE=PEI_LIBRARY LIBRARY_NAME=$(BUILD_DIR)\FloppyCtrlPei.lib + $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\ + /f $(BUILD_DIR)\FloppyCtrl.mak all\ + "CFLAGS=$(CFLAGS) /DDXE_FLOPPY_CTRL"\ + TYPE=LIBRARY LIBRARY_NAME=$(BUILD_DIR)\FloppyCtrlDxe.lib +!ENDIF +#********************************************************************** +#********************************************************************** +#** ** +#** (C)Copyright 1985-2007, American Megatrends, Inc. ** +#** ** +#** All Rights Reserved. ** +#** ** +#** 6145-F Northbelt Pkwy, Norcross, GA 30071 ** +#** ** +#** Phone: (770)-246-8600 ** +#** ** +#********************************************************************** +#********************************************************************** \ No newline at end of file diff --git a/Core/EM/FloppyCtrl/FloppyCtrl.sdl b/Core/EM/FloppyCtrl/FloppyCtrl.sdl new file mode 100644 index 0000000..26fdbf7 --- /dev/null +++ b/Core/EM/FloppyCtrl/FloppyCtrl.sdl @@ -0,0 +1,40 @@ +TOKEN + Name = "FLOPPY_CTRL_SRC_SUPPORT" + Value = "1" + Help = "Main switch to enable FloppyCtrl sources in Project" + TokenType = Boolean + TargetEQU = Yes + TargetMAK = Yes + Master = Yes + Token = "FLOPPY_CTRL_SUPPORT" "=" "1" +End + +PATH + Name = "FLOPPY_CTRL_DIR" +End + +MODULE + Help = "Includes FloppyCtrl.mak to Project" + File = "FloppyCtrl.mak" +End + +ELINK + Name = "$(BUILD_DIR)\FloppyCtrl.ffs" + Parent = "$(CORE_DIR)\FloppyCtrl.ffs" + InvokeOrder = ReplaceParent +End + +ELINK + Name = "FDCPeimEntryPoint," + Parent = "RecoveryInitialize" + Token = "x64_BUILD" "=" "1" + InvokeOrder = AfterParent +End + +ELINK + Name = " " + Parent = "$(BUILD_DIR)\FloppyCtrl.ffs" + Token = "x64_BUILD" "=" "1" + InvokeOrder = ReplaceParent +End + diff --git a/Core/EM/FloppyCtrl/FloppyCtrlPei.dxs b/Core/EM/FloppyCtrl/FloppyCtrlPei.dxs new file mode 100644 index 0000000..339e6f2 --- /dev/null +++ b/Core/EM/FloppyCtrl/FloppyCtrlPei.dxs @@ -0,0 +1,70 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2007, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 6145-F Northbelt Pkwy, Norcross, GA 30071 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Core/CORE_DXE/FloppyCtrl/FloppyCtrlPei.dxs 2 4/13/07 1:38p Ambikas $ +// +// $Revision: 2 $ +// +// $Date: 4/13/07 1:38p $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Core/CORE_DXE/FloppyCtrl/FloppyCtrlPei.dxs $ +// +// 2 4/13/07 1:38p Ambikas +// Coding standards changes: Updated year in AMI copyright header and +// footer; +// +// changed spaces, dashes, etc. +// +//********************************************************************** + + +// +//---------------------------------------------------------------------- +// +// Name: FloppyCtrlPei.dxs +// +// Description: PEI Dependancy expression for FloppyCtrl component +// +//---------------------------------------------------------------------- +// + + +//---------------------------------------------------------------------- + +#include + +//---------------------------------------------------------------------- + +DEPENDENCY_START +EFI_PEI_FV_FILE_LOADER_GUID +AND +EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI +AND +EFI_PEI_BOOT_IN_RECOVERY_MODE_PEIM_PPI +DEPENDENCY_END +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2007, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 6145-F Northbelt Pkwy, Norcross, GA 30071 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** \ No newline at end of file diff --git a/Core/EM/FloppyCtrl/Names.c b/Core/EM/FloppyCtrl/Names.c new file mode 100644 index 0000000..61d921a --- /dev/null +++ b/Core/EM/FloppyCtrl/Names.c @@ -0,0 +1,240 @@ +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** +//********************************************************************** +// $Header: /Alaska/SOURCE/Core/CORE_DXE/FloppyCtrl/Names.c 10 8/28/09 10:29a Felixp $ +// +// $Revision: 10 $ +// +// $Date: 8/28/09 10:29a $ +//********************************************************************** +// Revision History +// ---------------- +// $Log: /Alaska/SOURCE/Core/CORE_DXE/FloppyCtrl/Names.c $ +// +// 10 8/28/09 10:29a Felixp +// Component Name protocol implementation is upadted to support both +// ComponentName and ComponentName2 protocols +// (based on value of the EFI_SPECIFICATION_VERSION SDL token). +// +// 9 7/02/09 12:54p Yul +// Syns to coding standards +// +// 8 7/02/09 10:14a Yul +// Update Header and Tailer and syns with coding standards +// +// 7 4/13/07 1:38p Ambikas +// Coding standards changes: changed spaces, dashes, etc. +// +// 6 4/13/07 11:59a Ambikas +// +// 5 4/13/07 11:53a Ambikas +// Coding standard changes: updated the year in the AMI copyright header +// and footer; removed commented out _asm jmp $. +// +// 4 4/10/07 10:01a Felixp +// LookupHID routine renamed to LookupFloppyHid to avoid linking issue +// when linking with PS2CTRL module +// +// 3 3/13/06 2:22a Felixp +// +// 2 3/04/05 11:31a Mandal +// +//********************************************************************** + + +// +//---------------------------------------------------------------------- +// +// Name: Names.c +// +// Description: Definitions for EFI_COMPONENT_NAME_PROTOCOL +// (GetDriverName, GetControllerName) for FloppyCtrl driver. +// +//---------------------------------------------------------------------- +// + + +//---------------------------------------------------------------------- + +#include "FloppyCtrl.h" + +//---------------------------------------------------------------------- + +EFI_STATUS FloppyGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName ); + +EFI_STATUS FloppyGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName ); + +extern EFI_DRIVER_BINDING_PROTOCOL gFloppyCtrlDriverBindingProtocol; + +CHAR16 *gFloppyDriverName = L"AMI Floppy Driver"; +CHAR16 *gFloppyCtrlName = L"Floppy Controller"; + +//========================================================================== +// Driver component name instance for FloppyCtl Driver +//========================================================================== +#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID //old Core +#ifndef LANGUAGE_CODE_ENGLISH +#define LANGUAGE_CODE_ENGLISH "eng" +#endif +static BOOLEAN LanguageCodesEqual( + CONST CHAR8* LangCode1, CONST CHAR8* LangCode2 +){ + return LangCode1[0]==LangCode2[0] + && LangCode1[1]==LangCode2[1] + && LangCode1[2]==LangCode2[2]; +} +#endif +EFI_COMPONENT_NAME_PROTOCOL gFloppyCtlDriverName = { + FloppyGetDriverName, + FloppyGetControllerName, + LANGUAGE_CODE_ENGLISH +}; + +// +//--------------------------------------------------------------------------- +// +// FUNCTION: FloppyGetDriverName +// +// DESCRIPTION: Retrieves a Unicode string that is the user readable name of +// the EFI Driver. +// +// +// Input: +// This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance. +// Language - Pointer to a three character ISO 639-2 language identifier +// This is language of the driver name that that the caller +// is requesting, must match one of the languages specified +// in SupportedLanguages. Number of languages supported by a +// driver is up to the driver writer. +// DriverName - A pointer to the Unicode string to return. Unicode string +// is the name of the driver specified by This in the +// language specified by Language. +// +// Output: +// EFI_SUCCES - Unicode string for the Driver specified by This +// and the language specified by Language was +// returned in DriverName. +// EFI_INVALID_PARAMETER - Language is NULL. +// EFI_INVALID_PARAMETER - DriverName is NULL. +// EFI_UNSUPPORTED - The driver specified by This does not support +// language specified by Language. +// +//--------------------------------------------------------------------------- +// + +EFI_STATUS FloppyGetDriverName( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName ) +{ + if ( !Language || !DriverName ) { + return EFI_INVALID_PARAMETER; + } + + if ( !LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH) ) { + return EFI_UNSUPPORTED; + } + *DriverName = gFloppyDriverName; + return EFI_SUCCESS; +} + +// +//--------------------------------------------------------------------------- +// +// FUNCTION: FloppyGetControllerName +// +// DESCRIPTION: Retrieves a Unicode string that is the user readable name of +// the controller that is being managed by an EFI Driver. +// +// Input: +// IN EFI_COMPONENT_NAME_PROTOCOL *This, +// IN EFI_HANDLE Controller, +// IN EFI_HANDLE ChildHandle OPTIONAL, +// IN CHAR8 *Language, +// +// Output: +// OUT CHAR16 **ControllerName +// A pointer to the Unicode string to return. This Unicode +// string is the name of the controller specified by +// ControllerHandle and ChildHandle in the language +// specified by Language from the point of view of the +// driver specified by This. +// EFI_SUCCESS - Unicode string for the user readable name in +// language specified by Language for the driver +// specified by This was returned in DriverName. +// EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE. +// EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid +// EFI_HANDLE. +// EFI_INVALID_PARAMETER - Language is NULL. +// EFI_INVALID_PARAMETER - ControllerName is NULL. +// EFI_UNSUPPORTED - The driver specified by This is not currently +// managing the controller specified by +// ControllerHandle and ChildHandle. +// EFI_UNSUPPORTED - The driver specified by This does not support +// the language specified by Language. +// +//--------------------------------------------------------------------------- +// + +EFI_STATUS FloppyGetControllerName( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE Controller, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName ) +{ + ACPI_HID_DEVICE_PATH * acpiDP; + + if ( !Language || !ControllerName ) { + return EFI_INVALID_PARAMETER; + } + + if ( !LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH) ) { + return EFI_UNSUPPORTED; + } + + // + // Find the last device node in the device path and return "Supported" + // for mouse and/or keyboard depending on the SDL switches. + // + if ( !EFI_ERROR( GetFloppy_DP( &gFloppyCtrlDriverBindingProtocol, \ + Controller, &acpiDP, EFI_OPEN_PROTOCOL_GET_PROTOCOL, FALSE )) + && LookupFloppyHid( acpiDP->HID, acpiDP->UID )) { + *ControllerName = gFloppyCtrlName; + return EFI_SUCCESS; + } + return EFI_UNSUPPORTED; +} + +//********************************************************************** +//********************************************************************** +//** ** +//** (C)Copyright 1985-2009, American Megatrends, Inc. ** +//** ** +//** All Rights Reserved. ** +//** ** +//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 ** +//** ** +//** Phone: (770)-246-8600 ** +//** ** +//********************************************************************** +//********************************************************************** -- cgit v1.2.3