linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* PCI Memory mapping
@ 2004-03-16 11:40 Marc Leeman
  2004-03-16 16:39 ` Jeff Angielski
  0 siblings, 1 reply; 26+ messages in thread
From: Marc Leeman @ 2004-03-16 11:40 UTC (permalink / raw)
  To: linuxppc-dev


I am currently trying the following

 +-----+        +-----+
 | mem |        | mem |
 +-----+        +-----+
    |              |
 +-----+        +-----+
 | ppc |        | dsp |
 +-----+        +-----+
    |     pci      |
    +--------------+

For a number of reasons (load on ppc, dsp silicon bug), we are trying to
transform the ppc dma transfers (ppc master write) to transfers
initiated by the dsp; where the memory block that is the result of
processing by the ppc is fetched by the dsp (ppc slave read).

Mapping pci devices registers and memory  into ppc kernel memory is well
documented, but I seem to be missing information about the other way
around: I (ppc) want to signal the dsp that data is ready at address
0xXXXXXXXX, come and get it (virt_to_bus(0xXXXXXXXX)?).

Most likely I have been searching archives with the wrong keywords since
I haven't found a good reference next to some notes in IO-mapping.txt
which seem to indicate that this is possible.

Any pointers about making cpu memory visible on the pci bus would greatly
be appreciated.

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: PCI Memory mapping
  2004-03-16 11:40 Marc Leeman
@ 2004-03-16 16:39 ` Jeff Angielski
  2004-03-22  7:48   ` Marc Leeman
  0 siblings, 1 reply; 26+ messages in thread
From: Jeff Angielski @ 2004-03-16 16:39 UTC (permalink / raw)
  To: Marc Leeman; +Cc: linuxppc-dev


On Tue, 2004-03-16 at 06:40, Marc Leeman wrote:
> Any pointers about making cpu memory visible on the pci bus would greatly
> be appreciated.

Check your PPC documentation for the configuration of the PITARx,
PIBARx, and PICMRx.  Once you read about these it should all make sense.

Then look at your bootloader source code (hopefully you are using
u-boot) to see how these registers are being configured.

HTH,
Jeff Angielski
The PTR Group


** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: PCI Memory mapping
  2004-03-16 16:39 ` Jeff Angielski
@ 2004-03-22  7:48   ` Marc Leeman
  2004-03-22 11:02     ` Marc Leeman
  2004-03-23 11:17     ` Marc Leeman
  0 siblings, 2 replies; 26+ messages in thread
From: Marc Leeman @ 2004-03-22  7:48 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Jeff Angielski


> Check your PPC documentation for the configuration of the PITARx,
> PIBARx, and PICMRx. Once you read about these it should all make
> sense. Then look at your bootloader source code (hopefully you are
> using u-boot) to see how these registers are being configured.

Tnx for the info.

I am working on a solution, so instead of just posing a question on
the list, maybe the current working solution is a good contribution to
the lesser divine kernel hackers on the list :)

pci_map_single(driver_data.dev,driver_data.device[i]->\
    pciaddress,PCI_TRANSFER_SIZE,PCI_DMA_TODEVICE)

and

pci_unmap_single(driver_data.dev,driver_data.device[i]->\
    bus_addr,PCI_TRANSFER_SIZE,PCI_DMA_TODEVICE);

The data is transferred in blocks of 2k and first copied into a kernel
buffer from user space and then mapped on the PCI address range. Ideally
the user-space buffer would be mapped onto PCI (don't know if this is
possible, I did a quick, negative, test, but I suspect that I should
check the addresses again). However, this would put some logic at user
level, which is currently (in the transformation process) not desired.

The bus address (result of pci_map_single) is transferred to the DSP,
which it uses to fetch the data.

  +------+       +--------+     +------------+
  | user |------>| kernel |---->| pci-mapped |
  +------+       +--------+     +------------+

In the current kernel code (2.4.17 mvl2.1), pci_sync_single does not
seem to be implemented. In the code I checked, the successive mapping
and unmapping of the buffers does result in the same addresses.

I would assume that pci_sync_single would allow me to pass the mapped
address only once to the DSP, awaking it with an appropriate interrupt
when new data is available. Due to the absence of pci_sync_single, the
pci-mapped address needs to be passed to the DSP each time.

The observation based question is: to what degree can I be certain that
in a streaming data application, the successive mapping and unmapping of
the pci mapped addresses will result in the same bus addresses?

--
  Marc Leeman                                          Hardware R&D Engineer
  Barco Controlrooms Division                Noordlaan 5, B-8520 Kuurne (BE)
  Tel. +32 56 368 428 http://www.barcocontrolrooms.com marc.leeman@barco.com

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: PCI Memory mapping
  2004-03-22  7:48   ` Marc Leeman
@ 2004-03-22 11:02     ` Marc Leeman
  2004-03-23 11:17     ` Marc Leeman
  1 sibling, 0 replies; 26+ messages in thread
From: Marc Leeman @ 2004-03-22 11:02 UTC (permalink / raw)
  To: linuxppc-dev


> the list, maybe the current working solution is a good contribution to
> the lesser divine kernel hackers on the list :)

euhm, which include me :)

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: PCI Memory mapping
  2004-03-22  7:48   ` Marc Leeman
  2004-03-22 11:02     ` Marc Leeman
