SataInit.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. /** @file
  2. This driver module adds SATA controller support.
  3. Copyright 2017-2018, 2020 NXP
  4. SPDX-License-Identifier: BSD-2-Clause-Patent
  5. **/
  6. #include <Library/DebugLib.h>
  7. #include <Library/IoLib.h>
  8. #include <Library/NonDiscoverableDeviceRegistrationLib.h>
  9. #include <Library/UefiBootServicesTableLib.h>
  10. #define SATA_PPCFG 0xA8
  11. #define SATA_PTC 0xC8
  12. #define SATA_PAXIC 0xC0
  13. #define PORT_PHYSICAL 0xA003FFFE
  14. #define PORT_TRANSPORT 0x08000025
  15. #define PORT_RXWM 0x08000029
  16. #define ENABLE_NONZERO_4MB_PRD 0x10000000
  17. /**
  18. This function gets registered as a callback to perform USB controller intialization
  19. @param Event Event whose notification function is being invoked.
  20. @param Context Pointer to the notification function's context.
  21. **/
  22. STATIC
  23. VOID
  24. EFIAPI
  25. SataEndOfDxeCallback (
  26. IN EFI_EVENT Event,
  27. IN VOID *Context
  28. )
  29. {
  30. EFI_STATUS Status;
  31. UINT32 NumSataController;
  32. UINT32 Index;
  33. UINT32 Data;
  34. UINTN ControllerAddr;
  35. NumSataController = PcdGet32 (PcdNumSataController);
  36. for (Index = 0; Index < NumSataController; Index++) {
  37. ControllerAddr = PcdGet64 (PcdSataBaseAddr) +
  38. (Index * PcdGet32 (PcdSataSize));
  39. //
  40. // configuring Physical Control Layer parameters for Port 0
  41. //
  42. MmioWrite32 ((UINTN)(ControllerAddr + SATA_PPCFG), PORT_PHYSICAL);
  43. //
  44. // This register controls the configuration of the
  45. // Transport Layer for Port 0
  46. // Errata Description : The default Rx watermark value may be insufficient
  47. // for some hard drives and result in a false CRC or internal errors.
  48. // Workaround: Change PTC[RXWM] field at offset 0xC8 to 0x29. Do not change
  49. // the other reserved fields of the register.
  50. //
  51. Data = MmioRead32 ((UINTN)(ControllerAddr + SATA_PTC));
  52. if (PcdGetBool (PcdSataErratumA009185)) {
  53. Data |= PORT_RXWM;
  54. } else {
  55. Data |= PORT_TRANSPORT;
  56. }
  57. MmioWrite32 ((UINTN)(ControllerAddr + SATA_PTC), Data);
  58. //
  59. // Enable Non-Zero 4 MB PRD entries.
  60. //
  61. MmioOr32 ((UINTN)(ControllerAddr + SATA_PAXIC), ENABLE_NONZERO_4MB_PRD);
  62. Status = RegisterNonDiscoverableMmioDevice (
  63. NonDiscoverableDeviceTypeAhci,
  64. NonDiscoverableDeviceDmaTypeNonCoherent,
  65. NULL,
  66. NULL,
  67. 1,
  68. ControllerAddr, PcdGet32 (PcdSataSize)
  69. );
  70. if (EFI_ERROR (Status)) {
  71. DEBUG ((DEBUG_ERROR, "Failed to register SATA device 0x%x, error 0x%r \n",
  72. ControllerAddr, Status));
  73. }
  74. }
  75. }
  76. /**
  77. The Entry Point of module. It follows the standard UEFI driver model.
  78. @param[in] ImageHandle The firmware allocated handle for the EFI image.
  79. @param[in] SystemTable A pointer to the EFI System Table.
  80. @retval EFI_SUCCESS The entry point is executed successfully.
  81. @retval Other Some error occurs when executing this entry point
  82. **/
  83. EFI_STATUS
  84. EFIAPI
  85. InitializeSataController (
  86. IN EFI_HANDLE ImageHandle,
  87. IN EFI_SYSTEM_TABLE *SystemTable
  88. )
  89. {
  90. EFI_STATUS Status;
  91. EFI_EVENT EndOfDxeEvent;
  92. Status = gBS->CreateEventEx (
  93. EVT_NOTIFY_SIGNAL,
  94. TPL_CALLBACK,
  95. SataEndOfDxeCallback,
  96. NULL,
  97. &gEfiEndOfDxeEventGroupGuid,
  98. &EndOfDxeEvent
  99. );
  100. return Status;
  101. }