source: rtems/c/src/lib/libcpu/powerpc/mpc6xx/mmu/mmuAsm.S @ 83d7232

4.104.114.84.95
Last change on this file since 83d7232 was 83d7232, checked in by Eric Norum <WENorum@…>, on Oct 20, 2004 at 3:42:24 PM

Add Kate Feng's MVME5500 BSP.

  • Property mode set to 100644
File size: 12.7 KB
Line 
1/*
2 *  mmuAsm.S
3 *
4 *  $Id$
5 *
6 *  Copyright (C) 1999 Eric Valette (valette@crf.canon.fr)
7 *
8 *  This file contains the low-level support for various MMU
9 *  features.
10 *
11 *  The license and distribution terms for this file may be
12 *  found in found in the file LICENSE in this distribution or at
13 *  http://www.rtems.com/license/LICENSE.
14 *     
15 *  T. Straumann - 11/2001: added support for 7400 (no AltiVec yet)
16 *  S.K. Feng    - 10/2003: added support for 7455 (no AltiVec yet)
17 *
18 */
19
20#include <rtems/asm.h>
21#include <rtems/score/cpu.h>
22#include <libcpu/io.h>
23
24/* Unfortunately, the CPU types defined in cpu.h are
25 * an 'enum' type and hence not available :-(
26 */
27#define PPC_601   0x1
28#define PPC_603   0x3
29#define PPC_604   0x4
30#define PPC_603e  0x6
31#define PPC_603ev 0x7
32#define PPC_750   0x8
33#define PPC_604e  0x9
34#define PPC_604r  0xA
35#define PPC_7400  0xC
36#define PPC_7455  0x8001
37#define PPC_620   0x16
38#define PPC_860   0x50
39#define PPC_821   PPC_860
40#define PPC_8260  0x81
41
42/* ALTIVEC instructions (not recognized by off-the shelf gcc yet) */
43#define DSSALL  .long   0x7e00066c              /* DSSALL altivec instruction opcode */
44
45/* A couple of defines to make the code more readable */
46#define CACHE_LINE_SIZE 32
47
48#ifndef MSSCR0
49#define MSSCR0   1014
50#else
51#warning MSSCR0 seems to be known, update __FILE__
52#endif
53
54#define DL1HWF  (1<<(31-8))
55#define L2HWF   (1<<(31-20))
56       
57/*
58 * Each setdbat routine start by invalidating the DBAT as some
59 * proc (604e) request the valid bit set to 0 before accepting
60 * to write in BAT
61 */
62
63        .globl  asm_setdbat0
64        .type   asm_setdbat0,@function
65asm_setdbat0:
66        li      r0,0
67        sync
68        isync
69        mtspr   DBAT0U,r0
70        mtspr   DBAT0L,r0
71        sync
72        isync
73        mtspr DBAT0L, r4
74        mtspr DBAT0U, r3
75        sync
76        isync
77        blr
78
79        .globl  asm_setdbat1
80        .type   asm_setdbat1,@function
81asm_setdbat1:
82        li      r0,0
83        sync
84        isync
85        mtspr   DBAT1U,r0
86        mtspr   DBAT1L,r0
87        sync
88        isync
89        mtspr DBAT1L, r4
90        mtspr DBAT1U, r3
91        sync
92        isync
93        blr
94
95        .globl  asm_setdbat2
96        .type   asm_setdbat2,@function
97asm_setdbat2:   
98        li      r0,0
99        sync
100        isync
101        mtspr   DBAT2U,r0
102        mtspr   DBAT2L,r0
103        sync
104        isync
105        mtspr DBAT2L, r4
106        mtspr DBAT2U, r3
107        sync
108        isync
109        blr
110
111        .globl  asm_setdbat3
112        .type   asm_setdbat3,@function
113asm_setdbat3:   
114        li      r0,0
115        sync
116        isync
117        mtspr   DBAT3U,r0
118        mtspr   DBAT3L,r0
119        sync
120        isync
121        mtspr DBAT3L, r4
122        mtspr DBAT3U, r3
123        sync
124        isync
125        blr
126               
127        .globl L1_caches_enables
128        .type  L1_caches_enables, @function
129       
130L1_caches_enables:     
131        /*
132         * Enable caches and 604-specific features if necessary.
133         */
134        mfspr   r9,PVR
135        rlwinm  r9,r9,16,16,31
136        cmpi    0,r9,PPC_601
137        beq     4f                      /* not needed for 601 */
138        mfspr   r11,HID0
139        andi.   r0,r11,HID0_DCE
140        ori     r11,r11,HID0_ICE|HID0_DCE
141        ori     r8,r11,HID0_ICFI
142        bne     3f                      /* don't invalidate the D-cache */
143        ori     r8,r8,HID0_DCI          /* unless it wasn't enabled */
1443:
145        sync
146        mtspr   HID0,r8                 /* enable and invalidate caches */
147        sync
148        mtspr   HID0,r11                /* enable caches */
149        sync
150        isync
151        cmpi    1,r9,PPC_604    /* check for 604 */
152        cmpi    2,r9,PPC_604e   /* or 604e */
153        cmpi    3,r9,PPC_604r   /* or mach5 */
154        cror    6,6,10
155        cror    6,6,14
156        cmpi    2,r9,PPC_750    /* or 750 */
157        cror    6,6,10 
158        cmpi    2,r9,PPC_7400   /* or 7400 */
159        cror    6,6,10         
160        cmpli   0,r9,PPC_7455   /* or 7455 */
161        bne     2f
162        /* 7455:link register stack,branch folding &
163         * TBEN : enable the time base and decrementer.
164         * EMCP bit is defined in HID1. However, it's not used
165         * in mvme5500 board because of GT64260 (e.g. it's connected
166         * pull-up).
167         */
168        oris    r11,r11,(HID0_LRSTK|HID0_FOLD|HID0_TBEN)@h
169        ori     r11,r11,(HID0_LRSTK|HID0_FOLD|HID0_TBEN)@l
1702:      cror    2,2,10 
171        bne     3f
172        ori     r11,r11,HID0_BTIC       /* enable branch tgt cache on 7400 & 7455 */
1733:      cror    2,2,6
174        bne     4f
175        /* on 7400 SIED is actually SGE (store gathering enable) */
176        ori     r11,r11,HID0_SIED|HID0_BHTE /* for 604[e], enable */
177        bne     2,5f
178        ori     r11,r11,HID0_BTCD
1795:      mtspr   HID0,r11                /* superscalar exec & br history tbl */
180        sync                 /* for SGE bit */
181        isync                /* P2-17 to 2-22 in MPC7450UM */
1824:
183        blr
184
185        .globl get_L1CR
186.type  get_L1CR, @function     
187get_L1CR:
188        mfspr   r3,HID0
189        blr
190                       
191        .globl get_L2CR
192        .type  get_L2CR, @function     
193get_L2CR:       
194        /* Make sure this is a > 750 chip */
195        mfspr   r3,PVR
196        rlwinm  r3,r3,16,16,31
197        cmplwi  r3,PPC_750      /* it's a 750 */
198        beq     1f
199        cmplwi  r3,PPC_7400     /* it's a 7400 */
200        beq     1f
201        cmplwi  r3,PPC_7455     /* it's a 7455 */
202        beq     1f     
203        li      r3,-1
204        blr
205       
2061:
207        /* Return the L2CR contents */
208        mfspr   r3,L2CR
209        blr
210
211        .globl set_L2CR
212        .type  set_L2CR, @function
213set_L2CR:       
214        /* Usage:
215         * When setting the L2CR register, you must do a few special things. 
216         * If you are enabling the cache, you must perform a global invalidate.
217         * If you are disabling the cache, you must flush the cache contents first.
218         * This routine takes care of doing these things.  When first
219         * enabling the cache, make sure you pass in the L2CR you want, as well as
220         * passing in the global invalidate bit set.  A global invalidate will
221         * only be performed if the L2I bit is set in applyThis.  When enabling
222         * the cache, you should also set the L2E bit in applyThis.  If you
223         * want to modify the L2CR contents after the cache has been enabled,
224         * the recommended procedure is to first call __setL2CR(0) to disable
225         * the cache and then call it again with the new values for L2CR.  Examples:
226         *
227         *      _setL2CR(0)             -       disables the cache
228         *      _setL2CR(0xb9A14000)    -       enables my G3 MCP750 card:
229         *                              -       L2E set to turn on the cache
230         *                              -       L2SIZ set to 1MB
231         *                              -       L2CLK set to %2
232         *                              -       L2RAM set to pipelined syncronous late-write
233         *                              -       L2I set to perform a global invalidation
234         *                              -       L2OH set to 1 nS
235         *
236         * A similar call should work for your card.  You need to know the correct
237         * setting for your card and then place them in the fields I have outlined
238         * above.  Other fields support optional features, such as L2DO which caches
239         * only data, or L2TS which causes cache pushes from the L1 cache to go to
240         *the L2 cache instead of to main memory.
241         */
242       
243        /* Make sure this is a > 750 chip */
244        mfspr   r0,PVR
245        rlwinm  r0,r0,16,16,31
246        cmplwi  r0,PPC_750
247        beq     thisIs750
248        cmplwi  r0,PPC_7400
249        beq     thisIs750
250        cmplwi  r0,PPC_7455
251        beq     thisIs750       
252        li      r3,-1
253        blr
254       
255thisIs750:
256        /* Get the current enable bit of the L2CR into r4 */
257        mfspr   r4,L2CR
258        rlwinm  r4,r4,0,0,0
259       
260        /* See if we want to perform a global inval this time. */
261        rlwinm  r6,r3,0,10,10           /* r6 contains the new invalidate bit */
262        rlwinm. r5,r3,0,0,0             /* r5 contains the new enable bit */
263        rlwinm  r3,r3,0,11,9            /* Turn off the invalidate bit */
264        rlwinm  r3,r3,0,1,31            /* Turn off the enable bit */
265        or      r3,r3,r4                /* Keep the enable bit the same as it was for now. */
266        mfmsr   r7                      /* shut off interrupts around critical flush/invalidate sections */
267        rlwinm  r4,r7,0,17,15           /* Turn off EE bit - an external exception while we are flushing
268                                                                   the cache is fatal (comment this line and see!) */
269        mtmsr   r4
270        bne     dontDisableCache        /* Only disable the cache if L2CRApply has the enable bit off */
271
272        cmplwi  r0,PPC_7400             /* 7400 ? */
273        bne     disableCache            /* use traditional method */
274
275        /* On the 7400, they recommend using the hardware flush feature */
276        DSSALL                                          /* stop all data streams */
277        sync
278        /* we wouldn't have to flush L1, but for sake of consistency with the other code we do it anyway */
279        mfspr   r4, MSSCR0
280        oris    r4, r4, DL1HWF@h
281        mtspr   MSSCR0, r4
282        sync
283        /* L1 flushed */
284        mfspr   r4, L2CR
285        ori     r4, r4, L2HWF
286        mtspr   L2CR, r4
287        sync
288        /* L2 flushed */
289        b       flushDone
290
291disableCache:
292        /* Disable the cache.  First, we turn off data relocation. */
293        rlwinm  r4,r4,0,28,26           /* Turn off DR bit */
294        mtmsr   r4
295        isync                           /* make sure memory accesses have completed */
296        cmplwi  r0,PPC_7455             /* 7455 ? */
297        bne     not745x
298        /* 7455:L1 Load/Flush, L2, L3 :  hardware flush */
299        /* If not using AltiVec data streaming instructions,DSSALL not necessary */
300        sync
301        mfspr   r4, MSSCR0     
302        rlwinm  r4,r4,0,29,0            /* Turn off the L2PFE bits */
303        mtspr   MSSCR0, r4
304        sync   
305        /* flush L1 first */
306        lis     r4,0x0001
307        mtctr   r4
308        li      r4,0
309        li      r0,0
310loadFlush:
311        lwzx    r0,r0,r4
312        dcbf    r0,r4   
313        addi    r4,r4,CACHE_LINE_SIZE   /* Go to start of next cache line */
314        bdnz    loadFlush
315        sync
316        /* Set the L2CR[L2IO & L2DO] bits to completely lock the L2 cache */
317        mfspr   r0, L2CR
318        lis     r4,L2CR_LOCK_745x@h
319        ori     r4,r4,L2CR_LOCK_745x@l
320        or      r4,r0,r4
321        rlwinm  r4,r4,0,11,9           /* make sure the invalidate bit off */
322        mtspr   L2CR, r4
323        sync
324        ori     r4, r4, L2HWF
325        mtspr   L2CR, r4
326        sync
327        /* L2 flushed,L2IO & L2DO got cleared in the dontDisableCache:  */
328        b       reenableDR
329       
330not745x:                       
331        /*
332                Now, read the first 2MB of memory to put new data in the cache.
333                (Actually we only need the size of the L2 cache plus
334                the size of the L1 cache, but 2MB will cover everything just to be safe).
335        */
336        lis     r4,0x0001
337        mtctr   r4
338        li      r4,0
339loadLoop:
340        lwzx    r0,r0,r4
341        addi    r4,r4,CACHE_LINE_SIZE   /* Go to start of next cache line */
342        bdnz    loadLoop
343       
344        /* Now, flush the first 2MB of memory */
345        lis             r4,0x0001
346        mtctr   r4
347        li              r4,0
348        sync
349flushLoop:
350        dcbf    r0,r4
351        addi    r4,r4,CACHE_LINE_SIZE   /* Go to start of next cache line */
352        bdnz    flushLoop
353        sync
354reenableDR:     
355        rlwinm  r4,r7,0,17,15           /* still mask EE but reenable data relocation */
356        mtmsr   r4
357        isync
358
359flushDone:
360       
361        /* Turn off the L2CR enable bit. */
362        rlwinm  r3,r3,0,1,31
363       
364dontDisableCache:
365        /* Set up the L2CR configuration bits */
366        sync
367        mtspr   L2CR,r3
368        sync
369        cmplwi  r6,0
370        beq     noInval
371       
372        /* Perform a global invalidation */
373        oris    r3,r3,0x0020
374        sync
375        mtspr   L2CR,r3
376        sync
377invalCompleteLoop:                              /* Wait for the invalidation to complete */
378        mfspr   r3,L2CR
379        rlwinm. r4,r3,0,31,31
380        bne     invalCompleteLoop
381       
382        rlwinm  r3,r3,0,11,9;           /* Turn off the L2I bit */
383        sync
384        mtspr   L2CR,r3
385        sync
386       
387noInval:
388        /* re-enable interrupts, i.e. restore original MSR */
389        mtmsr   r7                                      /* (no sync needed) */
390        /* See if we need to enable the cache */
391        cmplwi  r5,0
392        beqlr
393       
394enableCache:
395        /* Enable the cache */
396        oris    r3,r3,0x8000
397        mtspr   L2CR,r3
398        sync
399        blr
400
401       
402        .globl get_L3CR
403        .type  get_L3CR, @function     
404get_L3CR:       
405        /* Make sure this is a 7455 chip */
406        mfspr   r3,PVR
407        rlwinm  r3,r3,16,16,31
408        cmplwi  r3,PPC_7455     /* it's a 7455 */
409        beq     1f     
410        li      r3,-1
411        blr
412       
4131:
414        /* Return the L3CR contents */
415        mfspr   r3,L3CR
416        blr
417
418        .globl set_L3CR
419        .type  set_L3CR, @function
420set_L3CR:       
421        /* Usage:
422         * When setting the L3CR register, you must do a few special things. 
423         * If you are enabling the cache, you must perform a global invalidate.
424         * Then call cpu_enable_l3cr(l3cr).
425         * If you are disabling the cache, you must flush the cache contents first.
426         * This routine takes care of doing these things.  If you
427         * want to modify the L3CR contents after the cache has been enabled,
428         * the recommended procedure is to first call __setL3CR(0) to disable
429         * the cache and then call cpu_enable_l3cr with the new values for
430         * L3CR.
431         */
432       
433        /* Make sure this is a 7455 chip */
434        mfspr   r0,PVR
435        rlwinm  r0,r0,16,16,31
436        cmplwi  r0,PPC_7455
437        beq     thisIs7455     
438        li      r3,-1
439        blr
440       
441thisIs7455:
442        /* Get the current enable bit of the L3CR into r4 */
443        mfspr   r4,L3CR
444        rlwinm  r4,r4,0,0,0
445       
446        /* See if we want to perform a global inval this time. */
447        rlwinm  r6,r3,0,10,10           /* r6 contains the new invalidate bit */
448        rlwinm. r5,r3,0,0,0             /* r5 contains the new enable bit */
449        rlwinm  r3,r3,0,11,9            /* Turn off the invalidate bit */
450        rlwinm  r3,r3,0,1,31            /* Turn off the enable bit */
451        or      r3,r3,r4                /* Keep the enable bit the same as it was for now. */
452        mfmsr   r7                      /* shut off interrupts around critical flush/invalidate sections */
453        rlwinm  r4,r7,0,17,15           /* Turn off EE bit - an external exception while we are flushing
454                                                                   the cache is fatal (comment this line and see!) */
455        mtmsr   r4
456        bne     dontDisableL3Cache      /* Only disable the cache if L3CRApply has the enable bit off */
457        /* Before the L3 is disabled, it must be flused to prevent coherency problems */
458        /* First, we turn off data relocation. */
459        rlwinm  r4,r4,0,28,26           /* Turn off DR bit */
460        mtmsr   r4
461        isync                           /* make sure memory accesses have completed */
462        /* 7455: L3 :    hardware flush         
463         * Set the L3CR[L3IO & L3DO] bits to completely lock the L3 cache */
464        mfspr   r0, L3CR
465        lis     r4, L3CR_LOCK_745x@h
466        ori     r4,r4, L3CR_LOCK_745x@l
467        or      r4,r0,r4
468        rlwinm  r4,r4,0,11,9           /* make sure the invalidate bit off */
469        mtspr   L3CR, r4
470        sync
471        ori     r4, r4, L3CR_L3HWF
472        mtspr   L3CR, r4
473        sync
474        /* L3 flushed,L3IO & L3DO got cleared in the dontDisableL3Cache:  */
475        rlwinm  r4,r7,0,17,15           /* still mask EE but reenable data relocation */
476        mtmsr   r4
477        isync
478       
479        /* Turn off the L3CR enable bit. */
480        rlwinm  r3,r3,0,1,31
481       
482dontDisableL3Cache:             
483        /* Set up the L3CR configuration bits */
484        sync
485        mtspr   L3CR,r3
486        sync
487ifL3Inval:     
488        cmplwi  r6,0
489        beq     noL3Inval
490       
491        /* Perform a global invalidation */
492        oris    r3,r3,0x0020
493        sync
494        mtspr   L3CR,r3
495        sync
496invalCompleteL3:                                /* Wait for the invalidation to complete */
497        mfspr   r3,L3CR
498        rlwinm. r4,r3,0,31,31
499        bne     invalCompleteL3
500       
501        rlwinm  r3,r3,0,11,9;           /* Turn off the L3I bit */
502        sync
503        mtspr   L3CR,r3
504        sync
505       
506noL3Inval:
507        /* re-enable interrupts, i.e. restore original MSR */
508        mtmsr   r7                                      /* (no sync needed) */
509        /* See if we need to enable the cache */
510        cmplwi  r5,0
511        beqlr
512       
513enableL3Cache:
514        /* Enable the cache */
515        oris    r3,r3,0x8000
516        mtspr   L3CR,r3
517        sync
518        blr
Note: See TracBrowser for help on using the repository browser.