@ 2004-03-23 11:17     ` Marc Leeman
  2004-03-23 16:01       ` Marc Leeman
  2004-03-24  0:04       ` Benjamin Herrenschmidt
  1 sibling, 2 replies; 26+ messages in thread
From: Marc Leeman @ 2004-03-23 11:17 UTC (permalink / raw)
  To: linuxppc-dev


>   +------+       +--------+     +------------+
>   | user |------>| kernel |---->| pci-mapped |
>   +------+       +--------+     +------------+

Hm, I'm not quite out of the woods yet it seems :-/

The system contains (amongst other components) a MPC8245 PPC and a
TMS320C6415 DSP. The PPC handles incoming data and passes it along to
the DSP. Partially due to a problem on the DSP, we want the DMA to be
initiated by the DSP.

As such, we prepare a kernel buffer:
if(!(driver_data.device[i]->kern_addr= \
  pci_alloc_consistent(driver_data.dev,PCI_TRANSFER_SIZE,\
  &(driver_data.device[i]->bus_addr)))){...}

that links/maps it on the PCI memory range. This dma_t (bus address) is
passed to the DSP. The DSP then reads the data over the PCI buss and
acknowledges this to the (currently polling) PPC.

The PPC prepares the data, and calls an ioctl that copies part of the
user buffer into kernel space (driver_data.device[i]->kern_addr);
following this, the DSP is warned that new data is available.

 ioctl(...,MAP_CONSISTENT,...);

 while(ptr<end){
   movebuftokernel(ptr,size); /* ioctl */
   ptr+=size;
 }

 ioctl(...,MAPOFF_CONSISTENT,...);

This process is repeated until the entire userspace buffer has been
processed.

Even though documentation indicates that consistent DMA mapping should
not have caching issues we have a problem that reflects this very much:

When data is passed to the DSP and every buffer is confirmed with an
[Enter] (i.e. __very__ slow_), data is passed correctly. When we try to
pass the same data without user intervention (comment out
waitforenter()),
parts of the transferred data are copied from other locations: most of
the time, part of the buffer (e.g. 2048 bytes) is not update yet (old
data).

e.g.

8 * 32 bit: correct
96 * 32 bit: wrong
... rest is OK.

Any ideas what might go wrong since consistent mappings 'should' not
have problems with caching...

--
  Marc Leeman                          Hardware R&D Engineer
  Barco Controlrooms Division Noordlaan 5, B-8520 Kuurne (BE)
  Tel. +32 56 368 428        http://www.barcocontrolrooms.com=20

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: PCI Memory mapping
  2004-03-23 11:17     ` Marc Leeman
@ 2004-03-23 16:01       ` Marc Leeman
  2004-03-24  2:04         ` Michael R. Zucca
  2004-03-24  0:04       ` Benjamin Herrenschmidt
  1 sibling, 1 reply; 26+ messages in thread
From: Marc Leeman @ 2004-03-23 16:01 UTC (permalink / raw)
  To: linuxppc-dev


> Any ideas what might go wrong since consistent mappings 'should' not
> have problems with caching...

OK, more tests.

I tried to make certain that cache was disabled for these pages by
including CONFIG_NOT_COHERENT_CACHE (which defaults back to

  consistent_alloc
instead of
  __get_free_pages

But we did not notice a difference. Adding a user space buffer of 2 Megs
that just got filled with a counter makes the DMA transfers OK (this
should have purged the cache I think).

But so does adding a delay of 1 second between 2 transfers.

Between two transfers, I even filled the kernel buffer inbetween with
0xCA in kernel space and in user space (by copying a user buffer into
the kernel buffer again).

The strange thing is that the second buffer is always corrupted with
seemingly 'old' data, at an offset of 4 words (32 bit) and this for only
24 words, the rest of the buffer is fine.

The common factor seems to be 'timing', but unfortunately, this does not
yet pinpoint the problem to either the DSP or the PPC side. Any
experienced insight or well educated guesses?

--
  Marc Leeman                          Hardware R&D Engineer
  Barco Controlrooms Division Noordlaan 5, B-8520 Kuurne (BE)
  Tel. +32 56 368 428        http://www.barcocontrolrooms.com

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: PCI Memory mapping
  2004-03-23 11:17     ` Marc Leeman
  2004-03-23 16:01       ` Marc Leeman
@ 2004-03-24  0:04       ` Benjamin Herrenschmidt
  2004-03-24 12:26         ` Marc Leeman
  1 sibling, 1 reply; 26+ messages in thread
From: Benjamin Herrenschmidt @ 2004-03-24  0:04 UTC (permalink / raw)
  To: Marc Leeman; +Cc: linuxppc-dev list


On Tue, 2004-03-23 at 22:17, Marc Leeman wrote:

> When data is passed to the DSP and every buffer is confirmed with an
> [Enter] (i.e. __very__ slow_), data is passed correctly. When we try to
> pass the same data without user intervention (comment out
> waitforenter()),
> parts of the transferred data are copied from other locations: most of
> the time, part of the buffer (e.g. 2048 bytes) is not update yet (old
> data).

One thing is: after having written your data to the consistent buffer,
you should make sure you have proper ordering with the MMIO write you
do to kick the DSP. On most CPUs, eieio appear to be enough and I
wouldn't suppose the 8245 to heavily reorder, but just in case, try
adding a sync.

Ben.


** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: PCI Memory mapping
  2004-03-23 16:01       ` Marc Leeman
@ 2004-03-24  2:04         ` Michael R. Zucca
  0 siblings, 0 replies; 26+ messages in thread
From: Michael R. Zucca @ 2004-03-24  2:04 UTC (permalink / raw)
  To: Marc Leeman; +Cc: linuxppc-dev


On Mar 23, 2004, at 11:01 AM, Marc Leeman wrote:

> The strange thing is that the second buffer is always corrupted with
> seemingly 'old' data, at an offset of 4 words (32 bit) and this for
> only
> 24 words, the rest of the buffer is fine.
>
> The common factor seems to be 'timing', but unfortunately, this does
> not
> yet pinpoint the problem to either the DSP or the PPC side. Any
> experienced insight or well educated guesses?

Are you putting in sync instructions where appropriate?

--
----------------------------------------------
  Michael Zucca - mrz5149@acm.org
----------------------------------------------
  "I'm too old to use Emacs." -- Rod MacDonald
----------------------------------------------


** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: PCI Memory mapping
  2004-03-24  0:04       ` Benjamin Herrenschmidt
@ 2004-03-24 12:26         ` Marc Leeman
  2004-03-24 14:25           ` Marc Leeman
  0 siblings, 1 reply; 26+ messages in thread
From: Marc Leeman @ 2004-03-24 12:26 UTC (permalink / raw)
  To: Benjamin Herrenschmidt; +Cc: linuxppc-dev list


I just added a [1]
  flush_cache_all();

after copying the buffer from user space, no change.

The same for
__asm__ __volatile__("sync\n");

However, more and more things seem to point to either the DSP or 'the
hardware':

For testing purposes, I allocate a 4k buffer and pass the address of the
buffer +0x400 to the DSP (the corrupted data always occur in the firsts
28 words: from word 5 to word 28).

In userspace, I fill the 0x400 bytes with 0xFF and only use the last
0xC00 bytes with 'userful' data. The 4k buffer is passed to kernel space
where it is mapped on the PCI.

  PPC user
  +-------+
  | 0x400 |
  +-------+
  |       |
  | 0xC00 |
  |       |
  +-------+

     || copy_from_user
     \/

  PPC kern            DSP
  +-------+
  | 0x400 |
  +-------+        +-------+
  |       |  PCI   |       |
  | 0xC00 |  ===>  | 0xC00 |
  |       |        |       |
  +-------+        +-------+



The DSP only reads the last 3k bytes but still, it gets the corrupted
data from word 5 to word 32 when no (excessive) delays are used.

Next to this, consistent_alloc() already uses _PAGE_NO_CACHE to avoid
caching of the buffer (called by pci_consistent_alloc()) in cachemap.c
(yes, the 8245 kernel configuration does not enable
CONFIG_NOT_COHERENT_CACHE normally [2], but I added it but the behaviour
is still identical).

Filling the user buffer with 0xCA after copy_from_user and re-copying it
into the kernel buffer (without interrupting the DSP this time) still
has no effect: the 'corrupted' data is still old data from the last
PCI transferred data on the DSP side (after a subsequent copy_from_user
with useful data and DSP interrupt).

However the first PCI transferred buffer is ALWAYS correct.

On the other hand, this DSP-type did read via PCI master read
operations and a PCI plugin card memory from w32 on an x86 arch (instead
of our internal PCI bus) a couple of yrs ago I'm told.

[1] hmmmmm, this is helpful code for ppc :)

/*
 * No cache flushing is required when address mappings are
 * changed, because the caches on PowerPCs are physically
 * addressed.  -- paulus
 * Also, when SMP we use the coherency (M) bit of the
 * BATs and PTEs.  -- Cort
 */
#define flush_cache_all()               do { } while (0)


[2]
6xx/7xx/74xx/8260      CONFIG_6xx
instead of
CONFIG_8xx

as Processor Type.

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: PCI Memory mapping
  2004-03-24 12:26         ` Marc Leeman
@ 2004-03-24 14:25           ` Marc Leeman
  2004-03-24 17:08             ` linas
  0 siblings, 1 reply; 26+ messages in thread
From: Marc Leeman @ 2004-03-24 14:25 UTC (permalink / raw)
  To: linuxppc-dev list


This is getting weird, I found a solution to the problem, well kind of.

Let's introduce the major players in this drama:

 /* communication struct between user and kernel space , in driver.h
  * kernel include */
 typedef struct SStreamPci {
         unsigned int pciaddress;
         unsigned int useraddress;
         unsigned char stream;
 }TSStreamPci;

 /* user space program */
 /* as long as not all data is transferred */
 while(userptr < (userbuffer + (TRANSFER_SIZE>>2))){
   /* currentstream is a struct that is passed to the kernel of
    * type TSStreamPci */
   currentstream.useraddress = (unsigned)userptr;

   /* copy our buffer to the kernel (PCI_TRANSFER_SIZE), 4k */
   ioctl(dsphandle,PPC2DSP_CONSISTENT_COPY_TO_KERNEL,&currentstream);

   /* Interrupt the DSP */
   WriteToDSP(PacketReady,0x1);
   ioctl(dsphandle,PPC2DSP_SET_HDCR,&interrupt);

   /* Wait until the DSP acknowledges transfer */
   while(ReadFromDSP(PacketReady)){}

   /* Read kernel buffer back */
   ioctl(dsphandle,PPC2DSP_CONSISTENT_COPY_FROM_KERNEL,&currentstream);

   /* increment pointer */
   userptr += (BLOCK_TRANSFER_SIZE >> 2);
 }

The strange thing is that this works only and only if I do a transfer
back from kernel space into the userbuffer AFTER the DSP has
acknowledged transferring the data. Note that this data is never used
again. Doing this copy_to_user before DSP acknowledgement still results
in the afore mentioned data corruption.

The associated ioctls are:
case PPC2DSP_CONSISTENT_COPY_TO_KERNEL:
  {
    TSStreamPci currentstream;
    if(copy_from_user(&currentstream,(TSStreamPci*) arg,sizeof(TSStreamPci))){
      return -EFAULT;
    }
    if(copy_from_user(driver_data.device[currentstream.stream]->kern_addr,(char*)currentstream.useraddress, PCI_TRANSFER_SIZE)){
      return -EFAULT;
    }
    break;
  }
case PPC2DSP_CONSISTENT_COPY_FROM_KERNEL:
  {
    TSStreamPci currentstream;
    if(copy_from_user(&currentstream,(TSStreamPci*) arg, sizeof(TSStreamPci))){
      return -EFAULT;
    }
    if(copy_to_user((char*)currentstream.useraddress,driver_data.device[currentstream.stream]->kern_addr, PCI_TRANSFER_SIZE)){
      return -EFAULT;
    }
    break;
  }

There is about a 10% bandwith reduction (due to PPC utilisation I would
assume) over the PCI, so I can live with that; but what bothers me is
not knowing _why_, ... Especially since I want my first module not to
contain too large beginners mistakes :)

  marc.

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: PCI Memory mapping
  2004-03-24 14:25           ` Marc Leeman
