/** @file This driver module adds SATA controller support. Copyright 2017-2018, 2020 NXP SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #define SATA_PPCFG 0xA8 #define SATA_PTC 0xC8 #define SATA_PAXIC 0xC0 #define PORT_PHYSICAL 0xA003FFFE #define PORT_TRANSPORT 0x08000025 #define PORT_RXWM 0x08000029 #define ENABLE_NONZERO_4MB_PRD 0x10000000 /** This function gets registered as a callback to perform USB controller intialization @param Event Event whose notification function is being invoked. @param Context Pointer to the notification function's context. **/ STATIC VOID EFIAPI SataEndOfDxeCallback ( IN EFI_EVENT Event, IN VOID *Context ) { EFI_STATUS Status; UINT32 NumSataController; UINT32 Index; UINT32 Data; UINTN ControllerAddr; NumSataController = PcdGet32 (PcdNumSataController); for (Index = 0; Index < NumSataController; Index++) { ControllerAddr = PcdGet64 (PcdSataBaseAddr) + (Index * PcdGet32 (PcdSataSize)); // // configuring Physical Control Layer parameters for Port 0 // MmioWrite32 ((UINTN)(ControllerAddr + SATA_PPCFG), PORT_PHYSICAL); // // This register controls the configuration of the // Transport Layer for Port 0 // Errata Description : The default Rx watermark value may be insufficient // for some hard drives and result in a false CRC or internal errors. // Workaround: Change PTC[RXWM] field at offset 0xC8 to 0x29. Do not change // the other reserved fields of the register. // Data = MmioRead32 ((UINTN)(ControllerAddr + SATA_PTC)); if (PcdGetBool (PcdSataErratumA009185)) { Data |= PORT_RXWM; } else { Data |= PORT_TRANSPORT; } MmioWrite32 ((UINTN)(ControllerAddr + SATA_PTC), Data); // // Enable Non-Zero 4 MB PRD entries. // MmioOr32 ((UINTN)(ControllerAddr + SATA_PAXIC), ENABLE_NONZERO_4MB_PRD); Status = RegisterNonDiscoverableMmioDevice ( NonDiscoverableDeviceTypeAhci, NonDiscoverableDeviceDmaTypeNonCoherent, NULL, NULL, 1, ControllerAddr, PcdGet32 (PcdSataSize) ); if (EFI_ERROR (Status)) { DEBUG ((DEBUG_ERROR, "Failed to register SATA device 0x%x, error 0x%r \n", ControllerAddr, Status)); } } } /** The Entry Point of module. It follows the standard UEFI driver model. @param[in] ImageHandle The firmware allocated handle for the EFI image. @param[in] SystemTable A pointer to the EFI System Table. @retval EFI_SUCCESS The entry point is executed successfully. @retval Other Some error occurs when executing this entry point **/ EFI_STATUS EFIAPI InitializeSataController ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; EFI_EVENT EndOfDxeEvent; Status = gBS->CreateEventEx ( EVT_NOTIFY_SIGNAL, TPL_CALLBACK, SataEndOfDxeCallback, NULL, &gEfiEndOfDxeEventGroupGuid, &EndOfDxeEvent ); return Status; }