+ CurrentSmramRangesIndex = 0;\r
+ //\r
+ // If Loadding Module At fixed Address feature is enabled, cache the SMRAM base here\r
+ //\r
+ if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) {\r
+ //\r
+ // Build tool will calculate the smm code size and then patch the PcdLoadFixAddressSmmCodePageNumber\r
+ //\r
+ SmmCodeSize = LShiftU64 (PcdGet32(PcdLoadFixAddressSmmCodePageNumber), EFI_PAGE_SHIFT);\r
+ \r
+ //\r
+ // Find the largest SMRAM range between 1MB and 4GB that is at least 256KB - 4K in size\r
+ //\r
+ for (Index = 0, MaxSize = SIZE_256KB - EFI_PAGE_SIZE; Index < SmramRangeCount; Index++) {\r
+ //\r
+ // Skip any SMRAM region that is already allocated, needs testing, or needs ECC initialization\r
+ //\r
+ if ((SmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) {\r
+ continue;\r
+ }\r
+\r
+ if (SmramRanges[Index].CpuStart >= BASE_1MB) {\r
+ if ((SmramRanges[Index].CpuStart + SmramRanges[Index].PhysicalSize) <= BASE_4GB) {\r
+ if (SmramRanges[Index].PhysicalSize >= MaxSize) {\r
+ MaxSize = SmramRanges[Index].PhysicalSize;\r
+ CurrentSmramRangesIndex = Index;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ gLoadModuleAtFixAddressSmramBase = SmramRanges[CurrentSmramRangesIndex].CpuStart;\r
+ \r
+ //\r
+ // cut out a memory range from this SMRAM range with the size SmmCodeSize to hold SMM driver code\r
+ // A notable thing is that SMM core is already loaded into this range.\r
+ //\r
+ SmramRanges[CurrentSmramRangesIndex].CpuStart = SmramRanges[CurrentSmramRangesIndex].CpuStart + SmmCodeSize; \r
+ SmramRanges[CurrentSmramRangesIndex].PhysicalSize = SmramRanges[CurrentSmramRangesIndex].PhysicalSize - SmmCodeSize;\r
+ }\r