@ 2004-03-24 17:08             ` linas
  2004-03-25 15:48               ` Marc Leeman
  0 siblings, 1 reply; 26+ messages in thread
From: linas @ 2004-03-24 17:08 UTC (permalink / raw)
  To: Marc Leeman; +Cc: linuxppc-dev list


On Wed, Mar 24, 2004 at 03:25:24PM +0100, Marc Leeman wrote:
>
> The strange thing is that this works only and only if I do a transfer
> back from kernel space into the userbuffer AFTER the DSP has
> acknowledged transferring the data. Note that this data is never used
> again. Doing this copy_to_user before DSP acknowledgement still results
> in the afore mentioned data corruption.

Excuse my total ignorance on this topic, but ... is it possible that the
DSP is using some sort of oddball bookmark mechanism to read the data?
This would be a rather poor design decision on the part of whomever
wrote the DSP code, but not out of the realms of impossible.  (I've
seen equally bizarre code in the past whose only excuse for existance
was stupidity.)  It could also be a bug in the DSP code.  The fact that
'everything is OK after DSP acks' is telling: in the end, the DSP *did*
do the right thing, by the time it ack'ed even if it did something weird
while data was flying around.

--linas

p.s. I did not read your code to see if it made sense, nor do I know
the ppc dma code.

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: PCI Memory mapping
  2004-03-24 17:08             ` linas
@ 2004-03-25 15:48               ` Marc Leeman
  2004-03-25 16:34                 ` linas
  0 siblings, 1 reply; 26+ messages in thread
From: Marc Leeman @ 2004-03-25 15:48 UTC (permalink / raw)
  To: linas; +Cc: linuxppc-dev list


> Excuse my total ignorance on this topic, but ... is it possible that
> the DSP is using some sort of oddball bookmark mechanism to read the
> data?

Not at all, we're at the point that we appreciate external comments,
clues, ...
The DSP gets the PCI address, configures a DMA transfer and fetches the
data to some predefined memory location. There is not further
functionality (next to checking the counter in the memory for data
consistency purposes) because we want to verify and debug the technique.

> This would be a rather poor design decision on the part of whomever
> wrote the DSP code, but not out of the realms of impossible. (I've
> seen equally bizarre code in the past whose only excuse for existence
> was stupidity.) It could also be a bug in the DSP code. The fact
> that 'everything is OK after DSP acks' is telling: in the end, the
> DSP *did* do the right thing, by the time it ack'ed even if it did
> something weird while data was flying around.

The DSP code is fairly simple, but I would not put it past a DSP/Bios
bug, it has happened before (unfortunately). The annoying thing is that
we are not able to pinpoint a location where it is happening (on the DSP
or the PPC side). Next to this, I have a bit more confidence in the guy
writing the code than that :)

The only pattern we notice is that the first 8 words (32 bit words) are
fine, the following 24 words are not, the rest of the buffer is fine
(tested with buffers of 512, 1024, 2048 and 4096).

We did some further experimentation and the minimum of data we need to
read back after a DSP ACK is 97 bytes. You will note that 24*4=96. I
don't believe in coincidences :) If we read 96 bytes or less, we get the
corrupted data again... I even tested and tried to verify that the code
which is being used by the kernel is the one from the 2.4.17 mvl for
memory management and not 'tainted' code.

Anyway, this is a workaround until we have some more time to try to
figure out where the problem lies (PPC/PCI/Kernel/DSP) and what it is...
As ever, insights are welcome :-/

  marc.

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: PCI Memory mapping
  2004-03-25 15:48               ` Marc Leeman
@ 2004-03-25 16:34                 ` linas
  2004-03-25 16:45                   ` linas
  0 siblings, 1 reply; 26+ messages in thread
From: linas @ 2004-03-25 16:34 UTC (permalink / raw)
  To: Marc Leeman; +Cc: linuxppc-dev list


On Thu, Mar 25, 2004 at 04:48:46PM +0100, Marc Leeman wrote:
> As ever, insights are welcome :-/

OK, another wild guess: are the cache lines properly invalidated?
I think you said that the corrpution was a copy of earlier data ...
well, where could 'earlier data' be hiding?  The offsets you're
reporting sound all wrong, but hey ...

Don't know how hard it would be for you to run the test with cachine disabled,
but it might be worth a try.

--linas

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: PCI Memory mapping
  2004-03-25 16:34                 ` linas
@ 2004-03-25 16:45                   ` linas
  2004-03-26  8:00                     ` Marc Leeman
  0 siblings, 1 reply; 26+ messages in thread
From: linas @ 2004-03-25 16:45 UTC (permalink / raw)
  To: Marc Leeman; +Cc: linuxppc-dev list


On Thu, Mar 25, 2004 at 10:34:14AM -0600, linas@austin.ibm.com wrote:
>
> On Thu, Mar 25, 2004 at 04:48:46PM +0100, Marc Leeman wrote:
> > As ever, insights are welcome :-/
>
> OK, another wild guess: are the cache lines properly invalidated?
> I think you said that the corrpution was a copy of earlier data ...
> well, where could 'earlier data' be hiding?  The offsets you're
> reporting sound all wrong, but hey ...

actually, if you have 32-byte cache lines on your cpu, and you
have, umm, something maybe 4-way set associative (I've forgotten
how it works) that might explain it.   I don't know what cpu's
have what cache sizes.

> Don't know how hard it would be for you to run the test with cachine disabled,
> but it might be worth a try.
>
> --linas
>
>

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: PCI Memory mapping
  2004-03-25 16:45                   ` linas
