ChorusOS 4.0 Porting Guide

ppc60x_init()

ppc60x_init() initializes the CPU for the PowerPC BKI (see "PowerPC BKI"). This routines applies to PowerPC 60x, 750, and MPC8260 processors. To put the CPU in an appropriate state for the PowerPC 60x BKI, the routine goes through the following steps:

  1. Clears all bits in the MSR register, except the ME and RI bits which are set:

    • disables external interrupts (MSR[EE])

    • disables instruction and data translations (MSR[IR], MSR[DR])

    • disables FPU instructions (MSR[FP])

    • puts the processor into a Supervisor privilege state (MSR[PR])

    • enables machine-check exceptions (MSR[ME)

    • puts the processor into a recoverable exception state (MSR[RI])

  2. Clears and invalidates all Segment Registers (SR) , including all Translation Lookaside Buffer (TLB) entries and Block Address Translation (BAT) registers. Also, resets, disables and/or invalidates all MMU registers.

  3. Invalidates all L1 data cache, for both L1 instruction and data caches and disables internal (L1) memory caches.

In addition, if the CPU is a MCP750 processor, then the L2 cache is also disabled as it is directly interfaced with the CPU.


Example 3-11 ppc60x_init()

#define MPC_750 8

        .text
        
        GLOBAL(ppc60x_init)
ppc60x_init:

        /*
         * Reset MSR register
         */
        li      r9, 0x0
        ori     r9, r9, MSR_ME | MSR_RI
        mtmsr   r9      
        isync
                
        /* 
         * Invalidate all segment registers 
         */
        lis     r9,   0x0
        mtsr    sr0,  r9
        mtsr    sr1,  r9
        mtsr    sr2,  r9
        mtsr    sr3,  r9
        mtsr    sr4,  r9
        mtsr    sr5,  r9
        mtsr    sr6,  r9
        mtsr    sr7,  r9
        mtsr    sr8,  r9
        mtsr    sr9,  r9
        mtsr    sr10, r9
        mtsr    sr11, r9
        mtsr    sr12, r9
        mtsr    sr13, r9
        mtsr    sr14, r9
        mtsr    sr15, r9

        /* 
         * Invalidate all TLB entries
         *
         * Implementation note:
         *
         *   as tlbia in not implemented on 604 nor on MPC750 processors,
         *   we use tlbie in a loop for the 64*4 entries (on 604e)
         *   followed by tlbsync
         */
        mfctr   r9
        li      r7, 64
        mtctr   r7
        li      r7, 0
loop:
        tlbie   r7
        addi    r7, r7, 0x1000
        bdnz    loop
        tlbsync
        mtctr   r9

        /* 
         * Reset BAT registers.
         *
         * Implementation note:
         *
         *   The 604 BAT registers are not initialized by the hardware
         *   after the power-up or reset sequence. Consequently, all valid
         *   bits in both instruction and data BAT areas must be cleared
         *   before setting any BAT area for the first time.
         *   This is true regardless of wether address translation is
         *   enabled. Also, software must avoid overlapping blocks while
         *   updating a BAT area or areas. Even if translation is
         *                               ^^^^^^^^^^^^^^^^^^^^^^
         *   disabled, multiple BAT area hits are treated as programming
         *   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         *   errors and can corrupt the BAT registers and produce
         *              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         *   unpredictable results.
         *
         *   from: "PowerPC 604 User's manual" 
         *         (Chapter 5: Memory management, p 5-13)
         *
         *   Note that this true for MPC750 too.
         */
        li      r9,     0
        mtspr   dbat0u, r9
        mtspr   dbat0l, r9
        mtspr   dbat1u, r9
        mtspr   dbat1l, r9
        mtspr   dbat2u, r9
        mtspr   dbat2l, r9
        mtspr   dbat3u, r9
        mtspr   dbat3l, r9
        mtspr   ibat0u, r9
        mtspr   ibat0l, r9
        mtspr   ibat1u, r9
        mtspr   ibat1l, r9
        mtspr   ibat2u, r9
        mtspr   ibat2l, r9
        mtspr   ibat3u, r9
        mtspr   ibat3l, r9
        isync

        /*
         * Disable L1 instruction and data caches
         */
        mfspr   r9, hid0
        andi.   r10, r9, (HID0_ICACHE_ENABLE | HID0_DCACHE_ENABLE)
        beq     L1Disabled              /* if disabled, nothing to do */
                /*
                 * flush L1 cache
                 */
        li      r3, 1024                /* 1024 blocks of 32 bytes*/
loop_load:
        lwz     r6, 0(r3)               /* load block       */
        addi    r3, r3, 32              /* go to next block */
        bdnz    loop_load
        li      r3, 1024                /* 1024 blocks of 32 bytes*/
        mtctr   r3
        li      r3, 0        
        mtctr   r3,
        li      r3, 0
loop_flush:
        dcbf    r0, r3
        addi    r3, r3, 32              /* cache line size */
        bdnz    loop_flush
                /*
                 * disable L1 cache
                 */
        rlwinm  r9, r9, 0, HID0_dce + 1, HID0_ice - 1
                                        /* Clear HID0[ICE,DCE] bits */
        isync
        mtspr   hid0, r9
        isync
L1Disabled:

        /*
         * Disable MPC750 L2 cache
         */
        mfspr   r9, pvr
        srwi    r9, r9, 16              /* only interested in version */
        cmpwi   r9, MPC_750             /* if not 750, nothing to do  */
        bne     L2Disabled              

        mfspr   r9, l2cr                
        andis.  r10, r9, HIWORDA(L2CR_ENABLE)
        beq     L2Disabled              /* if disabled, nothing to do */     
                                
        rlwinm  r10, r9, 0, L2CR_l2e + 1, 31
                                        /* clear L2CR[L2E] bit  */
        sync                    
        mtspr   l2cr, r10
        sync                    
        isync
L2Disabled:

        blr