RE: Endianness versus too many byte swaps??
Charles Krinke wrote: This routine uses a ccsr_pci struct to assign potar2, powar2, powbar2 and others like this: pci-potar2 = 0x0010; pci-powar2 = 0x8004401a; pci-powbar2 = 0x00888000; This is big-endian access to the registers, right? I tend to prefer explicit macros like the following when accessing CCSR and such. It also adds IO synchronization as a bonus. out_be32(pci-potar2, 0x0010); out_be32(pci-powar2, 0x8004401a); out_be32(pci-powbar2, 0x00888000); Where I have changed the constants for our board. The issue is that when I call readl to read back these same registers at the end of this same subroutine, I get into endianess issues. That is, I read back POTAR2 == 0x1000 POWAR2 == 0x1A400480 POWBAR2 == 0x00800800 Where the four bytes in each 32bit word are now exchanged so that 80_04_40_1A became 1A_40_04_80. I understand big versus little endian, that isn't the question. The question is What is really in the POTAR2, POWAR2 POWBAR2 registers and how can I prove that what is in the registers is really what I wish to be in the registers? You do understand that readl is in fact a call to in_le32() on ppc (cf. include/asm-ppc/io.h). The question now is, what endianness you would like in that register? Regards -- Stephane ___ Linuxppc-embedded mailing list Linuxppc-embedded@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-embedded
RE: Endianness versus too many byte swaps??
You do understand that readl is in fact a call to in_le32() on ppc (cf. include/asm-ppc/io.h). The question now is, what endianness you would like in that register? Regards -- Stephane Dear Stephane: Your point is well made. I can see that readl is in fact a call to in_le32. Maybe there is a more basic problem here. If I change the call to readl to a call to in_be32, things make sense again. So, maybe I don't quite understand the endianness setup of this Linux project. I am told that we are running this ppc in big endian, so would this mean that readl writel should actually be resolving to in_be32/out_be32 respectively? Is there some other setup that may be wrong? Charles ___ Linuxppc-embedded mailing list Linuxppc-embedded@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-embedded
Re: Endianness versus too many byte swaps??
On Mar 5, 2007, at 9:02 AM, Charles Krinke wrote: You do understand that readl is in fact a call to in_le32() on ppc (cf. include/asm-ppc/io.h). The question now is, what endianness you would like in that register? Regards -- Stephane Dear Stephane: Your point is well made. I can see that readl is in fact a call to in_le32. Maybe there is a more basic problem here. If I change the call to readl to a call to in_be32, things make sense again. So, maybe I don't quite understand the endianness setup of this Linux project. readl/writel are for PCI bus accesses. PCI is inherently little endian. I am told that we are running this ppc in big endian, so would this mean that readl writel should actually be resolving to in_be32/out_be32 respectively? Is there some other setup that may be wrong? Nope, readl/writel are doing the write thing, they will ALWAYS be little endian. You truly want in_be*/out_be* when accessing 85xx CCSR registers since all of them are big endian. - k ___ Linuxppc-embedded mailing list Linuxppc-embedded@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-embedded
RE: Endianness versus too many byte swaps??
Charles Krinke wrote: [...] I am told that we are running this ppc in big endian, so would this mean that readl writel should actually be resolving to in_be32/out_be32 respectively? Is there some other setup that may be wrong? IIRC, readl and writel were defined this way in order to ease PCI driver portability from x86 PC centric world to big-endian arch's. That's why now I'm always using in_be*/out_be*/in_le*/out_le*, to make things explicit, and let the header files do the swapping if need be. Regards -- Stephane ___ Linuxppc-embedded mailing list Linuxppc-embedded@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-embedded
RE: Endianness versus too many byte swaps??
Thank you Stephane and Kumar. I think the moral of this story is that the drive logic created by my predecessor that calls readl/writel to read/write ppc registers needs to be changed to call in_be32 outbe32 so I don't continue a mistake. Charles ___ Linuxppc-embedded mailing list Linuxppc-embedded@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-embedded
Endianness versus too many byte swaps??
This is probably a Timur question, but any enlightment is appreciated. This concerns Linux-2.6.17.11 from kernel.org with some modifications for our custom 8541 board. The original BSP was evolved from mpc85xx_cds. Down in the guts of arch/ppc/syslib/ppc85xx_seteup.c is a routine called mpc85xx_setup_pci1(). In this routine we do an assignment of some outbound window registers and I am most interested in POTAR2, POWAR2 POWBAR2 right now. This routine uses a ccsr_pci struct to assign potar2, powar2, powbar2 and others like this: pci-potar2 = 0x0010; pci-powar2 = 0x8004401a; pci-powbar2 = 0x00888000; Where I have changed the constants for our board. The issue is that when I call readl to read back these same registers at the end of this same subroutine, I get into endianess issues. That is, I read back POTAR2 == 0x1000 POWAR2 == 0x1A400480 POWBAR2 == 0x00800800 Where the four bytes in each 32bit word are now exchanged so that 80_04_40_1A became 1A_40_04_80. I understand big versus little endian, that isn't the question. The question is What is really in the POTAR2, POWAR2 POWBAR2 registers and how can I prove that what is in the registers is really what I wish to be in the registers? It may be that one or more endian swap things are going on within Linux and I have inherited some source from others, so actually proving what is in the registers is becoming important. Charles ___ Linuxppc-embedded mailing list Linuxppc-embedded@ozlabs.org https://ozlabs.org/mailman/listinfo/linuxppc-embedded