• We’re currently investigating an issue related to the forum theme and styling that is impacting page layout and visual formatting. The problem has been identified, and we are actively working on a resolution. There is no impact to user data or functionality, this is strictly a front-end display issue. We’ll post an update once the fix has been deployed. Thanks for your patience while we get this sorted.

Reading PCI configuration registers?

CTho9305

Elite Member
How do you read the configuration registers WPCREDIT displays? I'd like to write a program that does approximately the same thing.
 
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.
 
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 😱

edit: I don't know what I was thinking.
 
"PCITree" is a nice freeware app that should also let you check out the PCI regs

Edit: oops, it's shareware
 
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;
}
 
Back
Top