summaryrefslogtreecommitdiff
path: root/ChvRefCodePkg/CherryViewSoc
diff options
context:
space:
mode:
authorGuo Mang <mang.guo@intel.com>2016-06-02 14:02:33 +0800
committerHao Wu <hao.a.wu@intel.com>2016-06-07 09:55:47 +0800
commit0cf675ebfa4f8f8206bcd3cd09c14342eb3806c8 (patch)
treefd74480a87329088cfb2e8969c635c6fa4500217 /ChvRefCodePkg/CherryViewSoc
parent04d72518eeeeae2ed1f6b061455deac0c3d7a701 (diff)
downloadedk2-platforms-0cf675ebfa4f8f8206bcd3cd09c14342eb3806c8.tar.xz
ChvRefCodePkg: Add SataController driver.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Guo Mang <mang.guo@intel.com>
Diffstat (limited to 'ChvRefCodePkg/CherryViewSoc')
-rw-r--r--ChvRefCodePkg/CherryViewSoc/SouthCluster/SataController/Dxe/SataController.c947
-rw-r--r--ChvRefCodePkg/CherryViewSoc/SouthCluster/SataController/Dxe/SataController.h293
-rw-r--r--ChvRefCodePkg/CherryViewSoc/SouthCluster/SataController/Dxe/SataController.inf57
-rw-r--r--ChvRefCodePkg/CherryViewSoc/SouthCluster/SataController/Dxe/SataControllerName.c168
4 files changed, 1465 insertions, 0 deletions
diff --git a/ChvRefCodePkg/CherryViewSoc/SouthCluster/SataController/Dxe/SataController.c b/ChvRefCodePkg/CherryViewSoc/SouthCluster/SataController/Dxe/SataController.c
new file mode 100644
index 0000000000..9ba1b886ce
--- /dev/null
+++ b/ChvRefCodePkg/CherryViewSoc/SouthCluster/SataController/Dxe/SataController.c
@@ -0,0 +1,947 @@
+/** @file
+ This driver module produces IDE_CONTROLLER_INIT protocol for serial ATA
+ driver and will be used by IDE Bus driver to support chipset dependent timing
+ information, config SATA control/status registers. This driver
+ is responsible for early initialization of serial ATA controller.
+
+ Serial ATA spec requires SATA controller compatible with parallel IDE
+ controller. That's why lots of code here is the same with IDE controller
+ driver. However, We need this driver to optimize timing settings for SATA
+ device and set SATA config/error/status registers.
+
+ Copyright (c) 1999 - 2015, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "SataController.h"
+
+///
+/// EFI_DRIVER_BINDING_PROTOCOL instance
+///
+EFI_DRIVER_BINDING_PROTOCOL mSataControllerDriverBinding = {
+ SataControllerSupported,
+ SataControllerStart,
+ SataControllerStop,
+ 1,
+ NULL,
+ NULL
+};
+extern EFI_COMPONENT_NAME2_PROTOCOL mSataControllerName;
+
+//
+// Internal function definitions
+//
+EFI_STATUS
+CalculateBestPioMode (
+ IN EFI_IDENTIFY_DATA * IdentifyData,
+ IN UINT16 *DisPioMode OPTIONAL,
+ OUT UINT16 *SelectedMode
+ );
+
+EFI_STATUS
+CalculateBestUdmaMode (
+ IN EFI_IDENTIFY_DATA * IdentifyData,
+ IN UINT16 *DisUDmaMode OPTIONAL,
+ OUT UINT16 *SelectedMode
+ );
+
+/**
+ Chipset SATA Driver EntryPoint function. It follows the standard EFI driver
+ model. It's called by StartImage() of DXE Core
+
+ @param[in] ImageHandle While the driver image loaded be the ImageLoader(),
+ an image handle is assigned to this driver binary,
+ all activities of the driver is tied to this ImageHandle
+ @param[in] SystemTable A pointer to the system table, for all BS(Boo Services) and
+ RT(Runtime Services)
+
+ @retval EFI_SUCCESS Function completes successfully
+**/
+EFI_STATUS
+EFIAPI
+InitializeSataControllerDriver (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ //
+ // Install driver model protocol(s).
+ //
+ Status = EfiLibInstallDriverBindingComponentName2 (
+ ImageHandle,
+ SystemTable,
+ &mSataControllerDriverBinding,
+ ImageHandle,
+ NULL,
+ &mSataControllerName
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function checks to see if the driver supports a device specified by
+ "Controller handle" parameter. It is called by DXE Core StartImage() or
+ ConnectController() routines. The driver uses 'device path' and/or
+ 'services' from the Bus I/O abstraction attached to the controller handle
+ to determine if the driver support this controller handle.
+ Note: In the BDS (Boot Device Selection) phase, the DXE core enumerate all
+ devices (or, controller) and assigns GUIDs to them.
+
+ @param[in] This A pointer points to the Binding Protocol instance
+ @param[in] Controller The handle of controller to be tested.
+ @param[in] RemainingDevicePath A pointer to the device path. Ignored by device
+ driver but used by bus driver
+
+ @retval EFI_SUCCESS The device is supported
+ @exception EFI_UNSUPPORTED The device is not supported
+**/
+EFI_STATUS
+EFIAPI
+SataControllerSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ UINT32 SataDeviceIdFound;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ PCI_TYPE00 PciData;
+
+ ///
+ /// SATA Controller is a device driver, and should ingore the
+ /// "RemainingDevicePath" according to EFI spec
+ ///
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID *) &ParentDevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ ///
+ /// EFI_ALREADY_STARTED is also an error
+ ///
+ return Status;
+ }
+ ///
+ /// Close the protocol because we don't use it here
+ ///
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ ///
+ /// Now test the EfiPciIoProtocol
+ ///
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ ///
+ /// Now further check the PCI header: Base class (offset 0x0B) and
+ /// Sub Class (offset 0x0A). This controller should be an SATA controller
+ ///
+ Status = PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint8,
+ 0,
+ sizeof (PciData),
+ &PciData
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ return EFI_UNSUPPORTED;
+ }
+ ///
+ /// Since we already got the PciData, we can close protocol to avoid to carry it on for multiple exit points.
+ ///
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ ///
+ /// Examine SATA PCI Configuration table fields
+ ///
+ SataDeviceIdFound = FALSE;
+ ///
+ /// When found is storage device and provided by Intel then detect for right device Ids
+ ///
+ if (PciData.Hdr.VendorId == V_PCH_SATA_VENDOR_ID) {
+ if ((PciData.Hdr.ClassCode[2] == PCI_CLASS_MASS_STORAGE)) {
+ if ((PciData.Hdr.ClassCode[1] == V_PCH_SATA_CC_SCC_IDE)) {
+ if (IS_PCH_SATA_MODE_DEVICE_ID (PciData.Hdr.DeviceId)) {
+ SataDeviceIdFound = TRUE;
+ }
+ }
+
+ if (PciData.Hdr.ClassCode[1] == V_PCH_SATA_CC_SCC_AHCI) {
+ if (IS_PCH_SATA_AHCI_DEVICE_ID (PciData.Hdr.DeviceId)) {
+ SataDeviceIdFound = TRUE;
+ }
+ }
+
+ if (PciData.Hdr.ClassCode[1] == V_PCH_SATA_CC_SCC_RAID) {
+ if (IS_PCH_SATA_RAID_DEVICE_ID (PciData.Hdr.DeviceId)) {
+ SataDeviceIdFound = TRUE;
+ }
+ }
+ }
+ }
+
+ if (!SataDeviceIdFound) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return Status;
+}
+
+/**
+ This routine is called right after the .Supported() is called and returns
+ EFI_SUCCESS. Notes: The supported protocols are checked but the Protocols
+ are closed.
+
+ @param[in] This A pointer points to the Binding Protocol instance
+ @param[in] Controller The handle of controller to be tested. Parameter
+ passed by the caller
+ @param[in] RemainingDevicePath A pointer to the device path. Should be ignored by
+ device driver
+
+ @retval EFI_SUCCESS The device is started
+ @retval Other values Something error happened
+**/
+EFI_STATUS
+EFIAPI
+SataControllerStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_SATA_CONTROLLER_PRIVATE_DATA *SataPrivateData;
+ PCI_TYPE00 PciData;
+ UINTN SegNum;
+ UINTN BusNum;
+ UINTN DevNum;
+ UINTN FuncNum;
+ UINT64 CommandVal;
+
+ DEBUG ((EFI_D_INFO, "SataControllerStart() Start\n"));
+
+ SataPrivateData = NULL;
+ ///
+ /// Now test and open the EfiPciIoProtocol
+ ///
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ ///
+ /// Status == 0 - A normal execution flow, SUCCESS and the program proceeds.
+ /// Status == ALREADY_STARTED - A non-zero Status code returned. It indicates
+ /// that the protocol has been opened and should be treated as a
+ /// normal condition and the program proceeds. The Protocol will not
+ /// opened 'again' by this call.
+ /// Status != ALREADY_STARTED - Error status, terminate program execution
+ ///
+ if (EFI_ERROR (Status)) {
+ ///
+ /// EFI_ALREADY_STARTED is also an error
+ ///
+ return Status;
+ }
+ ///
+ /// Allocate SATA private data structure
+ ///
+ SataPrivateData = AllocatePool (sizeof (EFI_SATA_CONTROLLER_PRIVATE_DATA));
+ if (SataPrivateData == NULL) {
+ DEBUG ((EFI_D_ERROR, "SATA Controller START ERROR: Allocating pool for IdePrivateData failed!\n"));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ ///
+ /// Initialize SATA private data
+ ///
+ ZeroMem (SataPrivateData, sizeof (EFI_SATA_CONTROLLER_PRIVATE_DATA));
+ SataPrivateData->Signature = SATA_CONTROLLER_SIGNATURE;
+ SataPrivateData->PciIo = PciIo;
+ SataPrivateData->IdeInit.GetChannelInfo = IdeInitGetChannelInfo;
+ SataPrivateData->IdeInit.NotifyPhase = IdeInitNotifyPhase;
+ SataPrivateData->IdeInit.SubmitData = IdeInitSubmitData;
+ SataPrivateData->IdeInit.DisqualifyMode = IdeInitDisqualifyMode;
+ SataPrivateData->IdeInit.CalculateMode = IdeInitCalculateMode;
+ SataPrivateData->IdeInit.SetTiming = IdeInitSetTiming;
+ SataPrivateData->IdeInit.EnumAll = PCH_SATA_ENUMER_ALL;
+
+ Status = PciIo->GetLocation (
+ PciIo,
+ &SegNum,
+ &BusNum,
+ &DevNum,
+ &FuncNum
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint8,
+ 0,
+ sizeof (PciData),
+ &PciData
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Get device capabilities
+ ///
+ Status = PciIo->Attributes (
+ PciIo,
+ EfiPciIoAttributeOperationSupported,
+ 0,
+ &CommandVal
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ ///
+ /// Enable Command Register
+ ///
+ Status = PciIo->Attributes (
+ PciIo,
+ EfiPciIoAttributeOperationEnable,
+ CommandVal & EFI_PCI_DEVICE_ENABLE,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+ if (PciData.Hdr.ClassCode[1] == V_PCH_SATA_CC_SCC_IDE) {
+ SataPrivateData->IdeInit.ChannelCount = PCH_IDE_MAX_CHANNELS;
+ } else if (PciData.Hdr.ClassCode[1] == V_PCH_SATA_CC_SCC_AHCI ||
+ PciData.Hdr.ClassCode[1] == V_PCH_SATA_CC_SCC_RAID) {
+ ///
+ /// Default MAX port number
+ ///
+ SataPrivateData->IdeInit.ChannelCount = PCH_AHCI_MAX_PORTS;
+ }
+ ///
+ /// Install IDE_CONTROLLER_INIT protocol & private data to this instance
+ ///
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Controller,
+ &gSataControllerDriverGuid,
+ SataPrivateData,
+ &gEfiIdeControllerInitProtocolGuid,
+ &(SataPrivateData->IdeInit),
+ NULL
+ );
+
+Done:
+
+ if (EFI_ERROR (Status)) {
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ if (SataPrivateData != NULL) {
+ FreePool (SataPrivateData);
+ }
+ }
+
+ DEBUG ((EFI_D_INFO, "SataControllerStart() End\n"));
+
+ return Status;
+}
+
+/**
+ Stop managing the target device
+
+ @param[in] This A pointer pointing to the Binding Protocol instance
+ @param[in] Controller The handle of controller to be stopped
+ @param[in] NumberOfChildren Number of child devices
+ @param[in] ChildHandleBuffer Buffer holding child device handles
+
+ @retval EFI_SUCCESS The target device is stopped
+**/
+EFI_STATUS
+EFIAPI
+SataControllerStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+{
+ EFI_STATUS Status;
+ EFI_SATA_CONTROLLER_PRIVATE_DATA *SataPrivateData;
+
+ DEBUG ((EFI_D_INFO, "SataControllerStop() Start\n"));
+
+ ///
+ /// Get private data
+ ///
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gSataControllerDriverGuid,
+ (VOID **) &SataPrivateData,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ if (!EFI_ERROR (Status)) {
+ gBS->UninstallMultipleProtocolInterfaces (
+ Controller,
+ &gSataControllerDriverGuid,
+ SataPrivateData,
+ &gEfiIdeControllerInitProtocolGuid,
+ &(SataPrivateData->IdeInit),
+ NULL
+ );
+ }
+ ///
+ /// Close protocols opened by SATA controller driver
+ ///
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ if (SataPrivateData != NULL) {
+ FreePool (SataPrivateData);
+ }
+
+ DEBUG ((EFI_D_INFO, "SataControllerStop() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+//
+// Interface functions of IDE_CONTROLLER_INIT protocol
+//
+
+/**
+ This function can be used to obtain information about a specified channel.
+ It's usually used by IDE Bus driver during enumeration process.
+
+ @param[in] This the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+ @param[in] Channel Channel number (0 based, either 0 or 1)
+ @param[out] Enabled TRUE if the channel is enabled. If the channel is disabled,
+ then it will no be enumerated.
+ @param[out] MaxDevices The Max number of IDE devices that the bus driver can expect
+ on this channel. For ATA/ATAPI, this number is either 1 or 2.
+
+ @retval EFI_SUCCESS Function completes successfully
+ @retval Other Values Something error happened
+ @retval EFI_INVALID_PARAMETER The Channel parameter is invalid
+**/
+EFI_STATUS
+EFIAPI
+IdeInitGetChannelInfo (
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
+ IN UINT8 Channel,
+ OUT BOOLEAN *Enabled,
+ OUT UINT8 *MaxDevices
+ )
+{
+ ///
+ /// Channel number (0 based, either 0 or 1)
+ ///
+ EFI_SATA_CONTROLLER_PRIVATE_DATA *SataPrivateData;
+
+ SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
+ ASSERT (SataPrivateData);
+
+ if (Channel < This->ChannelCount) {
+ *Enabled = TRUE;
+ *MaxDevices = PCH_IDE_MAX_DEVICES;
+ return EFI_SUCCESS;
+ } else {
+ *Enabled = FALSE;
+ return EFI_INVALID_PARAMETER;
+ }
+}
+
+/**
+ This function is called by IdeBus driver before executing certain actions.
+ This allows IDE Controller Init to prepare for each action.
+
+ @param[in] This the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+ @param[in] Phase phase indicator defined by IDE_CONTROLLER_INIT protocol
+ @param[in] Channel Channel number (0 based, either 0 or 1)
+
+ @retval EFI_SUCCESS Function completes successfully
+ @retval EFI_INVALID_PARAMETER Channel parameter is out of range
+ @exception EFI_UNSUPPORTED Phase is not supported
+**/
+EFI_STATUS
+EFIAPI
+IdeInitNotifyPhase (
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
+ IN EFI_IDE_CONTROLLER_ENUM_PHASE Phase,
+ IN UINT8 Channel
+ )
+{
+ if (Channel >= This->ChannelCount) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (Phase) {
+
+ case EfiIdeBeforeChannelEnumeration:
+ case EfiIdeAfterChannelEnumeration:
+ case EfiIdeBeforeChannelReset:
+ case EfiIdeAfterChannelReset:
+ case EfiIdeBusBeforeDevicePresenceDetection:
+ case EfiIdeBusAfterDevicePresenceDetection:
+ case EfiIdeResetMode:
+ ///
+ /// Do nothing at present
+ ///
+ break;
+
+ default:
+ return EFI_UNSUPPORTED;
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function is called by IdeBus driver to submit EFI_IDENTIFY_DATA data structure
+ obtained from IDE deivce. This structure is used to set IDE timing
+
+ @param[in] This the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+ @param[in] Channel IDE channel number (0 based, either 0 or 1)
+ @param[in] Device IDE device number
+ @param[in] IdentifyData A pointer to EFI_IDENTIFY_DATA data structure
+
+ @retval EFI_SUCCESS Function completes successfully
+ @retval EFI_INVALID_PARAMETER Channel or Device parameter is out of range
+**/
+EFI_STATUS
+EFIAPI
+IdeInitSubmitData (
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
+ IN UINT8 Channel,
+ IN UINT8 Device,
+ IN EFI_IDENTIFY_DATA *IdentifyData
+ )
+{
+ EFI_SATA_CONTROLLER_PRIVATE_DATA *SataPrivateData;
+ SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
+ ASSERT (SataPrivateData);
+
+ if ((Channel >= This->ChannelCount) || (Device >= PCH_IDE_MAX_DEVICES)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ ///
+ /// Make a local copy of device's IdentifyData and mark the valid flag
+ ///
+ if (IdentifyData != NULL) {
+ CopyMem (
+ &(SataPrivateData->IdentifyData[Channel][Device]),
+ IdentifyData,
+ sizeof (EFI_IDENTIFY_DATA)
+ );
+
+ SataPrivateData->IdentifyValid[Channel][Device] = TRUE;
+ } else {
+ SataPrivateData->IdentifyValid[Channel][Device] = FALSE;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function is called by IdeBus driver to disqualify unsupported operation
+ mode on specfic IDE device
+
+ @param[in] This The EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+ @param[in] Channel IDE channel number (0 based, either 0 or 1)
+ @param[in] Device IDE device number
+ @param[in] BadModes Operation mode indicator
+
+ @retval EFI_SUCCESS Function completes successfully
+ @retval EFI_INVALID_PARAMETER Channel parameter or Devicde parameter is out of range,
+ or BadModes is NULL
+**/
+EFI_STATUS
+EFIAPI
+IdeInitDisqualifyMode (
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
+ IN UINT8 Channel,
+ IN UINT8 Device,
+ IN EFI_ATA_COLLECTIVE_MODE *BadModes
+ )
+{
+ EFI_SATA_CONTROLLER_PRIVATE_DATA *SataPrivateData;
+ SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
+ ASSERT (SataPrivateData);
+
+ if ((Channel >= This->ChannelCount) || (BadModes == NULL) || (Device >= PCH_IDE_MAX_DEVICES)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ ///
+ /// Record the disqualified modes per channel per device. From ATA/ATAPI spec,
+ /// if a mode is not supported, the modes higher than it is also not
+ /// supported
+ ///
+ CopyMem (
+ &(SataPrivateData->DisqulifiedModes[Channel][Device]),
+ BadModes,
+ sizeof (EFI_ATA_COLLECTIVE_MODE)
+ );
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function is called by IdeBus driver to calculate the best operation mode
+ supported by specific IDE device
+
+ @param[in] This The EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+ @param[in] Channel IDE channel number (0 based, either 0 or 1)
+ @param[in] Device IDE device number
+ @param[in,out] SupportedModes Modes collection supported by IDE device
+
+ @retval EFI_SUCCESS Function completes successfully
+ @retval EFI_INVALID_PARAMETER Channel parameter or Device parameter is out of range;
+ Or SupportedModes is NULL
+ @retval EFI_NOT_READY Identify data is not valid
+ @retval EFI_OUT_OF_RESOURCES SupportedModes is out of range
+**/
+EFI_STATUS
+EFIAPI
+IdeInitCalculateMode (
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
+ IN UINT8 Channel,
+ IN UINT8 Device,
+ IN OUT EFI_ATA_COLLECTIVE_MODE **SupportedModes
+ )
+{
+ EFI_SATA_CONTROLLER_PRIVATE_DATA *SataPrivateData;
+ EFI_IDENTIFY_DATA *IdentifyData;
+ BOOLEAN IdentifyValid;
+ EFI_ATA_COLLECTIVE_MODE *DisqulifiedModes;
+ UINT16 SelectedMode;
+ EFI_STATUS Status;
+
+ SataPrivateData = SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS (This);
+ ASSERT (SataPrivateData);
+
+ if ((Channel >= This->ChannelCount) || (SupportedModes == NULL) || (Device >= PCH_IDE_MAX_DEVICES)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ IdentifyData = &(SataPrivateData->IdentifyData[Channel][Device]);
+ DisqulifiedModes = &(SataPrivateData->DisqulifiedModes[Channel][Device]);
+ IdentifyValid = SataPrivateData->IdentifyValid[Channel][Device];
+
+ ///
+ /// Make sure we've got the valid identify data of the device from SubmitData()
+ ///
+ if (!IdentifyValid) {
+ return EFI_NOT_READY;
+ }
+
+ *SupportedModes = AllocateZeroPool (sizeof (EFI_ATA_COLLECTIVE_MODE));
+ if (*SupportedModes == NULL) {
+ ASSERT (FALSE);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = CalculateBestPioMode (
+ IdentifyData,
+ (DisqulifiedModes->PioMode.Valid ? ((UINT16 *) &(DisqulifiedModes->PioMode.Mode)) : NULL),
+ &SelectedMode
+ );
+ if (!EFI_ERROR (Status)) {
+ (*SupportedModes)->PioMode.Valid = TRUE;
+ (*SupportedModes)->PioMode.Mode = SelectedMode;
+
+ } else {
+ (*SupportedModes)->PioMode.Valid = FALSE;
+ }
+
+ Status = CalculateBestUdmaMode (
+ IdentifyData,
+ (DisqulifiedModes->UdmaMode.Valid ? ((UINT16 *) &(DisqulifiedModes->UdmaMode.Mode)) : NULL),
+ &SelectedMode
+ );
+
+ if (!EFI_ERROR (Status)) {
+ (*SupportedModes)->UdmaMode.Valid = TRUE;
+ (*SupportedModes)->UdmaMode.Mode = SelectedMode;
+
+ } else {
+ (*SupportedModes)->UdmaMode.Valid = FALSE;
+ }
+ ///
+ /// The modes other than PIO and UDMA are not supported by SATA controller
+ ///
+ return EFI_SUCCESS;
+}
+
+/**
+ This function is called by IdeBus driver to set appropriate timing on IDE
+ controller according supported operation mode
+
+ @param[in] This The EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+ @param[in] Channel IDE channel number (0 based, either 0 or 1)
+ @param[in] Device IDE device number
+ @param[in] Modes Operation modes
+
+ @retval EFI_SUCCESS This function always returns EFI_SUCCESS
+**/
+EFI_STATUS
+EFIAPI
+IdeInitSetTiming (
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
+ IN UINT8 Channel,
+ IN UINT8 Device,
+ IN EFI_ATA_COLLECTIVE_MODE *Modes
+ )
+{
+ return EFI_SUCCESS;
+}
+
+/**
+ This function is used to calculate the best PIO mode supported by
+ specific IDE device
+
+ @param[in] IdentifyData The identify data of specific IDE device
+ @param[in] DisPioMode Disqualified PIO modes collection
+ @param[out] SelectedMode Available PIO modes collection
+
+ @retval EFI_SUCCESS Function completes successfully
+ @exception EFI_UNSUPPORTED Some invalid condition
+**/
+EFI_STATUS
+CalculateBestPioMode (
+ IN EFI_IDENTIFY_DATA * IdentifyData,
+ IN UINT16 *DisPioMode OPTIONAL,
+ OUT UINT16 *SelectedMode
+ )
+{
+ UINT16 PioMode;
+ UINT16 AdvancedPioMode;
+ UINT16 Temp;
+ UINT16 Index;
+ UINT16 MinimumPioCycleTime;
+
+ Temp = 0xff;
+
+ PioMode = (UINT8) (IdentifyData->AtaData.obsolete_51_52[0] >> 8);
+
+ ///
+ /// see whether Identify Data word 64 - 70 are valid
+ ///
+ if ((IdentifyData->AtaData.field_validity & 0x02) == 0x02) {
+
+ AdvancedPioMode = IdentifyData->AtaData.advanced_pio_modes;
+
+ for (Index = 0; Index < 8; Index++) {
+ if ((AdvancedPioMode & 0x01) != 0) {
+ Temp = Index;
+ }
+
+ AdvancedPioMode >>= 1;
+ }
+ ///
+ /// if Temp is modified, meant the advanced_pio_modes is not zero;
+ /// if Temp is not modified, meant the no advanced PIO Mode is supported,
+ /// the best PIO Mode is the value in pio_cycle_timing.
+ ///
+ if (Temp != 0xff) {
+ AdvancedPioMode = (UINT16) (Temp + 3);
+ } else {
+ AdvancedPioMode = PioMode;
+ }
+ ///
+ /// Limit the PIO mode to at most PIO4.
+ ///
+ PioMode = (UINT16) (AdvancedPioMode < 4 ? AdvancedPioMode : 4);
+
+ MinimumPioCycleTime = IdentifyData->AtaData.min_pio_cycle_time_with_flow_control;
+
+ if (MinimumPioCycleTime <= 120) {
+ PioMode = (UINT16) (4 < PioMode ? 4 : PioMode);
+ } else if (MinimumPioCycleTime <= 180) {
+ PioMode = (UINT16) (3 < PioMode ? 3 : PioMode);
+ } else if (MinimumPioCycleTime <= 240) {
+ PioMode = (UINT16) (2 < PioMode ? 2 : PioMode);
+ } else {
+ PioMode = 0;
+ }
+ ///
+ /// Degrade the PIO mode if the mode has been disqualified
+ ///
+ if (DisPioMode != NULL) {
+
+ if (*DisPioMode < 2) {
+ return EFI_UNSUPPORTED;
+ ///
+ /// no mode below ATA_PIO_MODE_BELOW_2
+ ///
+ }
+
+ if (PioMode >= *DisPioMode) {
+ PioMode = (UINT16) (*DisPioMode - 1);
+ }
+ }
+
+ if (PioMode < 2) {
+ *SelectedMode = 1;
+ ///
+ /// ATA_PIO_MODE_BELOW_2;
+ ///
+ } else {
+ *SelectedMode = PioMode;
+ ///
+ /// ATA_PIO_MODE_2 to ATA_PIO_MODE_4;
+ ///
+ }
+
+ } else {
+ ///
+ /// Identify Data word 64 - 70 are not valid
+ /// Degrade the PIO mode if the mode has been disqualified
+ ///
+ if (DisPioMode != NULL) {
+
+ if (*DisPioMode < 2) {
+ return EFI_UNSUPPORTED;
+ ///
+ /// no mode below ATA_PIO_MODE_BELOW_2
+ ///
+ }
+
+ if (PioMode == *DisPioMode) {
+ PioMode--;
+ }
+ }
+
+ if (PioMode < 2) {
+ *SelectedMode = 1;
+ ///
+ /// ATA_PIO_MODE_BELOW_2;
+ ///
+ } else {
+ *SelectedMode = 2;
+ ///
+ /// ATA_PIO_MODE_2;
+ ///
+ }
+
+ }
+
+ DEBUG ((EFI_D_ERROR, "CalculateBestPioMode() End\n"));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function is used to calculate the best UDMA mode supported by
+ specific IDE device
+
+ @param[in] IdentifyData The identify data of specific IDE device
+ @param[in] DisUDmaMode Disqualified UDMA modes collection
+ @param[out] SelectedMode Available UMDA modes collection
+
+ @retval EFI_SUCCESS Function completes successfully
+ @exception EFI_UNSUPPORTED Some invalid condition
+**/
+EFI_STATUS
+CalculateBestUdmaMode (
+ IN EFI_IDENTIFY_DATA * IdentifyData,
+ IN UINT16 *DisUDmaMode OPTIONAL,
+ OUT UINT16 *SelectedMode
+ )
+{
+ UINT16 TempMode;
+ UINT16 DeviceUDmaMode;
+
+ DeviceUDmaMode = 0;
+ ///
+ /// flag for 'Udma mode is not supported'
+ ///
+ /// Check whether the WORD 88 (supported UltraDMA by drive) is valid
+ ///
+ if ((IdentifyData->AtaData.field_validity & 0x04) == 0x00) {
+ return EFI_UNSUPPORTED;
+ }
+
+ DeviceUDmaMode = IdentifyData->AtaData.ultra_dma_mode;
+ DeviceUDmaMode &= 0x3f;
+ TempMode = 0;
+ ///
+ /// initialize it to UDMA-0
+ ///
+ while ((DeviceUDmaMode >>= 1) != 0) {
+ TempMode++;
+ }
+ ///
+ /// Degrade the UDMA mode if the mode has been disqualified
+ ///
+ if (DisUDmaMode != NULL) {
+ if (*DisUDmaMode == 0) {
+ *SelectedMode = 0;
+ return EFI_UNSUPPORTED;
+ ///
+ /// no mode below ATA_UDMA_MODE_0
+ ///
+ }
+
+ if (TempMode >= *DisUDmaMode) {
+ TempMode = (UINT16) (*DisUDmaMode - 1);
+ }
+ }
+ ///
+ /// Possible returned mode is between ATA_UDMA_MODE_0 and ATA_UDMA_MODE_5
+ ///
+ *SelectedMode = TempMode;
+
+ return EFI_SUCCESS;
+}
diff --git a/ChvRefCodePkg/CherryViewSoc/SouthCluster/SataController/Dxe/SataController.h b/ChvRefCodePkg/CherryViewSoc/SouthCluster/SataController/Dxe/SataController.h
new file mode 100644
index 0000000000..38c5299573
--- /dev/null
+++ b/ChvRefCodePkg/CherryViewSoc/SouthCluster/SataController/Dxe/SataController.h
@@ -0,0 +1,293 @@
+/** @file
+ Header file for chipset Serial ATA controller driver.
+
+ Copyright (c) 1999 - 2015, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _SERIAL_ATA_CONTROLLER_H_
+#define _SERIAL_ATA_CONTROLLER_H_
+
+#include <IndustryStandard/Pci22.h>
+#include <PchAccess.h>
+#include <Protocol/IdeControllerInit.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/DriverBinding.h>
+#include <Protocol/ComponentName2.h>
+#include <Guid/SataControllerGuid.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+#include <Uefi/UefiBaseType.h>
+
+//
+// Global Variables definitions
+//
+extern EFI_DRIVER_BINDING_PROTOCOL mSataControllerDriverBinding;
+extern EFI_COMPONENT_NAME2_PROTOCOL mSataControllerName;
+
+#define PCH_SATA_ENUMER_ALL FALSE
+
+#define PCH_SATA_MASTER_DRIVE 0x00
+#define PCH_SATA_SLAVE_DRIVE 0x01
+
+///
+/// SATA controller driver private data structure
+///
+#define SATA_CONTROLLER_SIGNATURE SIGNATURE_32 ('S', 'A', 'T', 'A')
+
+typedef struct _EFI_SATA_CONTROLLER_PRIVATE_DATA {
+ ///
+ /// Standard signature used to identify SATA controller private data
+ ///
+ UINT32 Signature;
+
+ ///
+ /// Protocol instance of IDE_CONTROLLER_INIT produced by this driver
+ ///
+ EFI_IDE_CONTROLLER_INIT_PROTOCOL IdeInit;
+
+ ///
+ /// copy of protocol pointers used by this driver
+ ///
+ EFI_PCI_IO_PROTOCOL *PciIo;
+
+ ///
+ /// The highest disqulified mode for each attached SATA device.
+ /// Per ATA/ATAPI spec, if a mode is not supported, the modes higher than
+ /// it should not be supported
+ ///
+ EFI_ATA_COLLECTIVE_MODE DisqulifiedModes[PCH_AHCI_MAX_PORTS][PCH_SATA_MAX_DEVICES];
+
+ ///
+ /// A copy of IDENTIFY data for each attached SATA device and its flag
+ ///
+ EFI_IDENTIFY_DATA IdentifyData[PCH_AHCI_MAX_PORTS][PCH_SATA_MAX_DEVICES];
+ BOOLEAN IdentifyValid[PCH_AHCI_MAX_PORTS][PCH_SATA_MAX_DEVICES];
+} EFI_SATA_CONTROLLER_PRIVATE_DATA;
+
+#define SATA_CONTROLLER_PRIVATE_DATA_FROM_THIS(a) \
+ CR ( \
+ a, \
+ EFI_SATA_CONTROLLER_PRIVATE_DATA, \
+ IdeInit, \
+ SATA_CONTROLLER_SIGNATURE \
+ )
+
+//
+// Driver binding functions declaration
+//
+
+/**
+ This function checks to see if the driver supports a device specified by
+ "Controller handle" parameter. It is called by DXE Core StartImage() or
+ ConnectController() routines. The driver uses 'device path' and/or
+ 'services' from the Bus I/O abstraction attached to the controller handle
+ to determine if the driver support this controller handle.
+ Note: In the BDS (Boot Device Selection) phase, the DXE core enumerate all
+ devices (or, controller) and assigns GUIDs to them.
+
+ @param[in] This A pointer points to the Binding Protocol instance
+ @param[in] Controller The handle of controller to be tested.
+ @param[in] RemainingDevicePath A pointer to the device path. Ignored by device
+ driver but used by bus driver
+
+ @retval EFI_SUCCESS The device is supported
+ @exception EFI_UNSUPPORTED The device is not supported
+**/
+EFI_STATUS
+EFIAPI
+SataControllerSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+/**
+ This routine is called right after the .Supported() is called and returns
+ EFI_SUCCESS. Notes: The supported protocols are checked but the Protocols
+ are closed.
+
+ @param[in] This A pointer points to the Binding Protocol instance
+ @param[in] Controller The handle of controller to be tested. Parameter
+ passed by the caller
+ @param[in] RemainingDevicePath A pointer to the device path. Should be ignored by
+ device driver
+
+ @retval EFI_SUCCESS The device is started
+ @retval Other values Something error happened
+**/
+EFI_STATUS
+EFIAPI
+SataControllerStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+/**
+ Stop managing the target device
+
+ @param[in] This A pointer pointing to the Binding Protocol instance
+ @param[in] Controller The handle of controller to be stopped
+ @param[in] NumberOfChildren Number of child devices
+ @param[in] ChildHandleBuffer Buffer holding child device handles
+
+ @retval EFI_SUCCESS The target device is stopped
+**/
+EFI_STATUS
+EFIAPI
+SataControllerStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+//
+// IDE controller init functions declaration
+//
+
+/**
+ This function can be used to obtain information about a specified channel.
+ It's usually used by IDE Bus driver during enumeration process.
+
+ @param[in] This the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+ @param[in] Channel Channel number (0 based, either 0 or 1)
+ @param[out] Enabled TRUE if the channel is enabled. If the channel is disabled,
+ then it will no be enumerated.
+ @param[out] MaxDevices The Max number of IDE devices that the bus driver can expect
+ on this channel. For ATA/ATAPI, this number is either 1 or 2.
+
+ @retval EFI_SUCCESS Function completes successfully
+ @retval Other Values Something error happened
+ @retval EFI_INVALID_PARAMETER The Channel parameter is invalid
+**/
+EFI_STATUS
+EFIAPI
+IdeInitGetChannelInfo (
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
+ IN UINT8 Channel,
+ OUT BOOLEAN *Enabled,
+ OUT UINT8 *MaxDevices
+ );
+
+/**
+ This function is called by IdeBus driver before executing certain actions.
+ This allows IDE Controller Init to prepare for each action.
+
+ @param[in] This the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+ @param[in] Phase phase indicator defined by IDE_CONTROLLER_INIT protocol
+ @param[out] Channel Channel number (0 based, either 0 or 1)
+
+ @retval EFI_SUCCESS Function completes successfully
+ @retval EFI_INVALID_PARAMETER Channel parameter is out of range
+ @exception EFI_UNSUPPORTED Phase is not supported
+**/
+EFI_STATUS
+EFIAPI
+IdeInitNotifyPhase (
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
+ IN EFI_IDE_CONTROLLER_ENUM_PHASE Phase,
+ OUT UINT8 Channel
+ );
+
+/**
+ This function is called by IdeBus driver to submit EFI_IDENTIFY_DATA data structure
+ obtained from IDE deivce. This structure is used to set IDE timing
+
+ @param[in] This the EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+ @param[in] Channel IDE channel number (0 based, either 0 or 1)
+ @param[in] Device IDE device number
+ @param[in] IdentifyData A pointer to EFI_IDENTIFY_DATA data structure
+
+ @retval EFI_SUCCESS Function completes successfully
+ @retval EFI_INVALID_PARAMETER Channel or Device parameter is out of range
+**/
+EFI_STATUS
+EFIAPI
+IdeInitSubmitData (
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
+ IN UINT8 Channel,
+ IN UINT8 Device,
+ IN EFI_IDENTIFY_DATA *IdentifyData
+ );
+
+/**
+ This function is called by IdeBus driver to disqualify unsupported operation
+ mode on specfic IDE device
+
+ @param[in] This The EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+ @param[in] Channel IDE channel number (0 based, either 0 or 1)
+ @param[in] Device IDE device number
+ @param[in] BadModes Operation mode indicator
+
+ @retval EFI_SUCCESS Function completes successfully
+ @retval EFI_INVALID_PARAMETER Channel parameter or Devicde parameter is out of range,
+ or BadModes is NULL
+**/
+EFI_STATUS
+EFIAPI
+IdeInitDisqualifyMode (
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
+ IN UINT8 Channel,
+ IN UINT8 Device,
+ IN EFI_ATA_COLLECTIVE_MODE *BadModes
+ );
+
+/**
+ This function is called by IdeBus driver to calculate the best operation mode
+ supported by specific IDE device
+
+ @param[in] This The EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+ @param[in] Channel IDE channel number (0 based, either 0 or 1)
+ @param[in] Device IDE device number
+ @param[in,out] SupportedModes Modes collection supported by IDE device
+
+ @retval EFI_SUCCESS Function completes successfully
+ @retval EFI_INVALID_PARAMETER Channel parameter or Device parameter is out of range;
+ Or SupportedModes is NULL
+ @retval EFI_NOT_READY Identify data is not valid
+ @retval EFI_OUT_OF_RESOURCES SupportedModes is out of range
+**/
+EFI_STATUS
+EFIAPI
+IdeInitCalculateMode (
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
+ IN UINT8 Channel,
+ IN UINT8 Device,
+ IN OUT EFI_ATA_COLLECTIVE_MODE **SupportedModes
+ );
+
+/**
+ This function is called by IdeBus driver to set appropriate timing on IDE
+ controller according supported operation mode
+
+ @param[in] This The EFI_IDE_CONTROLLER_INIT_PROTOCOL instance.
+ @param[in] Channel IDE channel number (0 based, either 0 or 1)
+ @param[in] Device IDE device number
+ @param[in] Modes Operation modes
+
+ @retval EFI_SUCCESS This function always returns EFI_SUCCESS
+**/
+EFI_STATUS
+EFIAPI
+IdeInitSetTiming (
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *This,
+ IN UINT8 Channel,
+ IN UINT8 Device,
+ IN EFI_ATA_COLLECTIVE_MODE *Modes
+ );
+
+#endif
diff --git a/ChvRefCodePkg/CherryViewSoc/SouthCluster/SataController/Dxe/SataController.inf b/ChvRefCodePkg/CherryViewSoc/SouthCluster/SataController/Dxe/SataController.inf
new file mode 100644
index 0000000000..ebc830a2d0
--- /dev/null
+++ b/ChvRefCodePkg/CherryViewSoc/SouthCluster/SataController/Dxe/SataController.inf
@@ -0,0 +1,57 @@
+## @file
+# PCH SATA Controller Dxe Module
+#
+# Provides initializations on PCH SATA controller.
+#
+# Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = SataController
+ FILE_GUID = FA08DF51-3A3E-439C-B44B-4BBFE5C677E1
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializeSataControllerDriver
+
+[Sources]
+ SataController.h
+ SataController.c
+ SataControllerName.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ ChvRefCodePkg/ChvRefCodePkg.dec
+
+[LibraryClasses]
+ UefiDriverEntryPoint
+ DebugLib
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ BaseMemoryLib
+ UefiLib
+
+[Protocols]
+ ## BY_START
+ gEfiIdeControllerInitProtocolGuid
+
+ ## TO_START
+ gEfiDevicePathProtocolGuid
+
+ ## TO_START
+ gEfiPciIoProtocolGuid
+
+[Guids]
+ ## PRODUCES
+ ## CONSUMES
+ gSataControllerDriverGuid
+
diff --git a/ChvRefCodePkg/CherryViewSoc/SouthCluster/SataController/Dxe/SataControllerName.c b/ChvRefCodePkg/CherryViewSoc/SouthCluster/SataController/Dxe/SataControllerName.c
new file mode 100644
index 0000000000..51b933c0d9
--- /dev/null
+++ b/ChvRefCodePkg/CherryViewSoc/SouthCluster/SataController/Dxe/SataControllerName.c
@@ -0,0 +1,168 @@
+/** @file
+ This portion is to register the Sata Controller Driver name:
+ "SATA Controller Init Driver"
+
+ Copyright (c) 1999 - 2015, Intel Corporation. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "SataController.h"
+
+///
+/// Forward reference declaration
+///
+EFI_STATUS
+EFIAPI
+SataControllerGetDriverName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+EFI_STATUS
+EFIAPI
+SataControllerGetControllerName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+///
+/// EFI Component Name Protocol
+/// This portion declares a gloabl variable of EFI_COMPONENT_NAME_PROTOCOL type.
+///
+EFI_COMPONENT_NAME2_PROTOCOL mSataControllerName = {
+ SataControllerGetDriverName,
+ SataControllerGetControllerName,
+ "eng"
+};
+
+///
+/// Define the Driver's unicode name string
+///
+static EFI_UNICODE_STRING_TABLE mSataControllerDriverNameTable[] = {
+ {
+ "eng;en",
+ L"PCH Serial ATA Controller Initialization Driver"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
+static EFI_UNICODE_STRING_TABLE mSataControllerControllerNameTable[] = {
+ {
+ "eng;en",
+ L"PCH Serial ATA Controller"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
+/**
+ Retrieves a Unicode string that is the user readable name of the EFI Driver.
+
+ @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param[in] Language A pointer to a three character ISO 639-2 language identifier.
+ This is the language of the driver name that that the caller
+ is requesting, and it must match one of the languages specified
+ in SupportedLanguages. The number of languages supported by a
+ driver is up to the driver writer.
+ @param[out] DriverName A pointer to the Unicode string to return. This Unicode string
+ is the name of the driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by This
+ and the language specified by Language was returned
+ in DriverName.
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+ @exception EFI_UNSUPPORTED The driver specified by This does not support the
+ language specified by Language.
+**/
+EFI_STATUS
+EFIAPI
+SataControllerGetDriverName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+
+ return LookupUnicodeString (
+ Language,
+ mSataControllerName.SupportedLanguages,
+ mSataControllerDriverNameTable,
+ DriverName
+ );
+}
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by an EFI Driver.
+
+ @param[in] This A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ @param[in] ControllerHandle The handle of a controller that the driver specified by
+ This is managing. This handle specifies the controller
+ whose name is to be returned.
+ @param[in] ChildHandle The handle of the child controller to retrieve the name
+ of. This is an optional parameter that may be NULL. It
+ will be NULL for device drivers. It will also be NULL
+ for a bus drivers that wish to retrieve the name of the
+ bus controller. It will not be NULL for a bus driver
+ that wishes to retrieve the name of a child controller.
+ @param[in] Language A pointer to a three character ISO 639-2 language
+ identifier. This is the language of the controller name
+ that that the caller is requesting, and it must match one
+ of the languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up to the
+ driver writer.
+ @param[out] 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.
+
+ @retval EFI_SUCCESS The Unicode string for the user readable name in the
+ language specified by Language for the driver
+ specified by This was returned in DriverName.
+ @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid EFI_HANDLE.
+ ChildHandle is not NULL and it is not a valid EFI_HANDLE.
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+ ControllerName is NULL.
+ @exception EFI_UNSUPPORTED The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+ The driver specified by This does not support the
+ language specified by Language.
+**/
+EFI_STATUS
+EFIAPI
+SataControllerGetControllerName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ return LookupUnicodeString (
+ Language,
+ mSataControllerName.SupportedLanguages,
+ mSataControllerControllerNameTable,
+ ControllerName
+ );
+}