cfgtable.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*++
  2. Copyright (c) 2014 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. cfgtable.c
  9. Abstract:
  10. This module implements the install configuration table UEFI service.
  11. Author:
  12. Evan Green 25-Mar-2014
  13. Environment:
  14. Firmware
  15. --*/
  16. //
  17. // ------------------------------------------------------------------- Includes
  18. //
  19. #include "ueficore.h"
  20. //
  21. // ---------------------------------------------------------------- Definitions
  22. //
  23. #define EFI_CONFIGURATION_TABLE_EXPANSION_SIZE 0x10
  24. //
  25. // ------------------------------------------------------ Data Type Definitions
  26. //
  27. //
  28. // ----------------------------------------------- Internal Function Prototypes
  29. //
  30. //
  31. // -------------------------------------------------------------------- Globals
  32. //
  33. //
  34. // Store the size of the configuration table array allocation.
  35. //
  36. UINTN EfiSystemTableAllocationSize = 0;
  37. //
  38. // ------------------------------------------------------------------ Functions
  39. //
  40. EFIAPI
  41. EFI_STATUS
  42. EfiCoreInstallConfigurationTable (
  43. EFI_GUID *Guid,
  44. VOID *Table
  45. )
  46. /*++
  47. Routine Description:
  48. This routine adds, updates, or removes a configuration table entry from the
  49. EFI System Table.
  50. Arguments:
  51. Guid - Supplies a pointer to the GUID for the entry to add, update, or
  52. remove.
  53. Table - Supplies a pointer to the configuration table for the entry to add,
  54. update, or remove. This may be NULL.
  55. Return Value:
  56. EFI_SUCCESS on success.
  57. EFI_NOT_FOUND if an attempt was made to delete a nonexistant entry.
  58. EFI_INVALID_PARAMETER if the GUID is NULL.
  59. EFI_OUT_OF_RESOURCES if an allocation failed.
  60. --*/
  61. {
  62. EFI_CONFIGURATION_TABLE *ConfigurationTable;
  63. UINTN Index;
  64. BOOLEAN Match;
  65. UINTN NewSize;
  66. UINTN RemainderSize;
  67. if (Guid == NULL) {
  68. return EFI_INVALID_PARAMETER;
  69. }
  70. ConfigurationTable = EfiSystemTable->ConfigurationTable;
  71. //
  72. // Search all the tables for an entry that matches this one.
  73. //
  74. for (Index = 0; Index < EfiSystemTable->NumberOfTableEntries; Index += 1) {
  75. Match = EfiCoreCompareGuids(
  76. Guid,
  77. &(EfiSystemTable->ConfigurationTable[Index].VendorGuid));
  78. if (Match != FALSE) {
  79. break;
  80. }
  81. }
  82. //
  83. // If a match was found, then this is either a modify or a delete operation.
  84. //
  85. if (Index < EfiSystemTable->NumberOfTableEntries) {
  86. if (Table != NULL) {
  87. EfiSystemTable->ConfigurationTable[Index].VendorTable = Table;
  88. //
  89. // Signal a configuration table change.
  90. //
  91. EfipCoreNotifySignalList(Guid);
  92. return EFI_SUCCESS;
  93. }
  94. EfiSystemTable->NumberOfTableEntries -= 1;
  95. RemainderSize = (EfiSystemTable->NumberOfTableEntries - Index) *
  96. sizeof(EFI_CONFIGURATION_TABLE);
  97. EfiCopyMem(&(ConfigurationTable[Index]),
  98. &(EfiSystemTable->ConfigurationTable[Index + 1]),
  99. RemainderSize);
  100. //
  101. // No matching GUID was found, this is an add operation.
  102. //
  103. } else {
  104. if (Table == NULL) {
  105. return EFI_NOT_FOUND;
  106. }
  107. Index = EfiSystemTable->NumberOfTableEntries;
  108. if ((Index * sizeof(EFI_CONFIGURATION_TABLE)) >=
  109. EfiSystemTableAllocationSize) {
  110. NewSize = EfiSystemTableAllocationSize +
  111. (EFI_CONFIGURATION_TABLE_EXPANSION_SIZE *
  112. sizeof(EFI_CONFIGURATION_TABLE));
  113. ConfigurationTable = EfiCoreAllocateRuntimePool(NewSize);
  114. if (ConfigurationTable == NULL) {
  115. return EFI_OUT_OF_RESOURCES;
  116. }
  117. if (EfiSystemTable->ConfigurationTable != NULL) {
  118. ASSERT(EfiSystemTableAllocationSize != 0);
  119. EfiCopyMem(ConfigurationTable,
  120. EfiSystemTable->ConfigurationTable,
  121. Index * sizeof(EFI_CONFIGURATION_TABLE));
  122. EfiFreePool(EfiSystemTable->ConfigurationTable);
  123. }
  124. EfiSystemTable->ConfigurationTable = ConfigurationTable;
  125. EfiSystemTableAllocationSize = NewSize;
  126. }
  127. //
  128. // Fill in the new entry.
  129. //
  130. EfiCopyMem(&(ConfigurationTable[Index].VendorGuid),
  131. Guid,
  132. sizeof(EFI_GUID));
  133. ConfigurationTable[Index].VendorTable = Table;
  134. EfiSystemTable->NumberOfTableEntries += 1;
  135. }
  136. EfiCoreCalculateTableCrc32(&(EfiSystemTable->Hdr));
  137. EfipCoreNotifySignalList(Guid);
  138. return EFI_SUCCESS;
  139. }
  140. //
  141. // --------------------------------------------------------- Internal Functions
  142. //