PCI card hacking
This page describes using dsp_cmd and mce_cmd to debug MCE/PCI card communication issues. These instructions can be used to resolve questions like "is the data getting dropped by the PCI card, or does it never arrive at the PCI card?"
Contents
RAM areas on the DSP
The DSP has 3 RAM banks, known as X, Y, and P. User data is in X and Y, while the program code is in P. By default, all three banks contain something like 2k x 16bits. On our hardware, however, the Y bank has been extended with an external SRAM to 8M x 16bits.
In our firmware, X memory is used to store ordinary variables while Y memory is used for large buffers.
Reading and writing DSP RAM with dsp_cmd
We can use dsp_cmd to read back the values of variables and buffers in the PCI card RAM. This is done as follows:
mhasse@mce-ubc-2:~$ dsp_cmd -x read X 0 This is dsp_cmd version MAS/slotpc/327 Line 0 : ok : X[0] = 0x208
We can also write. Don't write to X or P memory unless you really know what you're doing.
mhasse@mce-ubc-2:~$ dsp_cmd -x write Y 0 0x1234 This is dsp_cmd version MAS/slotpc/327 Line 0 : ok
It is convenient to define a few functions to make this hacking easier (you can just dump this into your bash session, or put it in a file and run "source file" whenever you want the functions to be available):
function pciread { dsp_cmd -qpx read $1 $2 | cut -d' ' -f5 } function pciwrite { dsp_cmd -qpx write $1 $2 $3 } function pcidump { # usage: pcidump <BANK> <START> <COUNT> for i in `seq -f '%9.0f' $2 $(( $2 + $3 - 1 ))`; do printf "%s %#8x 0x%06x\n" $1 $i `pciread $1 $i`; done } function pciwash { # usage: pciwash <BANK> <START> <COUNT> <VALUE> for i in `seq -f '%9.0f' $2 $(( $2 + $3 - 1 ))`; do pciwrite $1 $i $4; done }
Then you use them like this:
mhasse@mce-ubc-2:~$ pciread x 0 0x208 mhasse@mce-ubc-2:~ pciwrite y 0 0x1234 mhasse@mce-ubc-2:~$ pcidump Y 0x100000 4 Y 0x100000 0x004f4b Y 0x100001 0x00474f Y 0x100002 0x000016 Y 0x100003 0x000003
MCE command, reply and data buffers
We can inspect the DSP's buffers if we know their addresses. This depends on DSP code firmware revision.
Version | Data | Reply | Command |
---|---|---|---|
U0104 and earlier | 0 | 0 | 0x200 |
U0105 | 0 | 0x100000 | 0x200000 |
- Note about data and reply packets!*: the preamble, packet type, and frame size are stripped off. These will not appear in the buffers in Y memory. They are available at special locations in X memory, however.
(Incidentally, the collision between the "data" and reply/command buffers is why U0104 and earlier cannot be used to issue STOP or other MCE commands during frame acquisition.)
DSP internal variables
There are a few DSP internal variables, stored in X memory, that are of use in comm. hacking:
Name | Address(U0104) | Address(U0105) | Description |
---|---|---|---|
STATUS | 0x00 | 0x00 | Status (and modes) of DSP, see bit break-down below |
MODE | n/a | 0x01 | Flags configuring certain modes of the DSP |
HEAD_W3_0 | 0x21 | 0x14 | Type of last reply or data packet, 'DA' or 'RP' |
PACKET_SIZE_LOW | 0x23 | n/a | Size of latest reply or data packet, in 16 bit words |
PACKET_SIZE | n/a | 0x2B | Size of latest reply or data packet, in 32 bit words |
QT_FRAME_SIZE | 0x53 | 0x3D | The expected size of data packets in bytes |
FRAME_COUNT | 0x01 | 0x02 | Number of DA packets received from the MCE (including discards) |
QT_DROPS | 0x5A | 0x44 | Number of data packets dropped due to full PC RAM buffer |
RP_DROPS | n/a | 0x48 | Number of reply packets dropped due to PC RAM buffer unavailable (quiet_RP mode only) |
Currently, the number of packets that are dropped due to a packet size mismatch between PACKET_SIZE and QT_FRAME_SIZE is not recorded explicitly. However, such packets will cause FRAME_COUNT to increment.
All of the above variables, except STATUS, MODE, and FRAME_COUNT are cleared by a DSP_RESET. You can zero the frame count manually using pciwrite.
(Incidentally, the addresses in the table above are determined from the .lod symbol table of the assembler output.)