@ 2004-03-26  8:00                     ` Marc Leeman
  2004-03-30 19:49                       ` Jeff Angielski
  0 siblings, 1 reply; 26+ messages in thread
From: Marc Leeman @ 2004-03-26  8:00 UTC (permalink / raw)
  To: linas; +Cc: linuxppc-dev list


> actually, if you have 32-byte cache lines on your cpu, and you have,
> umm, something maybe 4-way set associative (I've forgotten how it
> works) that might explain it. I don't know what cpu's have what cache
> sizes.

This was also one of the paths we were considering, but the following
tests have been performed in order to validate or invalidate this
assumption:
1. I was under the impression that 'consistent_alloc' (which I
activited by defining CONFIG_NOT_COHERENT_CACHE in the kernel
configuration for our board) assured that the pages were not using
cache, at least the following lines lead me to this:

[malm@bpscltpd linux-2.4.17_bl21]$ vim ./arch/ppc/mm/cachemap.c

<...>
        /*
         * we need to ensure that there are no cachelines in use,
         * or worse dirty in this area.
         */
        invalidate_dcache_range(page, page + size);
<...>

and

<...>
        flags = _PAGE_KERNEL | _PAGE_NO_CACHE;

        err = 0;
        for (i = 0; i < size && err == 0; i += PAGE_SIZE)
                err = map_page(va+i, pa+i, flags);
<...>

As told before, no change with or without this define enabled that uses
consistent_alloc.

2. Next I tried to invalidate the cache the naive way:
I refilled the used buffer with 0xCA in userspace and copied it back to
kernelspace (in the PCI mappded buffer). Next I transferred the next
'useful' data from user to kernel space. Still completely the same: the
data showing up (corrupted) on the DSP side was the 'old' lines of the
buffer last transferred (i.e. the buffer before bringing 0xCA into
kernel space).

3. I took the previous point one step further: I filled the kernel
buffer with 0xCA before copying in the userbuffer. Still the same old
data is showing up on the DSP side. Still, I understand that none of
these two techniques assure purging the cache.

4. I added sync's and the like which should sync cache and mem, still no
change.

Apparently, the closest I can come to pinpointing the location of the
problem at the moment is that 'something' must be happening at the point
where the DSP starts reading from the PPC memory. When no such read is
performed, the problem does not occur. The other way around, the DSP can
write into the PPC memory without corrupting data.

