+ FreePool (SourceBuffer);\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ SMM split SMRAM entry.\r
+\r
+ @param[in, out] RangeToCompare Pointer to EFI_SMRAM_DESCRIPTOR to compare.\r
+ @param[in, out] ReservedRangeToCompare Pointer to EFI_SMM_RESERVED_SMRAM_REGION to compare.\r
+ @param[out] Ranges Output pointer to hold split EFI_SMRAM_DESCRIPTOR entry.\r
+ @param[in, out] RangeCount Pointer to range count.\r
+ @param[out] ReservedRanges Output pointer to hold split EFI_SMM_RESERVED_SMRAM_REGION entry.\r
+ @param[in, out] ReservedRangeCount Pointer to reserved range count.\r
+ @param[out] FinalRanges Output pointer to hold split final EFI_SMRAM_DESCRIPTOR entry\r
+ that no need to be split anymore.\r
+ @param[in, out] FinalRangeCount Pointer to final range count.\r
+\r
+**/\r
+VOID\r
+SmmSplitSmramEntry (\r
+ IN OUT EFI_SMRAM_DESCRIPTOR *RangeToCompare,\r
+ IN OUT EFI_SMM_RESERVED_SMRAM_REGION *ReservedRangeToCompare,\r
+ OUT EFI_SMRAM_DESCRIPTOR *Ranges,\r
+ IN OUT UINTN *RangeCount,\r
+ OUT EFI_SMM_RESERVED_SMRAM_REGION *ReservedRanges,\r
+ IN OUT UINTN *ReservedRangeCount,\r
+ OUT EFI_SMRAM_DESCRIPTOR *FinalRanges,\r
+ IN OUT UINTN *FinalRangeCount\r
+ )\r
+{\r
+ UINT64 RangeToCompareEnd;\r
+ UINT64 ReservedRangeToCompareEnd;\r
+\r
+ RangeToCompareEnd = RangeToCompare->CpuStart + RangeToCompare->PhysicalSize;\r
+ ReservedRangeToCompareEnd = ReservedRangeToCompare->SmramReservedStart + ReservedRangeToCompare->SmramReservedSize;\r
+\r
+ if ((RangeToCompare->CpuStart >= ReservedRangeToCompare->SmramReservedStart) &&\r
+ (RangeToCompare->CpuStart < ReservedRangeToCompareEnd)) {\r
+ if (RangeToCompareEnd < ReservedRangeToCompareEnd) {\r
+ //\r
+ // RangeToCompare ReservedRangeToCompare\r
+ // ---- ---- --------------------------------------\r
+ // | | | | -> 1. ReservedRangeToCompare\r
+ // ---- | | |--| --------------------------------------\r
+ // | | | | | |\r
+ // | | | | | | -> 2. FinalRanges[*FinalRangeCount] and increment *FinalRangeCount\r
+ // | | | | | | RangeToCompare->PhysicalSize = 0\r
+ // ---- | | |--| --------------------------------------\r
+ // | | | | -> 3. ReservedRanges[*ReservedRangeCount] and increment *ReservedRangeCount\r
+ // ---- ---- --------------------------------------\r
+ //\r
+\r
+ //\r
+ // 1. Update ReservedRangeToCompare.\r
+ //\r
+ ReservedRangeToCompare->SmramReservedSize = RangeToCompare->CpuStart - ReservedRangeToCompare->SmramReservedStart;\r
+ //\r
+ // 2. Update FinalRanges[FinalRangeCount] and increment *FinalRangeCount.\r
+ // Zero RangeToCompare->PhysicalSize.\r
+ //\r
+ FinalRanges[*FinalRangeCount].CpuStart = RangeToCompare->CpuStart;\r
+ FinalRanges[*FinalRangeCount].PhysicalStart = RangeToCompare->PhysicalStart;\r
+ FinalRanges[*FinalRangeCount].RegionState = RangeToCompare->RegionState | EFI_ALLOCATED;\r
+ FinalRanges[*FinalRangeCount].PhysicalSize = RangeToCompare->PhysicalSize;\r
+ *FinalRangeCount += 1;\r
+ RangeToCompare->PhysicalSize = 0;\r
+ //\r
+ // 3. Update ReservedRanges[*ReservedRangeCount] and increment *ReservedRangeCount.\r
+ //\r
+ ReservedRanges[*ReservedRangeCount].SmramReservedStart = FinalRanges[*FinalRangeCount - 1].CpuStart + FinalRanges[*FinalRangeCount - 1].PhysicalSize;\r
+ ReservedRanges[*ReservedRangeCount].SmramReservedSize = ReservedRangeToCompareEnd - RangeToCompareEnd;\r
+ *ReservedRangeCount += 1;\r
+ } else {\r
+ //\r
+ // RangeToCompare ReservedRangeToCompare\r
+ // ---- ---- --------------------------------------\r
+ // | | | | -> 1. ReservedRangeToCompare\r
+ // ---- | | |--| --------------------------------------\r
+ // | | | | | |\r
+ // | | | | | | -> 2. FinalRanges[*FinalRangeCount] and increment *FinalRangeCount\r
+ // | | | | | |\r
+ // | | ---- |--| --------------------------------------\r
+ // | | | | -> 3. RangeToCompare\r
+ // ---- ---- --------------------------------------\r
+ //\r
+\r
+ //\r
+ // 1. Update ReservedRangeToCompare.\r
+ //\r
+ ReservedRangeToCompare->SmramReservedSize = RangeToCompare->CpuStart - ReservedRangeToCompare->SmramReservedStart;\r
+ //\r
+ // 2. Update FinalRanges[FinalRangeCount] and increment *FinalRangeCount.\r
+ //\r
+ FinalRanges[*FinalRangeCount].CpuStart = RangeToCompare->CpuStart;\r
+ FinalRanges[*FinalRangeCount].PhysicalStart = RangeToCompare->PhysicalStart;\r
+ FinalRanges[*FinalRangeCount].RegionState = RangeToCompare->RegionState | EFI_ALLOCATED;\r
+ FinalRanges[*FinalRangeCount].PhysicalSize = ReservedRangeToCompareEnd - RangeToCompare->CpuStart;\r
+ *FinalRangeCount += 1;\r
+ //\r
+ // 3. Update RangeToCompare.\r
+ //\r
+ RangeToCompare->CpuStart += FinalRanges[*FinalRangeCount - 1].PhysicalSize;\r
+ RangeToCompare->PhysicalStart += FinalRanges[*FinalRangeCount - 1].PhysicalSize;\r
+ RangeToCompare->PhysicalSize -= FinalRanges[*FinalRangeCount - 1].PhysicalSize;\r
+ }\r
+ } else if ((ReservedRangeToCompare->SmramReservedStart >= RangeToCompare->CpuStart) &&\r
+ (ReservedRangeToCompare->SmramReservedStart < RangeToCompareEnd)) {\r
+ if (ReservedRangeToCompareEnd < RangeToCompareEnd) {\r
+ //\r
+ // RangeToCompare ReservedRangeToCompare\r
+ // ---- ---- --------------------------------------\r
+ // | | | | -> 1. RangeToCompare\r
+ // | | ---- |--| --------------------------------------\r
+ // | | | | | |\r
+ // | | | | | | -> 2. FinalRanges[*FinalRangeCount] and increment *FinalRangeCount\r
+ // | | | | | | ReservedRangeToCompare->SmramReservedSize = 0\r
+ // | | ---- |--| --------------------------------------\r
+ // | | | | -> 3. Ranges[*RangeCount] and increment *RangeCount\r
+ // ---- ---- --------------------------------------\r
+ //\r
+\r
+ //\r
+ // 1. Update RangeToCompare.\r
+ //\r
+ RangeToCompare->PhysicalSize = ReservedRangeToCompare->SmramReservedStart - RangeToCompare->CpuStart;\r
+ //\r
+ // 2. Update FinalRanges[FinalRangeCount] and increment *FinalRangeCount.\r
+ // ReservedRangeToCompare->SmramReservedSize = 0\r
+ //\r
+ FinalRanges[*FinalRangeCount].CpuStart = ReservedRangeToCompare->SmramReservedStart;\r
+ FinalRanges[*FinalRangeCount].PhysicalStart = RangeToCompare->PhysicalStart + RangeToCompare->PhysicalSize;\r
+ FinalRanges[*FinalRangeCount].RegionState = RangeToCompare->RegionState | EFI_ALLOCATED;\r
+ FinalRanges[*FinalRangeCount].PhysicalSize = ReservedRangeToCompare->SmramReservedSize;\r
+ *FinalRangeCount += 1;\r
+ ReservedRangeToCompare->SmramReservedSize = 0;\r
+ //\r
+ // 3. Update Ranges[*RangeCount] and increment *RangeCount.\r
+ //\r
+ Ranges[*RangeCount].CpuStart = FinalRanges[*FinalRangeCount - 1].CpuStart + FinalRanges[*FinalRangeCount - 1].PhysicalSize;\r
+ Ranges[*RangeCount].PhysicalStart = FinalRanges[*FinalRangeCount - 1].PhysicalStart + FinalRanges[*FinalRangeCount - 1].PhysicalSize;\r
+ Ranges[*RangeCount].RegionState = RangeToCompare->RegionState;\r
+ Ranges[*RangeCount].PhysicalSize = RangeToCompareEnd - ReservedRangeToCompareEnd;\r
+ *RangeCount += 1;\r
+ } else {\r
+ //\r
+ // RangeToCompare ReservedRangeToCompare\r
+ // ---- ---- --------------------------------------\r
+ // | | | | -> 1. RangeToCompare\r
+ // | | ---- |--| --------------------------------------\r
+ // | | | | | |\r
+ // | | | | | | -> 2. FinalRanges[*FinalRangeCount] and increment *FinalRangeCount\r
+ // | | | | | |\r
+ // ---- | | |--| --------------------------------------\r
+ // | | | | -> 3. ReservedRangeToCompare\r
+ // ---- ---- --------------------------------------\r
+ //\r
+\r
+ //\r
+ // 1. Update RangeToCompare.\r
+ //\r
+ RangeToCompare->PhysicalSize = ReservedRangeToCompare->SmramReservedStart - RangeToCompare->CpuStart;\r
+ //\r
+ // 2. Update FinalRanges[FinalRangeCount] and increment *FinalRangeCount.\r
+ // ReservedRangeToCompare->SmramReservedSize = 0\r
+ //\r
+ FinalRanges[*FinalRangeCount].CpuStart = ReservedRangeToCompare->SmramReservedStart;\r
+ FinalRanges[*FinalRangeCount].PhysicalStart = RangeToCompare->PhysicalStart + RangeToCompare->PhysicalSize;\r
+ FinalRanges[*FinalRangeCount].RegionState = RangeToCompare->RegionState | EFI_ALLOCATED;\r
+ FinalRanges[*FinalRangeCount].PhysicalSize = RangeToCompareEnd - ReservedRangeToCompare->SmramReservedStart;\r
+ *FinalRangeCount += 1;\r
+ //\r
+ // 3. Update ReservedRangeToCompare.\r
+ //\r
+ ReservedRangeToCompare->SmramReservedStart += FinalRanges[*FinalRangeCount - 1].PhysicalSize;\r
+ ReservedRangeToCompare->SmramReservedSize -= FinalRanges[*FinalRangeCount - 1].PhysicalSize;\r
+ }\r