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

4.115
Last change on this file since e71a3a84 was e71a3a84, checked in by Joel Sherrill <joel.sherrill@…>, on 01/28/11 at 20:38:13

2011-01-28 Joel Sherrill <joel.sherrilL@…>

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