Two dedicated I/O ports (to be accessed via IN/OUT instructions):
0xCF8 – selects the address (Bus, Node, Function, Offset)
0xCFC – data port
I/O mapped memory:
PCI configuration space, power management registers, ACPI PM base
Memory mapped:
LAPIC, IOAPIC
More in this presentation:
http://72.3.219.184/conference/2007/papers/rutkowska-joanna-slides.pdf
Showing posts with label PCI. Show all posts
Showing posts with label PCI. Show all posts
Monday, August 19, 2013
Saturday, February 5, 2011
Understanding PCI Device / Configuration Registers
what is PCI?
PCI is a standard, which help devices on board to communicate with each other.
What is PCI device?
E.g. all kinds of controllers, like SATA controller at southbridge, Memory controller at northbridge.
What is controller?
this controller may have single or multiple funtions (based on board m2v-mx_se)SATA controller: bus0, device15, function0 (see vt8237r datasheet page 61)
Memory controller: bus0, device 18, function0,1,2,3 (see AMDK8 BKDG page 39)
What is in the function?
each function has 256 bytes, (offset from 0x00 to 0xff), there are many PCI configuration registers in each function. you can access these registers by standard PCI function. see previous article pci programmingPCI configuration Space:
Total 256 bytes, first 64 bytes of configuration space are standardized; the remainder are available for vendor-defined purposes. The format of the head can be found here
Sunday, January 16, 2011
PCI programming
use a example to explain PCI programming:
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.
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
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();#define BUS (0x0)
#define DEV (0x18)
#define FUNC (0x2)
void writeMemConfig(int flag)
{
struct pci_access *pacc;
struct pci_dev *dev;
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
Subscribe to:
Posts (Atom)