- ppnum_t base, num;
- vm_size_t size;
- uint32_t bank, num_banks;
- uint32_t pages, page_count;
- hibernate_page_list_t * list;
- hibernate_bitmap_t * bitmap;
-
- EfiMemoryRange * mptr;
- uint32_t mcount, msize, i;
- hibernate_bitmap_t dram_ranges[MAX_BANKS];
- boot_args * args = (boot_args *) PE_state.bootArgs;
-
- mptr = (EfiMemoryRange *)args->MemoryMap;
- if (args->MemoryMapDescriptorSize == 0)
- panic("Invalid memory map descriptor size");
- msize = args->MemoryMapDescriptorSize;
- mcount = args->MemoryMapSize / msize;
-
- num_banks = 0;
- for (i = 0; i < mcount; i++, mptr = (EfiMemoryRange *)(((vm_offset_t)mptr) + msize))
- {
- base = (ppnum_t) (mptr->PhysicalStart >> I386_PGSHIFT);
- num = (ppnum_t) mptr->NumberOfPages;
- if (!num)
- continue;
-
- switch (mptr->Type)
- {
- // any kind of dram
- case kEfiLoaderCode:
- case kEfiLoaderData:
- case kEfiBootServicesCode:
- case kEfiBootServicesData:
- case kEfiConventionalMemory:
- case kEfiACPIReclaimMemory:
- case kEfiACPIMemoryNVS:
- case kEfiPalCode:
-
- if (!num_banks || (base != (1 + dram_ranges[num_banks - 1].last_page)))
- {
- num_banks++;
- if (num_banks >= MAX_BANKS)
+ ppnum_t base, num;
+ vm_size_t size;
+ uint32_t bank, num_banks;
+ uint32_t pages, page_count;
+ hibernate_page_list_t * list;
+ hibernate_bitmap_t * bitmap;
+
+ EfiMemoryRange * mptr;
+ uint32_t mcount, msize, i;
+ hibernate_bitmap_t dram_ranges[MAX_BANKS];
+ boot_args * args = (boot_args *) PE_state.bootArgs;
+ uint32_t non_os_pagecount;
+ ppnum_t pnmax = max_ppnum;
+
+ mptr = (EfiMemoryRange *)ml_static_ptovirt(args->MemoryMap);
+ if (args->MemoryMapDescriptorSize == 0) {
+ panic("Invalid memory map descriptor size");
+ }
+ msize = args->MemoryMapDescriptorSize;
+ mcount = args->MemoryMapSize / msize;
+
+#if KASAN
+ /* adjust max page number to include stolen memory */
+ if (atop(shadow_ptop) > pnmax) {
+ pnmax = (ppnum_t)atop(shadow_ptop);
+ }
+#endif
+
+ num_banks = 0;
+ non_os_pagecount = 0;
+ for (i = 0; i < mcount; i++, mptr = (EfiMemoryRange *)(((vm_offset_t)mptr) + msize)) {
+ base = (ppnum_t) (mptr->PhysicalStart >> I386_PGSHIFT);
+ num = (ppnum_t) mptr->NumberOfPages;
+
+#if KASAN
+ if (i == shadow_stolen_idx) {
+ /*
+ * Add all stolen pages to the bitmap. Later we will prune the unused
+ * pages.
+ */
+ num += shadow_pages_total;
+ }
+#endif
+
+ if (base > pnmax) {
+ continue;
+ }
+ if ((base + num - 1) > pnmax) {
+ num = pnmax - base + 1;
+ }
+ if (!num) {
+ continue;
+ }
+
+ switch (mptr->Type) {
+ // any kind of dram
+ case kEfiACPIMemoryNVS:
+ case kEfiPalCode:
+ non_os_pagecount += num;
+
+ // OS used dram
+ case kEfiLoaderCode:
+ case kEfiLoaderData:
+ case kEfiBootServicesCode:
+ case kEfiBootServicesData:
+ case kEfiConventionalMemory:
+
+ for (bank = 0; bank < num_banks; bank++) {
+ if (dram_ranges[bank].first_page <= base) {
+ continue;
+ }
+ if ((base + num) == dram_ranges[bank].first_page) {
+ dram_ranges[bank].first_page = base;
+ num = 0;
+ }
+ break;
+ }
+ if (!num) {
+ break;
+ }
+
+ if (bank && (base == (1 + dram_ranges[bank - 1].last_page))) {
+ bank--;
+ } else {
+ num_banks++;
+ if (num_banks >= MAX_BANKS) {
+ break;
+ }
+ bcopy(&dram_ranges[bank],
+ &dram_ranges[bank + 1],
+ (num_banks - bank - 1) * sizeof(hibernate_bitmap_t));
+ dram_ranges[bank].first_page = base;
+ }
+ dram_ranges[bank].last_page = base + num - 1;
+ break;
+
+ // runtime services will be restarted, so no save
+ case kEfiRuntimeServicesCode:
+ case kEfiRuntimeServicesData:
+ // contents are volatile once the platform expert starts
+ case kEfiACPIReclaimMemory:
+ // non dram
+ case kEfiReservedMemoryType:
+ case kEfiUnusableMemory:
+ case kEfiMemoryMappedIO:
+ case kEfiMemoryMappedIOPortSpace:
+ default: