| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * linux/arch/sh/mm/init.c |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 11 | 12 | #include <linux/swap.h> |
|---|
| 12 | 13 | #include <linux/init.h> |
|---|
| 13 | 14 | #include <linux/gfp.h> |
|---|
| 14 | | -#include <linux/bootmem.h> |
|---|
| 15 | +#include <linux/memblock.h> |
|---|
| 15 | 16 | #include <linux/proc_fs.h> |
|---|
| 16 | 17 | #include <linux/pagemap.h> |
|---|
| 17 | 18 | #include <linux/percpu.h> |
|---|
| 18 | 19 | #include <linux/io.h> |
|---|
| 19 | | -#include <linux/memblock.h> |
|---|
| 20 | 20 | #include <linux/dma-mapping.h> |
|---|
| 21 | 21 | #include <linux/export.h> |
|---|
| 22 | 22 | #include <asm/mmu_context.h> |
|---|
| .. | .. |
|---|
| 27 | 27 | #include <asm/sections.h> |
|---|
| 28 | 28 | #include <asm/setup.h> |
|---|
| 29 | 29 | #include <asm/cache.h> |
|---|
| 30 | | -#include <asm/sizes.h> |
|---|
| 30 | +#include <asm/pgalloc.h> |
|---|
| 31 | +#include <linux/sizes.h> |
|---|
| 32 | +#include "ioremap.h" |
|---|
| 31 | 33 | |
|---|
| 32 | 34 | pgd_t swapper_pg_dir[PTRS_PER_PGD]; |
|---|
| 33 | 35 | |
|---|
| .. | .. |
|---|
| 45 | 47 | static pte_t *__get_pte_phys(unsigned long addr) |
|---|
| 46 | 48 | { |
|---|
| 47 | 49 | pgd_t *pgd; |
|---|
| 50 | + p4d_t *p4d; |
|---|
| 48 | 51 | pud_t *pud; |
|---|
| 49 | 52 | pmd_t *pmd; |
|---|
| 50 | 53 | |
|---|
| .. | .. |
|---|
| 54 | 57 | return NULL; |
|---|
| 55 | 58 | } |
|---|
| 56 | 59 | |
|---|
| 57 | | - pud = pud_alloc(NULL, pgd, addr); |
|---|
| 60 | + p4d = p4d_alloc(NULL, pgd, addr); |
|---|
| 61 | + if (unlikely(!p4d)) { |
|---|
| 62 | + p4d_ERROR(*p4d); |
|---|
| 63 | + return NULL; |
|---|
| 64 | + } |
|---|
| 65 | + |
|---|
| 66 | + pud = pud_alloc(NULL, p4d, addr); |
|---|
| 58 | 67 | if (unlikely(!pud)) { |
|---|
| 59 | 68 | pud_ERROR(*pud); |
|---|
| 60 | 69 | return NULL; |
|---|
| .. | .. |
|---|
| 128 | 137 | if (pud_none(*pud)) { |
|---|
| 129 | 138 | pmd_t *pmd; |
|---|
| 130 | 139 | |
|---|
| 131 | | - pmd = alloc_bootmem_pages(PAGE_SIZE); |
|---|
| 140 | + pmd = memblock_alloc(PAGE_SIZE, PAGE_SIZE); |
|---|
| 141 | + if (!pmd) |
|---|
| 142 | + panic("%s: Failed to allocate %lu bytes align=0x%lx\n", |
|---|
| 143 | + __func__, PAGE_SIZE, PAGE_SIZE); |
|---|
| 132 | 144 | pud_populate(&init_mm, pud, pmd); |
|---|
| 133 | 145 | BUG_ON(pmd != pmd_offset(pud, 0)); |
|---|
| 134 | 146 | } |
|---|
| .. | .. |
|---|
| 141 | 153 | if (pmd_none(*pmd)) { |
|---|
| 142 | 154 | pte_t *pte; |
|---|
| 143 | 155 | |
|---|
| 144 | | - pte = alloc_bootmem_pages(PAGE_SIZE); |
|---|
| 156 | + pte = memblock_alloc(PAGE_SIZE, PAGE_SIZE); |
|---|
| 157 | + if (!pte) |
|---|
| 158 | + panic("%s: Failed to allocate %lu bytes align=0x%lx\n", |
|---|
| 159 | + __func__, PAGE_SIZE, PAGE_SIZE); |
|---|
| 145 | 160 | pmd_populate_kernel(&init_mm, pmd, pte); |
|---|
| 146 | 161 | BUG_ON(pte != pte_offset_kernel(pmd, 0)); |
|---|
| 147 | 162 | } |
|---|
| .. | .. |
|---|
| 166 | 181 | unsigned long vaddr; |
|---|
| 167 | 182 | |
|---|
| 168 | 183 | vaddr = start; |
|---|
| 169 | | - i = __pgd_offset(vaddr); |
|---|
| 170 | | - j = __pud_offset(vaddr); |
|---|
| 171 | | - k = __pmd_offset(vaddr); |
|---|
| 184 | + i = pgd_index(vaddr); |
|---|
| 185 | + j = pud_index(vaddr); |
|---|
| 186 | + k = pmd_index(vaddr); |
|---|
| 172 | 187 | pgd = pgd_base + i; |
|---|
| 173 | 188 | |
|---|
| 174 | 189 | for ( ; (i < PTRS_PER_PGD) && (vaddr != end); pgd++, i++) { |
|---|
| .. | .. |
|---|
| 193 | 208 | void __init allocate_pgdat(unsigned int nid) |
|---|
| 194 | 209 | { |
|---|
| 195 | 210 | unsigned long start_pfn, end_pfn; |
|---|
| 196 | | -#ifdef CONFIG_NEED_MULTIPLE_NODES |
|---|
| 197 | | - unsigned long phys; |
|---|
| 198 | | -#endif |
|---|
| 199 | 211 | |
|---|
| 200 | 212 | get_pfn_range_for_nid(nid, &start_pfn, &end_pfn); |
|---|
| 201 | 213 | |
|---|
| 202 | 214 | #ifdef CONFIG_NEED_MULTIPLE_NODES |
|---|
| 203 | | - phys = __memblock_alloc_base(sizeof(struct pglist_data), |
|---|
| 204 | | - SMP_CACHE_BYTES, end_pfn << PAGE_SHIFT); |
|---|
| 205 | | - /* Retry with all of system memory */ |
|---|
| 206 | | - if (!phys) |
|---|
| 207 | | - phys = __memblock_alloc_base(sizeof(struct pglist_data), |
|---|
| 208 | | - SMP_CACHE_BYTES, memblock_end_of_DRAM()); |
|---|
| 209 | | - if (!phys) |
|---|
| 215 | + NODE_DATA(nid) = memblock_alloc_try_nid( |
|---|
| 216 | + sizeof(struct pglist_data), |
|---|
| 217 | + SMP_CACHE_BYTES, MEMBLOCK_LOW_LIMIT, |
|---|
| 218 | + MEMBLOCK_ALLOC_ACCESSIBLE, nid); |
|---|
| 219 | + if (!NODE_DATA(nid)) |
|---|
| 210 | 220 | panic("Can't allocate pgdat for node %d\n", nid); |
|---|
| 211 | | - |
|---|
| 212 | | - NODE_DATA(nid) = __va(phys); |
|---|
| 213 | | - memset(NODE_DATA(nid), 0, sizeof(struct pglist_data)); |
|---|
| 214 | 221 | #endif |
|---|
| 215 | 222 | |
|---|
| 216 | 223 | NODE_DATA(nid)->node_start_pfn = start_pfn; |
|---|
| .. | .. |
|---|
| 219 | 226 | |
|---|
| 220 | 227 | static void __init do_init_bootmem(void) |
|---|
| 221 | 228 | { |
|---|
| 222 | | - struct memblock_region *reg; |
|---|
| 229 | + unsigned long start_pfn, end_pfn; |
|---|
| 230 | + int i; |
|---|
| 223 | 231 | |
|---|
| 224 | 232 | /* Add active regions with valid PFNs. */ |
|---|
| 225 | | - for_each_memblock(memory, reg) { |
|---|
| 226 | | - unsigned long start_pfn, end_pfn; |
|---|
| 227 | | - start_pfn = memblock_region_memory_base_pfn(reg); |
|---|
| 228 | | - end_pfn = memblock_region_memory_end_pfn(reg); |
|---|
| 233 | + for_each_mem_pfn_range(i, MAX_NUMNODES, &start_pfn, &end_pfn, NULL) |
|---|
| 229 | 234 | __add_active_range(0, start_pfn, end_pfn); |
|---|
| 230 | | - } |
|---|
| 231 | 235 | |
|---|
| 232 | 236 | /* All of system RAM sits in node 0 for the non-NUMA case */ |
|---|
| 233 | 237 | allocate_pgdat(0); |
|---|
| .. | .. |
|---|
| 235 | 239 | |
|---|
| 236 | 240 | plat_mem_setup(); |
|---|
| 237 | 241 | |
|---|
| 238 | | - for_each_memblock(memory, reg) { |
|---|
| 239 | | - int nid = memblock_get_region_node(reg); |
|---|
| 240 | | - |
|---|
| 241 | | - memory_present(nid, memblock_region_memory_base_pfn(reg), |
|---|
| 242 | | - memblock_region_memory_end_pfn(reg)); |
|---|
| 243 | | - } |
|---|
| 244 | 242 | sparse_init(); |
|---|
| 245 | 243 | } |
|---|
| 246 | 244 | |
|---|
| .. | .. |
|---|
| 336 | 334 | |
|---|
| 337 | 335 | memset(max_zone_pfns, 0, sizeof(max_zone_pfns)); |
|---|
| 338 | 336 | max_zone_pfns[ZONE_NORMAL] = max_low_pfn; |
|---|
| 339 | | - free_area_init_nodes(max_zone_pfns); |
|---|
| 337 | + free_area_init(max_zone_pfns); |
|---|
| 340 | 338 | } |
|---|
| 341 | 339 | |
|---|
| 342 | 340 | unsigned int mem_init_done = 0; |
|---|
| .. | .. |
|---|
| 350 | 348 | high_memory = max_t(void *, high_memory, |
|---|
| 351 | 349 | __va(pgdat_end_pfn(pgdat) << PAGE_SHIFT)); |
|---|
| 352 | 350 | |
|---|
| 353 | | - free_all_bootmem(); |
|---|
| 351 | + memblock_free_all(); |
|---|
| 354 | 352 | |
|---|
| 355 | 353 | /* Set this up early, so we can take care of the zero page */ |
|---|
| 356 | 354 | cpu_cache_init(); |
|---|
| .. | .. |
|---|
| 406 | 404 | mem_init_done = 1; |
|---|
| 407 | 405 | } |
|---|
| 408 | 406 | |
|---|
| 409 | | -void free_initmem(void) |
|---|
| 410 | | -{ |
|---|
| 411 | | - free_initmem_default(-1); |
|---|
| 412 | | -} |
|---|
| 413 | | - |
|---|
| 414 | | -#ifdef CONFIG_BLK_DEV_INITRD |
|---|
| 415 | | -void free_initrd_mem(unsigned long start, unsigned long end) |
|---|
| 416 | | -{ |
|---|
| 417 | | - free_reserved_area((void *)start, (void *)end, -1, "initrd"); |
|---|
| 418 | | -} |
|---|
| 419 | | -#endif |
|---|
| 420 | | - |
|---|
| 421 | 407 | #ifdef CONFIG_MEMORY_HOTPLUG |
|---|
| 422 | | -int arch_add_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap, |
|---|
| 423 | | - bool want_memblock) |
|---|
| 408 | +int arch_add_memory(int nid, u64 start, u64 size, |
|---|
| 409 | + struct mhp_params *params) |
|---|
| 424 | 410 | { |
|---|
| 425 | 411 | unsigned long start_pfn = PFN_DOWN(start); |
|---|
| 426 | 412 | unsigned long nr_pages = size >> PAGE_SHIFT; |
|---|
| 427 | 413 | int ret; |
|---|
| 428 | 414 | |
|---|
| 415 | + if (WARN_ON_ONCE(params->pgprot.pgprot != PAGE_KERNEL.pgprot)) |
|---|
| 416 | + return -EINVAL; |
|---|
| 417 | + |
|---|
| 429 | 418 | /* We only have ZONE_NORMAL, so this is easy.. */ |
|---|
| 430 | | - ret = __add_pages(nid, start_pfn, nr_pages, altmap, want_memblock); |
|---|
| 419 | + ret = __add_pages(nid, start_pfn, nr_pages, params); |
|---|
| 431 | 420 | if (unlikely(ret)) |
|---|
| 432 | 421 | printk("%s: Failed, __add_pages() == %d\n", __func__, ret); |
|---|
| 433 | 422 | |
|---|
| 434 | 423 | return ret; |
|---|
| 435 | 424 | } |
|---|
| 436 | | - |
|---|
| 437 | | -#ifdef CONFIG_NUMA |
|---|
| 438 | | -int memory_add_physaddr_to_nid(u64 addr) |
|---|
| 439 | | -{ |
|---|
| 440 | | - /* Node 0 for now.. */ |
|---|
| 441 | | - return 0; |
|---|
| 442 | | -} |
|---|
| 443 | | -EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); |
|---|
| 444 | | -#endif |
|---|
| 445 | 425 | |
|---|
| 446 | 426 | void arch_remove_memory(int nid, u64 start, u64 size, |
|---|
| 447 | 427 | struct vmem_altmap *altmap) |
|---|