1/* tlb-flush.S: TLB flushing routines 2 * 3 * Copyright (C) 2004 Red Hat, Inc. All Rights Reserved. 4 * Written by David Howells (dhowells@redhat.com) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License 8 * as published by the Free Software Foundation; either version 9 * 2 of the License, or (at your option) any later version. 10 */ 11 12#include <linux/sys.h> 13#include <linux/linkage.h> 14#include <asm/page.h> 15#include <asm/ptrace.h> 16#include <asm/spr-regs.h> 17 18.macro DEBUG ch 19# sethi.p %hi(0xfeff9c00),gr4 20# setlo %lo(0xfeff9c00),gr4 21# setlos #\ch,gr5 22# stbi gr5,@(gr4,#0) 23# membar 24.endm 25 26 .section .rodata 27 28 # sizes corresponding to TPXR.LMAX 29 .balign 1 30__tlb_lmax_sizes: 31 .byte 0, 64, 0, 0 32 .byte 0, 0, 0, 0 33 .byte 0, 0, 0, 0 34 .byte 0, 0, 0, 0 35 36 .section .text 37 .balign 4 38 39############################################################################### 40# 41# flush everything 42# - void __flush_tlb_all(void) 43# 44############################################################################### 45 .globl __flush_tlb_all 46 .type __flush_tlb_all,@function 47__flush_tlb_all: 48 DEBUG 'A' 49 50 # kill cached PGE value 51 setlos #0xffffffff,gr4 52 movgs gr4,scr0 53 movgs gr4,scr1 54 55 # kill AMPR-cached TLB values 56 movgs gr0,iamlr1 57 movgs gr0,iampr1 58 movgs gr0,damlr1 59 movgs gr0,dampr1 60 61 # find out how many lines there are 62 movsg tpxr,gr5 63 sethi.p %hi(__tlb_lmax_sizes),gr4 64 srli gr5,#TPXR_LMAX_SHIFT,gr5 65 setlo.p %lo(__tlb_lmax_sizes),gr4 66 andi gr5,#TPXR_LMAX_SMASK,gr5 67 ldub @(gr4,gr5),gr4 68 69 # now, we assume that the TLB line step is page size in size 70 setlos.p #PAGE_SIZE,gr5 71 setlos #0,gr6 721: 73 tlbpr gr6,gr0,#6,#0 74 subicc.p gr4,#1,gr4,icc0 75 add gr6,gr5,gr6 76 bne icc0,#2,1b 77 78 DEBUG 'B' 79 bralr 80 81 .size __flush_tlb_all, .-__flush_tlb_all 82 83############################################################################### 84# 85# flush everything to do with one context 86# - void __flush_tlb_mm(unsigned long contextid [GR8]) 87# 88############################################################################### 89 .globl __flush_tlb_mm 90 .type __flush_tlb_mm,@function 91__flush_tlb_mm: 92 DEBUG 'M' 93 94 # kill cached PGE value 95 setlos #0xffffffff,gr4 96 movgs gr4,scr0 97 movgs gr4,scr1 98 99 # specify the context we want to flush 100 movgs gr8,tplr 101 102 # find out how many lines there are 103 movsg tpxr,gr5 104 sethi.p %hi(__tlb_lmax_sizes),gr4 105 srli gr5,#TPXR_LMAX_SHIFT,gr5 106 setlo.p %lo(__tlb_lmax_sizes),gr4 107 andi gr5,#TPXR_LMAX_SMASK,gr5 108 ldub @(gr4,gr5),gr4 109 110 # now, we assume that the TLB line step is page size in size 111 setlos.p #PAGE_SIZE,gr5 112 setlos #0,gr6 1130: 114 tlbpr gr6,gr0,#5,#0 115 subicc.p gr4,#1,gr4,icc0 116 add gr6,gr5,gr6 117 bne icc0,#2,0b 118 119 DEBUG 'N' 120 bralr 121 122 .size __flush_tlb_mm, .-__flush_tlb_mm 123 124############################################################################### 125# 126# flush a range of addresses from the TLB 127# - void __flush_tlb_page(unsigned long contextid [GR8], 128# unsigned long start [GR9]) 129# 130############################################################################### 131 .globl __flush_tlb_page 132 .type __flush_tlb_page,@function 133__flush_tlb_page: 134 # kill cached PGE value 135 setlos #0xffffffff,gr4 136 movgs gr4,scr0 137 movgs gr4,scr1 138 139 # specify the context we want to flush 140 movgs gr8,tplr 141 142 # zap the matching TLB line and AMR values 143 setlos #~(PAGE_SIZE-1),gr5 144 and gr9,gr5,gr9 145 tlbpr gr9,gr0,#5,#0 146 147 bralr 148 149 .size __flush_tlb_page, .-__flush_tlb_page 150 151############################################################################### 152# 153# flush a range of addresses from the TLB 154# - void __flush_tlb_range(unsigned long contextid [GR8], 155# unsigned long start [GR9], 156# unsigned long end [GR10]) 157# 158############################################################################### 159 .globl __flush_tlb_range 160 .type __flush_tlb_range,@function 161__flush_tlb_range: 162 # kill cached PGE value 163 setlos #0xffffffff,gr4 164 movgs gr4,scr0 165 movgs gr4,scr1 166 167 # specify the context we want to flush 168 movgs gr8,tplr 169 170 # round the start down to beginning of TLB line and end up to beginning of next TLB line 171 setlos.p #~(PAGE_SIZE-1),gr5 172 setlos #PAGE_SIZE,gr6 173 subi.p gr10,#1,gr10 174 and gr9,gr5,gr9 175 and gr10,gr5,gr10 1762: 177 tlbpr gr9,gr0,#5,#0 178 subcc.p gr9,gr10,gr0,icc0 179 add gr9,gr6,gr9 180 bne icc0,#0,2b ; most likely a 1-page flush 181 182 bralr 183 184 .size __flush_tlb_range, .-__flush_tlb_range 185