^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Low level x86 E820 memory map handling functions.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * The firmware and bootloader passes us the "E820 table", which is the primary
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * physical memory layout description available about x86 systems.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * The kernel takes the E820 memory layout and optionally modifies it with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * quirks and other tweaks, and feeds that into the generic Linux memory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * allocation code routines via a platform independent interface (memblock, etc.).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/crash_dump.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/memblock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/suspend.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/firmware-map.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/sort.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/memory_hotplug.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <asm/e820/api.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <asm/setup.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * We organize the E820 table into three main data structures:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * - 'e820_table_firmware': the original firmware version passed to us by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * bootloader - not modified by the kernel. It is composed of two parts:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * the first 128 E820 memory entries in boot_params.e820_table and the remaining
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * (if any) entries of the SETUP_E820_EXT nodes. We use this to:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * - inform the user about the firmware's notion of memory layout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * via /sys/firmware/memmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * - the hibernation code uses it to generate a kernel-independent CRC32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * checksum of the physical memory layout of a system.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * - 'e820_table_kexec': a slightly modified (by the kernel) firmware version
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * passed to us by the bootloader - the major difference between
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * e820_table_firmware[] and this one is that, the latter marks the setup_data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * list created by the EFI boot stub as reserved, so that kexec can reuse the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * setup_data information in the second kernel. Besides, e820_table_kexec[]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * might also be modified by the kexec itself to fake a mptable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * We use this to:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * - kexec, which is a bootloader in disguise, uses the original E820
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * layout to pass to the kexec-ed kernel. This way the original kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * can have a restricted E820 map while the kexec()-ed kexec-kernel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * can have access to full memory - etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * - 'e820_table': this is the main E820 table that is massaged by the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * low level x86 platform code, or modified by boot parameters, before
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * passed on to higher level MM layers.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * Once the E820 map has been converted to the standard Linux memory layout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * information its role stops - modifying it has no effect and does not get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * re-propagated. So itsmain role is a temporary bootstrap storage of firmware
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * specific memory layout data during early bootup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static struct e820_table e820_table_init __initdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) static struct e820_table e820_table_kexec_init __initdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static struct e820_table e820_table_firmware_init __initdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) struct e820_table *e820_table __refdata = &e820_table_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct e820_table *e820_table_kexec __refdata = &e820_table_kexec_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) struct e820_table *e820_table_firmware __refdata = &e820_table_firmware_init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* For PCI or other memory-mapped resources */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) unsigned long pci_mem_start = 0xaeedbabe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #ifdef CONFIG_PCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) EXPORT_SYMBOL(pci_mem_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * This function checks if any part of the range <start,end> is mapped
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) * with type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static bool _e820__mapped_any(struct e820_table *table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) u64 start, u64 end, enum e820_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) for (i = 0; i < table->nr_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) struct e820_entry *entry = &table->entries[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (type && entry->type != type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (entry->addr >= end || entry->addr + entry->size <= start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) bool e820__mapped_raw_any(u64 start, u64 end, enum e820_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return _e820__mapped_any(e820_table_firmware, start, end, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) EXPORT_SYMBOL_GPL(e820__mapped_raw_any);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) bool e820__mapped_any(u64 start, u64 end, enum e820_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) return _e820__mapped_any(e820_table, start, end, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) EXPORT_SYMBOL_GPL(e820__mapped_any);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * This function checks if the entire <start,end> range is mapped with 'type'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * Note: this function only works correctly once the E820 table is sorted and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * not-overlapping (at least for the range specified), which is the case normally.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static struct e820_entry *__e820__mapped_all(u64 start, u64 end,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) enum e820_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) for (i = 0; i < e820_table->nr_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct e820_entry *entry = &e820_table->entries[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) if (type && entry->type != type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) /* Is the region (part) in overlap with the current region? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (entry->addr >= end || entry->addr + entry->size <= start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * If the region is at the beginning of <start,end> we move
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) * 'start' to the end of the region since it's ok until there
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (entry->addr <= start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) start = entry->addr + entry->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * If 'start' is now at or beyond 'end', we're done, full
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) * coverage of the desired range exists:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) if (start >= end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) return entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * This function checks if the entire range <start,end> is mapped with type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) bool __init e820__mapped_all(u64 start, u64 end, enum e820_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return __e820__mapped_all(start, end, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) * This function returns the type associated with the range <start,end>.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) int e820__get_entry_type(u64 start, u64 end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) struct e820_entry *entry = __e820__mapped_all(start, end, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return entry ? entry->type : -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * Add a memory region to the kernel E820 map.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static void __init __e820__range_add(struct e820_table *table, u64 start, u64 size, enum e820_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) int x = table->nr_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (x >= ARRAY_SIZE(table->entries)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) pr_err("too many entries; ignoring [mem %#010llx-%#010llx]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) start, start + size - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) table->entries[x].addr = start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) table->entries[x].size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) table->entries[x].type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) table->nr_entries++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) void __init e820__range_add(u64 start, u64 size, enum e820_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) __e820__range_add(e820_table, start, size, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) static void __init e820_print_type(enum e820_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) case E820_TYPE_RAM: /* Fall through: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) case E820_TYPE_RESERVED_KERN: pr_cont("usable"); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) case E820_TYPE_RESERVED: pr_cont("reserved"); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) case E820_TYPE_SOFT_RESERVED: pr_cont("soft reserved"); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) case E820_TYPE_ACPI: pr_cont("ACPI data"); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) case E820_TYPE_NVS: pr_cont("ACPI NVS"); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) case E820_TYPE_UNUSABLE: pr_cont("unusable"); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) case E820_TYPE_PMEM: /* Fall through: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) case E820_TYPE_PRAM: pr_cont("persistent (type %u)", type); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) default: pr_cont("type %u", type); break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) void __init e820__print_table(char *who)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) for (i = 0; i < e820_table->nr_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) pr_info("%s: [mem %#018Lx-%#018Lx] ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) who,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) e820_table->entries[i].addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) e820_table->entries[i].addr + e820_table->entries[i].size - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) e820_print_type(e820_table->entries[i].type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) pr_cont("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) * Sanitize an E820 map.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * Some E820 layouts include overlapping entries. The following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) * replaces the original E820 map with a new one, removing overlaps,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) * and resolving conflicting memory types in favor of highest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) * numbered type.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) * The input parameter 'entries' points to an array of 'struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * e820_entry' which on entry has elements in the range [0, *nr_entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * valid, and which has space for up to max_nr_entries entries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * On return, the resulting sanitized E820 map entries will be in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * overwritten in the same location, starting at 'entries'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * The integer pointed to by nr_entries must be valid on entry (the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) * current number of valid entries located at 'entries'). If the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) * sanitizing succeeds the *nr_entries will be updated with the new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * number of valid entries (something no more than max_nr_entries).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * The return value from e820__update_table() is zero if it
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * successfully 'sanitized' the map entries passed in, and is -1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * if it did nothing, which can happen if either of (1) it was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * only passed one map entry, or (2) any of the input map entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * were invalid (start + size < start, meaning that the size was
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * so big the described memory range wrapped around through zero.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * Visually we're performing the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) * (1,2,3,4 = memory types)...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) * Sample memory map (w/overlaps):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * ____22__________________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * ______________________4_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * ____1111________________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * _44_____________________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * 11111111________________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * ____________________33__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * ___________44___________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) * __________33333_________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * ______________22________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * ___________________2222_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * _________111111111______
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * _____________________11_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * _________________4______
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * Sanitized equivalent (no overlap):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * 1_______________________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) * _44_____________________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) * ___1____________________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) * ____22__________________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) * ______11________________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * _________1______________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * __________3_____________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * ___________44___________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * _____________33_________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * _______________2________
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * ________________1_______
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * _________________4______
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * ___________________2____
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) * ____________________33__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) * ______________________4_
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) struct change_member {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) /* Pointer to the original entry: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct e820_entry *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) /* Address for this change point: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) unsigned long long addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) static struct change_member change_point_list[2*E820_MAX_ENTRIES] __initdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) static struct change_member *change_point[2*E820_MAX_ENTRIES] __initdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) static struct e820_entry *overlap_list[E820_MAX_ENTRIES] __initdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) static struct e820_entry new_entries[E820_MAX_ENTRIES] __initdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) static int __init cpcompare(const void *a, const void *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) struct change_member * const *app = a, * const *bpp = b;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) const struct change_member *ap = *app, *bp = *bpp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * Inputs are pointers to two elements of change_point[]. If their
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * addresses are not equal, their difference dominates. If the addresses
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) * are equal, then consider one that represents the end of its region
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * to be greater than one that does not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) if (ap->addr != bp->addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) return ap->addr > bp->addr ? 1 : -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return (ap->addr != ap->entry->addr) - (bp->addr != bp->entry->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) static bool e820_nomerge(enum e820_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * These types may indicate distinct platform ranges aligned to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * numa node, protection domain, performance domain, or other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) * boundaries. Do not merge them.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (type == E820_TYPE_PRAM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (type == E820_TYPE_SOFT_RESERVED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) int __init e820__update_table(struct e820_table *table)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) struct e820_entry *entries = table->entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) u32 max_nr_entries = ARRAY_SIZE(table->entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) enum e820_type current_type, last_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) unsigned long long last_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) u32 new_nr_entries, overlap_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) u32 i, chg_idx, chg_nr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) /* If there's only one memory region, don't bother: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) if (table->nr_entries < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) BUG_ON(table->nr_entries > max_nr_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) /* Bail out if we find any unreasonable addresses in the map: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) for (i = 0; i < table->nr_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) if (entries[i].addr + entries[i].size < entries[i].addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /* Create pointers for initial change-point information (for sorting): */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) for (i = 0; i < 2 * table->nr_entries; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) change_point[i] = &change_point_list[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) * Record all known change-points (starting and ending addresses),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * omitting empty memory regions:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) chg_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) for (i = 0; i < table->nr_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) if (entries[i].size != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) change_point[chg_idx]->addr = entries[i].addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) change_point[chg_idx++]->entry = &entries[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) change_point[chg_idx]->addr = entries[i].addr + entries[i].size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) change_point[chg_idx++]->entry = &entries[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) chg_nr = chg_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) /* Sort change-point list by memory addresses (low -> high): */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) sort(change_point, chg_nr, sizeof(*change_point), cpcompare, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) /* Create a new memory map, removing overlaps: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) overlap_entries = 0; /* Number of entries in the overlap table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) new_nr_entries = 0; /* Index for creating new map entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) last_type = 0; /* Start with undefined memory type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) last_addr = 0; /* Start with 0 as last starting address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) /* Loop through change-points, determining effect on the new map: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) for (chg_idx = 0; chg_idx < chg_nr; chg_idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) /* Keep track of all overlapping entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) if (change_point[chg_idx]->addr == change_point[chg_idx]->entry->addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) /* Add map entry to overlap list (> 1 entry implies an overlap) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) overlap_list[overlap_entries++] = change_point[chg_idx]->entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) /* Remove entry from list (order independent, so swap with last): */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) for (i = 0; i < overlap_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) if (overlap_list[i] == change_point[chg_idx]->entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) overlap_list[i] = overlap_list[overlap_entries-1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) overlap_entries--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) * If there are overlapping entries, decide which
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) * "type" to use (larger value takes precedence --
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) * 1=usable, 2,3,4,4+=unusable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) current_type = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) for (i = 0; i < overlap_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) if (overlap_list[i]->type > current_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) current_type = overlap_list[i]->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) /* Continue building up new map based on this information: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (current_type != last_type || e820_nomerge(current_type)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) if (last_type != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) new_entries[new_nr_entries].size = change_point[chg_idx]->addr - last_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) /* Move forward only if the new size was non-zero: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) if (new_entries[new_nr_entries].size != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) /* No more space left for new entries? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) if (++new_nr_entries >= max_nr_entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) if (current_type != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) new_entries[new_nr_entries].addr = change_point[chg_idx]->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) new_entries[new_nr_entries].type = current_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) last_addr = change_point[chg_idx]->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) last_type = current_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /* Copy the new entries into the original location: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) memcpy(entries, new_entries, new_nr_entries*sizeof(*entries));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) table->nr_entries = new_nr_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) static int __init __append_e820_table(struct boot_e820_entry *entries, u32 nr_entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) struct boot_e820_entry *entry = entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) while (nr_entries) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) u64 start = entry->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) u64 size = entry->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) u64 end = start + size - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) u32 type = entry->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) /* Ignore the entry on 64-bit overflow: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) if (start > end && likely(size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) e820__range_add(start, size, type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) entry++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) nr_entries--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * Copy the BIOS E820 map into a safe place.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) * Sanity-check it while we're at it..
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * If we're lucky and live on a modern system, the setup code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) * will have given us a memory map that we can use to properly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) * set up memory. If we aren't, we'll fake a memory map.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) static int __init append_e820_table(struct boot_e820_entry *entries, u32 nr_entries)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) /* Only one memory region (or negative)? Ignore it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) if (nr_entries < 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) return __append_e820_table(entries, nr_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static u64 __init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) __e820__range_update(struct e820_table *table, u64 start, u64 size, enum e820_type old_type, enum e820_type new_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) u64 end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) unsigned int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) u64 real_updated_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) BUG_ON(old_type == new_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (size > (ULLONG_MAX - start))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) size = ULLONG_MAX - start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) end = start + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) printk(KERN_DEBUG "e820: update [mem %#010Lx-%#010Lx] ", start, end - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) e820_print_type(old_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) pr_cont(" ==> ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) e820_print_type(new_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) pr_cont("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) for (i = 0; i < table->nr_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) struct e820_entry *entry = &table->entries[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) u64 final_start, final_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) u64 entry_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) if (entry->type != old_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) entry_end = entry->addr + entry->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) /* Completely covered by new range? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) if (entry->addr >= start && entry_end <= end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) entry->type = new_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) real_updated_size += entry->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) /* New range is completely covered? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (entry->addr < start && entry_end > end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) __e820__range_add(table, start, size, new_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) __e820__range_add(table, end, entry_end - end, entry->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) entry->size = start - entry->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) real_updated_size += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) /* Partially covered: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) final_start = max(start, entry->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) final_end = min(end, entry_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) if (final_start >= final_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) __e820__range_add(table, final_start, final_end - final_start, new_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) real_updated_size += final_end - final_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) * Left range could be head or tail, so need to update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * its size first:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) entry->size -= final_end - final_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) if (entry->addr < final_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) entry->addr = final_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) return real_updated_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) u64 __init e820__range_update(u64 start, u64 size, enum e820_type old_type, enum e820_type new_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) return __e820__range_update(e820_table, start, size, old_type, new_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) static u64 __init e820__range_update_kexec(u64 start, u64 size, enum e820_type old_type, enum e820_type new_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) return __e820__range_update(e820_table_kexec, start, size, old_type, new_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) /* Remove a range of memory from the E820 table: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) u64 __init e820__range_remove(u64 start, u64 size, enum e820_type old_type, bool check_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) u64 end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) u64 real_removed_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (size > (ULLONG_MAX - start))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) size = ULLONG_MAX - start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) end = start + size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) printk(KERN_DEBUG "e820: remove [mem %#010Lx-%#010Lx] ", start, end - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) if (check_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) e820_print_type(old_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) pr_cont("\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) for (i = 0; i < e820_table->nr_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) struct e820_entry *entry = &e820_table->entries[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) u64 final_start, final_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) u64 entry_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) if (check_type && entry->type != old_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) entry_end = entry->addr + entry->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) /* Completely covered? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) if (entry->addr >= start && entry_end <= end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) real_removed_size += entry->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) memset(entry, 0, sizeof(*entry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) /* Is the new range completely covered? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) if (entry->addr < start && entry_end > end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) e820__range_add(end, entry_end - end, entry->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) entry->size = start - entry->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) real_removed_size += size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) /* Partially covered: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) final_start = max(start, entry->addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) final_end = min(end, entry_end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) if (final_start >= final_end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) real_removed_size += final_end - final_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) * Left range could be head or tail, so need to update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) * the size first:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) entry->size -= final_end - final_start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) if (entry->addr < final_start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) entry->addr = final_end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return real_removed_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) void __init e820__update_table_print(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) if (e820__update_table(e820_table))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) pr_info("modified physical RAM map:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) e820__print_table("modified");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) static void __init e820__update_table_kexec(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) e820__update_table(e820_table_kexec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) #define MAX_GAP_END 0x100000000ull
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) * Search for a gap in the E820 memory space from 0 to MAX_GAP_END (4GB).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) static int __init e820_search_gap(unsigned long *gapstart, unsigned long *gapsize)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) unsigned long long last = MAX_GAP_END;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) int i = e820_table->nr_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) int found = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) while (--i >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) unsigned long long start = e820_table->entries[i].addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) unsigned long long end = start + e820_table->entries[i].size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) * Since "last" is at most 4GB, we know we'll
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) * fit in 32 bits if this condition is true:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) if (last > end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) unsigned long gap = last - end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) if (gap >= *gapsize) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) *gapsize = gap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) *gapstart = end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (start < last)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) last = start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) return found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) * Search for the biggest gap in the low 32 bits of the E820
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) * memory space. We pass this space to the PCI subsystem, so
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) * that it can assign MMIO resources for hotplug or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) * unconfigured devices in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) * Hopefully the BIOS let enough space left.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) __init void e820__setup_pci_gap(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) unsigned long gapstart, gapsize;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) int found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) gapsize = 0x400000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) found = e820_search_gap(&gapstart, &gapsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) if (!found) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) #ifdef CONFIG_X86_64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) gapstart = (max_pfn << PAGE_SHIFT) + 1024*1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) pr_err("Cannot find an available gap in the 32-bit address range\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) pr_err("PCI devices with unassigned 32-bit BARs may not work!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) gapstart = 0x10000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) * e820__reserve_resources_late() protects stolen RAM already:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) pci_mem_start = gapstart;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) pr_info("[mem %#010lx-%#010lx] available for PCI devices\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) gapstart, gapstart + gapsize - 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) * Called late during init, in free_initmem().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) * Initial e820_table and e820_table_kexec are largish __initdata arrays.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) * Copy them to a (usually much smaller) dynamically allocated area that is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) * sized precisely after the number of e820 entries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) * This is done after we've performed all the fixes and tweaks to the tables.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) * All functions which modify them are __init functions, which won't exist
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) * after free_initmem().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) __init void e820__reallocate_tables(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) struct e820_table *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) size = offsetof(struct e820_table, entries) + sizeof(struct e820_entry)*e820_table->nr_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) n = kmemdup(e820_table, size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) BUG_ON(!n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) e820_table = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) size = offsetof(struct e820_table, entries) + sizeof(struct e820_entry)*e820_table_kexec->nr_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) n = kmemdup(e820_table_kexec, size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) BUG_ON(!n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) e820_table_kexec = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) size = offsetof(struct e820_table, entries) + sizeof(struct e820_entry)*e820_table_firmware->nr_entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) n = kmemdup(e820_table_firmware, size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) BUG_ON(!n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) e820_table_firmware = n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) * Because of the small fixed size of struct boot_params, only the first
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) * 128 E820 memory entries are passed to the kernel via boot_params.e820_table,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) * the remaining (if any) entries are passed via the SETUP_E820_EXT node of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) * struct setup_data, which is parsed here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) void __init e820__memory_setup_extended(u64 phys_addr, u32 data_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) int entries;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) struct boot_e820_entry *extmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) struct setup_data *sdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) sdata = early_memremap(phys_addr, data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) entries = sdata->len / sizeof(*extmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) extmap = (struct boot_e820_entry *)(sdata->data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) __append_e820_table(extmap, entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) e820__update_table(e820_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) memcpy(e820_table_kexec, e820_table, sizeof(*e820_table_kexec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) memcpy(e820_table_firmware, e820_table, sizeof(*e820_table_firmware));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) early_memunmap(sdata, data_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) pr_info("extended physical RAM map:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) e820__print_table("extended");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) * Find the ranges of physical addresses that do not correspond to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) * E820 RAM areas and register the corresponding pages as 'nosave' for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) * hibernation (32-bit) or software suspend and suspend to RAM (64-bit).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) * This function requires the E820 map to be sorted and without any
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) * overlapping entries.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) void __init e820__register_nosave_regions(unsigned long limit_pfn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) unsigned long pfn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) for (i = 0; i < e820_table->nr_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) struct e820_entry *entry = &e820_table->entries[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (pfn < PFN_UP(entry->addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) register_nosave_region(pfn, PFN_UP(entry->addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) pfn = PFN_DOWN(entry->addr + entry->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) if (entry->type != E820_TYPE_RAM && entry->type != E820_TYPE_RESERVED_KERN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) register_nosave_region(PFN_UP(entry->addr), pfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) if (pfn >= limit_pfn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) #ifdef CONFIG_ACPI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) * Register ACPI NVS memory regions, so that we can save/restore them during
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) * hibernation and the subsequent resume:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) static int __init e820__register_nvs_regions(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) for (i = 0; i < e820_table->nr_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) struct e820_entry *entry = &e820_table->entries[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) if (entry->type == E820_TYPE_NVS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) acpi_nvs_register(entry->addr, entry->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) core_initcall(e820__register_nvs_regions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) * Allocate the requested number of bytes with the requsted alignment
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) * and return (the physical address) to the caller. Also register this
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) * range in the 'kexec' E820 table as a reserved range.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) * This allows kexec to fake a new mptable, as if it came from the real
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) * system.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) u64 __init e820__memblock_alloc_reserved(u64 size, u64 align)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) u64 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) addr = memblock_phys_alloc(size, align);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) if (addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) e820__range_update_kexec(addr, size, E820_TYPE_RAM, E820_TYPE_RESERVED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) pr_info("update e820_table_kexec for e820__memblock_alloc_reserved()\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) e820__update_table_kexec();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) return addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) #ifdef CONFIG_X86_32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) # ifdef CONFIG_X86_PAE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) # define MAX_ARCH_PFN (1ULL<<(36-PAGE_SHIFT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) # else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) # define MAX_ARCH_PFN (1ULL<<(32-PAGE_SHIFT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) # endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) #else /* CONFIG_X86_32 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) # define MAX_ARCH_PFN MAXMEM>>PAGE_SHIFT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) * Find the highest page frame number we have available
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) static unsigned long __init e820_end_pfn(unsigned long limit_pfn, enum e820_type type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) unsigned long last_pfn = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) unsigned long max_arch_pfn = MAX_ARCH_PFN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) for (i = 0; i < e820_table->nr_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) struct e820_entry *entry = &e820_table->entries[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) unsigned long start_pfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) unsigned long end_pfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) if (entry->type != type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) start_pfn = entry->addr >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) end_pfn = (entry->addr + entry->size) >> PAGE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) if (start_pfn >= limit_pfn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) if (end_pfn > limit_pfn) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) last_pfn = limit_pfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) if (end_pfn > last_pfn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) last_pfn = end_pfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) if (last_pfn > max_arch_pfn)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) last_pfn = max_arch_pfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) pr_info("last_pfn = %#lx max_arch_pfn = %#lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) last_pfn, max_arch_pfn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) return last_pfn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) unsigned long __init e820__end_of_ram_pfn(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) return e820_end_pfn(MAX_ARCH_PFN, E820_TYPE_RAM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) unsigned long __init e820__end_of_low_ram_pfn(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return e820_end_pfn(1UL << (32 - PAGE_SHIFT), E820_TYPE_RAM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) static void __init early_panic(char *msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) early_printk(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) panic(msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) static int userdef __initdata;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) /* The "mem=nopentium" boot option disables 4MB page tables on 32-bit kernels: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) static int __init parse_memopt(char *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) u64 mem_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) if (!strcmp(p, "nopentium")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) #ifdef CONFIG_X86_32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) setup_clear_cpu_cap(X86_FEATURE_PSE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) pr_warn("mem=nopentium ignored! (only supported on x86_32)\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) userdef = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) mem_size = memparse(p, &p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) /* Don't remove all memory when getting "mem={invalid}" parameter: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) if (mem_size == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) e820__range_remove(mem_size, ULLONG_MAX - mem_size, E820_TYPE_RAM, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) #ifdef CONFIG_MEMORY_HOTPLUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) max_mem_size = mem_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) early_param("mem", parse_memopt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) static int __init parse_memmap_one(char *p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) char *oldp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) u64 start_at, mem_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) if (!strncmp(p, "exactmap", 8)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) e820_table->nr_entries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) userdef = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) oldp = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) mem_size = memparse(p, &p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) if (p == oldp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) userdef = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) if (*p == '@') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) start_at = memparse(p+1, &p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) e820__range_add(start_at, mem_size, E820_TYPE_RAM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) } else if (*p == '#') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) start_at = memparse(p+1, &p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) e820__range_add(start_at, mem_size, E820_TYPE_ACPI);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) } else if (*p == '$') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) start_at = memparse(p+1, &p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) e820__range_add(start_at, mem_size, E820_TYPE_RESERVED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) } else if (*p == '!') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) start_at = memparse(p+1, &p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) e820__range_add(start_at, mem_size, E820_TYPE_PRAM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) } else if (*p == '%') {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) enum e820_type from = 0, to = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) start_at = memparse(p + 1, &p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) if (*p == '-')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) from = simple_strtoull(p + 1, &p, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) if (*p == '+')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) to = simple_strtoull(p + 1, &p, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) if (*p != '\0')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) if (from && to)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) e820__range_update(start_at, mem_size, from, to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) else if (to)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) e820__range_add(start_at, mem_size, to);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) else if (from)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) e820__range_remove(start_at, mem_size, from, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) e820__range_remove(start_at, mem_size, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) e820__range_remove(mem_size, ULLONG_MAX - mem_size, E820_TYPE_RAM, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) return *p == '\0' ? 0 : -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) static int __init parse_memmap_opt(char *str)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) while (str) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) char *k = strchr(str, ',');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) if (k)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) *k++ = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) parse_memmap_one(str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) str = k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) early_param("memmap", parse_memmap_opt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) * Reserve all entries from the bootloader's extensible data nodes list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) * because if present we are going to use it later on to fetch e820
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) * entries from it:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) void __init e820__reserve_setup_data(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) struct setup_indirect *indirect;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) struct setup_data *data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) u64 pa_data, pa_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) u32 len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) pa_data = boot_params.hdr.setup_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) if (!pa_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) while (pa_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) data = early_memremap(pa_data, sizeof(*data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (!data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) pr_warn("e820: failed to memremap setup_data entry\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) len = sizeof(*data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) pa_next = data->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) e820__range_update(pa_data, sizeof(*data)+data->len, E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) * SETUP_EFI is supplied by kexec and does not need to be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) * reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) if (data->type != SETUP_EFI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) e820__range_update_kexec(pa_data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) sizeof(*data) + data->len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) if (data->type == SETUP_INDIRECT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) len += data->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) early_memunmap(data, sizeof(*data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) data = early_memremap(pa_data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) if (!data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) pr_warn("e820: failed to memremap indirect setup_data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) indirect = (struct setup_indirect *)data->data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (indirect->type != SETUP_INDIRECT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) e820__range_update(indirect->addr, indirect->len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) e820__range_update_kexec(indirect->addr, indirect->len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) E820_TYPE_RAM, E820_TYPE_RESERVED_KERN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) pa_data = pa_next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) early_memunmap(data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) e820__update_table(e820_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) e820__update_table(e820_table_kexec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) pr_info("extended physical RAM map:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) e820__print_table("reserve setup_data");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) * Called after parse_early_param(), after early parameters (such as mem=)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) * have been processed, in which case we already have an E820 table filled in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) * via the parameter callback function(s), but it's not sorted and printed yet:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) void __init e820__finish_early_params(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) if (userdef) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) if (e820__update_table(e820_table) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) early_panic("Invalid user supplied memory map");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) pr_info("user-defined physical RAM map:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) e820__print_table("user");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) static const char *__init e820_type_to_string(struct e820_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) switch (entry->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) case E820_TYPE_RESERVED_KERN: /* Fall-through: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) case E820_TYPE_RAM: return "System RAM";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) case E820_TYPE_ACPI: return "ACPI Tables";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) case E820_TYPE_NVS: return "ACPI Non-volatile Storage";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) case E820_TYPE_UNUSABLE: return "Unusable memory";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) case E820_TYPE_PRAM: return "Persistent Memory (legacy)";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) case E820_TYPE_PMEM: return "Persistent Memory";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) case E820_TYPE_RESERVED: return "Reserved";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) case E820_TYPE_SOFT_RESERVED: return "Soft Reserved";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) default: return "Unknown E820 type";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) static unsigned long __init e820_type_to_iomem_type(struct e820_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) switch (entry->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) case E820_TYPE_RESERVED_KERN: /* Fall-through: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) case E820_TYPE_RAM: return IORESOURCE_SYSTEM_RAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) case E820_TYPE_ACPI: /* Fall-through: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) case E820_TYPE_NVS: /* Fall-through: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) case E820_TYPE_UNUSABLE: /* Fall-through: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) case E820_TYPE_PRAM: /* Fall-through: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) case E820_TYPE_PMEM: /* Fall-through: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) case E820_TYPE_RESERVED: /* Fall-through: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) case E820_TYPE_SOFT_RESERVED: /* Fall-through: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) default: return IORESOURCE_MEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) static unsigned long __init e820_type_to_iores_desc(struct e820_entry *entry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) switch (entry->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) case E820_TYPE_ACPI: return IORES_DESC_ACPI_TABLES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) case E820_TYPE_NVS: return IORES_DESC_ACPI_NV_STORAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) case E820_TYPE_PMEM: return IORES_DESC_PERSISTENT_MEMORY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) case E820_TYPE_PRAM: return IORES_DESC_PERSISTENT_MEMORY_LEGACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) case E820_TYPE_RESERVED: return IORES_DESC_RESERVED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) case E820_TYPE_SOFT_RESERVED: return IORES_DESC_SOFT_RESERVED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) case E820_TYPE_RESERVED_KERN: /* Fall-through: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) case E820_TYPE_RAM: /* Fall-through: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) case E820_TYPE_UNUSABLE: /* Fall-through: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) default: return IORES_DESC_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) static bool __init do_mark_busy(enum e820_type type, struct resource *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) /* this is the legacy bios/dos rom-shadow + mmio region */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) if (res->start < (1ULL<<20))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) * Treat persistent memory and other special memory ranges like
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) * device memory, i.e. reserve it for exclusive use of a driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) case E820_TYPE_RESERVED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) case E820_TYPE_SOFT_RESERVED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) case E820_TYPE_PRAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) case E820_TYPE_PMEM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) case E820_TYPE_RESERVED_KERN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) case E820_TYPE_RAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) case E820_TYPE_ACPI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) case E820_TYPE_NVS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) case E820_TYPE_UNUSABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) * Mark E820 reserved areas as busy for the resource manager:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) static struct resource __initdata *e820_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) void __init e820__reserve_resources(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) u64 end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) res = memblock_alloc(sizeof(*res) * e820_table->nr_entries,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) SMP_CACHE_BYTES);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) if (!res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) panic("%s: Failed to allocate %zu bytes\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) sizeof(*res) * e820_table->nr_entries);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) e820_res = res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) for (i = 0; i < e820_table->nr_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) struct e820_entry *entry = e820_table->entries + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) end = entry->addr + entry->size - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) if (end != (resource_size_t)end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) res++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) res->start = entry->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) res->end = end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) res->name = e820_type_to_string(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) res->flags = e820_type_to_iomem_type(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) res->desc = e820_type_to_iores_desc(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) * Don't register the region that could be conflicted with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) * PCI device BAR resources and insert them later in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) * pcibios_resource_survey():
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) if (do_mark_busy(entry->type, res)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) res->flags |= IORESOURCE_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) insert_resource(&iomem_resource, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) res++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) /* Expose the bootloader-provided memory layout to the sysfs. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) for (i = 0; i < e820_table_firmware->nr_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) struct e820_entry *entry = e820_table_firmware->entries + i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) firmware_map_add_early(entry->addr, entry->addr + entry->size, e820_type_to_string(entry));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) * How much should we pad the end of RAM, depending on where it is?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) static unsigned long __init ram_alignment(resource_size_t pos)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) unsigned long mb = pos >> 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) /* To 64kB in the first megabyte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) if (!mb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) return 64*1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) /* To 1MB in the first 16MB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) if (mb < 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) return 1024*1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) /* To 64MB for anything above that */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) return 64*1024*1024;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) #define MAX_RESOURCE_SIZE ((resource_size_t)-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) void __init e820__reserve_resources_late(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) struct resource *res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) res = e820_res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) for (i = 0; i < e820_table->nr_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) if (!res->parent && res->end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) insert_resource_expand_to_fit(&iomem_resource, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) res++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) * Try to bump up RAM regions to reasonable boundaries, to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) * avoid stolen RAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) for (i = 0; i < e820_table->nr_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) struct e820_entry *entry = &e820_table->entries[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) u64 start, end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) if (entry->type != E820_TYPE_RAM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) start = entry->addr + entry->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) end = round_up(start, ram_alignment(start)) - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) if (end > MAX_RESOURCE_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) end = MAX_RESOURCE_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) if (start >= end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) printk(KERN_DEBUG "e820: reserve RAM buffer [mem %#010llx-%#010llx]\n", start, end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) reserve_region_with_split(&iomem_resource, start, end, "RAM buffer");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) * Pass the firmware (bootloader) E820 map to the kernel and process it:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) char *__init e820__memory_setup_default(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) char *who = "BIOS-e820";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) * Try to copy the BIOS-supplied E820-map.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) * Otherwise fake a memory map; one section from 0k->640k,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) * the next section from 1mb->appropriate_mem_k
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) if (append_e820_table(boot_params.e820_table, boot_params.e820_entries) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) u64 mem_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) /* Compare results from other methods and take the one that gives more RAM: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) if (boot_params.alt_mem_k < boot_params.screen_info.ext_mem_k) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) mem_size = boot_params.screen_info.ext_mem_k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) who = "BIOS-88";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) mem_size = boot_params.alt_mem_k;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) who = "BIOS-e801";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) e820_table->nr_entries = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) e820__range_add(0, LOWMEMSIZE(), E820_TYPE_RAM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) e820__range_add(HIGH_MEMORY, mem_size << 10, E820_TYPE_RAM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) /* We just appended a lot of ranges, sanitize the table: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) e820__update_table(e820_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) return who;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) * Calls e820__memory_setup_default() in essence to pick up the firmware/bootloader
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) * E820 map - with an optional platform quirk available for virtual platforms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) * to override this method of boot environment processing:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) void __init e820__memory_setup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) char *who;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) /* This is a firmware interface ABI - make sure we don't break it: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) BUILD_BUG_ON(sizeof(struct boot_e820_entry) != 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) who = x86_init.resources.memory_setup();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) memcpy(e820_table_kexec, e820_table, sizeof(*e820_table_kexec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) memcpy(e820_table_firmware, e820_table, sizeof(*e820_table_firmware));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) pr_info("BIOS-provided physical RAM map:\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) e820__print_table(who);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) void __init e820__memblock_setup(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) u64 end;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) * The bootstrap memblock region count maximum is 128 entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) * (INIT_MEMBLOCK_REGIONS), but EFI might pass us more E820 entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) * than that - so allow memblock resizing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) * This is safe, because this call happens pretty late during x86 setup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) * so we know about reserved memory regions already. (This is important
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) * so that memblock resizing does no stomp over reserved areas.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) memblock_allow_resize();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) for (i = 0; i < e820_table->nr_entries; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) struct e820_entry *entry = &e820_table->entries[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) end = entry->addr + entry->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) if (end != (resource_size_t)end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) if (entry->type == E820_TYPE_SOFT_RESERVED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) memblock_reserve(entry->addr, entry->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) if (entry->type != E820_TYPE_RAM && entry->type != E820_TYPE_RESERVED_KERN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) memblock_add(entry->addr, entry->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) /* Throw away partial pages: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) memblock_trim_memory(PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) memblock_dump_all();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) }