BCM1250/BCM1125/BCM1125H
User Manual
10/21/02
B r o a d c o m C o r p o r a t i o n
Page
86
Section 4: System Control and Debug Unit
Document
1250_1125-UM100CB-R
T
RACE
E
XAMPLE
3: PCI D
RIVER
D
EBUGGING
Device drivers for PCI devices quite often rely heavily on macros and library input/output routines. Particularly
when porting code from a little endian (e.g. x86) driver to the BCM1250 or BCM1125/H running big endian, it
can be hard for the programmer to track down exactly what is being transferred back and forth to the device
on the PCI bus. This example uses the trace buffer to record every transfer between the CPU and the PCI bus,
and any DMA activity initiated by the PCI device.
The driver code has writes to the
trace_cfg
register added to start and stop samples, and to freeze and read
out the results.
Any access from the CPU to the PCI range is detected by trace0. If the transaction is a write then trace2 will
detect the data transfer; the resp_id indicates that the data source is the CPU and the data_id indicates that
the transaction was initiated by the CPU. (This detects any write data from the CPU, it is used in sequence with
trace0 to detect this particular write.) If the transaction is a read then trace3 detects the data returning from the
I/O bridge in response to the CPU request (the I/O space read is uncacheable and the CPU only has one
outstanding, so in sequence with trace0 this always catches the correct data).
Master mode accesses from the PCI are detected by trace1 for addresses and trace4 for the data These just
use the transaction id to identify the I/O bridge as the initiator of the operation. Note that since trace4 is used
the detection sequence had to move to seq4 on the second sequencer block. This will detect DMAs from
devices on the HyperTransport fabric too, so this is not a perfect trace. However, since it is being used to debug
during the device driver bring-up, it should be relatively easy to prevent other DMA devices from being active.
Addr0 = PCI range
trace0 = reqid=cpu0 & Addrmatch0 & (read|write)
trace1 = reqid=iobr0 & (read|write)
trace2 = rspid=cpu0 & dataid=cpu0
trace3 = rspid=iobr0 & dataid=cpu0
trace4 = dataid=iobr0
seq0 = trace0, ignore, ignore, ignore -> A-sample
seq1 = trace0, trace2 | trace3, ignore, ignore -> D-sample
seq2 = trace1, ignore, ignore, ignore -> A-sample
seq4 = trace4, ignore, ignore, ignore -> D-sample