EfiRegTableLib.c 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. /*++
  2. Copyright (c) 1999 - 2019, Intel Corporation. All rights reserved
  3. SPDX-License-Identifier: BSD-2-Clause-Patent
  4. Module Name:
  5. EfiRegTableLib.c
  6. Abstract:
  7. Lib function for table driven register initialization.
  8. Revision History
  9. --*/
  10. #include <Library/EfiRegTableLib.h>
  11. #include <Library/S3BootScriptLib.h>
  12. //
  13. // Local Functions
  14. //
  15. /**
  16. Local worker function to process PCI_WRITE table entries. Performs write and
  17. may also call BootScriptSave protocol if indicated in the Entry flags
  18. @param Entry A pointer to the PCI_WRITE entry to process
  19. @param PciRootBridgeIo A pointer to the instance of PciRootBridgeIo that is used
  20. when processing the entry.
  21. @retval Nothing.
  22. **/
  23. STATIC
  24. VOID
  25. PciWrite (
  26. EFI_REG_TABLE_PCI_WRITE *Entry,
  27. EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo
  28. )
  29. {
  30. EFI_STATUS Status;
  31. Status = PciRootBridgeIo->Pci.Write (
  32. PciRootBridgeIo,
  33. (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
  34. (UINT64) Entry->PciAddress,
  35. 1,
  36. &Entry->Data
  37. );
  38. ASSERT_EFI_ERROR (Status);
  39. if (OPCODE_FLAGS (Entry->OpCode) & OPCODE_FLAG_S3SAVE) {
  40. Status = S3BootScriptSavePciCfgWrite (
  41. (EFI_BOOT_SCRIPT_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
  42. (UINT64) Entry->PciAddress,
  43. 1,
  44. &Entry->Data
  45. );
  46. ASSERT_EFI_ERROR (Status);
  47. }
  48. }
  49. /**
  50. Local worker function to process PCI_READ_MODIFY_WRITE table entries.
  51. Performs RMW write and may also call BootScriptSave protocol if indicated in
  52. the Entry flags.
  53. @param Entry A pointer to the PCI_READ_MODIFY_WRITE entry to process.
  54. @param PciRootBridgeIo A pointer to the instance of PciRootBridgeIo that is used
  55. when processing the entry.
  56. @retval Nothing.
  57. **/
  58. STATIC
  59. VOID
  60. PciReadModifyWrite (
  61. EFI_REG_TABLE_PCI_READ_MODIFY_WRITE *Entry,
  62. EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo
  63. )
  64. {
  65. EFI_STATUS Status;
  66. UINT32 TempData;
  67. Status = PciRootBridgeIo->Pci.Read (
  68. PciRootBridgeIo,
  69. (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
  70. (UINT64) Entry->PciAddress,
  71. 1,
  72. &TempData
  73. );
  74. ASSERT_EFI_ERROR (Status);
  75. Entry->OrMask &= Entry->AndMask;
  76. TempData &= ~Entry->AndMask;
  77. TempData |= Entry->OrMask;
  78. Status = PciRootBridgeIo->Pci.Write (
  79. PciRootBridgeIo,
  80. (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
  81. (UINT64) Entry->PciAddress,
  82. 1,
  83. &TempData
  84. );
  85. ASSERT_EFI_ERROR (Status);
  86. if (OPCODE_FLAGS (Entry->OpCode) & OPCODE_FLAG_S3SAVE) {
  87. Status = S3BootScriptSavePciCfgReadWrite (
  88. (EFI_BOOT_SCRIPT_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
  89. (UINT64) Entry->PciAddress,
  90. &Entry->OrMask,
  91. &Entry->AndMask
  92. );
  93. ASSERT_EFI_ERROR (Status);
  94. }
  95. }
  96. /**
  97. Local worker function to process MEM_READ_MODIFY_WRITE table entries.
  98. Performs RMW write and may also call BootScriptSave protocol if indicated in
  99. the Entry flags.
  100. @param Entry A pointer to the MEM_READ_MODIFY_WRITE entry to process.
  101. @param PciRootBridgeIo A pointer to the instance of PciRootBridgeIo that is used
  102. when processing the entry.
  103. @retval Nothing.
  104. **/
  105. STATIC
  106. VOID
  107. MemReadModifyWrite (
  108. EFI_REG_TABLE_MEM_READ_MODIFY_WRITE *Entry,
  109. EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo
  110. )
  111. {
  112. EFI_STATUS Status;
  113. UINT32 TempData;
  114. Status = PciRootBridgeIo->Mem.Read (
  115. PciRootBridgeIo,
  116. (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
  117. (UINT64) Entry->MemAddress,
  118. 1,
  119. &TempData
  120. );
  121. ASSERT_EFI_ERROR (Status);
  122. Entry->OrMask &= Entry->AndMask;
  123. TempData &= ~Entry->AndMask;
  124. TempData |= Entry->OrMask;
  125. Status = PciRootBridgeIo->Mem.Write (
  126. PciRootBridgeIo,
  127. (EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
  128. (UINT64) Entry->MemAddress,
  129. 1,
  130. &TempData
  131. );
  132. ASSERT_EFI_ERROR (Status);
  133. if (OPCODE_FLAGS (Entry->OpCode) & OPCODE_FLAG_S3SAVE) {
  134. Status = S3BootScriptSaveMemReadWrite (
  135. (EFI_BOOT_SCRIPT_WIDTH) (OPCODE_EXTRA_DATA (Entry->OpCode)),
  136. Entry->MemAddress,
  137. &Entry->OrMask,
  138. &Entry->AndMask
  139. );
  140. ASSERT_EFI_ERROR (Status);
  141. }
  142. }
  143. //
  144. // Exported functions
  145. //
  146. /**
  147. Processes register table assuming which may contain PCI, IO, MEM, and STALL
  148. entries.
  149. No parameter checking is done so the caller must be careful about omitting
  150. values for PciRootBridgeIo parameters. If the regtable does
  151. not contain any PCI accesses, it is safe to omit the PciRootBridgeIo (supply
  152. NULL).
  153. The RegTableEntry parameter is not checked, but is required.
  154. gBS is assumed to have been defined and is used when processing stalls.
  155. The function processes each entry sequentially until an OP_TERMINATE_TABLE
  156. entry is encountered.
  157. @param RegTableEntry A pointer to the register table to process
  158. @param PciRootBridgeIo A pointer to the instance of PciRootBridgeIo that is used
  159. when processing PCI table entries
  160. @retval Nothing.
  161. **/
  162. VOID
  163. ProcessRegTablePci (
  164. EFI_REG_TABLE *RegTableEntry,
  165. EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo
  166. )
  167. {
  168. while (OPCODE_BASE (RegTableEntry->Generic.OpCode) != OP_TERMINATE_TABLE) {
  169. switch (OPCODE_BASE (RegTableEntry->Generic.OpCode)) {
  170. case OP_PCI_WRITE:
  171. PciWrite ((EFI_REG_TABLE_PCI_WRITE *) RegTableEntry, PciRootBridgeIo);
  172. break;
  173. case OP_PCI_READ_MODIFY_WRITE:
  174. PciReadModifyWrite ((EFI_REG_TABLE_PCI_READ_MODIFY_WRITE *) RegTableEntry, PciRootBridgeIo);
  175. break;
  176. case OP_MEM_READ_MODIFY_WRITE:
  177. MemReadModifyWrite ((EFI_REG_TABLE_MEM_READ_MODIFY_WRITE *) RegTableEntry, PciRootBridgeIo);
  178. break;
  179. default:
  180. DEBUG ((EFI_D_ERROR, "RegTable ERROR: Unknown RegTable OpCode (%x)\n", OPCODE_BASE (RegTableEntry->Generic.OpCode)));
  181. ASSERT (0);
  182. break;
  183. }
  184. RegTableEntry++;
  185. }
  186. }