+;
+; 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:
+ 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 hid0,r9 ; Restore entry hid0
+ mfspr r9,hid0 ; Yes, this is silly, keep it here
+ mfspr r9,hid0 ; Yes, this is a duplicate, keep it here
+ mfspr r9,hid0 ; Yes, this is a duplicate, keep it here
+ mfspr r9,hid0 ; Yes, this is a duplicate, keep it here
+ mfspr r9,hid0 ; Yes, this is a duplicate, keep it here
+ mfspr r9,hid0 ; Yes, this is a duplicate, keep it here
+ 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...
+
+
+