* Strange transmit corruption in jsm driver on geode sc1200 system @ 2006-08-25 20:30 Lennart Sorensen 2006-08-25 21:20 ` Alan Cox 0 siblings, 1 reply; 9+ messages in thread From: Lennart Sorensen @ 2006-08-25 20:30 UTC (permalink / raw) To: Linux Kernel Mailing List; +Cc: Len Sorensen I am seeing a very strange problem with the jsm driver. I am using a Digi Neo 2 DB9 card on a system with a Geode SC1200 cpu. This is essentially an EXAR XC17D152 chip rebranded for Digi. Kernel is based on debian's 2.6.16-17 which is 2.6.16.25 with a few patches. When I use minicom to transmit a chunk of text by sending a text file, the data is transmitted in the wrong order. testfile: 0123456789ABCDEF Received text: 123056749AB8DEFC If I use the same driver and the same card on a P4 system, everything works fine. The driver is doing memcpy_toio to tranfer data to the transmit FIFO (which is a 64byte memory mapped block of memory on the PCI bus as far as I can tell). The data in the transmit queue is in the right order being passed to memcpy_toio, but somehow by the time it is in the uart and goes out the transmiter, every 4th byte is moved 3 bytes back. Transmitting a single character at a time works fine of course since there is nothing to swap it around with, and it is only copying a single byte to the UART rather than a block of bytes. I read something about the geodes doing memory write reordering, but that it is supposed to magically not screw up PCI writes. I have no idea if it is or not though. I have no problem with pcnet32 or any of the other PCI devices I use. Does anyone have any suggestions for something to try? The cpu in question has this information: processor : 0 vendor_id : CyrixInstead cpu family : 5 model : 9 model name : Unknown stepping : 1 cpu MHz : 266.760 fdiv_bug : no hlt_bug : no f00f_bug : no coma_bug : no fpu : yes fpu_exception : yes cpuid level : 2 wp : yes flags : fpu tsc msr cx8 cmov mmx cxmmx bogomips : 535.33 I noticed that cyrix.c has some code for controlling reordering and such, although it doesn't seem to match this particular cpu's ID, so it isn't called. I have no idea if it should have. -- Len Sorensen ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Strange transmit corruption in jsm driver on geode sc1200 system 2006-08-25 20:30 Strange transmit corruption in jsm driver on geode sc1200 system Lennart Sorensen @ 2006-08-25 21:20 ` Alan Cox 2006-08-25 21:03 ` Lennart Sorensen 0 siblings, 1 reply; 9+ messages in thread From: Alan Cox @ 2006-08-25 21:20 UTC (permalink / raw) To: Lennart Sorensen; +Cc: Linux Kernel Mailing List Ar Gwe, 2006-08-25 am 16:30 -0400, ysgrifennodd Lennart Sorensen: > The driver is doing memcpy_toio to tranfer data to the transmit FIFO > (which is a 64byte memory mapped block of memory on the PCI bus as far > as I can tell). The data in the transmit queue is in the right order That should be staying in order unless the device memory is mislabelled and prefetchable etc. > being passed to memcpy_toio, but somehow by the time it is in the uart > and goes out the transmiter, every 4th byte is moved 3 bytes back. What happens if you swap the memcpy_toio with while() writeb() ? > I read something about the geodes doing memory write reordering, but > that it is supposed to magically not screw up PCI writes. I have no > idea if it is or not though. They do a lot of stuff but it should not affect the PCI side and I'd expect it to do other things than byte lane re-ordering. > Does anyone have any suggestions for something to try? Is the buffer 32bit aligned ? ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Strange transmit corruption in jsm driver on geode sc1200 system 2006-08-25 21:20 ` Alan Cox @ 2006-08-25 21:03 ` Lennart Sorensen 2006-08-25 21:24 ` Alexey Dobriyan 0 siblings, 1 reply; 9+ messages in thread From: Lennart Sorensen @ 2006-08-25 21:03 UTC (permalink / raw) To: Alan Cox; +Cc: Linux Kernel Mailing List On Fri, Aug 25, 2006 at 10:20:17PM +0100, Alan Cox wrote: > That should be staying in order unless the device memory is mislabelled > and prefetchable etc. Hmm, no according to lspci the memory is labeled non-prefetachble, and the pci bridge agrees with that setting too. > What happens if you swap the memcpy_toio with while() writeb() ? I tried changing it to a for loop that calles memcpy_toio with one byte at a time, and it works fine that way (although probably less efficient). I expect the writeb one at a time will work too. > They do a lot of stuff but it should not affect the PCI side and I'd > expect it to do other things than byte lane re-ordering. Yeah no kidding. > Is the buffer 32bit aligned ? I honestly don't know. I am just trying to figure out why the jsm driver isn't working on this system while it works on other types of hardware, and so far it seems to come down to the __memcpy assembly not being happy on the SC1200 doing more than one byte at a time. it is very consistently making the same mistake all the time. -- Len Sorensen ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Strange transmit corruption in jsm driver on geode sc1200 system 2006-08-25 21:03 ` Lennart Sorensen @ 2006-08-25 21:24 ` Alexey Dobriyan 2006-08-25 21:57 ` Lennart Sorensen 0 siblings, 1 reply; 9+ messages in thread From: Alexey Dobriyan @ 2006-08-25 21:24 UTC (permalink / raw) To: Lennart Sorensen; +Cc: Alan Cox, linux-kernel On Fri, Aug 25, 2006 at 05:03:05PM -0400, Lennart Sorensen wrote: > > Is the buffer 32bit aligned ? > > I honestly don't know. But you can check. Insert something like this in right place: printk("%p\n", buffer); > I am just trying to figure out why the jsm > driver isn't working on this system while it works on other types of > hardware, and so far it seems to come down to the __memcpy assembly not > being happy on the SC1200 doing more than one byte at a time. it is > very consistently making the same mistake all the time. ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Strange transmit corruption in jsm driver on geode sc1200 system 2006-08-25 21:24 ` Alexey Dobriyan @ 2006-08-25 21:57 ` Lennart Sorensen 2006-08-28 17:30 ` Lennart Sorensen 2006-08-28 18:11 ` Lennart Sorensen 0 siblings, 2 replies; 9+ messages in thread From: Lennart Sorensen @ 2006-08-25 21:57 UTC (permalink / raw) To: Alexey Dobriyan; +Cc: Alan Cox, linux-kernel On Sat, Aug 26, 2006 at 01:24:41AM +0400, Alexey Dobriyan wrote: > But you can check. Insert something like this in right place: > > printk("%p\n", buffer); It would be 1/4 of the time given the code is this: memcpy_toio(&ch->ch_neo_uart->txrxburst, ch->ch_wqueue + tail, s); tail is the offset in the write queue in the jsm driver, which can be any offset whatsoever. So sometimes it is 32bit aligned, but often it isn't. The txrxburst of course is 32bit alligned. Receiving works fine when copying from the alligned buffer in hardware to wherever in the receiver queue. Of course given the __memcpy assembly seems to work fine unalligned on a pentium4, and probably most othe systems, what could make it not work correctly on a geode SC1200? This is the chunk of assembly in use: static __always_inline void * __memcpy(void * to, const void * from, size_t n) { int d0, d1, d2; __asm__ __volatile__( "rep ; movsl\n\t" "movl %4,%%ecx\n\t" "andl $3,%%ecx\n\t" #if 1 /* want to pay 2 byte penalty for a chance to skip microcoded rep? */ "jz 1f\n\t" #endif "rep ; movsb\n\t" "1:" : "=&c" (d0), "=&D" (d1), "=&S" (d2) : "0" (n/4), "g" (n), "1" ((long) to), "2" ((long) from) : "memory"); return (to); } I am affraid I don't know the rep instruction on x86, so it really doesn't make sense to me. I suppose if nothing else works, I can do one byte at a time until the tail is 32bit alligned, and then do the rest of the transfer as a block and see if that makes it work, or whether it is broken no matter what the allignement of the buffer is. -- Len Sorensen ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Strange transmit corruption in jsm driver on geode sc1200 system 2006-08-25 21:57 ` Lennart Sorensen @ 2006-08-28 17:30 ` Lennart Sorensen 2006-08-28 18:11 ` Lennart Sorensen 1 sibling, 0 replies; 9+ messages in thread From: Lennart Sorensen @ 2006-08-28 17:30 UTC (permalink / raw) To: Alexey Dobriyan; +Cc: Alan Cox, linux-kernel On Fri, Aug 25, 2006 at 05:57:24PM -0400, Lennart Sorensen wrote: > It would be 1/4 of the time given the code is this: > > memcpy_toio(&ch->ch_neo_uart->txrxburst, ch->ch_wqueue + tail, s); > > tail is the offset in the write queue in the jsm driver, which can be > any offset whatsoever. So sometimes it is 32bit aligned, but often it > isn't. > > The txrxburst of course is 32bit alligned. Receiving works fine when > copying from the alligned buffer in hardware to wherever in the receiver > queue. > > Of course given the __memcpy assembly seems to work fine unalligned on a > pentium4, and probably most othe systems, what could make it not work > correctly on a geode SC1200? > > This is the chunk of assembly in use: > > static __always_inline void * __memcpy(void * to, const void * from, size_t n) > { > int d0, d1, d2; > __asm__ __volatile__( > "rep ; movsl\n\t" > "movl %4,%%ecx\n\t" > "andl $3,%%ecx\n\t" > #if 1 /* want to pay 2 byte penalty for a chance to skip microcoded rep? */ > "jz 1f\n\t" > #endif > "rep ; movsb\n\t" > "1:" > : "=&c" (d0), "=&D" (d1), "=&S" (d2) > : "0" (n/4), "g" (n), "1" ((long) to), "2" ((long) from) > : "memory"); > return (to); > } > > I am affraid I don't know the rep instruction on x86, so it really > doesn't make sense to me. > > I suppose if nothing else works, I can do one byte at a time until the > tail is 32bit alligned, and then do the rest of the transfer as a block > and see if that makes it work, or whether it is broken no matter what > the allignement of the buffer is. I tried to do a check on the alignment, and only do the whole transfer as a block with memcpy_toio if it was 32bit aligned. It breaks the same way no matter how it is aligned. It really seems that somehow using this __memcpy assembly block on the geode sc1200 doesn't work correctly. Doing the call using a loop with d2=1 works fine, but anything bigger seems broken. -- Len Sorensen ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Strange transmit corruption in jsm driver on geode sc1200 system 2006-08-25 21:57 ` Lennart Sorensen 2006-08-28 17:30 ` Lennart Sorensen @ 2006-08-28 18:11 ` Lennart Sorensen 2006-08-28 19:09 ` Alan Cox 1 sibling, 1 reply; 9+ messages in thread From: Lennart Sorensen @ 2006-08-28 18:11 UTC (permalink / raw) To: Alexey Dobriyan; +Cc: Alan Cox, linux-kernel On Fri, Aug 25, 2006 at 05:57:24PM -0400, Lennart Sorensen wrote: > Of course given the __memcpy assembly seems to work fine unalligned on a > pentium4, and probably most othe systems, what could make it not work > correctly on a geode SC1200? Related to the SC1200, I notied cyrix.c doesn't actually know about the SC1200 that we are using. This one returs dir0_msn = 11, while cyrix.c only knows about 0 through 5. If I add 11 to the block handling geode GX1, then I get this cpuinfo: processor : 0 vendor_id : CyrixInstead cpu family : 5 model : 9 model name : Geode(TM) Integrated Processor by National Semi stepping : 1 cpu MHz : 266.729 cache size : 16 KB fdiv_bug : no hlt_bug : no f00f_bug : no coma_bug : no fpu : yes fpu_exception : yes cpuid level : 2 wp : yes flags : fpu tsc msr cx8 cmov mmx cxmmx bogomips : 535.35 So the get_model_name function seems to do something on it. Otherwise I get "model name" of Unknown, since there is no entry for it in cyrix.c Since it is unknown, no setup calls are being done, although it seems a number of features exist that could be enabled on the geode gx1, which I believe is what a geode sc1200 really is. The full label of the CPU is: (national semi conductors logo) Geode(tm) SC1200 SC1200UL-266 (C)(M)NSC1999 D3 VS424AB Does anyone know what should be called on this CPU type, and how to fix cyrix.c to handle it correcly rather than ignoring it? Forcing it to be treated like a GX1 and calling the geode_configure function call, does not make my memcpy_toio problem go away. On the other hand I have a small optimistic hope that if it actually turns on power saving on HLT, and some cache and memory optimizations, that it might actually make the system run slightly faster and use slightly less power. If someone knows that part for sure I would love to know. -- Len Sorensen ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Strange transmit corruption in jsm driver on geode sc1200 system 2006-08-28 18:11 ` Lennart Sorensen @ 2006-08-28 19:09 ` Alan Cox 2006-08-28 19:18 ` Lennart Sorensen 0 siblings, 1 reply; 9+ messages in thread From: Alan Cox @ 2006-08-28 19:09 UTC (permalink / raw) To: Lennart Sorensen; +Cc: Alexey Dobriyan, linux-kernel Ar Llu, 2006-08-28 am 14:11 -0400, ysgrifennodd Lennart Sorensen: > Related to the SC1200, I notied cyrix.c doesn't actually know about the > SC1200 that we are using. This one returs dir0_msn = 11, while cyrix.c > only knows about 0 through 5. If I add 11 to the block handling geode That is worth fixing. > Does anyone know what should be called on this CPU type, and how to fix > cyrix.c to handle it correcly rather than ignoring it? The databook is available from www.amd.com I believe. You'd need to look at that and see what needs setting. It is quite similar so it probably will benefit a little - but that also depends what the BIOS does for you and with ACPI that should be handled by the ACPI. Alan ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Strange transmit corruption in jsm driver on geode sc1200 system 2006-08-28 19:09 ` Alan Cox @ 2006-08-28 19:18 ` Lennart Sorensen 0 siblings, 0 replies; 9+ messages in thread From: Lennart Sorensen @ 2006-08-28 19:18 UTC (permalink / raw) To: Alan Cox; +Cc: Alexey Dobriyan, linux-kernel On Mon, Aug 28, 2006 at 08:09:38PM +0100, Alan Cox wrote: > That is worth fixing. Well changing case 4: to case 4: case 11: dir0_msn = 4; Makes the geode code appear to be called, and nothing is broken so far. Minimal testing so far actually seems to indicate a slight performance improvement. And /proc/cpuinfo no longer shows Unknown model. I am pretty sure in the past I have seen the model name show MediaGX, so I suspect sometime in the last year there was a revision change or something in the cpu modules we are using, since it now shows Unknown. > The databook is available from www.amd.com I believe. You'd need to look > at that and see what needs setting. It is quite similar so it probably > will benefit a little - but that also depends what the BIOS does for you > and with ACPI that should be handled by the ACPI. This BIOS has no ACPI. At best it could do APM. Seems the amd site requires an NDA to get at anything useful. Maybe I looked in the wrong place. -- Len Sorensen ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2006-08-28 19:18 UTC | newest] Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2006-08-25 20:30 Strange transmit corruption in jsm driver on geode sc1200 system Lennart Sorensen 2006-08-25 21:20 ` Alan Cox 2006-08-25 21:03 ` Lennart Sorensen 2006-08-25 21:24 ` Alexey Dobriyan 2006-08-25 21:57 ` Lennart Sorensen 2006-08-28 17:30 ` Lennart Sorensen 2006-08-28 18:11 ` Lennart Sorensen 2006-08-28 19:09 ` Alan Cox 2006-08-28 19:18 ` Lennart Sorensen
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.