Linux Audio

Check our new training course

Loading...
  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