Lines Matching +full:memory +full:- +full:map
1 // SPDX-License-Identifier: GPL-2.0-only
3 * Low level x86 E820 memory map handling functions.
6 * physical memory layout description available about x86 systems.
8 * The kernel takes the E820 memory layout and optionally modifies it with
9 * quirks and other tweaks, and feeds that into the generic Linux memory
16 #include <linux/firmware-map.h>
26 * - 'e820_table_firmware': the original firmware version passed to us by the
27 * bootloader - not modified by the kernel. It is composed of two parts:
28 * the first 128 E820 memory entries in boot_params.e820_table and the remaining
31 * - the hibernation code uses it to generate a kernel-independent CRC32
32 * checksum of the physical memory layout of a system.
34 * - 'e820_table_kexec': a slightly modified (by the kernel) firmware version
35 * passed to us by the bootloader - the major difference between
40 * - kexec, which is a bootloader in disguise, uses the original E820
41 * layout to pass to the kexec-ed kernel. This way the original kernel
42 * can have a restricted E820 map while the kexec()-ed kexec-kernel
43 * can have access to full memory - etc.
45 * Export the memory layout via /sys/firmware/memmap. kexec-tools uses
48 * kexec_file_load in-kernel code uses the table for the kexec kernel.
50 * - 'e820_table': this is the main E820 table that is massaged by the
54 * Once the E820 map has been converted to the standard Linux memory layout
55 * information its role stops - modifying it has no effect and does not get
56 * re-propagated. So its main role is a temporary bootstrap storage of firmware
57 * specific memory layout data during early bootup.
67 /* For PCI or other memory-mapped resources */
82 for (i = 0; i < table->nr_entries; i++) { in _e820__mapped_any()
83 struct e820_entry *entry = &table->entries[i]; in _e820__mapped_any()
85 if (type && entry->type != type) in _e820__mapped_any()
87 if (entry->addr >= end || entry->addr + entry->size <= start) in _e820__mapped_any()
110 * not-overlapping (at least for the range specified), which is the case normally.
117 for (i = 0; i < e820_table->nr_entries; i++) { in __e820__mapped_all()
118 struct e820_entry *entry = &e820_table->entries[i]; in __e820__mapped_all()
120 if (type && entry->type != type) in __e820__mapped_all()
124 if (entry->addr >= end || entry->addr + entry->size <= start) in __e820__mapped_all()
131 if (entry->addr <= start) in __e820__mapped_all()
132 start = entry->addr + entry->size; in __e820__mapped_all()
160 return entry ? entry->type : -EINVAL; in e820__get_entry_type()
164 * Add a memory region to the kernel E820 map.
168 int x = table->nr_entries; in __e820__range_add()
170 if (x >= ARRAY_SIZE(table->entries)) { in __e820__range_add()
171 pr_err("too many entries; ignoring [mem %#010llx-%#010llx]\n", in __e820__range_add()
172 start, start + size - 1); in __e820__range_add()
176 table->entries[x].addr = start; in __e820__range_add()
177 table->entries[x].size = size; in __e820__range_add()
178 table->entries[x].type = type; in __e820__range_add()
179 table->nr_entries++; in __e820__range_add()
206 for (i = 0; i < e820_table->nr_entries; i++) { in e820__print_table()
207 pr_info("%s: [mem %#018Lx-%#018Lx] ", in e820__print_table()
209 e820_table->entries[i].addr, in e820__print_table()
210 e820_table->entries[i].addr + e820_table->entries[i].size - 1); in e820__print_table()
212 e820_print_type(e820_table->entries[i].type); in e820__print_table()
218 * Sanitize an E820 map.
221 * replaces the original E820 map with a new one, removing overlaps,
222 * and resolving conflicting memory types in favor of highest
228 * On return, the resulting sanitized E820 map entries will be in
237 * successfully 'sanitized' the map entries passed in, and is -1
239 * only passed one map entry, or (2) any of the input map entries
241 * so big the described memory range wrapped around through zero.)
244 * (1,2,3,4 = memory types)...
246 * Sample memory map (w/overlaps):
301 if (ap->addr != bp->addr) in cpcompare()
302 return ap->addr > bp->addr ? 1 : -1; in cpcompare()
304 return (ap->addr != ap->entry->addr) - (bp->addr != bp->entry->addr); in cpcompare()
323 struct e820_entry *entries = table->entries; in e820__update_table()
324 u32 max_nr_entries = ARRAY_SIZE(table->entries); in e820__update_table()
330 /* If there's only one memory region, don't bother: */ in e820__update_table()
331 if (table->nr_entries < 2) in e820__update_table()
332 return -1; in e820__update_table()
334 BUG_ON(table->nr_entries > max_nr_entries); in e820__update_table()
336 /* Bail out if we find any unreasonable addresses in the map: */ in e820__update_table()
337 for (i = 0; i < table->nr_entries; i++) { in e820__update_table()
339 return -1; in e820__update_table()
342 /* Create pointers for initial change-point information (for sorting): */ in e820__update_table()
343 for (i = 0; i < 2 * table->nr_entries; i++) in e820__update_table()
347 * Record all known change-points (starting and ending addresses), in e820__update_table()
348 * omitting empty memory regions: in e820__update_table()
351 for (i = 0; i < table->nr_entries; i++) { in e820__update_table()
353 change_point[chg_idx]->addr = entries[i].addr; in e820__update_table()
354 change_point[chg_idx++]->entry = &entries[i]; in e820__update_table()
355 change_point[chg_idx]->addr = entries[i].addr + entries[i].size; in e820__update_table()
356 change_point[chg_idx++]->entry = &entries[i]; in e820__update_table()
361 /* Sort change-point list by memory addresses (low -> high): */ in e820__update_table()
364 /* Create a new memory map, removing overlaps: */ in e820__update_table()
366 new_nr_entries = 0; /* Index for creating new map entries */ in e820__update_table()
367 last_type = 0; /* Start with undefined memory type */ in e820__update_table()
370 /* Loop through change-points, determining effect on the new map: */ in e820__update_table()
373 if (change_point[chg_idx]->addr == change_point[chg_idx]->entry->addr) { in e820__update_table()
374 /* Add map entry to overlap list (> 1 entry implies an overlap) */ in e820__update_table()
375 overlap_list[overlap_entries++] = change_point[chg_idx]->entry; in e820__update_table()
379 if (overlap_list[i] == change_point[chg_idx]->entry) in e820__update_table()
380 overlap_list[i] = overlap_list[overlap_entries-1]; in e820__update_table()
382 overlap_entries--; in e820__update_table()
386 * "type" to use (larger value takes precedence -- in e820__update_table()
391 if (overlap_list[i]->type > current_type) in e820__update_table()
392 current_type = overlap_list[i]->type; in e820__update_table()
395 /* Continue building up new map based on this information: */ in e820__update_table()
398 new_entries[new_nr_entries].size = change_point[chg_idx]->addr - last_addr; in e820__update_table()
399 /* Move forward only if the new size was non-zero: */ in e820__update_table()
406 new_entries[new_nr_entries].addr = change_point[chg_idx]->addr; in e820__update_table()
408 last_addr = change_point[chg_idx]->addr; in e820__update_table()
416 table->nr_entries = new_nr_entries; in e820__update_table()
426 u64 start = entry->addr; in __append_e820_table()
427 u64 size = entry->size; in __append_e820_table()
428 u64 end = start + size - 1; in __append_e820_table()
429 u32 type = entry->type; in __append_e820_table()
431 /* Ignore the entry on 64-bit overflow: */ in __append_e820_table()
433 return -1; in __append_e820_table()
438 nr_entries--; in __append_e820_table()
444 * Copy the BIOS E820 map into a safe place.
446 * Sanity-check it while we're at it..
449 * will have given us a memory map that we can use to properly
450 * set up memory. If we aren't, we'll fake a memory map.
454 /* Only one memory region (or negative)? Ignore it */ in append_e820_table()
456 return -1; in append_e820_table()
470 if (size > (ULLONG_MAX - start)) in __e820__range_update()
471 size = ULLONG_MAX - start; in __e820__range_update()
474 printk(KERN_DEBUG "e820: update [mem %#010Lx-%#010Lx] ", start, end - 1); in __e820__range_update()
480 for (i = 0; i < table->nr_entries; i++) { in __e820__range_update()
481 struct e820_entry *entry = &table->entries[i]; in __e820__range_update()
485 if (entry->type != old_type) in __e820__range_update()
488 entry_end = entry->addr + entry->size; in __e820__range_update()
491 if (entry->addr >= start && entry_end <= end) { in __e820__range_update()
492 entry->type = new_type; in __e820__range_update()
493 real_updated_size += entry->size; in __e820__range_update()
498 if (entry->addr < start && entry_end > end) { in __e820__range_update()
500 __e820__range_add(table, end, entry_end - end, entry->type); in __e820__range_update()
501 entry->size = start - entry->addr; in __e820__range_update()
507 final_start = max(start, entry->addr); in __e820__range_update()
512 __e820__range_add(table, final_start, final_end - final_start, new_type); in __e820__range_update()
514 real_updated_size += final_end - final_start; in __e820__range_update()
520 entry->size -= final_end - final_start; in __e820__range_update()
521 if (entry->addr < final_start) in __e820__range_update()
524 entry->addr = final_end; in __e820__range_update()
540 /* Remove a range of memory from the E820 table: */
547 if (size > (ULLONG_MAX - start)) in e820__range_remove()
548 size = ULLONG_MAX - start; in e820__range_remove()
551 printk(KERN_DEBUG "e820: remove [mem %#010Lx-%#010Lx] ", start, end - 1); in e820__range_remove()
556 for (i = 0; i < e820_table->nr_entries; i++) { in e820__range_remove()
557 struct e820_entry *entry = &e820_table->entries[i]; in e820__range_remove()
561 if (check_type && entry->type != old_type) in e820__range_remove()
564 entry_end = entry->addr + entry->size; in e820__range_remove()
567 if (entry->addr >= start && entry_end <= end) { in e820__range_remove()
568 real_removed_size += entry->size; in e820__range_remove()
574 if (entry->addr < start && entry_end > end) { in e820__range_remove()
575 e820__range_add(end, entry_end - end, entry->type); in e820__range_remove()
576 entry->size = start - entry->addr; in e820__range_remove()
582 final_start = max(start, entry->addr); in e820__range_remove()
587 real_removed_size += final_end - final_start; in e820__range_remove()
593 entry->size -= final_end - final_start; in e820__range_remove()
594 if (entry->addr < final_start) in e820__range_remove()
597 entry->addr = final_end; in e820__range_remove()
607 pr_info("modified physical RAM map:\n"); in e820__update_table_print()
619 * Search for a gap in the E820 memory space from 0 to MAX_GAP_END (4GB).
624 int i = e820_table->nr_entries; in e820_search_gap()
627 while (--i >= 0) { in e820_search_gap()
628 unsigned long long start = e820_table->entries[i].addr; in e820_search_gap()
629 unsigned long long end = start + e820_table->entries[i].size; in e820_search_gap()
636 unsigned long gap = last - end; in e820_search_gap()
652 * memory space. We pass this space to the PCI subsystem, so
669 pr_err("Cannot find an available gap in the 32-bit address range\n"); in e820__setup_pci_gap()
670 pr_err("PCI devices with unassigned 32-bit BARs may not work!\n"); in e820__setup_pci_gap()
681 pr_info("[mem %#010lx-%#010lx] available for PCI devices\n", in e820__setup_pci_gap()
682 gapstart, gapstart + gapsize - 1); in e820__setup_pci_gap()
702 size = offsetof(struct e820_table, entries) + sizeof(struct e820_entry)*e820_table->nr_entries; in e820__reallocate_tables()
707 …size = offsetof(struct e820_table, entries) + sizeof(struct e820_entry)*e820_table_kexec->nr_entri… in e820__reallocate_tables()
712 …size = offsetof(struct e820_table, entries) + sizeof(struct e820_entry)*e820_table_firmware->nr_en… in e820__reallocate_tables()
720 * 128 E820 memory entries are passed to the kernel via boot_params.e820_table,
731 entries = sdata->len / sizeof(*extmap); in e820__memory_setup_extended()
732 extmap = (struct boot_e820_entry *)(sdata->data); in e820__memory_setup_extended()
741 pr_info("extended physical RAM map:\n"); in e820__memory_setup_extended()
748 * hibernation (32-bit) or software suspend and suspend to RAM (64-bit).
750 * This function requires the E820 map to be sorted and without any
758 for (i = 0; i < e820_table->nr_entries; i++) { in e820__register_nosave_regions()
759 struct e820_entry *entry = &e820_table->entries[i]; in e820__register_nosave_regions()
761 if (entry->type != E820_TYPE_RAM) in e820__register_nosave_regions()
764 if (last_addr < entry->addr) in e820__register_nosave_regions()
765 register_nosave_region(PFN_DOWN(last_addr), PFN_UP(entry->addr)); in e820__register_nosave_regions()
767 last_addr = entry->addr + entry->size; in e820__register_nosave_regions()
775 * Register ACPI NVS memory regions, so that we can save/restore them during
782 for (i = 0; i < e820_table->nr_entries; i++) { in e820__register_nvs_regions()
783 struct e820_entry *entry = &e820_table->entries[i]; in e820__register_nvs_regions()
785 if (entry->type == E820_TYPE_NVS) in e820__register_nvs_regions()
786 acpi_nvs_register(entry->addr, entry->size); in e820__register_nvs_regions()
818 # define MAX_ARCH_PFN (1ULL<<(36-PAGE_SHIFT))
820 # define MAX_ARCH_PFN (1ULL<<(32-PAGE_SHIFT))
835 for (i = 0; i < e820_table->nr_entries; i++) { in e820__end_ram_pfn()
836 struct e820_entry *entry = &e820_table->entries[i]; in e820__end_ram_pfn()
840 if (entry->type != E820_TYPE_RAM && in e820__end_ram_pfn()
841 entry->type != E820_TYPE_ACPI) in e820__end_ram_pfn()
844 start_pfn = entry->addr >> PAGE_SHIFT; in e820__end_ram_pfn()
845 end_pfn = (entry->addr + entry->size) >> PAGE_SHIFT; in e820__end_ram_pfn()
872 return e820__end_ram_pfn(1UL << (32 - PAGE_SHIFT)); in e820__end_of_low_ram_pfn()
883 /* The "mem=nopentium" boot option disables 4MB page tables on 32-bit kernels: */
889 return -EINVAL; in parse_memopt()
897 return -EINVAL; in parse_memopt()
904 /* Don't remove all memory when getting "mem={invalid}" parameter: */ in parse_memopt()
906 return -EINVAL; in parse_memopt()
908 e820__range_remove(mem_size, ULLONG_MAX - mem_size, E820_TYPE_RAM, 1); in parse_memopt()
924 return -EINVAL; in parse_memmap_one()
927 e820_table->nr_entries = 0; in parse_memmap_one()
935 return -EINVAL; in parse_memmap_one()
954 if (*p == '-') in parse_memmap_one()
959 return -EINVAL; in parse_memmap_one()
969 e820__range_remove(mem_size, ULLONG_MAX - mem_size, E820_TYPE_RAM, 1); in parse_memmap_one()
972 return *p == '\0' ? 0 : -EINVAL; in parse_memmap_one()
1000 early_panic("Invalid user supplied memory map"); in e820__finish_early_params()
1002 pr_info("user-defined physical RAM map:\n"); in e820__finish_early_params()
1009 switch (entry->type) { in e820_type_to_string()
1012 case E820_TYPE_NVS: return "ACPI Non-volatile Storage"; in e820_type_to_string()
1013 case E820_TYPE_UNUSABLE: return "Unusable memory"; in e820_type_to_string()
1014 case E820_TYPE_PRAM: return "Persistent Memory (legacy)"; in e820_type_to_string()
1015 case E820_TYPE_PMEM: return "Persistent Memory"; in e820_type_to_string()
1024 switch (entry->type) { in e820_type_to_iomem_type()
1026 case E820_TYPE_ACPI: /* Fall-through: */ in e820_type_to_iomem_type()
1027 case E820_TYPE_NVS: /* Fall-through: */ in e820_type_to_iomem_type()
1028 case E820_TYPE_UNUSABLE: /* Fall-through: */ in e820_type_to_iomem_type()
1029 case E820_TYPE_PRAM: /* Fall-through: */ in e820_type_to_iomem_type()
1030 case E820_TYPE_PMEM: /* Fall-through: */ in e820_type_to_iomem_type()
1031 case E820_TYPE_RESERVED: /* Fall-through: */ in e820_type_to_iomem_type()
1032 case E820_TYPE_SOFT_RESERVED: /* Fall-through: */ in e820_type_to_iomem_type()
1039 switch (entry->type) { in e820_type_to_iores_desc()
1046 case E820_TYPE_RAM: /* Fall-through: */ in e820_type_to_iores_desc()
1047 case E820_TYPE_UNUSABLE: /* Fall-through: */ in e820_type_to_iores_desc()
1054 /* this is the legacy bios/dos rom-shadow + mmio region */ in do_mark_busy()
1055 if (res->start < (1ULL<<20)) in do_mark_busy()
1059 * Treat persistent memory and other special memory ranges like in do_mark_busy()
1060 * device memory, i.e. reserve it for exclusive use of a driver in do_mark_busy()
1089 res = memblock_alloc_or_panic(sizeof(*res) * e820_table->nr_entries, in e820__reserve_resources()
1093 for (i = 0; i < e820_table->nr_entries; i++) { in e820__reserve_resources()
1094 struct e820_entry *entry = e820_table->entries + i; in e820__reserve_resources()
1096 end = entry->addr + entry->size - 1; in e820__reserve_resources()
1101 res->start = entry->addr; in e820__reserve_resources()
1102 res->end = end; in e820__reserve_resources()
1103 res->name = e820_type_to_string(entry); in e820__reserve_resources()
1104 res->flags = e820_type_to_iomem_type(entry); in e820__reserve_resources()
1105 res->desc = e820_type_to_iores_desc(entry); in e820__reserve_resources()
1112 if (do_mark_busy(entry->type, res)) { in e820__reserve_resources()
1113 res->flags |= IORESOURCE_BUSY; in e820__reserve_resources()
1120 for (i = 0; i < e820_table_kexec->nr_entries; i++) { in e820__reserve_resources()
1121 struct e820_entry *entry = e820_table_kexec->entries + i; in e820__reserve_resources()
1123 firmware_map_add_early(entry->addr, entry->addr + entry->size, e820_type_to_string(entry)); in e820__reserve_resources()
1146 #define MAX_RESOURCE_SIZE ((resource_size_t)-1)
1154 for (i = 0; i < e820_table->nr_entries; i++) { in e820__reserve_resources_late()
1155 if (!res->parent && res->end) in e820__reserve_resources_late()
1164 for (i = 0; i < e820_table->nr_entries; i++) { in e820__reserve_resources_late()
1165 struct e820_entry *entry = &e820_table->entries[i]; in e820__reserve_resources_late()
1168 if (entry->type != E820_TYPE_RAM) in e820__reserve_resources_late()
1171 start = entry->addr + entry->size; in e820__reserve_resources_late()
1172 end = round_up(start, ram_alignment(start)) - 1; in e820__reserve_resources_late()
1178 printk(KERN_DEBUG "e820: reserve RAM buffer [mem %#010llx-%#010llx]\n", start, end); in e820__reserve_resources_late()
1184 * Pass the firmware (bootloader) E820 map to the kernel and process it:
1188 char *who = "BIOS-e820"; in e820__memory_setup_default()
1191 * Try to copy the BIOS-supplied E820-map. in e820__memory_setup_default()
1193 * Otherwise fake a memory map; one section from 0k->640k, in e820__memory_setup_default()
1194 * the next section from 1mb->appropriate_mem_k in e820__memory_setup_default()
1202 who = "BIOS-88"; in e820__memory_setup_default()
1205 who = "BIOS-e801"; in e820__memory_setup_default()
1208 e820_table->nr_entries = 0; in e820__memory_setup_default()
1221 * E820 map - with an optional platform quirk available for virtual platforms
1228 /* This is a firmware interface ABI - make sure we don't break it: */ in e820__memory_setup()
1236 pr_info("BIOS-provided physical RAM map:\n"); in e820__memory_setup()
1247 * Memory used by the kernel cannot be hot-removed because Linux in e820__memblock_setup()
1248 * cannot migrate the kernel pages. When memory hotplug is in e820__memblock_setup()
1249 * enabled, we should prevent memblock from allocating memory in e820__memblock_setup()
1252 * ACPI SRAT records all hotpluggable memory ranges. But before in e820__memblock_setup()
1255 * The kernel image is loaded into memory at very early time. We in e820__memblock_setup()
1257 * node the kernel resides in as un-hotpluggable. in e820__memblock_setup()
1259 * Since on modern servers, one node could have double-digit in e820__memblock_setup()
1260 * gigabytes memory, we can assume the memory around the kernel in e820__memblock_setup()
1261 * image is also un-hotpluggable. So before SRAT is parsed, just in e820__memblock_setup()
1262 * allocate memory near the kernel image to try the best to keep in e820__memblock_setup()
1263 * the kernel away from hotpluggable memory. in e820__memblock_setup()
1271 * rest of the memory cannot be used for memblock resizing in e820__memblock_setup()
1278 * than that - so allow memblock resizing. in e820__memblock_setup()
1281 * so we know about reserved memory regions already. (This is important in e820__memblock_setup()
1286 for (i = 0; i < e820_table->nr_entries; i++) { in e820__memblock_setup()
1287 struct e820_entry *entry = &e820_table->entries[i]; in e820__memblock_setup()
1289 end = entry->addr + entry->size; in e820__memblock_setup()
1293 if (entry->type == E820_TYPE_SOFT_RESERVED) in e820__memblock_setup()
1294 memblock_reserve(entry->addr, entry->size); in e820__memblock_setup()
1296 if (entry->type != E820_TYPE_RAM) in e820__memblock_setup()
1299 memblock_add(entry->addr, entry->size); in e820__memblock_setup()
1303 * At this point memblock is only allowed to allocate from memory in e820__memblock_setup()
1304 * below 1M (aka ISA_END_ADDRESS) up until direct map is completely set in e820__memblock_setup()
1307 * KHO kernels are special and use only scratch memory for memblock in e820__memblock_setup()
1308 * allocations, but memory below 1M is ignored by kernel after early in e820__memblock_setup()
1311 * To allow allocation of the real-mode trampoline and a few (if any) in e820__memblock_setup()
1312 * other very early allocations from below 1M forcibly mark the memory in e820__memblock_setup()
1321 * 32-bit systems are limited to 4BG of memory even with HIGHMEM and in e820__memblock_setup()
1323 * Discard memory after max_pfn - the actual limit detected at runtime. in e820__memblock_setup()
1326 memblock_remove(PFN_PHYS(max_pfn), -1); in e820__memblock_setup()