Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
PCI_CONFIG_ADDRESS=0x0CF8;
PCI_CONFIG_DATA=0x0CFC;
for (BUS=0, BUS<256, BUS++) {
for (DEV=0, DEV<32, DEV++) {
for (FN=0, FN<8, FN++) {
asm {
mov ax, 32768
or al, [BUS]
shl eax, 16
mov ax, [DEV]
shl ax, 11
mov al, [FN]
or ah, al
mov al, [VEN_ID]
mov dx, [PCI_CONFIG_ADDRESS]
out dx, eax
mov dx, [PCI_CONFIG_DATA]
in eax, dx
mov [RESULT], eax
}
I was testing this on Bochs and without my kernel on FreeDOS and DosBox, it doesn't work on either of them. But why? I don't see any problems with the code.
Postmann wrote:I was testing this on Bochs and without my kernel on FreeDOS and DosBox, it doesn't work on either of them. But why? I don't see any problems with the code.
mov dx, PCI_CONFIG_ADDRESS
out dx, eax
mov dx, PCI_CONFIG_DATA
in eax, dx
mov [RESULT], eax
~ wrote:Why do you use 32768 as the first value in AX?
That's the "enable" flag (that ends up at bit 31).
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
You could first make a program to list the bit fields you are generating. That could be the first problem if it isn't really producing the values you want for bus, device, function.
You could also see the PCI example from Chris Giese, it seems to be better. It has helped me in the past. I have even been able to get the base address of graphics modes with it: http://devel.archefire.org/mirrors/my.e ... /pnp/pci.c
I translated that code to assembly several years ago. I have attached it, maybe it can serve as an additional example.
mov ax, 32768
or al, [BUS]
shl eax, 16
mov ax, [DEV]
shl ax, 11
mov al, [FN]
or ah, al
mov al, [VEN_ID]
cli
mov dx, 0x0CF8
out dx, eax
mov dx, 0x0CFC
in eax, dx
mov [RESULT], eax
sti
No change though.
That should work, unless there's a bug somewhere else (not in the assembly itself). One possibility is that whichever compiler you're using doesn't know that you're accessing variables and keeps the values in registers (without updating the values in memory).
I'd recommend posting a disassembly of whatever the compiler generated.
Note that there is an unrelated bug (you shouldn't look at functions 1 to 7 unless the device says it is a multi-function device because if you do the information for "function 0" can be return for functions 1 to 7).
Also (for performance) you could do something like this:
for(uint32_t i = 0x80000000; i <= 0x80000000 | 255<<24 | 31<<11 | 7<<8 | 0; i += 1 << 8) {
asm {
mov eax,[i]
cli
mov dx, 0x0CF8
out dx, eax
mov dx, 0x0CFC
in eax, dx
mov [RESULT], eax
sti
}
Cheers,
Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
It seems you've modified your code from what's in the OP but not included that in your last post.. Also mentioning what the current issue is also helps, even if it's still the same..
Not sure if I'm looking at your code correctly but your initial code has this:
mov al, [VEN_ID]
But most recent doesn't seem to have it? So at:
or ah, al
cli
The "or ah, al" leaves "al" with presumably the "FN"?
Also, have you tried debugging, checking what exactly is in EAX before the OUT? And what the response is with IN? Might be useful..
key takeaway after spending yrs on sw industry: big issue small because everyone jumps on it and fixes it. small issue is big since everyone ignores and it causes catastrophy later. #devilisinthedetails
Be sure to mark your thread as [SOLVED] so that others can use it in the future to troubleshoot their own problems.
I'm not sure if I can change the thread title just by replying to your thread, but I'll give it a shot. If not, you can go back to your initial post and change the title there.
Project: OZone
Source: GitHub
Current Task: LIB/OBJ file support
"The more they overthink the plumbing, the easier it is to stop up the drain." - Montgomery Scott
mov dx, 0x0CF8
out dx, eax
mov dx, 0x0CFC
in eax, dx
mov [RESULT], eax
sti
There's no need to disable/enable hardware interrupts while accessing the PCI configuration space, as there is never a reason for an interrupt handler to access the PCI configuration space registers. Even if the interrupt handler of a PCI device should read PCI configuration status registers or such, it shouldn't do so in the handler itself, and rather just notify the driver by setting a flag.
You know your OS is advanced when you stop using the Intel programming guide as a reference.