12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 2fc34d1ebSMichal Simek /* 3fc34d1ebSMichal Simek * This file contains the routines for handling the MMU. 4fc34d1ebSMichal Simek * 5fc34d1ebSMichal Simek * Copyright (C) 2007 Xilinx, Inc. All rights reserved. 6fc34d1ebSMichal Simek * 7fc34d1ebSMichal Simek * Derived from arch/ppc/mm/4xx_mmu.c: 8fc34d1ebSMichal Simek * -- paulus 9fc34d1ebSMichal Simek * 10fc34d1ebSMichal Simek * Derived from arch/ppc/mm/init.c: 11fc34d1ebSMichal Simek * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 12fc34d1ebSMichal Simek * 13fc34d1ebSMichal Simek * Modifications by Paul Mackerras (PowerMac) (paulus@cs.anu.edu.au) 14fc34d1ebSMichal Simek * and Cort Dougan (PReP) (cort@cs.nmt.edu) 15fc34d1ebSMichal Simek * Copyright (C) 1996 Paul Mackerras 16fc34d1ebSMichal Simek * Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk). 17fc34d1ebSMichal Simek * 18fc34d1ebSMichal Simek * Derived from "arch/i386/mm/init.c" 19fc34d1ebSMichal Simek * Copyright (C) 1991, 1992, 1993, 1994 Linus Torvalds 20fc34d1ebSMichal Simek */ 21fc34d1ebSMichal Simek 22fc34d1ebSMichal Simek #include <linux/mm.h> 23fc34d1ebSMichal Simek #include <linux/init.h> 24fc34d1ebSMichal Simek 25fc34d1ebSMichal Simek #include <asm/tlbflush.h> 26fc34d1ebSMichal Simek #include <asm/mmu_context.h> 27fc34d1ebSMichal Simek 28fc34d1ebSMichal Simek mm_context_t next_mmu_context; 29fc34d1ebSMichal Simek unsigned long context_map[LAST_CONTEXT / BITS_PER_LONG + 1]; 30fc34d1ebSMichal Simek atomic_t nr_free_contexts; 31fc34d1ebSMichal Simek struct mm_struct *context_mm[LAST_CONTEXT+1]; 32fc34d1ebSMichal Simek 33fc34d1ebSMichal Simek /* 34fc34d1ebSMichal Simek * Initialize the context management stuff. 35fc34d1ebSMichal Simek */ mmu_context_init(void)36fc34d1ebSMichal Simekvoid __init mmu_context_init(void) 37fc34d1ebSMichal Simek { 38fc34d1ebSMichal Simek /* 39fc34d1ebSMichal Simek * The use of context zero is reserved for the kernel. 40fc34d1ebSMichal Simek * This code assumes FIRST_CONTEXT < 32. 41fc34d1ebSMichal Simek */ 42fc34d1ebSMichal Simek context_map[0] = (1 << FIRST_CONTEXT) - 1; 43fc34d1ebSMichal Simek next_mmu_context = FIRST_CONTEXT; 44fc34d1ebSMichal Simek atomic_set(&nr_free_contexts, LAST_CONTEXT - FIRST_CONTEXT + 1); 45fc34d1ebSMichal Simek } 46fc34d1ebSMichal Simek 47fc34d1ebSMichal Simek /* 48fc34d1ebSMichal Simek * Steal a context from a task that has one at the moment. 49fc34d1ebSMichal Simek * 50fc34d1ebSMichal Simek * This isn't an LRU system, it just frees up each context in 51fc34d1ebSMichal Simek * turn (sort-of pseudo-random replacement :). This would be the 52fc34d1ebSMichal Simek * place to implement an LRU scheme if anyone were motivated to do it. 53fc34d1ebSMichal Simek */ steal_context(void)54fc34d1ebSMichal Simekvoid steal_context(void) 55fc34d1ebSMichal Simek { 56fc34d1ebSMichal Simek struct mm_struct *mm; 57fc34d1ebSMichal Simek 58fc34d1ebSMichal Simek /* free up context `next_mmu_context' */ 59fc34d1ebSMichal Simek /* if we shouldn't free context 0, don't... */ 60fc34d1ebSMichal Simek if (next_mmu_context < FIRST_CONTEXT) 61fc34d1ebSMichal Simek next_mmu_context = FIRST_CONTEXT; 62fc34d1ebSMichal Simek mm = context_mm[next_mmu_context]; 63fc34d1ebSMichal Simek flush_tlb_mm(mm); 64fc34d1ebSMichal Simek destroy_context(mm); 65fc34d1ebSMichal Simek } 66