source: rtems/c/src/lib/libcpu/powerpc/mpc6xx/mmu/mmuAsm.S @ 8209461b

Last change on this file since 8209461b was 8209461b, checked in by Joel Sherrill <joel.sherrill@…>, on 09/04/03 at 18:45:53

2003-09-04 Joel Sherrill <joel@…>

  • mpc6xx/clock/c_clock.c, mpc6xx/clock/c_clock.h, mpc6xx/exceptions/raw_exception.c, mpc6xx/exceptions/raw_exception.h, mpc6xx/mmu/bat.c, mpc6xx/mmu/bat.h, mpc6xx/mmu/mmuAsm.S, mpc6xx/timer/timer.c, mpc8260/clock/clock.c, mpc8260/console-generic/console-generic.c, mpc8260/cpm/brg.c, mpc8260/exceptions/raw_exception.c, mpc8260/exceptions/raw_exception.h, mpc8260/include/cpm.h, mpc8260/include/mmu.h, mpc8260/mmu/mmu.c, mpc8260/timer/timer.c, mpc8xx/clock/clock.c, mpc8xx/console-generic/console-generic.c, mpc8xx/exceptions/raw_exception.c, mpc8xx/exceptions/raw_exception.h, mpc8xx/include/cpm.h, mpc8xx/include/mmu.h, mpc8xx/mmu/mmu.c, mpc8xx/timer/timer.c, ppc403/clock/clock.c, ppc403/console/console.c.polled, ppc403/timer/timer.c, rtems/powerpc/debugmod.h, shared/include/byteorder.h, shared/include/cpuIdent.c, shared/include/cpuIdent.h, shared/include/io.h, shared/include/mmu.h, shared/include/page.h, shared/include/pgtable.h, shared/include/spr.h: URL for license changed.
  • Property mode set to 100644
File size: 7.9 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 */
17
18#include <asm.h>
19#include <rtems/score/cpu.h>
20#include <libcpu/io.h>
21
22/* Unfortunately, the CPU types defined in cpu.h are
23 * an 'enum' type and hence not available :-(
24 */
25#define PPC_601   0x1
26#define PPC_603   0x3
27#define PPC_604   0x4
28#define PPC_603e  0x6
29#define PPC_603ev 0x7
30#define PPC_750   0x8
31#define PPC_604e  0x9
32#define PPC_604r  0xA
33#define PPC_7400  0xC
34#define PPC_620   0x16
35#define PPC_860   0x50
36#define PPC_821   PPC_860
37#define PPC_8260  0x81
38
39/* ALTIVEC instructions (not recognized by off-the shelf gcc yet) */
40#define DSSALL  .long   0x7e00066c              /* DSSALL altivec instruction opcode */
41
42/* A couple of defines to make the code more readable */
43#define CACHE_LINE_SIZE 32
44
45#ifndef MSSCR0
46#define MSSCR0   1014
47#else
48#warning MSSCR0 seems to be known, update __FILE__
49#endif
50
51#define DL1HWF  (1<<(31-8))
52#define L2HWF   (1<<(31-20))
53
54
55
56/*
57 * Each setdbat routine start by invalidating the DBAT as some
58 * proc (604e) request the valid bit set to 0 before accepting
59 * to write in BAT
60 */
61
62        .globl  asm_setdbat0
63        .type   asm_setdbat0,@function
64asm_setdbat0:
65        li      r0,0
66        sync
67        isync
68        mtspr   DBAT0U,r0
69        mtspr   DBAT0L,r0
70        sync
71        isync
72        mtspr DBAT0L, r4
73        mtspr DBAT0U, r3
74        sync
75        isync
76        blr
77
78        .globl  asm_setdbat1
79        .type   asm_setdbat1,@function
80asm_setdbat1:
81        li      r0,0
82        sync
83        isync
84        mtspr   DBAT1U,r0
85        mtspr   DBAT1L,r0
86        sync
87        isync
88        mtspr DBAT1L, r4
89        mtspr DBAT1U, r3
90        sync
91        isync
92        blr
93
94        .globl  asm_setdbat2
95        .type   asm_setdbat2,@function
96asm_setdbat2:   
97        li      r0,0
98        sync
99        isync
100        mtspr   DBAT2U,r0
101        mtspr   DBAT2L,r0
102        sync
103        isync
104        mtspr DBAT2L, r4
105        mtspr DBAT2U, r3
106        sync
107        isync
108        blr
109
110        .globl  asm_setdbat3
111        .type   asm_setdbat3,@function
112asm_setdbat3:   
113        li      r0,0
114        sync
115        isync
116        mtspr   DBAT3U,r0
117        mtspr   DBAT3L,r0
118        sync
119        isync
120        mtspr DBAT3L, r4
121        mtspr DBAT3U, r3
122        sync
123        isync
124        blr
125               
126        .globl L1_caches_enables
127        .type  L1_caches_enables, @function
128       
129L1_caches_enables:     
130        /*
131         * Enable caches and 604-specific features if necessary.
132         */
133        mfspr   r9,PVR
134        rlwinm  r9,r9,16,16,31
135        cmpi    0,r9,PPC_601
136        beq     4f                      /* not needed for 601 */
137        mfspr   r11,HID0
138        andi.   r0,r11,HID0_DCE
139        ori     r11,r11,HID0_ICE|HID0_DCE
140        ori     r8,r11,HID0_ICFI
141        bne     3f                      /* don't invalidate the D-cache */
142        ori     r8,r8,HID0_DCI          /* unless it wasn't enabled */
1433:
144        sync
145        mtspr   HID0,r8                 /* enable and invalidate caches */
146        sync
147        mtspr   HID0,r11                /* enable caches */
148        sync
149        isync
150        cmpi    0,r9,PPC_604    /* check for 604 */
151        cmpi    1,r9,PPC_604e   /* or 604e */
152        cmpi    2,r9,PPC_604r   /* or mach5 */
153        cror    2,2,6
154        cror    2,2,10
155        cmpi    1,r9,PPC_750    /* or 750 */
156        cror    2,2,6
157        cmpi    1,r9,PPC_7400   /* or 7400 */
158        bne     3f
159        ori     r11,r11,HID0_BTIC       /* enable branch tgt cache on 7400 */
1603:      cror    2,2,6
161        bne     4f
162        /* on 7400 SIED is actually SGE (store gathering enable) */
163        ori     r11,r11,HID0_SIED|HID0_BHTE /* for 604[e], enable */
164        bne     2,5f
165        ori     r11,r11,HID0_BTCD
1665:      mtspr   HID0,r11                /* superscalar exec & br history tbl */
1674:
168        blr
169       
170        .globl get_L2CR
171        .type  get_L2CR, @function     
172get_L2CR:       
173        /* Make sure this is a > 750 chip */
174        mfspr   r3,PVR
175        rlwinm  r3,r3,16,16,31
176        cmplwi  r3,PPC_750      /* it's a 750 */
177        beq     1f
178        cmplwi  r3,PPC_7400     /* it's a 7400 */
179        beq     1f
180        li      r3,0
181        blr
182       
1831:
184        /* Return the L2CR contents */
185        mfspr   r3,L2CR
186        blr
187
188        .globl set_L2CR
189        .type  set_L2CR, @function
190set_L2CR:       
191        /* Usage:
192         * When setting the L2CR register, you must do a few special things. 
193         * If you are enabling the cache, you must perform a global invalidate.
194         * If you are disabling the cache, you must flush the cache contents first.
195         * This routine takes care of doing these things.  When first
196         * enabling the cache, make sure you pass in the L2CR you want, as well as
197         * passing in the global invalidate bit set.  A global invalidate will
198         * only be performed if the L2I bit is set in applyThis.  When enabling
199         * the cache, you should also set the L2E bit in applyThis.  If you
200         * want to modify the L2CR contents after the cache has been enabled,
201         * the recommended procedure is to first call __setL2CR(0) to disable
202         * the cache and then call it again with the new values for L2CR.  Examples:
203         *
204         *      _setL2CR(0)             -       disables the cache
205         *      _setL2CR(0xb9A14000)    -       enables my G3 MCP750 card:
206         *                              -       L2E set to turn on the cache
207         *                              -       L2SIZ set to 1MB
208         *                              -       L2CLK set to %2
209         *                              -       L2RAM set to pipelined syncronous late-write
210         *                              -       L2I set to perform a global invalidation
211         *                              -       L2OH set to 1 nS
212         *
213         * A similar call should work for your card.  You need to know the correct
214         * setting for your card and then place them in the fields I have outlined
215         * above.  Other fields support optional features, such as L2DO which caches
216         * only data, or L2TS which causes cache pushes from the L1 cache to go to
217         *the L2 cache instead of to main memory.
218         */
219       
220        /* Make sure this is a > 750 chip */
221        mfspr   r0,PVR
222        rlwinm  r0,r0,16,16,31
223        cmplwi  r0,PPC_750
224        beq     thisIs750
225        cmplwi  r0,PPC_7400
226        beq     thisIs750
227        li      r3,-1
228        blr
229       
230thisIs750:
231        /* Get the current enable bit of the L2CR into r4 */
232        mfspr   r4,L2CR
233        rlwinm  r4,r4,0,0,0
234       
235        /* See if we want to perform a global inval this time. */
236        rlwinm  r6,r3,0,10,10           /* r6 contains the new invalidate bit */
237        rlwinm. r5,r3,0,0,0                     /* r5 contains the new enable bit */
238        rlwinm  r3,r3,0,11,9            /* Turn off the invalidate bit */
239        rlwinm  r3,r3,0,1,31            /* Turn off the enable bit */
240        or              r3,r3,r4                        /* Keep the enable bit the same as it was for now. */
241        mfmsr   r7                                      /* shut off interrupts around critical flush/invalidate sections */
242        rlwinm  r4,r7,0,17,15           /* Turn off EE bit - an external exception while we are flushing
243                                                                   the cache is fatal (comment this line and see!) */
244        mtmsr   r4
245        bne             dontDisableCache        /* Only disable the cache if L2CRApply has the enable bit off */
246
247        cmplwi  r0,PPC_7400                     /* > 7400 ? */
248        bne             disableCache            /* use traditional method */
249
250        /* On the 7400, they recommend using the hardware flush feature */
251        DSSALL                                          /* stop all data streams */
252        sync
253        /* we wouldn't have to flush L1, but for sake of consistency with the other code we do it anyway */
254        mfspr   r4, MSSCR0
255        oris    r4, r4, DL1HWF@h
256        mtspr   MSSCR0, r4
257        sync
258        /* L1 flushed */
259        mfspr   r4, L2CR
260        ori             r4, r4, L2HWF
261        mtspr   L2CR, r4
262        sync
263        /* L2 flushed */
264        b               flushDone
265
266disableCache:
267        /* Disable the cache.  First, we turn off data relocation. */
268        rlwinm  r4,r4,0,28,26           /* Turn off DR bit */
269        mtmsr   r4
270        isync                                           /* make sure memory accesses have completed */
271       
272        /*
273                Now, read the first 2MB of memory to put new data in the cache.
274                (Actually we only need the size of the L2 cache plus
275                the size of the L1 cache, but 2MB will cover everything just to be safe).
276        */
277        lis             r4,0x0001
278        mtctr   r4
279        li              r4,0
280loadLoop:
281        lwzx    r0,r0,r4
282        addi    r4,r4,CACHE_LINE_SIZE   /* Go to start of next cache line */
283        bdnz    loadLoop
284       
285        /* Now, flush the first 2MB of memory */
286        lis             r4,0x0001
287        mtctr   r4
288        li              r4,0
289        sync
290flushLoop:
291        dcbf    r0,r4
292        addi    r4,r4,CACHE_LINE_SIZE   /* Go to start of next cache line */
293        bdnz    flushLoop
294        sync
295
296        rlwinm  r4,r7,0,17,15           /* still mask EE but reenable data relocation */
297        mtmsr   r4
298        isync
299
300flushDone:
301       
302        /* Turn off the L2CR enable bit. */
303        rlwinm  r3,r3,0,1,31
304       
305dontDisableCache:
306        /* Set up the L2CR configuration bits */
307        sync
308        mtspr   L2CR,r3
309        sync
310        cmplwi  r6,0
311        beq     noInval
312       
313        /* Perform a global invalidation */
314        oris    r3,r3,0x0020
315        sync
316        mtspr   L2CR,r3
317        sync
318invalCompleteLoop:                              /* Wait for the invalidation to complete */
319        mfspr   r3,L2CR
320        rlwinm. r4,r3,0,31,31
321        bne     invalCompleteLoop
322       
323        rlwinm  r3,r3,0,11,9;           /* Turn off the L2I bit */
324        sync
325        mtspr   L2CR,r3
326        sync
327       
328noInval:
329        /* re-enable interrupts, i.e. restore original MSR */
330        mtmsr   r7                                      /* (no sync needed) */
331        /* See if we need to enable the cache */
332        cmplwi  r5,0
333        beqlr
334       
335enableCache:
336        /* Enable the cache */
337        oris    r3,r3,0x8000
338        mtspr   L2CR,r3
339        sync
340        blr
Note: See TracBrowser for help on using the repository browser.