18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * linux/arch/m68k/mm/init.c 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 1995 Hamish Macdonald 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Contains common initialization routines, specific init code moved 88c2ecf20Sopenharmony_ci * to motorola.c and sun3mmu.c 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/module.h> 128c2ecf20Sopenharmony_ci#include <linux/signal.h> 138c2ecf20Sopenharmony_ci#include <linux/sched.h> 148c2ecf20Sopenharmony_ci#include <linux/mm.h> 158c2ecf20Sopenharmony_ci#include <linux/swap.h> 168c2ecf20Sopenharmony_ci#include <linux/kernel.h> 178c2ecf20Sopenharmony_ci#include <linux/string.h> 188c2ecf20Sopenharmony_ci#include <linux/types.h> 198c2ecf20Sopenharmony_ci#include <linux/init.h> 208c2ecf20Sopenharmony_ci#include <linux/memblock.h> 218c2ecf20Sopenharmony_ci#include <linux/gfp.h> 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#include <asm/setup.h> 248c2ecf20Sopenharmony_ci#include <linux/uaccess.h> 258c2ecf20Sopenharmony_ci#include <asm/page.h> 268c2ecf20Sopenharmony_ci#include <asm/pgalloc.h> 278c2ecf20Sopenharmony_ci#include <asm/traps.h> 288c2ecf20Sopenharmony_ci#include <asm/machdep.h> 298c2ecf20Sopenharmony_ci#include <asm/io.h> 308c2ecf20Sopenharmony_ci#ifdef CONFIG_ATARI 318c2ecf20Sopenharmony_ci#include <asm/atari_stram.h> 328c2ecf20Sopenharmony_ci#endif 338c2ecf20Sopenharmony_ci#include <asm/sections.h> 348c2ecf20Sopenharmony_ci#include <asm/tlb.h> 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci/* 378c2ecf20Sopenharmony_ci * ZERO_PAGE is a special page that is used for zero-initialized 388c2ecf20Sopenharmony_ci * data and COW. 398c2ecf20Sopenharmony_ci */ 408c2ecf20Sopenharmony_civoid *empty_zero_page; 418c2ecf20Sopenharmony_ciEXPORT_SYMBOL(empty_zero_page); 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci#ifdef CONFIG_MMU 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_cipg_data_t pg_data_map[MAX_NUMNODES]; 468c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pg_data_map); 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ciint m68k_virt_to_node_shift; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci#ifndef CONFIG_SINGLE_MEMORY_CHUNK 518c2ecf20Sopenharmony_cipg_data_t *pg_data_table[65]; 528c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pg_data_table); 538c2ecf20Sopenharmony_ci#endif 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_civoid __init m68k_setup_node(int node) 568c2ecf20Sopenharmony_ci{ 578c2ecf20Sopenharmony_ci#ifndef CONFIG_SINGLE_MEMORY_CHUNK 588c2ecf20Sopenharmony_ci struct m68k_mem_info *info = m68k_memory + node; 598c2ecf20Sopenharmony_ci int i, end; 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci i = (unsigned long)phys_to_virt(info->addr) >> __virt_to_node_shift(); 628c2ecf20Sopenharmony_ci end = (unsigned long)phys_to_virt(info->addr + info->size - 1) >> __virt_to_node_shift(); 638c2ecf20Sopenharmony_ci for (; i <= end; i++) { 648c2ecf20Sopenharmony_ci if (pg_data_table[i]) 658c2ecf20Sopenharmony_ci pr_warn("overlap at %u for chunk %u\n", i, node); 668c2ecf20Sopenharmony_ci pg_data_table[i] = pg_data_map + node; 678c2ecf20Sopenharmony_ci } 688c2ecf20Sopenharmony_ci#endif 698c2ecf20Sopenharmony_ci node_set_online(node); 708c2ecf20Sopenharmony_ci} 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci#else /* CONFIG_MMU */ 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci/* 758c2ecf20Sopenharmony_ci * paging_init() continues the virtual memory environment setup which 768c2ecf20Sopenharmony_ci * was begun by the code in arch/head.S. 778c2ecf20Sopenharmony_ci * The parameters are pointers to where to stick the starting and ending 788c2ecf20Sopenharmony_ci * addresses of available kernel virtual memory. 798c2ecf20Sopenharmony_ci */ 808c2ecf20Sopenharmony_civoid __init paging_init(void) 818c2ecf20Sopenharmony_ci{ 828c2ecf20Sopenharmony_ci /* 838c2ecf20Sopenharmony_ci * Make sure start_mem is page aligned, otherwise bootmem and 848c2ecf20Sopenharmony_ci * page_alloc get different views of the world. 858c2ecf20Sopenharmony_ci */ 868c2ecf20Sopenharmony_ci unsigned long end_mem = memory_end & PAGE_MASK; 878c2ecf20Sopenharmony_ci unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0, }; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci high_memory = (void *) end_mem; 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci empty_zero_page = memblock_alloc(PAGE_SIZE, PAGE_SIZE); 928c2ecf20Sopenharmony_ci if (!empty_zero_page) 938c2ecf20Sopenharmony_ci panic("%s: Failed to allocate %lu bytes align=0x%lx\n", 948c2ecf20Sopenharmony_ci __func__, PAGE_SIZE, PAGE_SIZE); 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_ci /* 978c2ecf20Sopenharmony_ci * Set up SFC/DFC registers (user data space). 988c2ecf20Sopenharmony_ci */ 998c2ecf20Sopenharmony_ci set_fs (USER_DS); 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_ci max_zone_pfn[ZONE_DMA] = end_mem >> PAGE_SHIFT; 1028c2ecf20Sopenharmony_ci free_area_init(max_zone_pfn); 1038c2ecf20Sopenharmony_ci} 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci#endif /* CONFIG_MMU */ 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_civoid free_initmem(void) 1088c2ecf20Sopenharmony_ci{ 1098c2ecf20Sopenharmony_ci#ifndef CONFIG_MMU_SUN3 1108c2ecf20Sopenharmony_ci free_initmem_default(-1); 1118c2ecf20Sopenharmony_ci#endif /* CONFIG_MMU_SUN3 */ 1128c2ecf20Sopenharmony_ci} 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci#if defined(CONFIG_MMU) && !defined(CONFIG_COLDFIRE) 1158c2ecf20Sopenharmony_ci#define VECTORS &vectors[0] 1168c2ecf20Sopenharmony_ci#else 1178c2ecf20Sopenharmony_ci#define VECTORS _ramvec 1188c2ecf20Sopenharmony_ci#endif 1198c2ecf20Sopenharmony_ci 1208c2ecf20Sopenharmony_cistatic inline void init_pointer_tables(void) 1218c2ecf20Sopenharmony_ci{ 1228c2ecf20Sopenharmony_ci#if defined(CONFIG_MMU) && !defined(CONFIG_SUN3) && !defined(CONFIG_COLDFIRE) 1238c2ecf20Sopenharmony_ci int i, j; 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci /* insert pointer tables allocated so far into the tablelist */ 1268c2ecf20Sopenharmony_ci init_pointer_table(kernel_pg_dir, TABLE_PGD); 1278c2ecf20Sopenharmony_ci for (i = 0; i < PTRS_PER_PGD; i++) { 1288c2ecf20Sopenharmony_ci pud_t *pud = (pud_t *)&kernel_pg_dir[i]; 1298c2ecf20Sopenharmony_ci pmd_t *pmd_dir; 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci if (!pud_present(*pud)) 1328c2ecf20Sopenharmony_ci continue; 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci pmd_dir = (pmd_t *)pgd_page_vaddr(kernel_pg_dir[i]); 1358c2ecf20Sopenharmony_ci init_pointer_table(pmd_dir, TABLE_PMD); 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci for (j = 0; j < PTRS_PER_PMD; j++) { 1388c2ecf20Sopenharmony_ci pmd_t *pmd = &pmd_dir[j]; 1398c2ecf20Sopenharmony_ci pte_t *pte_dir; 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci if (!pmd_present(*pmd)) 1428c2ecf20Sopenharmony_ci continue; 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci pte_dir = (pte_t *)pmd_page_vaddr(*pmd); 1458c2ecf20Sopenharmony_ci init_pointer_table(pte_dir, TABLE_PTE); 1468c2ecf20Sopenharmony_ci } 1478c2ecf20Sopenharmony_ci } 1488c2ecf20Sopenharmony_ci#endif 1498c2ecf20Sopenharmony_ci} 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_civoid __init mem_init(void) 1528c2ecf20Sopenharmony_ci{ 1538c2ecf20Sopenharmony_ci /* this will put all memory onto the freelists */ 1548c2ecf20Sopenharmony_ci memblock_free_all(); 1558c2ecf20Sopenharmony_ci init_pointer_tables(); 1568c2ecf20Sopenharmony_ci mem_init_print_info(NULL); 1578c2ecf20Sopenharmony_ci} 158