Maybe reading of the DSP over PCI and the resulting DMA setup causes a
[hardware|software] timing problem with purging the cache (which should
not be used for these pages to start with (see [1]), or the DSP ack's
too early on and reading these 97 bytes after the DSP ACK causes some
hardware lock to be released, giving the DSP just enough time to
correctly fetch the data before the PPC starts pumping in new, ...

  marc.

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: PCI Memory mapping
  2004-03-26  8:00                     ` Marc Leeman
@ 2004-03-30 19:49                       ` Jeff Angielski
  2004-03-31 15:56                         ` Marc Leeman
  0 siblings, 1 reply; 26+ messages in thread
From: Jeff Angielski @ 2004-03-30 19:49 UTC (permalink / raw)
  To: Marc Leeman; +Cc: linas, linuxppc-dev list


Marc,

How is the PICMRx configured?  Do you have snoop enabled or disabled?

This will sound obvious, but have you stuck a PCI bus analyzer into the
system to watch the actual PCI transactions?  They more than make up for
their cost in time savings.  :)

Jeff


On Fri, 2004-03-26 at 03:00, Marc Leeman wrote:
> > actually, if you have 32-byte cache lines on your cpu, and you have,
> > umm, something maybe 4-way set associative (I've forgotten how it
> > works) that might explain it. I don't know what cpu's have what cache
> > sizes.
>
> This was also one of the paths we were considering, but the following
> tests have been performed in order to validate or invalidate this
> assumption:
> 1. I was under the impression that 'consistent_alloc' (which I
> activited by defining CONFIG_NOT_COHERENT_CACHE in the kernel
> configuration for our board) assured that the pages were not using
> cache, at least the following lines lead me to this:
>
> [malm@bpscltpd linux-2.4.17_bl21]$ vim ./arch/ppc/mm/cachemap.c
>
> <...>
>         /*
>          * we need to ensure that there are no cachelines in use,
>          * or worse dirty in this area.
>          */
>         invalidate_dcache_range(page, page + size);
> <...>
>
> and
>
> <...>
>         flags = _PAGE_KERNEL | _PAGE_NO_CACHE;
>
>         err = 0;
>         for (i = 0; i < size && err == 0; i += PAGE_SIZE)
>                 err = map_page(va+i, pa+i, flags);
> <...>
>
> As told before, no change with or without this define enabled that uses
> consistent_alloc.
>
> 2. Next I tried to invalidate the cache the naive way:
> I refilled the used buffer with 0xCA in userspace and copied it back to
> kernelspace (in the PCI mappded buffer). Next I transferred the next
> 'useful' data from user to kernel space. Still completely the same: the
> data showing up (corrupted) on the DSP side was the 'old' lines of the
> buffer last transferred (i.e. the buffer before bringing 0xCA into
> kernel space).
>
> 3. I took the previous point one step further: I filled the kernel
> buffer with 0xCA before copying in the userbuffer. Still the same old
> data is showing up on the DSP side. Still, I understand that none of
> these two techniques assure purging the cache.
>
> 4. I added sync's and the like which should sync cache and mem, still no
> change.
>
> Apparently, the closest I can come to pinpointing the location of the
> problem at the moment is that 'something' must be happening at the point
> where the DSP starts reading from the PPC memory. When no such read is
> performed, the problem does not occur. The other way around, the DSP can
> write into the PPC memory without corrupting data.
>
> Maybe reading of the DSP over PCI and the resulting DMA setup causes a
> [hardware|software] timing problem with purging the cache (which should
> not be used for these pages to start with (see [1]), or the DSP ack's
> too early on and reading these 97 bytes after the DSP ACK causes some
> hardware lock to be released, giving the DSP just enough time to
> correctly fetch the data before the PPC starts pumping in new, ...
>
>   marc.
>


** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: PCI Memory mapping
  2004-03-30 19:49                       ` Jeff Angielski
@ 2004-03-31 15:56                         ` Marc Leeman
  2004-03-31 16:02                           ` Marc Leeman
  2004-04-01 12:33                           ` Marc Leeman
  0 siblings, 2 replies; 26+ messages in thread
From: Marc Leeman @ 2004-03-31 15:56 UTC (permalink / raw)
  To: Jeff Angielski; +Cc: linuxppc-dev


> How is the PICMRx configured? Do you have snoop enabled or disabled?

This is what I like about my job: problem based digging deeper into code
internals :)

Anyway, the time of day difference between us enables me to try to come
up with some kind of founded answer. We are using ppcboot (yeah, I know,
but unfortunately, there are too many things in the todo queue to
upgraced to uboot).

After some digging into kernel code, ppcboot code and the mpc8245
documentation, I assume you are trying to point me to the following:
In Section 7.5:
"Because a snoop transaction is required to establish a lock, the
MPC8245 does not honour the assertion of a LOCK when PICR1[NO_SNOOP_EN]
is set."; when describing exclusive access to data.

In cpu/mpc824x/cpu_init.c:
    CONFIG_WRITE_HALFWORD(PCICR, 0x06);
    /* bus master, respond to PCI accesses */
    CONFIG_READ_WORD(PICR1, val);
    CONFIG_WRITE_WORD( PICR1,
       (val & (PICR1_RCS0)) |
               PICR1_PROC_TYPE_603E |
               PICR1_FLASH_WR_EN | PICR1_MCP_EN |
               PICR1_CF_DPARK | PICR1_NO_BUSW_CK |
               PICR1_DEC| PICR1_CF_APARK | 0x10);
/* 8245 UM says bit 4 must be set */

#define PICR1_RCS0              0x00100000
#define PICR1_PROC_TYPE_603E    0x00040000
#define PICR1_FLASH_WR_EN       0x00001000
#define PICR1_MCP_EN            0x00000800
#define PICR1_CF_DPARK          0x00000200
#define PICR1_NO_BUSW_CK        0x00000080 /* no bus width check for
flash writes */
#define PICR1_DEC               0x00000100 /* Time Base enable on
8245/8241 */
#define PICR1_CF_APARK          0x00000008

And for PICR2:
    CONFIG_READ_WORD(PICR2, val);
    val= val & ~ (PICR2_CF_SNOOP_WS_MASK | PICR2_CF_APHASE_WS_MASK);
    /*mask off waitstate bits*/

#define PICR2_CF_APHASE_WS_MASK 0x0000000c
#define PICR2_CF_SNOOP_WS_MASK  0x000c0000

k. I got the (relevant) registers states at bootup now, I am still
looking for the NO_SNOOP_EN bit, it must be somewhere in the docs...

4.7: Speculative PCI reads see Chapter 13;

but NO_SNOOP_EN is defined for PICR2 on bit 27, could it be that the
the description in section (note) 7.5 is referring to PICR2 instead of
the mentioned PICR1?

which should be 0x8000000

I'll masking PICR2 with this tomorrow...

> will sound obvious, but have you stuck a PCI bus analyzer into the
> system to watch the actual PCI transactions? They more than make up
> for their cost in time savings. :)

Not yet, mainly because we want to interactively PPC/DSP rule out other
possibilities (an infamous DSP reset which is extremely difficult to
pinpoint); combined with the usual growing to do list with continuous
interrupts for 'paramount' things to do...

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: PCI Memory mapping
  2004-03-31 15:56                         ` Marc Leeman
@ 2004-03-31 16:02                           ` Marc Leeman
  2004-04-01 12:33                           ` Marc Leeman
  1 sibling, 0 replies; 26+ messages in thread
From: Marc Leeman @ 2004-03-31 16:02 UTC (permalink / raw)
  To: Jeff Angielski; +Cc: linuxppc-dev


> which should be 0x8000000 I'll masking PICR2 with this tomorrow...

Of course, I should't enable this bit, but at least I'll be able to see
if the situation gets worse by enabling it...

I need more coffee...

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: PCI Memory mapping
  2004-03-31 15:56                         ` Marc Leeman
  2004-03-31 16:02                           ` Marc Leeman
@ 2004-04-01 12:33                           ` Marc Leeman
  2004-04-04 22:53                             ` Benjamin Herrenschmidt
                                               ` (2 more replies)
  1 sibling, 3 replies; 26+ messages in thread
From: Marc Leeman @ 2004-04-01 12:33 UTC (permalink / raw)
  To: Jeff Angielski; +Cc: linuxppc-dev


> I'll masking PICR2 with this tomorrow...

I have obtained some results by setting some 8245 registers at bootup.

I tested the following:

. enabling NO_SNOOP_EN (27 in PICR2): nfs does not boot anymore
. increasing the snoop and address wait cycles to 5 (default ppc bootup),
no real change.
. disable speculative reads  (2 in PICR1): doesn't boot nfs anymore
(via eepro100?)

No real success, until I came accross the PCMBCR register which defines
the number of PCI to Local Memory Read and Write Buffers. When I set
both to 1 ( & 0xF0), the data copy back is no longer needed to assure
data consistency between the PPC and DSP (default is 4 32 byte buffers).

include/mpc824x.h:
#define PCMBCR          0x800000e1  /* PCI/Memory Buffer Configuration
Register */

cpu/mpc824x/cpu_init.c:
CONFIG_READ_BYTE(PCMBCR,val);
CONFIG_WRITE_BYTE(PCMBCR,(val | 0xF0));

Double checking this by setting both on 4 again (during cpu_init of
ppcboot) resulted in severe MPEG data corruption. These results at least
seems to point in the direction you suggested.

This is the only way I seem to be able to assure data consistency (the
kernel copy back is no longer required), but the documentation also
suggests that (obviously) this degrades performance and is mainly used
for debugging.0

Still, when reading the explanations that could case this behaviour
(copy back buffer and filling the PCMRBs) , they point to cache
operations, which, I thought, were disabled in the linux kernel for
these particular PCI mapped buffers.

By adding __asm__ __volatile__("eieio"); in user and kernel space,
which lets the CCU buffers to be flushed, no change is observed (sect.
5.4.3.1; CCU Responses to the Processor Transactions).

It looks to me as if I should disable the bus snooping, but as mentioned
before, initialising this in ppc boot inhibits the NFS boot process.

Can this be disabled at runtime (possibly with re-enabling it) and if
so, is this a good practice to do so?

  marc.

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: PCI Memory mapping
  2004-04-01 12:33                           ` Marc Leeman
@ 2004-04-04 22:53                             ` Benjamin Herrenschmidt
  2004-04-05  8:46                             ` Adrian Cox
       [not found]                             ` <20040402140130.GG22365@smtp.barco.com>
  2 siblings, 0 replies; 26+ messages in thread
From: Benjamin Herrenschmidt @ 2004-04-04 22:53 UTC (permalink / raw)
  To: Marc Leeman; +Cc: Jeff Angielski, linuxppc-dev list


On Thu, 2004-04-01 at 22:33, Marc Leeman wrote:

> No real success, until I came accross the PCMBCR register which defines
> the number of PCI to Local Memory Read and Write Buffers. When I set
> both to 1 ( & 0xF0), the data copy back is no longer needed to assure
> data consistency between the PPC and DSP (default is 4 32 byte buffers).
>
> include/mpc824x.h:
> #define PCMBCR          0x800000e1  /* PCI/Memory Buffer Configuration
> Register */
>
> cpu/mpc824x/cpu_init.c:
> CONFIG_READ_BYTE(PCMBCR,val);
> CONFIG_WRITE_BYTE(PCMBCR,(val | 0xF0));
>
> Double checking this by setting both on 4 again (during cpu_init of
> ppcboot) resulted in severe MPEG data corruption. These results at least
> seems to point in the direction you suggested.
>
> This is the only way I seem to be able to assure data consistency (the
> kernel copy back is no longer required), but the documentation also
> suggests that (obviously) this degrades performance and is mainly used
> for debugging.0
>
> Still, when reading the explanations that could case this behaviour
> (copy back buffer and filling the PCMRBs) , they point to cache
> operations, which, I thought, were disabled in the linux kernel for
> these particular PCI mapped buffers.
>
> By adding __asm__ __volatile__("eieio"); in user and kernel space,
> which lets the CCU buffers to be flushed, no change is observed (sect.
> 5.4.3.1; CCU Responses to the Processor Transactions).
>
> It looks to me as if I should disable the bus snooping, but as mentioned
> before, initialising this in ppc boot inhibits the NFS boot process.
>
> Can this be disabled at runtime (possibly with re-enabling it) and if
> so, is this a good practice to do so?

Looks like your north bridge is horribly buggy...

Ben.


** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: PCI Memory mapping
  2004-04-01 12:33                           ` Marc Leeman
  2004-04-04 22:53                             ` Benjamin Herrenschmidt
@ 2004-04-05  8:46                             ` Adrian Cox
       [not found]                             ` <20040402140130.GG22365@smtp.barco.com>
  2 siblings, 0 replies; 26+ messages in thread
From: Adrian Cox @ 2004-04-05  8:46 UTC (permalink / raw)
  To: Marc Leeman; +Cc: Jeff Angielski, linuxppc-dev


On Thu, 2004-04-01 at 13:33, Marc Leeman wrote:

> By adding __asm__ __volatile__("eieio"); in user and kernel space,
> which lets the CCU buffers to be flushed, no change is observed (sect.
> 5.4.3.1; CCU Responses to the Processor Transactions).
>
> It looks to me as if I should disable the bus snooping, but as mentioned
> before, initialising this in ppc boot inhibits the NFS boot process.

Here's one possible scenario:

Your user space buffer is cleared with dcbz operations. This may be done
by standard library functions, rather than explicitly in your code. (If
that's not true, what follows could still bite someone else.)

The 603e core will only broadcast the dcbz when the page is marked
coherent. The page is only marked coherent when the kernel is compiled
for SMP.

If the above hypothesis is correct, the 824x CPUs will need to have
CPU_FTR_NEED_COHERENT set in this patch:

 http://lists.linuxppc.org/linuxppc-embedded/200403/msg00218.html

- Adrian Cox
http://www.humboldt.co.uk/


** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: PCI Memory mapping
       [not found]                               ` <1081175362.20952.30.camel@localhost.localdomain>
@ 2004-04-06  6:21                                 ` Marc Leeman
  0 siblings, 0 replies; 26+ messages in thread
From: Marc Leeman @ 2004-04-06  6:21 UTC (permalink / raw)
  To: linuxppc-embedded


Hi,

I know I've been flooding the mailing list with this particular little
topic and thanks to some valuable comments [1], we were able to
pinpoint our problem fairly quickly.

Partly based on a number of related known silicon bugs, I have drafted
the following description (and work-around) that explains our data
corruption.

http://scorpius.homelinux.org/~marc/masterwrite/

[1] There is still one comment which is in the queue to be investigated.

 marc.

** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: PCI Memory mapping
@ 2004-04-07  7:15 Marc Leeman
  0 siblings, 0 replies; 26+ messages in thread
From: Marc Leeman @ 2004-04-07  7:15 UTC (permalink / raw)
  To: linuxppc-dev


I now realise I sent to the wrong mailing list :-/
(thread was on linuxppc-dev instead of linuxppc-embedded).

Hi,

I know I've been flooding the mailing list with this particular little
topic and thanks to some valuable comments [1], we were able to
pinpoint our problem fairly quickly.

Partly based on a number of related known silicon bugs, I have drafted
the following description (and work-around) that explains our data
corruption.

http://scorpius.homelinux.org/~marc/masterwrite/

[1] There is still one comment which is in the queue to be investigated.

 marc.

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: PCI Memory mapping
@ 2011-04-15  5:44 koteswararaom
  2011-04-15  6:32 ` David Hawkins
  2011-04-15  6:48 ` Michael Neuling
  0 siblings, 2 replies; 26+ messages in thread
From: koteswararaom @ 2011-04-15  5:44 UTC (permalink / raw)
  To: linuxppc-dev

[-- Attachment #1: Type: text/plain, Size: 574 bytes --]

Hi, 

 

I have come across this forum, and I have a question. I am working on PCI
device driver, I am trying to insert the  pci card in to the pci slot of the
main computer, I am finding a problem here, when I insert the card in to the
pci slot, my pci device ID and vendor Id are not getting displayed. I am
using windows xp o/s.

 

I am trying to map pci memory. Can you suggest me how can we map the pci
memory. What steps should I take in order to make my Device Id and Vendor Id
displayed when I insert the card in to the pci slot.

 

With Kind regards,

Ajith.

 


[-- Attachment #2: Type: text/html, Size: 2426 bytes --]

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: PCI Memory mapping
  2011-04-15  5:44 PCI Memory mapping koteswararaom
@ 2011-04-15  6:32 ` David Hawkins
  2011-04-15  6:48 ` Michael Neuling
  1 sibling, 0 replies; 26+ messages in thread
From: David Hawkins @ 2011-04-15  6:32 UTC (permalink / raw)
  To: koteswararaom; +Cc: linuxppc-dev

Hi Ajith,

> I have come across this forum, and I have a question. I am working on
> PCI device driver, I am trying to insert the pci card in to the pci slot
> of the main computer, I am finding a problem here, when I insert the
> card in to the pci slot, my pci device ID and vendor Id are not getting
> displayed. I am using windows xp o/s.
>
> I am trying to map pci memory. Can you suggest me how can we map the pci
> memory. What steps should I take in order to make my Device Id and
> Vendor Id displayed when I insert the card in to the pci slot.

This is a PowerPC Linux developer list so your question is
way off-topic here.

If your PCI card is not showing up at all, it could be due to the
fact that it is not being powered. I have found old motherboards
that do not supply both the 5V and 3.3V rails to PCI slots.
Check the power supplies on your PCI board, or at least
measure the PCI power pins in the slots. Then if power is present,
check there is a PCI clock in the slot. After that, boot Linux
from a bootable CD-ROM and type lspci to see if your device is
listed.

Cheers,
Dave

^ permalink raw reply	[flat|nested] 26+ messages in thread

* Re: PCI Memory mapping
  2011-04-15  5:44 PCI Memory mapping koteswararaom
  2011-04-15  6:32 ` David Hawkins
@ 2011-04-15  6:48 ` Michael Neuling
  1 sibling, 0 replies; 26+ messages in thread
From: Michael Neuling @ 2011-04-15  6:48 UTC (permalink / raw)
  To: koteswararaom; +Cc: linuxppc-dev

> I have come across this forum, and I have a question. I am working on PCI
> device driver, I am trying to insert the  pci card in to the pci slot of the
> main computer, I am finding a problem here, when I insert the card in to the
> pci slot, my pci device ID and vendor Id are not getting displayed. I am
> using windows xp o/s.

Err, so err, humm... er...  how do I put this..?!

This is the "Linux on PowerPC" mailing list.  Your question is neither
Linux or PowerPC related.  

I'm not sure how you expect anyone here to help.

> I am trying to map pci memory. Can you suggest me how can we map the pci
> memory. What steps should I take in order to make my Device Id and Vendor Id
> displayed when I insert the card in to the pci slot.


Mikey

^ permalink raw reply	[flat|nested] 26+ messages in thread

end of thread, other threads:[~2011-04-15  6:52 UTC | newest]

Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-15  5:44 PCI Memory mapping koteswararaom
2011-04-15  6:32 ` David Hawkins
2011-04-15  6:48 ` Michael Neuling
  -- strict thread matches above, loose matches on Subject: below --
2004-04-07  7:15 Marc Leeman
2004-03-16 11:40 Marc Leeman
2004-03-16 16:39 ` Jeff Angielski
2004-03-22  7:48   ` Marc Leeman
2004-03-22 11:02     ` Marc Leeman
2004-03-23 11:17     ` Marc Leeman
2004-03-23 16:01       ` Marc Leeman
2004-03-24  2:04         ` Michael R. Zucca
2004-03-24  0:04       ` Benjamin Herrenschmidt
2004-03-24 12:26         ` Marc Leeman
2004-03-24 14:25           ` Marc Leeman
2004-03-24 17:08             ` linas
2004-03-25 15:48               ` Marc Leeman
2004-03-25 16:34                 ` linas
2004-03-25 16:45                   ` linas
2004-03-26  8:00                     ` Marc Leeman
2004-03-30 19:49                       ` Jeff Angielski
2004-03-31 15:56                         ` Marc Leeman
2004-03-31 16:02                           ` Marc Leeman
2004-04-01 12:33                           ` Marc Leeman
2004-04-04 22:53                             ` Benjamin Herrenschmidt
2004-04-05  8:46                             ` Adrian Cox
     [not found]                             ` <20040402140130.GG22365@smtp.barco.com>
     [not found]                               ` <1081175362.20952.30.camel@localhost.localdomain>
2004-04-06  6:21                                 ` Marc Leeman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).