Sunday, January 16, 2011

PCI programming

use a example to explain PCI programming:
access the memory controller register in AMD K8 machine

1. read the BKDG (BIOS and Kernel Developer's Guide), then you know what PCI device you are going to access(bus, dev, fun). Each 32 bit is a register, the first 32 bit is: vendor ID and device ID. E.g. memory system configuration register(function 2) in AMDK8 BKDG is: 1102h 1022h. From the vendor ID, and the device ID, you will know which one is high bit(31), which one is low bit(0).

2. write a program to read/write PCI device. This is an example to write memory system configuration registers.
#define DOMAIN (0x0)
#define BUS    (0x0)
#define DEV    (0x18)
#define FUNC   (0x2)

void writeMemConfig(int flag)
{
    struct pci_access *pacc;
    struct pci_dev    *dev;
    pacc = pci_alloc();
    pci_init(pacc);
   
    dev = pci_get_dev(pacc, DOMAIN, BUS, DEV, FUNC);

    printf("DRAM CS mask reg:\n");
    val1 = pci_read_long(dev, 0x60);
    printf("val is 0x%x\n", val1);

    u32 data;        
    printf("write to DRAM CS MASK 0 reg, offset 0x60\n");
    data = 0x00783fe0;
    pci_write_long(dev, 0x60, data);

    pci_cleanup(pacc); /* close everything */
}

3. this PCI register is 256 bytes, you could use PCI API access which byte you want. For AMD K8, you have to read/wirite as double word.

4. compile the program with -lpci

No comments: