18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * Copyright (C) 2007-2008 Michal Simek <monstr@monstr.eu> 38c2ecf20Sopenharmony_ci * Copyright (C) 2006 Atmark Techno, Inc. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * This file is subject to the terms and conditions of the GNU General Public 68c2ecf20Sopenharmony_ci * License. See the file "COPYING" in the main directory of this archive 78c2ecf20Sopenharmony_ci * for more details. 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/dma-map-ops.h> 118c2ecf20Sopenharmony_ci#include <linux/memblock.h> 128c2ecf20Sopenharmony_ci#include <linux/init.h> 138c2ecf20Sopenharmony_ci#include <linux/kernel.h> 148c2ecf20Sopenharmony_ci#include <linux/mm.h> /* mem_init */ 158c2ecf20Sopenharmony_ci#include <linux/initrd.h> 168c2ecf20Sopenharmony_ci#include <linux/pagemap.h> 178c2ecf20Sopenharmony_ci#include <linux/pfn.h> 188c2ecf20Sopenharmony_ci#include <linux/slab.h> 198c2ecf20Sopenharmony_ci#include <linux/swap.h> 208c2ecf20Sopenharmony_ci#include <linux/export.h> 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci#include <asm/page.h> 238c2ecf20Sopenharmony_ci#include <asm/mmu_context.h> 248c2ecf20Sopenharmony_ci#include <asm/pgalloc.h> 258c2ecf20Sopenharmony_ci#include <asm/sections.h> 268c2ecf20Sopenharmony_ci#include <asm/tlb.h> 278c2ecf20Sopenharmony_ci#include <asm/fixmap.h> 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci/* Use for MMU and noMMU because of PCI generic code */ 308c2ecf20Sopenharmony_ciint mem_init_done; 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci#ifndef CONFIG_MMU 338c2ecf20Sopenharmony_ciunsigned int __page_offset; 348c2ecf20Sopenharmony_ciEXPORT_SYMBOL(__page_offset); 358c2ecf20Sopenharmony_ci#endif /* CONFIG_MMU */ 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_cichar *klimit = _end; 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci/* 408c2ecf20Sopenharmony_ci * Initialize the bootmem system and give it all the memory we 418c2ecf20Sopenharmony_ci * have available. 428c2ecf20Sopenharmony_ci */ 438c2ecf20Sopenharmony_ciunsigned long memory_start; 448c2ecf20Sopenharmony_ciEXPORT_SYMBOL(memory_start); 458c2ecf20Sopenharmony_ciunsigned long memory_size; 468c2ecf20Sopenharmony_ciEXPORT_SYMBOL(memory_size); 478c2ecf20Sopenharmony_ciunsigned long lowmem_size; 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ciEXPORT_SYMBOL(min_low_pfn); 508c2ecf20Sopenharmony_ciEXPORT_SYMBOL(max_low_pfn); 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci#ifdef CONFIG_HIGHMEM 538c2ecf20Sopenharmony_cipte_t *kmap_pte; 548c2ecf20Sopenharmony_ciEXPORT_SYMBOL(kmap_pte); 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_cistatic void __init highmem_init(void) 578c2ecf20Sopenharmony_ci{ 588c2ecf20Sopenharmony_ci pr_debug("%x\n", (u32)PKMAP_BASE); 598c2ecf20Sopenharmony_ci map_page(PKMAP_BASE, 0, 0); /* XXX gross */ 608c2ecf20Sopenharmony_ci pkmap_page_table = virt_to_kpte(PKMAP_BASE); 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci kmap_pte = virt_to_kpte(__fix_to_virt(FIX_KMAP_BEGIN)); 638c2ecf20Sopenharmony_ci} 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_cistatic void highmem_setup(void) 668c2ecf20Sopenharmony_ci{ 678c2ecf20Sopenharmony_ci unsigned long pfn; 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci for (pfn = max_low_pfn; pfn < max_pfn; ++pfn) { 708c2ecf20Sopenharmony_ci struct page *page = pfn_to_page(pfn); 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci /* FIXME not sure about */ 738c2ecf20Sopenharmony_ci if (!memblock_is_reserved(pfn << PAGE_SHIFT)) 748c2ecf20Sopenharmony_ci free_highmem_page(page); 758c2ecf20Sopenharmony_ci } 768c2ecf20Sopenharmony_ci} 778c2ecf20Sopenharmony_ci#endif /* CONFIG_HIGHMEM */ 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci/* 808c2ecf20Sopenharmony_ci * paging_init() sets up the page tables - in fact we've already done this. 818c2ecf20Sopenharmony_ci */ 828c2ecf20Sopenharmony_cistatic void __init paging_init(void) 838c2ecf20Sopenharmony_ci{ 848c2ecf20Sopenharmony_ci unsigned long zones_size[MAX_NR_ZONES]; 858c2ecf20Sopenharmony_ci#ifdef CONFIG_MMU 868c2ecf20Sopenharmony_ci int idx; 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci /* Setup fixmaps */ 898c2ecf20Sopenharmony_ci for (idx = 0; idx < __end_of_fixed_addresses; idx++) 908c2ecf20Sopenharmony_ci clear_fixmap(idx); 918c2ecf20Sopenharmony_ci#endif 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci /* Clean every zones */ 948c2ecf20Sopenharmony_ci memset(zones_size, 0, sizeof(zones_size)); 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci#ifdef CONFIG_HIGHMEM 978c2ecf20Sopenharmony_ci highmem_init(); 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci zones_size[ZONE_DMA] = max_low_pfn; 1008c2ecf20Sopenharmony_ci zones_size[ZONE_HIGHMEM] = max_pfn; 1018c2ecf20Sopenharmony_ci#else 1028c2ecf20Sopenharmony_ci zones_size[ZONE_DMA] = max_pfn; 1038c2ecf20Sopenharmony_ci#endif 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci /* We don't have holes in memory map */ 1068c2ecf20Sopenharmony_ci free_area_init(zones_size); 1078c2ecf20Sopenharmony_ci} 1088c2ecf20Sopenharmony_ci 1098c2ecf20Sopenharmony_civoid __init setup_memory(void) 1108c2ecf20Sopenharmony_ci{ 1118c2ecf20Sopenharmony_ci#ifndef CONFIG_MMU 1128c2ecf20Sopenharmony_ci u32 kernel_align_start, kernel_align_size; 1138c2ecf20Sopenharmony_ci phys_addr_t start, end; 1148c2ecf20Sopenharmony_ci u64 i; 1158c2ecf20Sopenharmony_ci 1168c2ecf20Sopenharmony_ci /* Find main memory where is the kernel */ 1178c2ecf20Sopenharmony_ci for_each_mem_range(i, &start, &end) { 1188c2ecf20Sopenharmony_ci memory_start = start; 1198c2ecf20Sopenharmony_ci lowmem_size = end - start; 1208c2ecf20Sopenharmony_ci if ((memory_start <= (u32)_text) && 1218c2ecf20Sopenharmony_ci ((u32)_text <= (memory_start + lowmem_size - 1))) { 1228c2ecf20Sopenharmony_ci memory_size = lowmem_size; 1238c2ecf20Sopenharmony_ci PAGE_OFFSET = memory_start; 1248c2ecf20Sopenharmony_ci pr_info("%s: Main mem: 0x%x, size 0x%08x\n", 1258c2ecf20Sopenharmony_ci __func__, (u32) memory_start, 1268c2ecf20Sopenharmony_ci (u32) memory_size); 1278c2ecf20Sopenharmony_ci break; 1288c2ecf20Sopenharmony_ci } 1298c2ecf20Sopenharmony_ci } 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci if (!memory_start || !memory_size) { 1328c2ecf20Sopenharmony_ci panic("%s: Missing memory setting 0x%08x, size=0x%08x\n", 1338c2ecf20Sopenharmony_ci __func__, (u32) memory_start, (u32) memory_size); 1348c2ecf20Sopenharmony_ci } 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci /* reservation of region where is the kernel */ 1378c2ecf20Sopenharmony_ci kernel_align_start = PAGE_DOWN((u32)_text); 1388c2ecf20Sopenharmony_ci /* ALIGN can be remove because _end in vmlinux.lds.S is align */ 1398c2ecf20Sopenharmony_ci kernel_align_size = PAGE_UP((u32)klimit) - kernel_align_start; 1408c2ecf20Sopenharmony_ci pr_info("%s: kernel addr:0x%08x-0x%08x size=0x%08x\n", 1418c2ecf20Sopenharmony_ci __func__, kernel_align_start, kernel_align_start 1428c2ecf20Sopenharmony_ci + kernel_align_size, kernel_align_size); 1438c2ecf20Sopenharmony_ci memblock_reserve(kernel_align_start, kernel_align_size); 1448c2ecf20Sopenharmony_ci#endif 1458c2ecf20Sopenharmony_ci /* 1468c2ecf20Sopenharmony_ci * Kernel: 1478c2ecf20Sopenharmony_ci * start: base phys address of kernel - page align 1488c2ecf20Sopenharmony_ci * end: base phys address of kernel - page align 1498c2ecf20Sopenharmony_ci * 1508c2ecf20Sopenharmony_ci * min_low_pfn - the first page (mm/bootmem.c - node_boot_start) 1518c2ecf20Sopenharmony_ci * max_low_pfn 1528c2ecf20Sopenharmony_ci * max_mapnr - the first unused page (mm/bootmem.c - node_low_pfn) 1538c2ecf20Sopenharmony_ci */ 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci /* memory start is from the kernel end (aligned) to higher addr */ 1568c2ecf20Sopenharmony_ci min_low_pfn = memory_start >> PAGE_SHIFT; /* minimum for allocation */ 1578c2ecf20Sopenharmony_ci /* RAM is assumed contiguous */ 1588c2ecf20Sopenharmony_ci max_mapnr = memory_size >> PAGE_SHIFT; 1598c2ecf20Sopenharmony_ci max_low_pfn = ((u64)memory_start + (u64)lowmem_size) >> PAGE_SHIFT; 1608c2ecf20Sopenharmony_ci max_pfn = ((u64)memory_start + (u64)memory_size) >> PAGE_SHIFT; 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci pr_info("%s: max_mapnr: %#lx\n", __func__, max_mapnr); 1638c2ecf20Sopenharmony_ci pr_info("%s: min_low_pfn: %#lx\n", __func__, min_low_pfn); 1648c2ecf20Sopenharmony_ci pr_info("%s: max_low_pfn: %#lx\n", __func__, max_low_pfn); 1658c2ecf20Sopenharmony_ci pr_info("%s: max_pfn: %#lx\n", __func__, max_pfn); 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_ci paging_init(); 1688c2ecf20Sopenharmony_ci} 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_civoid __init mem_init(void) 1718c2ecf20Sopenharmony_ci{ 1728c2ecf20Sopenharmony_ci high_memory = (void *)__va(memory_start + lowmem_size - 1); 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_ci /* this will put all memory onto the freelists */ 1758c2ecf20Sopenharmony_ci memblock_free_all(); 1768c2ecf20Sopenharmony_ci#ifdef CONFIG_HIGHMEM 1778c2ecf20Sopenharmony_ci highmem_setup(); 1788c2ecf20Sopenharmony_ci#endif 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_ci mem_init_print_info(NULL); 1818c2ecf20Sopenharmony_ci mem_init_done = 1; 1828c2ecf20Sopenharmony_ci} 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci#ifndef CONFIG_MMU 1858c2ecf20Sopenharmony_ciint page_is_ram(unsigned long pfn) 1868c2ecf20Sopenharmony_ci{ 1878c2ecf20Sopenharmony_ci return __range_ok(pfn, 0); 1888c2ecf20Sopenharmony_ci} 1898c2ecf20Sopenharmony_ci#else 1908c2ecf20Sopenharmony_ciint page_is_ram(unsigned long pfn) 1918c2ecf20Sopenharmony_ci{ 1928c2ecf20Sopenharmony_ci return pfn < max_low_pfn; 1938c2ecf20Sopenharmony_ci} 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci/* 1968c2ecf20Sopenharmony_ci * Check for command-line options that affect what MMU_init will do. 1978c2ecf20Sopenharmony_ci */ 1988c2ecf20Sopenharmony_cistatic void mm_cmdline_setup(void) 1998c2ecf20Sopenharmony_ci{ 2008c2ecf20Sopenharmony_ci unsigned long maxmem = 0; 2018c2ecf20Sopenharmony_ci char *p = cmd_line; 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci /* Look for mem= option on command line */ 2048c2ecf20Sopenharmony_ci p = strstr(cmd_line, "mem="); 2058c2ecf20Sopenharmony_ci if (p) { 2068c2ecf20Sopenharmony_ci p += 4; 2078c2ecf20Sopenharmony_ci maxmem = memparse(p, &p); 2088c2ecf20Sopenharmony_ci if (maxmem && memory_size > maxmem) { 2098c2ecf20Sopenharmony_ci memory_size = maxmem; 2108c2ecf20Sopenharmony_ci memblock.memory.regions[0].size = memory_size; 2118c2ecf20Sopenharmony_ci } 2128c2ecf20Sopenharmony_ci } 2138c2ecf20Sopenharmony_ci} 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci/* 2168c2ecf20Sopenharmony_ci * MMU_init_hw does the chip-specific initialization of the MMU hardware. 2178c2ecf20Sopenharmony_ci */ 2188c2ecf20Sopenharmony_cistatic void __init mmu_init_hw(void) 2198c2ecf20Sopenharmony_ci{ 2208c2ecf20Sopenharmony_ci /* 2218c2ecf20Sopenharmony_ci * The Zone Protection Register (ZPR) defines how protection will 2228c2ecf20Sopenharmony_ci * be applied to every page which is a member of a given zone. At 2238c2ecf20Sopenharmony_ci * present, we utilize only two of the zones. 2248c2ecf20Sopenharmony_ci * The zone index bits (of ZSEL) in the PTE are used for software 2258c2ecf20Sopenharmony_ci * indicators, except the LSB. For user access, zone 1 is used, 2268c2ecf20Sopenharmony_ci * for kernel access, zone 0 is used. We set all but zone 1 2278c2ecf20Sopenharmony_ci * to zero, allowing only kernel access as indicated in the PTE. 2288c2ecf20Sopenharmony_ci * For zone 1, we set a 01 binary (a value of 10 will not work) 2298c2ecf20Sopenharmony_ci * to allow user access as indicated in the PTE. This also allows 2308c2ecf20Sopenharmony_ci * kernel access as indicated in the PTE. 2318c2ecf20Sopenharmony_ci */ 2328c2ecf20Sopenharmony_ci __asm__ __volatile__ ("ori r11, r0, 0x10000000;" \ 2338c2ecf20Sopenharmony_ci "mts rzpr, r11;" 2348c2ecf20Sopenharmony_ci : : : "r11"); 2358c2ecf20Sopenharmony_ci} 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_ci/* 2388c2ecf20Sopenharmony_ci * MMU_init sets up the basic memory mappings for the kernel, 2398c2ecf20Sopenharmony_ci * including both RAM and possibly some I/O regions, 2408c2ecf20Sopenharmony_ci * and sets up the page tables and the MMU hardware ready to go. 2418c2ecf20Sopenharmony_ci */ 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci/* called from head.S */ 2448c2ecf20Sopenharmony_ciasmlinkage void __init mmu_init(void) 2458c2ecf20Sopenharmony_ci{ 2468c2ecf20Sopenharmony_ci unsigned int kstart, ksize; 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci if (!memblock.reserved.cnt) { 2498c2ecf20Sopenharmony_ci pr_emerg("Error memory count\n"); 2508c2ecf20Sopenharmony_ci machine_restart(NULL); 2518c2ecf20Sopenharmony_ci } 2528c2ecf20Sopenharmony_ci 2538c2ecf20Sopenharmony_ci if ((u32) memblock.memory.regions[0].size < 0x400000) { 2548c2ecf20Sopenharmony_ci pr_emerg("Memory must be greater than 4MB\n"); 2558c2ecf20Sopenharmony_ci machine_restart(NULL); 2568c2ecf20Sopenharmony_ci } 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci if ((u32) memblock.memory.regions[0].size < kernel_tlb) { 2598c2ecf20Sopenharmony_ci pr_emerg("Kernel size is greater than memory node\n"); 2608c2ecf20Sopenharmony_ci machine_restart(NULL); 2618c2ecf20Sopenharmony_ci } 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci /* Find main memory where the kernel is */ 2648c2ecf20Sopenharmony_ci memory_start = (u32) memblock.memory.regions[0].base; 2658c2ecf20Sopenharmony_ci lowmem_size = memory_size = (u32) memblock.memory.regions[0].size; 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci if (lowmem_size > CONFIG_LOWMEM_SIZE) { 2688c2ecf20Sopenharmony_ci lowmem_size = CONFIG_LOWMEM_SIZE; 2698c2ecf20Sopenharmony_ci#ifndef CONFIG_HIGHMEM 2708c2ecf20Sopenharmony_ci memory_size = lowmem_size; 2718c2ecf20Sopenharmony_ci#endif 2728c2ecf20Sopenharmony_ci } 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci mm_cmdline_setup(); /* FIXME parse args from command line - not used */ 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci /* 2778c2ecf20Sopenharmony_ci * Map out the kernel text/data/bss from the available physical 2788c2ecf20Sopenharmony_ci * memory. 2798c2ecf20Sopenharmony_ci */ 2808c2ecf20Sopenharmony_ci kstart = __pa(CONFIG_KERNEL_START); /* kernel start */ 2818c2ecf20Sopenharmony_ci /* kernel size */ 2828c2ecf20Sopenharmony_ci ksize = PAGE_ALIGN(((u32)_end - (u32)CONFIG_KERNEL_START)); 2838c2ecf20Sopenharmony_ci memblock_reserve(kstart, ksize); 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci#if defined(CONFIG_BLK_DEV_INITRD) 2868c2ecf20Sopenharmony_ci /* Remove the init RAM disk from the available memory. */ 2878c2ecf20Sopenharmony_ci if (initrd_start) { 2888c2ecf20Sopenharmony_ci unsigned long size; 2898c2ecf20Sopenharmony_ci size = initrd_end - initrd_start; 2908c2ecf20Sopenharmony_ci memblock_reserve(__virt_to_phys(initrd_start), size); 2918c2ecf20Sopenharmony_ci } 2928c2ecf20Sopenharmony_ci#endif /* CONFIG_BLK_DEV_INITRD */ 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_ci /* Initialize the MMU hardware */ 2958c2ecf20Sopenharmony_ci mmu_init_hw(); 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci /* Map in all of RAM starting at CONFIG_KERNEL_START */ 2988c2ecf20Sopenharmony_ci mapin_ram(); 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci /* Extend vmalloc and ioremap area as big as possible */ 3018c2ecf20Sopenharmony_ci#ifdef CONFIG_HIGHMEM 3028c2ecf20Sopenharmony_ci ioremap_base = ioremap_bot = PKMAP_BASE; 3038c2ecf20Sopenharmony_ci#else 3048c2ecf20Sopenharmony_ci ioremap_base = ioremap_bot = FIXADDR_START; 3058c2ecf20Sopenharmony_ci#endif 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ci /* Initialize the context management stuff */ 3088c2ecf20Sopenharmony_ci mmu_context_init(); 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_ci /* Shortly after that, the entire linear mapping will be available */ 3118c2ecf20Sopenharmony_ci /* This will also cause that unflatten device tree will be allocated 3128c2ecf20Sopenharmony_ci * inside 768MB limit */ 3138c2ecf20Sopenharmony_ci memblock_set_current_limit(memory_start + lowmem_size - 1); 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_ci parse_early_param(); 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_ci /* CMA initialization */ 3188c2ecf20Sopenharmony_ci dma_contiguous_reserve(memory_start + lowmem_size - 1); 3198c2ecf20Sopenharmony_ci} 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci/* This is only called until mem_init is done. */ 3228c2ecf20Sopenharmony_civoid __init *early_get_page(void) 3238c2ecf20Sopenharmony_ci{ 3248c2ecf20Sopenharmony_ci /* 3258c2ecf20Sopenharmony_ci * Mem start + kernel_tlb -> here is limit 3268c2ecf20Sopenharmony_ci * because of mem mapping from head.S 3278c2ecf20Sopenharmony_ci */ 3288c2ecf20Sopenharmony_ci return memblock_alloc_try_nid_raw(PAGE_SIZE, PAGE_SIZE, 3298c2ecf20Sopenharmony_ci MEMBLOCK_LOW_LIMIT, memory_start + kernel_tlb, 3308c2ecf20Sopenharmony_ci NUMA_NO_NODE); 3318c2ecf20Sopenharmony_ci} 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_ci#endif /* CONFIG_MMU */ 3348c2ecf20Sopenharmony_ci 3358c2ecf20Sopenharmony_civoid * __ref zalloc_maybe_bootmem(size_t size, gfp_t mask) 3368c2ecf20Sopenharmony_ci{ 3378c2ecf20Sopenharmony_ci void *p; 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci if (mem_init_done) { 3408c2ecf20Sopenharmony_ci p = kzalloc(size, mask); 3418c2ecf20Sopenharmony_ci } else { 3428c2ecf20Sopenharmony_ci p = memblock_alloc(size, SMP_CACHE_BYTES); 3438c2ecf20Sopenharmony_ci if (!p) 3448c2ecf20Sopenharmony_ci panic("%s: Failed to allocate %zu bytes\n", 3458c2ecf20Sopenharmony_ci __func__, size); 3468c2ecf20Sopenharmony_ci } 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci return p; 3498c2ecf20Sopenharmony_ci} 350