source: rtems/c/src/lib/libbsp/mips/shared/startup/idttlb.S @ 1c554014

4.115
Last change on this file since 1c554014 was 1c554014, checked in by Ralf Corsépius <ralf.corsepius@…>, on 07/19/12 at 14:14:53

Remove CVS-Ids.

  • Property mode set to 100644
File size: 9.4 KB
Line 
1/*
2
3Based upon IDT provided code with the following release:
4
5This source code has been made available to you by IDT on an AS-IS
6basis. Anyone receiving this source is licensed under IDT copyrights
7to use it in any way he or she deems fit, including copying it,
8modifying it, compiling it, and redistributing it either with or
9without modifications.  No license under IDT patents or patent
10applications is to be implied by the copyright license.
11
12Any user of this software should understand that IDT cannot provide
13technical support for this software and will not be responsible for
14any consequences resulting from the use of this software.
15
16Any person who transfers this source code or any derivative work must
17include the IDT copyright notice, this paragraph, and the preceeding
18two paragraphs in the transferred software.
19
20COPYRIGHT IDT CORPORATION 1996
21LICENSED MATERIAL - PROGRAM PROPERTY OF IDT
22*/
23
24
25/*
26**      idttlb.s - fetch the registers associated with and the contents
27**                 of the tlb.
28**
29*/
30/* 950308: Ketan patched a few tlb functions that would not have worked.*/
31#include <rtems/mips/iregdef.h>
32#include <rtems/mips/idtcpu.h>
33#include <rtems/asm.h>
34
35
36        .text
37
38#if __mips == 1
39/*
40** ret_tlblo -- returns the 'entrylo' contents for the TLB
41**      'c' callable - as ret_tlblo(index) - where index is the
42**      tlb entry to return the lo value for - if called from assembly
43**      language then index should be in register a0.
44*/
45FRAME(ret_tlblo,sp,0,ra)
46        .set    noreorder
47        mfc0    t0,C0_SR                # save sr
48        nop
49        and     t0,~SR_PE               # dont inadvertantly clear PE
50        mtc0    zero,C0_SR              # clear interrupts
51        mfc0    t1,C0_TLBHI             # save pid
52        sll     a0,TLBINX_INXSHIFT      # position index
53        mtc0    a0,C0_INX               # write to index register
54        nop
55        tlbr                            # put tlb entry in entrylo and hi
56        nop
57        mfc0    v0,C0_TLBLO             # get the requested entry lo
58        mtc0    t1,C0_TLBHI             # restore pid
59        mtc0    t0,C0_SR                # restore status register
60        j       ra
61        nop
62        .set    reorder
63ENDFRAME(ret_tlblo)
64#endif
65#if __mips == 3
66/*
67** ret_tlblo[01] -- returns the 'entrylo' contents for the TLB
68**      'c' callable - as ret_tlblo(index) - where index is the
69**      tlb entry to return the lo value for - if called from assembly
70**      language then index should be in register a0.
71*/
72FRAME(ret_tlblo0,sp,0,ra)
73        mfc0    t0,C0_SR                # save sr
74        mtc0    zero,C0_SR              # clear interrupts
75        mfc0    t1,C0_TLBHI             # save pid
76        mtc0    a0,C0_INX               # write to index register
77        .set noreorder
78        nop; nop; nop; nop; nop; nop; nop; nop
79        .set reorder
80        tlbr                            # put tlb entry in entrylo and hi
81        .set noreorder
82        nop; nop; nop; nop; nop; nop; nop; nop
83        .set reorder
84        mfc0    v0,C0_TLBLO0            # get the requested entry lo
85        mtc0    t1,C0_TLBHI             # restore pid
86        mtc0    t0,C0_SR                # restore status register
87        j       ra
88ENDFRAME(ret_tlblo0)
89
90FRAME(ret_tlblo1,sp,0,ra)
91        mfc0    t0,C0_SR                # save sr
92        mtc0    zero,C0_SR              # clear interrupts
93        mfc0    t1,C0_TLBHI             # save pid
94        mtc0    a0,C0_INX               # write to index register
95        .set noreorder
96        nop; nop; nop; nop; nop; nop; nop; nop
97        .set reorder
98        tlbr                            # put tlb entry in entrylo and hi
99        .set noreorder
100        nop; nop; nop; nop; nop; nop; nop; nop
101        .set reorder
102        mfc0    v0,C0_TLBLO1            # get the requested entry lo
103        mtc0    t1,C0_TLBHI             # restore pid
104        mtc0    t0,C0_SR                # restore status register
105        j       ra
106ENDFRAME(ret_tlblo1)
107
108/*
109** ret_pagemask(index) -- return pagemask contents of tlb entry "index"
110*/
111FRAME(ret_pagemask,sp,0,ra)
112        mfc0    t0,C0_SR                # save sr
113        mtc0    zero,C0_SR              # disable interrupts
114        mfc0    t1,C0_TLBHI             # save current pid
115        mtc0    a0,C0_INX               # drop it in C0 register
116        .set noreorder
117        nop; nop; nop; nop; nop; nop; nop; nop
118        .set reorder
119        tlbr                            # read entry to entry hi/lo
120        .set noreorder
121        nop; nop; nop; nop; nop; nop; nop; nop
122        .set reorder
123        mfc0    v0,C0_PAGEMASK          # to return value
124        mtc0    t1,C0_TLBHI             # restore current pid
125        mtc0    t0,C0_SR                # restore sr
126        j       ra
127ENDFRAME(ret_pagemask)
128
129/*
130** ret_tlbwired(void) -- return wired register
131*/
132FRAME(ret_tlbwired,sp,0,ra)
133        mfc0    v0,C0_WIRED
134        j       ra
135ENDFRAME(ret_tlbwired)
136#endif
137
138/*
139** ret_tlbhi -- return the tlb entry high content for tlb entry
140**                      index
141*/
142FRAME(ret_tlbhi,sp,0,ra)
143#if __mips == 1
144        .set    noreorder
145        mfc0    t0,C0_SR                # save sr
146        nop
147        and     t0,~SR_PE
148        mtc0    zero,C0_SR              # disable interrupts
149        mfc0    t1,C0_TLBHI             # save current pid
150        sll     a0,TLBINX_INXSHIFT      # position index
151        mtc0    a0,C0_INX               # drop it in C0 register
152        nop
153        tlbr                            # read entry to entry hi/lo
154        nop
155        mfc0    v0,C0_TLBHI             # to return value
156        mtc0    t1,C0_TLBHI             # restore current pid
157        mtc0    t0,C0_SR                # restore sr
158        j       ra
159        nop
160        .set    reorder
161#endif
162#if __mips == 3
163        mfc0    t0,C0_SR                # save sr
164        mtc0    zero,C0_SR              # disable interrupts
165        mfc0    t1,C0_TLBHI             # save current pid
166        mtc0    a0,C0_INX               # drop it in C0 register
167        .set noreorder
168        nop; nop; nop; nop; nop; nop; nop; nop
169        .set reorder
170        tlbr                            # read entry to entry hi/lo0/lo1/mask
171        .set noreorder
172        nop; nop; nop; nop; nop; nop; nop; nop
173        .set reorder
174        mfc0    v0,C0_TLBHI             # to return value
175        mtc0    t1,C0_TLBHI             # restore current pid
176        mtc0    t0,C0_SR                # restore sr
177        j       ra
178#endif
179ENDFRAME(ret_tlbhi)
180
181/*
182** ret_tlbpid() -- return tlb pid contained in the current entry hi
183*/
184FRAME(ret_tlbpid,sp,0,ra)
185#if __mips == 1
186        .set    noreorder
187        mfc0    v0,C0_TLBHI             # fetch tlb high
188        nop
189        and     v0,TLBHI_PIDMASK        # isolate and position
190        srl     v0,TLBHI_PIDSHIFT
191        j       ra
192        nop
193        .set    reorder
194#endif
195#if __mips == 3
196        mfc0    v0,C0_TLBHI     # to return value
197        nop
198        and     v0,TLBHI_PIDMASK
199        j       ra
200#endif
201ENDFRAME(ret_tlbpid)
202
203/*
204** tlbprobe(address, pid) -- probe the tlb to see if address is currently
205**                              mapped
206**      a0 = vpn  - virtual page numbers are 0=0 1=0x1000, 2=0x2000...
207**                      virtual page numbers for the r3000 are in
208**                      entry hi bits 31-12
209**      a1 = pid  - this is a process id ranging from 0 to 63
210**                  this process id is shifted left 6 bits and or'ed into
211**                  the entry hi register
212**      returns an index value (0-63) if successful -1 -f not
213*/
214FRAME(tlbprobe,sp,0,ra)
215#if __mips == 1
216        .set    noreorder
217        mfc0    t0,C0_SR                /* fetch status reg */
218        and     a0,TLBHI_VPNMASK        /* isolate just the vpn */
219        and     t0,~SR_PE               /* don't inadvertantly clear pe */
220        mtc0    zero,C0_SR
221        mfc0    t1,C0_TLBHI
222        sll     a1,TLBHI_PIDSHIFT       /* possition the pid */
223        and     a1,TLBHI_PIDMASK
224        or      a0,a1                   /* build entry hi value */
225        mtc0    a0,C0_TLBHI
226        nop
227        tlbp                            /* do the probe */
228        nop
229        mfc0    v1,C0_INX
230        li      v0,-1
231        bltz    v1,1f
232        nop
233        sra     v0,v1,TLBINX_INXSHIFT   /* get index positioned for return */
2341:
235        mtc0    t1,C0_TLBHI             /* restore tlb hi */
236        mtc0    t0,C0_SR                /* restore the status reg */
237        j       ra
238        nop
239        .set    reorder
240#endif
241#if __mips == 3
242        mfc0    t0,C0_SR                # save sr
243        mtc0    zero,C0_SR              # disable interrupts
244        mfc0    t1,C0_TLBHI             # save current pid
245        and     a0,TLBHI_VPN2MASK       # construct tlbhi for probe
246        and     a1,TLBHI_PIDMASK
247        or      a0,a1
248        mtc0    a0,C0_TLBHI
249        .set noreorder
250        nop; nop; nop; nop; nop; nop; nop; nop
251        .set reorder
252        tlbp                            # probe entry to entry hi/lo0/lo1/mask
253        .set noreorder
254        nop; nop; nop; nop; nop; nop; nop; nop
255        .set reorder
256        mfc0    v1,C0_INX
257        li      v0,-1
258        bltz    v1,1f
259        move    v0,v1
2601:      mtc0    t1,C0_TLBHI             # restore current pid
261        mtc0    t0,C0_SR                # restore sr
262        j       ra
263#endif
264ENDFRAME(tlbprobe)
265
266/*
267** resettlb(index) Invalidate the  TLB entry specified by index
268*/
269FRAME(resettlb,sp,0,ra)
270#if __mips == 1
271        .set    noreorder
272        mfc0    t0,C0_TLBHI             # fetch the current hi
273        mfc0    v0,C0_SR                # fetch the status reg.
274        li      t2,K0BASE&TLBHI_VPNMASK
275        and     v0,~SR_PE               # dont inadvertantly clear PE
276        mtc0    zero,C0_SR
277        mtc0    t2,C0_TLBHI             # set up tlbhi
278        mtc0    zero,C0_TLBLO
279        sll     a0,TLBINX_INXSHIFT
280        mtc0    a0,C0_INX
281        nop
282        tlbwi                           # do actual invalidate
283        nop
284        mtc0    t0,C0_TLBHI
285        mtc0    v0,C0_SR
286        j       ra
287        nop
288        .set    reorder
289#endif
290#if __mips == 3
291        li      t2,K0BASE&TLBHI_VPN2MASK
292        mfc0    t0,C0_TLBHI             # save current TLBHI
293        mfc0    v0,C0_SR                # save SR and disable interrupts
294        mtc0    zero,C0_SR
295        mtc0    t2,C0_TLBHI             # invalidate entry
296        mtc0    zero,C0_TLBLO0
297        mtc0    zero,C0_TLBLO1
298        mtc0    a0,C0_INX
299        .set noreorder
300        nop; nop; nop; nop; nop; nop; nop; nop
301        .set reorder
302        tlbwi
303        .set noreorder
304        nop; nop; nop; nop; nop; nop; nop; nop
305        .set reorder
306        mtc0    t0,C0_TLBHI
307        mtc0    v0,C0_SR
308        j       ra
309#endif
310ENDFRAME(resettlb)
311
312#if __mips == 1
313/*
314** Setup TLB entry
315**
316** map_tlb(index, tlbhi, phypage)
317**      a0  =  TLB entry index
318**      a1  =  virtual page number and PID
319**      a2  =  physical page
320*/
321FRAME(map_tlb,sp,0,ra)
322        .set    noreorder
323        sll     a0,TLBINX_INXSHIFT
324        mfc0    v0,C0_SR                # fetch the current status
325        mfc0    a3,C0_TLBHI             # save the current hi
326        and     v0,~SR_PE               # dont inadvertantly clear parity
327
328        mtc0    zero,C0_SR
329        mtc0    a1,C0_TLBHI             # set the hi entry
330        mtc0    a2,C0_TLBLO             # set the lo entry
331        mtc0    a0,C0_INX               # load the index
332        nop
333        tlbwi                           # put the hi/lo in tlb entry indexed
334        nop
335        mtc0    a3,C0_TLBHI             # put back the tlb hi reg
336        mtc0    v0,C0_SR                # restore the status register
337        j       ra
338        nop
339        .set    reorder
340ENDFRAME(map_tlb)
341#endif
342#if __mips == 3
343/*
344** Setup R4000 TLB entry
345**
346** map_tlb4000(mask_index, tlbhi, pte_even, pte_odd)
347**      a0  =  TLB entry index and page mask
348**      a1  =  virtual page number and PID
349**      a2  =  pte -- contents of even pte
350**      a3  =  pte -- contents of odd pte
351*/
352FRAME(map_tlb4000,sp,0,ra)
353        and     t2,a0,TLBPGMASK_MASK
354        and     a0,TLBINX_INXMASK
355        mfc0    t1,C0_TLBHI             # save current TLBPID
356        mfc0    v0,C0_SR                # save SR and disable interrupts
357        mtc0    zero,C0_SR
358        mtc0    t2,C0_PAGEMASK          # set
359        mtc0    a1,C0_TLBHI             # set VPN and TLBPID
360        mtc0    a2,C0_TLBLO0            # set PPN and access bits
361        mtc0    a3,C0_TLBLO1            # set PPN and access bits
362        mtc0    a0,C0_INX               # set INDEX to wired entry
363        .set noreorder
364        nop; nop; nop; nop; nop; nop; nop; nop
365        .set reorder
366        tlbwi                           # drop it in
367        .set noreorder
368        nop; nop; nop; nop; nop; nop; nop; nop
369        .set reorder
370        mtc0    t1,C0_TLBHI             # restore TLBPID
371        mtc0    v0,C0_SR                # restore SR
372        j       ra
373ENDFRAME(map_tlb4000)
374#endif
375
376
377/*
378** Set current TLBPID. This assumes PID is positioned correctly in reg.
379**                      a0.
380*/
381FRAME(set_tlbpid,sp,0,ra)
382        .set    noreorder
383        mtc0    a0,C0_TLBHI
384        j       ra
385        nop
386        .set    reorder
387ENDFRAME(set_tlbpid)
388
Note: See TracBrowser for help on using the repository browser.