-;
-; Handle 64-bit architecture
-; This processor can not run without caches, so we just push everything out
-; and flush. It will be relativily clean afterwards
-;
-
- .align 5
-
-cin64:
- li r10,hi16(dozem|napm|sleepm) ; Mask of power management bits we want cleared
- sldi r10,r10,32 ; Position the masks
- andc r9,r9,r10 ; Clean up the old power bits
- mr r4,r9
- isync
- mtspr hid0,r4 ; Set up the HID
- mfspr r4,hid0 ; Yes, this is silly, keep it here
- mfspr r4,hid0 ; Yes, this is a duplicate, keep it here
- mfspr r4,hid0 ; Yes, this is a duplicate, keep it here
- mfspr r4,hid0 ; Yes, this is a duplicate, keep it here
- mfspr r4,hid0 ; Yes, this is a duplicate, keep it here
- mfspr r4,hid0 ; Yes, this is a duplicate, keep it here
- isync
-
- mfspr r10,hid1 ; Save hid1
- mfspr r4,hid4 ; Save hid4
- mr r12,r10 ; Really save hid1
- mr r11,r4 ; Get a working copy of hid4
-
- li r0,0 ; Get a 0
- eqv r2,r2,r2 ; Get all foxes
-
- rldimi r10,r0,55,7 ; Clear I$ prefetch bits (7:8)
-
- isync
- mtspr hid1,r10 ; Stick it
- mtspr hid1,r10 ; Stick it again
- isync
-
- rldimi r11,r2,38,25 ; Disable D$ prefetch (25:25)
-
- sync
- mtspr hid4,r11 ; Stick it
- isync
-
- li r3,8 ; Set bit 28+32
- sldi r3,r3,32 ; Make it bit 28
- or r3,r3,r11 ; Turn on the flash invalidate L1D$
-
- oris r5,r11,0x0600 ; Set disable L1D$ bits
- sync
- mtspr hid4,r3 ; Invalidate
- isync
-
- mtspr hid4,r5 ; Un-invalidate and disable L1D$
- isync
-
- lis r8,GUSModeReg ; Get the GUS mode ring address
- mfsprg r0,2 ; Get the feature flags
- ori r8,r8,0x8000 ; Set to read data
- rlwinm. r0,r0,pfSCOMFixUpb+1,31,31 ; Set shift if we need a fix me up
-
- sync
-
- mtspr scomc,r8 ; Request the GUS mode
- mfspr r11,scomd ; Get the GUS mode
- mfspr r8,scomc ; Get back the status (we just ignore it)
- sync
- isync
-
- sld r11,r11,r0 ; Fix up if needed
-
- ori r6,r11,lo16(GUSMdmapen) ; Set the bit that means direct L2 cache address
- lis r8,GUSModeReg ; Get GUS mode register address
-
- sync
-
- mtspr scomd,r6 ; Set that we want direct L2 mode
- mtspr scomc,r8 ; Tell GUS we want direct L2 mode
- mfspr r3,scomc ; Get back the status
- sync
- isync
-
- li r3,0 ; Clear start point
-
-cflushlp: lis r6,0x0040 ; Pick 4MB line as our target
- or r6,r6,r3 ; Put in the line offset
- lwz r5,0(r6) ; Load a line
- addis r6,r6,8 ; Roll bit 42:44
- lwz r5,0(r6) ; Load a line
- addis r6,r6,8 ; Roll bit 42:44
- lwz r5,0(r6) ; Load a line
- addis r6,r6,8 ; Roll bit 42:44
- lwz r5,0(r6) ; Load a line
- addis r6,r6,8 ; Roll bit 42:44
- lwz r5,0(r6) ; Load a line
- addis r6,r6,8 ; Roll bit 42:44
- lwz r5,0(r6) ; Load a line
- addis r6,r6,8 ; Roll bit 42:44
- lwz r5,0(r6) ; Load a line
- addis r6,r6,8 ; Roll bit 42:44
- lwz r5,0(r6) ; Load a line
-
- addi r3,r3,128 ; Next line
- andis. r5,r3,8 ; Have we done enough?
- beq++ cflushlp ; Not yet...
-
- sync
-
- lis r6,0x0040 ; Pick 4MB line as our target
-
-cflushx: dcbf 0,r6 ; Flush line and invalidate
- addi r6,r6,128 ; Next line
- andis. r5,r6,0x0080 ; Have we done enough?
- beq++ cflushx ; Keep on flushing...
-
- mr r3,r10 ; Copy current hid1
- rldimi r3,r2,54,9 ; Set force icbi match mode
-
- li r6,0 ; Set start if ICBI range
- isync
- mtspr hid1,r3 ; Stick it
- mtspr hid1,r3 ; Stick it again
- isync
-
-cflicbi: icbi 0,r6 ; Kill I$
- addi r6,r6,128 ; Next line
- andis. r5,r6,1 ; Have we done them all?
- beq++ cflicbi ; Not yet...
-
- lis r8,GUSModeReg ; Get GUS mode register address
-
- sync
-
- mtspr scomd,r11 ; Set that we do not want direct mode
- mtspr scomc,r8 ; Tell GUS we do not want direct mode
- mfspr r3,scomc ; Get back the status
- sync
- isync
-
- isync
- mtspr hid1,r12 ; Restore entry hid1
- mtspr hid1,r12 ; Stick it again
- isync
-
- sync
- mtspr hid4,r4 ; Restore entry hid4
- isync
-
- sync
- mtmsr r7 ; Restore MSR to entry
- isync
- blr ; Return...
-
-
-