Lines Matching +full:non +full:- +full:overlapping
1 // SPDX-License-Identifier: GPL-2.0-only
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:
31 * - inform the user about the firmware's notion of memory layout
34 * - the hibernation code uses it to generate a kernel-independent CRC32
37 * - 'e820_table_kexec': a slightly modified (by the kernel) firmware version
38 * passed to us by the bootloader - the major difference between
45 * - kexec, which is a bootloader in disguise, uses the original E820
46 * layout to pass to the kexec-ed kernel. This way the original kernel
47 * can have a restricted E820 map while the kexec()-ed kexec-kernel
48 * can have access to full memory - etc.
50 * - 'e820_table': this is the main E820 table that is massaged by the
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
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()
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()
207 for (i = 0; i < e820_table->nr_entries; i++) { in e820__print_table()
208 pr_info("%s: [mem %#018Lx-%#018Lx] ", in e820__print_table()
210 e820_table->entries[i].addr, in e820__print_table()
211 e820_table->entries[i].addr + e820_table->entries[i].size - 1); in e820__print_table()
213 e820_print_type(e820_table->entries[i].type); in e820__print_table()
221 * Some E820 layouts include overlapping entries. The following
238 * successfully 'sanitized' the map entries passed in, and is -1
302 if (ap->addr != bp->addr) in cpcompare()
303 return ap->addr > bp->addr ? 1 : -1; in cpcompare()
305 return (ap->addr != ap->entry->addr) - (bp->addr != bp->entry->addr); in cpcompare()
324 struct e820_entry *entries = table->entries; in e820__update_table()
325 u32 max_nr_entries = ARRAY_SIZE(table->entries); in e820__update_table()
332 if (table->nr_entries < 2) in e820__update_table()
333 return -1; in e820__update_table()
335 BUG_ON(table->nr_entries > max_nr_entries); in e820__update_table()
338 for (i = 0; i < table->nr_entries; i++) { in e820__update_table()
340 return -1; in e820__update_table()
343 /* Create pointers for initial change-point information (for sorting): */ in e820__update_table()
344 for (i = 0; i < 2 * table->nr_entries; i++) in e820__update_table()
348 * Record all known change-points (starting and ending addresses), in e820__update_table()
352 for (i = 0; i < table->nr_entries; i++) { in e820__update_table()
354 change_point[chg_idx]->addr = entries[i].addr; in e820__update_table()
355 change_point[chg_idx++]->entry = &entries[i]; in e820__update_table()
356 change_point[chg_idx]->addr = entries[i].addr + entries[i].size; in e820__update_table()
357 change_point[chg_idx++]->entry = &entries[i]; in e820__update_table()
362 /* Sort change-point list by memory addresses (low -> high): */ in e820__update_table()
371 /* Loop through change-points, determining effect on the new map: */ in e820__update_table()
373 /* Keep track of all overlapping entries */ in e820__update_table()
374 if (change_point[chg_idx]->addr == change_point[chg_idx]->entry->addr) { in e820__update_table()
376 overlap_list[overlap_entries++] = change_point[chg_idx]->entry; in e820__update_table()
380 if (overlap_list[i] == change_point[chg_idx]->entry) in e820__update_table()
381 overlap_list[i] = overlap_list[overlap_entries-1]; in e820__update_table()
383 overlap_entries--; in e820__update_table()
386 * If there are overlapping entries, decide which in e820__update_table()
387 * "type" to use (larger value takes precedence -- in e820__update_table()
392 if (overlap_list[i]->type > current_type) in e820__update_table()
393 current_type = overlap_list[i]->type; in e820__update_table()
399 new_entries[new_nr_entries].size = change_point[chg_idx]->addr - last_addr; in e820__update_table()
400 /* Move forward only if the new size was non-zero: */ in e820__update_table()
407 new_entries[new_nr_entries].addr = change_point[chg_idx]->addr; in e820__update_table()
409 last_addr = change_point[chg_idx]->addr; in e820__update_table()
417 table->nr_entries = new_nr_entries; in e820__update_table()
427 u64 start = entry->addr; in __append_e820_table()
428 u64 size = entry->size; in __append_e820_table()
429 u64 end = start + size - 1; in __append_e820_table()
430 u32 type = entry->type; in __append_e820_table()
432 /* Ignore the entry on 64-bit overflow: */ in __append_e820_table()
434 return -1; in __append_e820_table()
439 nr_entries--; in __append_e820_table()
447 * Sanity-check it while we're at it..
457 return -1; in append_e820_table()
471 if (size > (ULLONG_MAX - start)) in __e820__range_update()
472 size = ULLONG_MAX - start; in __e820__range_update()
475 printk(KERN_DEBUG "e820: update [mem %#010Lx-%#010Lx] ", start, end - 1); in __e820__range_update()
481 for (i = 0; i < table->nr_entries; i++) { in __e820__range_update()
482 struct e820_entry *entry = &table->entries[i]; in __e820__range_update()
486 if (entry->type != old_type) in __e820__range_update()
489 entry_end = entry->addr + entry->size; in __e820__range_update()
492 if (entry->addr >= start && entry_end <= end) { in __e820__range_update()
493 entry->type = new_type; in __e820__range_update()
494 real_updated_size += entry->size; in __e820__range_update()
499 if (entry->addr < start && entry_end > end) { in __e820__range_update()
501 __e820__range_add(table, end, entry_end - end, entry->type); in __e820__range_update()
502 entry->size = start - entry->addr; in __e820__range_update()
508 final_start = max(start, entry->addr); in __e820__range_update()
513 __e820__range_add(table, final_start, final_end - final_start, new_type); in __e820__range_update()
515 real_updated_size += final_end - final_start; in __e820__range_update()
521 entry->size -= final_end - final_start; in __e820__range_update()
522 if (entry->addr < final_start) in __e820__range_update()
525 entry->addr = final_end; in __e820__range_update()
548 if (size > (ULLONG_MAX - start)) in e820__range_remove()
549 size = ULLONG_MAX - start; in e820__range_remove()
552 printk(KERN_DEBUG "e820: remove [mem %#010Lx-%#010Lx] ", start, end - 1); in e820__range_remove()
557 for (i = 0; i < e820_table->nr_entries; i++) { in e820__range_remove()
558 struct e820_entry *entry = &e820_table->entries[i]; in e820__range_remove()
562 if (check_type && entry->type != old_type) in e820__range_remove()
565 entry_end = entry->addr + entry->size; in e820__range_remove()
568 if (entry->addr >= start && entry_end <= end) { in e820__range_remove()
569 real_removed_size += entry->size; in e820__range_remove()
575 if (entry->addr < start && entry_end > end) { in e820__range_remove()
576 e820__range_add(end, entry_end - end, entry->type); in e820__range_remove()
577 entry->size = start - entry->addr; in e820__range_remove()
583 final_start = max(start, entry->addr); in e820__range_remove()
588 real_removed_size += final_end - final_start; in e820__range_remove()
594 entry->size -= final_end - final_start; in e820__range_remove()
595 if (entry->addr < final_start) in e820__range_remove()
598 entry->addr = final_end; in e820__range_remove()
625 int i = e820_table->nr_entries; in e820_search_gap()
628 while (--i >= 0) { in e820_search_gap()
629 unsigned long long start = e820_table->entries[i].addr; in e820_search_gap()
630 unsigned long long end = start + e820_table->entries[i].size; in e820_search_gap()
637 unsigned long gap = last - end; in e820_search_gap()
670 pr_err("Cannot find an available gap in the 32-bit address range\n"); in e820__setup_pci_gap()
671 pr_err("PCI devices with unassigned 32-bit BARs may not work!\n"); in e820__setup_pci_gap()
682 pr_info("[mem %#010lx-%#010lx] available for PCI devices\n", in e820__setup_pci_gap()
683 gapstart, gapstart + gapsize - 1); in e820__setup_pci_gap()
703 size = offsetof(struct e820_table, entries) + sizeof(struct e820_entry)*e820_table->nr_entries; in e820__reallocate_tables()
708 …size = offsetof(struct e820_table, entries) + sizeof(struct e820_entry)*e820_table_kexec->nr_entri… in e820__reallocate_tables()
713 …size = offsetof(struct e820_table, entries) + sizeof(struct e820_entry)*e820_table_firmware->nr_en… in e820__reallocate_tables()
732 entries = sdata->len / sizeof(*extmap); in e820__memory_setup_extended()
733 extmap = (struct boot_e820_entry *)(sdata->data); in e820__memory_setup_extended()
749 * hibernation (32-bit) or software suspend and suspend to RAM (64-bit).
752 * overlapping entries.
759 for (i = 0; i < e820_table->nr_entries; i++) { in e820__register_nosave_regions()
760 struct e820_entry *entry = &e820_table->entries[i]; in e820__register_nosave_regions()
762 if (pfn < PFN_UP(entry->addr)) in e820__register_nosave_regions()
763 register_nosave_region(pfn, PFN_UP(entry->addr)); in e820__register_nosave_regions()
765 pfn = PFN_DOWN(entry->addr + entry->size); in e820__register_nosave_regions()
767 if (entry->type != E820_TYPE_RAM && entry->type != E820_TYPE_RESERVED_KERN) in e820__register_nosave_regions()
768 register_nosave_region(PFN_UP(entry->addr), pfn); in e820__register_nosave_regions()
784 for (i = 0; i < e820_table->nr_entries; i++) { in e820__register_nvs_regions()
785 struct e820_entry *entry = &e820_table->entries[i]; in e820__register_nvs_regions()
787 if (entry->type == E820_TYPE_NVS) in e820__register_nvs_regions()
788 acpi_nvs_register(entry->addr, entry->size); in e820__register_nvs_regions()
820 # define MAX_ARCH_PFN (1ULL<<(36-PAGE_SHIFT))
822 # define MAX_ARCH_PFN (1ULL<<(32-PAGE_SHIFT))
837 for (i = 0; i < e820_table->nr_entries; i++) { in e820__end_ram_pfn()
838 struct e820_entry *entry = &e820_table->entries[i]; in e820__end_ram_pfn()
842 if (entry->type != E820_TYPE_RAM && in e820__end_ram_pfn()
843 entry->type != E820_TYPE_ACPI) in e820__end_ram_pfn()
846 start_pfn = entry->addr >> PAGE_SHIFT; in e820__end_ram_pfn()
847 end_pfn = (entry->addr + entry->size) >> PAGE_SHIFT; in e820__end_ram_pfn()
874 return e820__end_ram_pfn(1UL << (32 - PAGE_SHIFT)); in e820__end_of_low_ram_pfn()
885 /* The "mem=nopentium" boot option disables 4MB page tables on 32-bit kernels: */
891 return -EINVAL; in parse_memopt()
899 return -EINVAL; in parse_memopt()
908 return -EINVAL; in parse_memopt()
910 e820__range_remove(mem_size, ULLONG_MAX - mem_size, E820_TYPE_RAM, 1); in parse_memopt()
926 return -EINVAL; in parse_memmap_one()
929 e820_table->nr_entries = 0; in parse_memmap_one()
937 return -EINVAL; in parse_memmap_one()
956 if (*p == '-') in parse_memmap_one()
961 return -EINVAL; in parse_memmap_one()
971 e820__range_remove(mem_size, ULLONG_MAX - mem_size, E820_TYPE_RAM, 1); in parse_memmap_one()
974 return *p == '\0' ? 0 : -EINVAL; in parse_memmap_one()
1017 pa_next = data->next; in e820__reserve_setup_data()
1019 e820__range_update(pa_data, sizeof(*data)+data->len, E820_TYPE_RAM, E820_TYPE_RESERVED_KERN); in e820__reserve_setup_data()
1021 if (data->type == SETUP_INDIRECT) { in e820__reserve_setup_data()
1022 len += data->len; in e820__reserve_setup_data()
1030 indirect = (struct setup_indirect *)data->data; in e820__reserve_setup_data()
1032 if (indirect->type != SETUP_INDIRECT) in e820__reserve_setup_data()
1033 e820__range_update(indirect->addr, indirect->len, in e820__reserve_setup_data()
1058 pr_info("user-defined physical RAM map:\n"); in e820__finish_early_params()
1065 switch (entry->type) { in e820_type_to_string()
1066 case E820_TYPE_RESERVED_KERN: /* Fall-through: */ in e820_type_to_string()
1069 case E820_TYPE_NVS: return "ACPI Non-volatile Storage"; in e820_type_to_string()
1081 switch (entry->type) { in e820_type_to_iomem_type()
1082 case E820_TYPE_RESERVED_KERN: /* Fall-through: */ in e820_type_to_iomem_type()
1084 case E820_TYPE_ACPI: /* Fall-through: */ in e820_type_to_iomem_type()
1085 case E820_TYPE_NVS: /* Fall-through: */ in e820_type_to_iomem_type()
1086 case E820_TYPE_UNUSABLE: /* Fall-through: */ in e820_type_to_iomem_type()
1087 case E820_TYPE_PRAM: /* Fall-through: */ in e820_type_to_iomem_type()
1088 case E820_TYPE_PMEM: /* Fall-through: */ in e820_type_to_iomem_type()
1089 case E820_TYPE_RESERVED: /* Fall-through: */ in e820_type_to_iomem_type()
1090 case E820_TYPE_SOFT_RESERVED: /* Fall-through: */ in e820_type_to_iomem_type()
1097 switch (entry->type) { in e820_type_to_iores_desc()
1104 case E820_TYPE_RESERVED_KERN: /* Fall-through: */ in e820_type_to_iores_desc()
1105 case E820_TYPE_RAM: /* Fall-through: */ in e820_type_to_iores_desc()
1106 case E820_TYPE_UNUSABLE: /* Fall-through: */ in e820_type_to_iores_desc()
1113 /* this is the legacy bios/dos rom-shadow + mmio region */ in do_mark_busy()
1114 if (res->start < (1ULL<<20)) in do_mark_busy()
1149 res = memblock_alloc(sizeof(*res) * e820_table->nr_entries, in e820__reserve_resources()
1153 sizeof(*res) * e820_table->nr_entries); in e820__reserve_resources()
1156 for (i = 0; i < e820_table->nr_entries; i++) { in e820__reserve_resources()
1157 struct e820_entry *entry = e820_table->entries + i; in e820__reserve_resources()
1159 end = entry->addr + entry->size - 1; in e820__reserve_resources()
1164 res->start = entry->addr; in e820__reserve_resources()
1165 res->end = end; in e820__reserve_resources()
1166 res->name = e820_type_to_string(entry); in e820__reserve_resources()
1167 res->flags = e820_type_to_iomem_type(entry); in e820__reserve_resources()
1168 res->desc = e820_type_to_iores_desc(entry); in e820__reserve_resources()
1175 if (do_mark_busy(entry->type, res)) { in e820__reserve_resources()
1176 res->flags |= IORESOURCE_BUSY; in e820__reserve_resources()
1182 /* Expose the bootloader-provided memory layout to the sysfs. */ in e820__reserve_resources()
1183 for (i = 0; i < e820_table_firmware->nr_entries; i++) { in e820__reserve_resources()
1184 struct e820_entry *entry = e820_table_firmware->entries + i; in e820__reserve_resources()
1186 firmware_map_add_early(entry->addr, entry->addr + entry->size, e820_type_to_string(entry)); in e820__reserve_resources()
1209 #define MAX_RESOURCE_SIZE ((resource_size_t)-1)
1217 for (i = 0; i < e820_table->nr_entries; i++) { in e820__reserve_resources_late()
1218 if (!res->parent && res->end) in e820__reserve_resources_late()
1227 for (i = 0; i < e820_table->nr_entries; i++) { in e820__reserve_resources_late()
1228 struct e820_entry *entry = &e820_table->entries[i]; in e820__reserve_resources_late()
1231 if (entry->type != E820_TYPE_RAM) in e820__reserve_resources_late()
1234 start = entry->addr + entry->size; in e820__reserve_resources_late()
1235 end = round_up(start, ram_alignment(start)) - 1; in e820__reserve_resources_late()
1241 printk(KERN_DEBUG "e820: reserve RAM buffer [mem %#010llx-%#010llx]\n", start, end); in e820__reserve_resources_late()
1251 char *who = "BIOS-e820"; in e820__memory_setup_default()
1254 * Try to copy the BIOS-supplied E820-map. in e820__memory_setup_default()
1256 * Otherwise fake a memory map; one section from 0k->640k, in e820__memory_setup_default()
1257 * the next section from 1mb->appropriate_mem_k in e820__memory_setup_default()
1265 who = "BIOS-88"; in e820__memory_setup_default()
1268 who = "BIOS-e801"; in e820__memory_setup_default()
1271 e820_table->nr_entries = 0; in e820__memory_setup_default()
1284 * E820 map - with an optional platform quirk available for virtual platforms
1291 /* This is a firmware interface ABI - make sure we don't break it: */ in e820__memory_setup()
1299 pr_info("BIOS-provided physical RAM map:\n"); in e820__memory_setup()
1311 * than that - so allow memblock resizing. in e820__memblock_setup()
1319 for (i = 0; i < e820_table->nr_entries; i++) { in e820__memblock_setup()
1320 struct e820_entry *entry = &e820_table->entries[i]; in e820__memblock_setup()
1322 end = entry->addr + entry->size; in e820__memblock_setup()
1326 if (entry->type == E820_TYPE_SOFT_RESERVED) in e820__memblock_setup()
1327 memblock_reserve(entry->addr, entry->size); in e820__memblock_setup()
1329 if (entry->type != E820_TYPE_RAM && entry->type != E820_TYPE_RESERVED_KERN) in e820__memblock_setup()
1332 memblock_add(entry->addr, entry->size); in e820__memblock_setup()