162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * linux/arch/m68k/mm/sun3mmu.c 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Implementations of mm routines specific to the sun3 MMU. 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Moved here 8/20/1999 Sam Creasey 862306a36Sopenharmony_ci * 962306a36Sopenharmony_ci */ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/signal.h> 1262306a36Sopenharmony_ci#include <linux/sched.h> 1362306a36Sopenharmony_ci#include <linux/mm.h> 1462306a36Sopenharmony_ci#include <linux/swap.h> 1562306a36Sopenharmony_ci#include <linux/kernel.h> 1662306a36Sopenharmony_ci#include <linux/string.h> 1762306a36Sopenharmony_ci#include <linux/types.h> 1862306a36Sopenharmony_ci#include <linux/init.h> 1962306a36Sopenharmony_ci#include <linux/memblock.h> 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#include <asm/setup.h> 2262306a36Sopenharmony_ci#include <linux/uaccess.h> 2362306a36Sopenharmony_ci#include <asm/page.h> 2462306a36Sopenharmony_ci#include <asm/machdep.h> 2562306a36Sopenharmony_ci#include <asm/io.h> 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ciextern void mmu_emu_init (unsigned long bootmem_end); 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ciconst char bad_pmd_string[] = "Bad pmd in pte_alloc: %08lx\n"; 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ciextern unsigned long num_pages; 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ci/* For the sun3 we try to follow the i386 paging_init() more closely */ 3462306a36Sopenharmony_ci/* start_mem and end_mem have PAGE_OFFSET added already */ 3562306a36Sopenharmony_ci/* now sets up tables using sun3 PTEs rather than i386 as before. --m */ 3662306a36Sopenharmony_civoid __init paging_init(void) 3762306a36Sopenharmony_ci{ 3862306a36Sopenharmony_ci pgd_t * pg_dir; 3962306a36Sopenharmony_ci pte_t * pg_table; 4062306a36Sopenharmony_ci int i; 4162306a36Sopenharmony_ci unsigned long address; 4262306a36Sopenharmony_ci unsigned long next_pgtable; 4362306a36Sopenharmony_ci unsigned long bootmem_end; 4462306a36Sopenharmony_ci unsigned long max_zone_pfn[MAX_NR_ZONES] = { 0, }; 4562306a36Sopenharmony_ci unsigned long size; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci empty_zero_page = memblock_alloc(PAGE_SIZE, PAGE_SIZE); 4862306a36Sopenharmony_ci if (!empty_zero_page) 4962306a36Sopenharmony_ci panic("%s: Failed to allocate %lu bytes align=0x%lx\n", 5062306a36Sopenharmony_ci __func__, PAGE_SIZE, PAGE_SIZE); 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci address = PAGE_OFFSET; 5362306a36Sopenharmony_ci pg_dir = swapper_pg_dir; 5462306a36Sopenharmony_ci memset (swapper_pg_dir, 0, sizeof (swapper_pg_dir)); 5562306a36Sopenharmony_ci memset (kernel_pg_dir, 0, sizeof (kernel_pg_dir)); 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci size = num_pages * sizeof(pte_t); 5862306a36Sopenharmony_ci size = (size + PAGE_SIZE) & ~(PAGE_SIZE-1); 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_ci next_pgtable = (unsigned long)memblock_alloc(size, PAGE_SIZE); 6162306a36Sopenharmony_ci if (!next_pgtable) 6262306a36Sopenharmony_ci panic("%s: Failed to allocate %lu bytes align=0x%lx\n", 6362306a36Sopenharmony_ci __func__, size, PAGE_SIZE); 6462306a36Sopenharmony_ci bootmem_end = (next_pgtable + size + PAGE_SIZE) & PAGE_MASK; 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci /* Map whole memory from PAGE_OFFSET (0x0E000000) */ 6762306a36Sopenharmony_ci pg_dir += PAGE_OFFSET >> PGDIR_SHIFT; 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci while (address < (unsigned long)high_memory) { 7062306a36Sopenharmony_ci pg_table = (pte_t *) __pa (next_pgtable); 7162306a36Sopenharmony_ci next_pgtable += PTRS_PER_PTE * sizeof (pte_t); 7262306a36Sopenharmony_ci pgd_val(*pg_dir) = (unsigned long) pg_table; 7362306a36Sopenharmony_ci pg_dir++; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci /* now change pg_table to kernel virtual addresses */ 7662306a36Sopenharmony_ci pg_table = (pte_t *) __va ((unsigned long) pg_table); 7762306a36Sopenharmony_ci for (i=0; i<PTRS_PER_PTE; ++i, ++pg_table) { 7862306a36Sopenharmony_ci pte_t pte = pfn_pte(virt_to_pfn((void *)address), PAGE_INIT); 7962306a36Sopenharmony_ci if (address >= (unsigned long)high_memory) 8062306a36Sopenharmony_ci pte_val (pte) = 0; 8162306a36Sopenharmony_ci set_pte (pg_table, pte); 8262306a36Sopenharmony_ci address += PAGE_SIZE; 8362306a36Sopenharmony_ci } 8462306a36Sopenharmony_ci } 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci mmu_emu_init(bootmem_end); 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci current->mm = NULL; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci /* memory sizing is a hack stolen from motorola.c.. hope it works for us */ 9162306a36Sopenharmony_ci max_zone_pfn[ZONE_DMA] = ((unsigned long)high_memory) >> PAGE_SHIFT; 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci /* I really wish I knew why the following change made things better... -- Sam */ 9462306a36Sopenharmony_ci free_area_init(max_zone_pfn); 9562306a36Sopenharmony_ci 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci} 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_cistatic const pgprot_t protection_map[16] = { 10062306a36Sopenharmony_ci [VM_NONE] = PAGE_NONE, 10162306a36Sopenharmony_ci [VM_READ] = PAGE_READONLY, 10262306a36Sopenharmony_ci [VM_WRITE] = PAGE_COPY, 10362306a36Sopenharmony_ci [VM_WRITE | VM_READ] = PAGE_COPY, 10462306a36Sopenharmony_ci [VM_EXEC] = PAGE_READONLY, 10562306a36Sopenharmony_ci [VM_EXEC | VM_READ] = PAGE_READONLY, 10662306a36Sopenharmony_ci [VM_EXEC | VM_WRITE] = PAGE_COPY, 10762306a36Sopenharmony_ci [VM_EXEC | VM_WRITE | VM_READ] = PAGE_COPY, 10862306a36Sopenharmony_ci [VM_SHARED] = PAGE_NONE, 10962306a36Sopenharmony_ci [VM_SHARED | VM_READ] = PAGE_READONLY, 11062306a36Sopenharmony_ci [VM_SHARED | VM_WRITE] = PAGE_SHARED, 11162306a36Sopenharmony_ci [VM_SHARED | VM_WRITE | VM_READ] = PAGE_SHARED, 11262306a36Sopenharmony_ci [VM_SHARED | VM_EXEC] = PAGE_READONLY, 11362306a36Sopenharmony_ci [VM_SHARED | VM_EXEC | VM_READ] = PAGE_READONLY, 11462306a36Sopenharmony_ci [VM_SHARED | VM_EXEC | VM_WRITE] = PAGE_SHARED, 11562306a36Sopenharmony_ci [VM_SHARED | VM_EXEC | VM_WRITE | VM_READ] = PAGE_SHARED 11662306a36Sopenharmony_ci}; 11762306a36Sopenharmony_ciDECLARE_VM_GET_PAGE_PROT 118