mfmsr r1 ; /* unset MSR_SF */ \ clrlwi r1,r1,0 ; \
- mtmsr r1 ; \
- mtmsrd r1 ; \
clrlwi 1,1,0 is rlwinm 1,1,0,0,31 which clears all the top 32 bits, not only MSR[SF]. Importantly it clears MSR[HV], which you do not want. Use rldicl instead?
Now that we actually detect if we're on a 64-bit CPU, we can indeed be a bit more clever about it. However, I don't think any of the upper 32 bits are important to us, no?
You set MSR[HV]=0. That will cause trouble: many mtspr's are then treated as a noop, for example. And if you have an RMO, things break. Etc. Trouble :-)
But we don't run on any of those, do we? You're probably right though
- let's make this clean.
You probably don't set real mode offset in the firmware, no -- but the SPR thing will kill you. In non-hypervisor mode you cannot write most of the fun SPRs.
lis x,0x8000 ; add. x,x,x ; beq ohai_we_are_32bit
lis x,0x8000 would result in 0xffffffff80000000 or 0x80000000 in x respectively. add. compares the full register with 0, so we also get to analyze the shifted out 8. Very nice trick indeed and exactly what I was searching for! Thanks a lot!
add. sets CR0 based on the low 32 bits of the result, in 32-bit mode. 64-bit CPUs always load 0xffffffff80000000 for lis x,0x8000, no matter what mode the CPU is in.
Oh, sure, I meant that on 32-bit CPUs it won't set the f's since they don't exist :)
Yeah. And the result in 32-bit mode on a 64-bit CPU is exactly the same, for all 32-bit Book I instructions :-)
I don't think there is any nice way to detect the CPU you're running on is 64-bit capable, when running in 32-bit mode. But you don't need that here.
Segher