Reading PCI configuration registers?

CTho9305

Elite Member
Jul 26, 2000
9,214
1
81
How do you read the configuration registers WPCREDIT displays? I'd like to write a program that does approximately the same thing.
 

borealiss

Senior member
Jun 23, 2000
913
0
0
you need to use addresses 0cfch and 0cf8h using "out" and "in" instructions to access pci config space registers. one acts as a data index and the other an address index to the config space settings. the address you are indexing depends on bus number, device, offset, etc... it's been a while since i've had to write code that does that, but check out a book called "the undocumented PC". you can also pick up a PCI architecture book. it will tell you how to calculate all of this. if you've got a jtag debugger handy on an x86 system, you can also look at when BIOS code initializes all of your chipset devices.
 

CTho9305

Elite Member
Jul 26, 2000
9,214
1
81
Oh. I had found those addresses in the "BIOS and Kernel Developer?s Guide for the AMD Athlon? 64 and AMD Opteron? Processors" but couldn't figure out how to access them - I guess that's what I get for thinking of out and in as 16-bit instructions w/immediates :eek:

edit: I don't know what I was thinking.
 

helpme

Diamond Member
Feb 6, 2000
3,090
0
0
"PCITree" is a nice freeware app that should also let you check out the PCI regs

Edit: oops, it's shareware
 

CTho9305

Elite Member
Jul 26, 2000
9,214
1
81
If anybody is curious what I ended up doing:

#include <ntddk.h>

void DriverUnload(PDRIVER_OBJECT pDriverObject)
{
DbgPrint("Driver unloading\n");
}

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
int val;

DriverObject->DriverUnload = DriverUnload;

__asm {
mov ax, 0x8000;
or al, 0;
shl eax, 16;

mov ax, 0;
shl ax, 11;
mov al, 0;
or ah, al;
mov al, 0;

cli;
mov dx, 0x0CF8;
out dx, eax;

mov dx, 0x0CFC;
in eax, dx;
sti;

mov val, eax;
}

/*
READ VENDOR AND DEVICE ID
mov ax, 8000h ; set top bit
or al, 0 ; bus 0
shl eax, 16

mov ax, 0 ; device 0
shl ax, 11 ; slide device # up to bits 15:11
mov al, 0 ; function 0
or ah, al ; add function into bits 10:8
mov al, 0 ; read registers 0, 1 (vendor ID)

cli
mov dx, 0cf8h ; PCI index
out dx, eax ; send the request

mov dx, 0cfc ; PCI data
in eax, dx
sti

EAX = device ID (upper 16 bits)
AX = vendor ID
*/

DbgPrint("Hello, World\n");
DbgPrint("%x\n", val);

return STATUS_SUCCESS;
}