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

Last change on this file since d700909e was d700909e, checked in by Joel Sherrill <joel.sherrill@…>, on Nov 10, 2004 at 10:37:57 PM

2004-11-10 Richard Campbell <richard.campbell@…>

  • configure.ac, mpc6xx/exceptions/raw_exception.c, mpc6xx/exceptions/raw_exception.h, mpc6xx/mmu/bat.c, mpc6xx/mmu/bat.h, mpc6xx/mmu/mmuAsm.S, shared/include/cpuIdent.c, shared/include/cpuIdent.h: Add MPC8240 and MPC8245 support. There was also a significant amount of spelling and whitespace cleanup.
  • 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#define PPC_8240  PPC_8260
39
40/* ALTIVEC instructions (not recognized by off-the shelf gcc yet) */
41#define DSSALL  .long   0x7e00066c              /* DSSALL altivec instruction opcode */
42
43/* A couple of defines to make the code more readable */
44#define CACHE_LINE_SIZE 32
45
46#ifndef MSSCR0
47#define MSSCR0   1014
48#else
49#warning MSSCR0 seems to be known, update __FILE__
50#endif
51
52#define DL1HWF  (1<<(31-8))
53#define L2HWF   (1<<(31-20))
54
55
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    0,r9,PPC_604    /* check for 604 */
152        cmpi    1,r9,PPC_604e   /* or 604e */
153        cmpi    2,r9,PPC_604r   /* or mach5 */
154        cror    2,2,6
155        cror    2,2,10
156        cmpi    1,r9,PPC_750    /* or 750 */
157        cror    2,2,6
158        cmpi    1,r9,PPC_7400   /* or 7400 */
159        bne     3f
160        ori     r11,r11,HID0_BTIC       /* enable branch tgt cache on 7400 */
1613:      cror    2,2,6
162        bne     4f
163        /* on 7400 SIED is actually SGE (store gathering enable) */
164        ori     r11,r11,HID0_SIED|HID0_BHTE /* for 604[e], enable */
165        bne     2,5f
166        ori     r11,r11,HID0_BTCD
1675:      mtspr   HID0,r11                /* superscalar exec & br history tbl */
1684:
169        blr
170       
171        .globl get_L2CR
172        .type  get_L2CR, @function     
173get_L2CR:       
174        /* Make sure this is a > 750 chip */
175        mfspr   r3,PVR
176        rlwinm  r3,r3,16,16,31
177        cmplwi  r3,PPC_750      /* it's a 750 */
178        beq     1f
179        cmplwi  r3,PPC_7400     /* it's a 7400 */
180        beq     1f
181        li      r3,0
182        blr
183       
1841:
185        /* Return the L2CR contents */
186        mfspr   r3,L2CR
187        blr
188
189        .globl set_L2CR
190        .type  set_L2CR, @function
191set_L2CR:       
192        /* Usage:
193         * When setting the L2CR register, you must do a few special things. 
194         * If you are enabling the cache, you must perform a global invalidate.
195         * If you are disabling the cache, you must flush the cache contents first.
196         * This routine takes care of doing these things.  When first
197         * enabling the cache, make sure you pass in the L2CR you want, as well as
198         * passing in the global invalidate bit set.  A global invalidate will
199         * only be performed if the L2I bit is set in applyThis.  When enabling
200         * the cache, you should also set the L2E bit in applyThis.  If you
201         * want to modify the L2CR contents after the cache has been enabled,
202         * the recommended procedure is to first call __setL2CR(0) to disable
203         * the cache and then call it again with the new values for L2CR.  Examples:
204         *
205         *      _setL2CR(0)             -       disables the cache
206         *      _setL2CR(0xb9A14000)    -       enables my G3 MCP750 card:
207         *                              -       L2E set to turn on the cache
208         *                              -       L2SIZ set to 1MB
209         *                              -       L2CLK set to %2
210         *                              -       L2RAM set to pipelined syncronous late-write
211         *                              -       L2I set to perform a global invalidation
212         *                              -       L2OH set to 1 nS
213         *
214         * A similar call should work for your card.  You need to know the correct
215         * setting for your card and then place them in the fields I have outlined
216         * above.  Other fields support optional features, such as L2DO which caches
217         * only data, or L2TS which causes cache pushes from the L1 cache to go to
218         *the L2 cache instead of to main memory.
219         */
220       
221        /* Make sure this is a > 750 chip */
222        mfspr   r0,PVR
223        rlwinm  r0,r0,16,16,31
224        cmplwi  r0,PPC_750
225        beq     thisIs750
226        cmplwi  r0,PPC_7400
227        beq     thisIs750
228        li      r3,-1
229        blr
230       
231thisIs750:
232        /* Get the current enable bit of the L2CR into r4 */
233        mfspr   r4,L2CR
234        rlwinm  r4,r4,0,0,0
235       
236        /* See if we want to perform a global inval this time. */
237        rlwinm  r6,r3,0,10,10           /* r6 contains the new invalidate bit */
238        rlwinm. r5,r3,0,0,0                     /* r5 contains the new enable bit */
239        rlwinm  r3,r3,0,11,9            /* Turn off the invalidate bit */
240        rlwinm  r3,r3,0,1,31            /* Turn off the enable bit */
241        or              r3,r3,r4                        /* Keep the enable bit the same as it was for now. */
242        mfmsr   r7                                      /* shut off interrupts around critical flush/invalidate sections */
243        rlwinm  r4,r7,0,17,15           /* Turn off EE bit - an external exception while we are flushing
244                                                                   the cache is fatal (comment this line and see!) */
245        mtmsr   r4
246        bne             dontDisableCache        /* Only disable the cache if L2CRApply has the enable bit off */
247
248        cmplwi  r0,PPC_7400                     /* > 7400 ? */
249        bne             disableCache            /* use traditional method */
250
251        /* On the 7400, they recommend using the hardware flush feature */
252        DSSALL                                          /* stop all data streams */
253        sync
254        /* we wouldn't have to flush L1, but for sake of consistency with the other code we do it anyway */
255        mfspr   r4, MSSCR0
256        oris    r4, r4, DL1HWF@h
257        mtspr   MSSCR0, r4
258        sync
259        /* L1 flushed */
260        mfspr   r4, L2CR
261        ori             r4, r4, L2HWF
262        mtspr   L2CR, r4
263        sync
264        /* L2 flushed */
265        b               flushDone
266
267disableCache:
268        /* Disable the cache.  First, we turn off data relocation. */
269        rlwinm  r4,r4,0,28,26           /* Turn off DR bit */
270        mtmsr   r4
271        isync                                           /* make sure memory accesses have completed */
272       
273        /*
274                Now, read the first 2MB of memory to put new data in the cache.
275                (Actually we only need the size of the L2 cache plus
276                the size of the L1 cache, but 2MB will cover everything just to be safe).
277        */
278        lis             r4,0x0001
279        mtctr   r4
280        li              r4,0
281loadLoop:
282        lwzx    r0,r0,r4
283        addi    r4,r4,CACHE_LINE_SIZE   /* Go to start of next cache line */
284        bdnz    loadLoop
285       
286        /* Now, flush the first 2MB of memory */
287        lis             r4,0x0001
288        mtctr   r4
289        li              r4,0
290        sync
291flushLoop:
292        dcbf    r0,r4
293        addi    r4,r4,CACHE_LINE_SIZE   /* Go to start of next cache line */
294        bdnz    flushLoop
295        sync
296
297        rlwinm  r4,r7,0,17,15           /* still mask EE but reenable data relocation */
298        mtmsr   r4
299        isync
300
301flushDone:
302       
303        /* Turn off the L2CR enable bit. */
304        rlwinm  r3,r3,0,1,31
305       
306dontDisableCache:
307        /* Set up the L2CR configuration bits */
308        sync
309        mtspr   L2CR,r3
310        sync
311        cmplwi  r6,0
312        beq     noInval
313       
314        /* Perform a global invalidation */
315        oris    r3,r3,0x0020
316        sync
317        mtspr   L2CR,r3
318        sync
319invalCompleteLoop:                              /* Wait for the invalidation to complete */
320        mfspr   r3,L2CR
321        rlwinm. r4,r3,0,31,31
322        bne     invalCompleteLoop
323       
324        rlwinm  r3,r3,0,11,9;           /* Turn off the L2I bit */
325        sync
326        mtspr   L2CR,r3
327        sync
328       
329noInval:
330        /* re-enable interrupts, i.e. restore original MSR */
331        mtmsr   r7                                      /* (no sync needed) */
332        /* See if we need to enable the cache */
333        cmplwi  r5,0
334        beqlr
335       
336enableCache:
337        /* Enable the cache */
338        oris    r3,r3,0x8000
339        mtspr   L2CR,r3
340        sync
341        blr
Note: See TracBrowser for help on using the repository browser.