Page 1 of 1
PCI Enumeration can't find any devices
Posted: Wed Jul 05, 2017 9:48 pm
by Postmann
Hello
I have a problem with my PCI enumeration. Somehow it's returning only 0xFFFF for the vendor ID (in AX) for every bus:
Code: Select all
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.
Re: PCI Enumeration can't find any devices
Posted: Wed Jul 05, 2017 9:51 pm
by ~
Why do you use 32768 as the first value in AX?
Re: PCI Enumeration can't find any devices
Posted: Wed Jul 05, 2017 9:58 pm
by Postmann
Re: PCI Enumeration can't find any devices
Posted: Wed Jul 05, 2017 10:09 pm
by Brendan
Hi,
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.
Change this part:
Code: Select all
mov dx, [PCI_CONFIG_ADDRESS]
out dx, eax
mov dx, [PCI_CONFIG_DATA]
in eax, dx
mov [RESULT], eax
To this:
Code: Select all
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
Re: PCI Enumeration can't find any devices
Posted: Wed Jul 05, 2017 10:12 pm
by ~
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.
Re: PCI Enumeration can't find any devices
Posted: Wed Jul 05, 2017 10:40 pm
by Postmann
Brendan wrote:Change this part to this ...
I tried adding the address manually, since without the brackets it generates some weird erros:
Code: Select all
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.
Re: PCI Enumeration can't find any devices
Posted: Thu Jul 06, 2017 1:04 am
by Brendan
Hi,
Postmann wrote:Code: Select all
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:
Code: Select all
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
Re: PCI Enumeration can't find any devices
Posted: Thu Jul 06, 2017 9:26 am
by Postmann
This is the generated assembly:
https://pastebin.com/v8ScCtRQ
This is the most important part:
Code: Select all
mov WORD PTR [rbp-60], 3320
mov WORD PTR [rbp-62], 3324
.L3:
mov WORD PTR [rbp-72], 0
.L4:
mov BYTE PTR [rbp-73], 0
.L5:
#APP
# 55 "DEVICE.c" 1
mov ax, 32768
# 0 "" 2
# 56 "DEVICE.c" 1
or al, [BYTE PTR [rbp-69]]
# 0 "" 2
# 57 "DEVICE.c" 1
shl eax, 16
# 0 "" 2
# 58 "DEVICE.c" 1
mov ax, [WORD PTR [rbp-72]]
# 0 "" 2
# 59 "DEVICE.c" 1
shl ax, 11
# 0 "" 2
# 60 "DEVICE.c" 1
mov al, [BYTE PTR [rbp-73]]
# 0 "" 2
# 61 "DEVICE.c" 1
or ah, al
# 0 "" 2
# 62 "DEVICE.c" 1
cli
# 0 "" 2
# 63 "DEVICE.c" 1
mov dx, 0x0CF8
# 0 "" 2
# 64 "DEVICE.c" 1
out dx, eax
# 0 "" 2
# 65 "DEVICE.c" 1
mov dx, 0x0CFC
# 0 "" 2
# 66 "DEVICE.c" 1
in eax, dx
# 0 "" 2
# 67 "DEVICE.c" 1
mov [DWORD PTR [rbp-68]], eax
# 0 "" 2
# 68 "DEVICE.c" 1
sti
# 0 "" 2
#NO_APP
mov eax, DWORD PTR [rbp-68]
mov eax, eax
movzx eax, ax
cmp rax, 65535
je .L20
;DEVICE FOUND!
mov edi, -1
jmp .L9
Re: PCI Enumeration can't find any devices
Posted: Fri Jul 07, 2017 5:29 am
by LtG
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..
Re: PCI Enumeration can't find any devices
Posted: Fri Jul 07, 2017 6:17 pm
by ggodw000
hire a detective
Re: PCI Enumeration can't find any devices
Posted: Sat Jul 08, 2017 12:21 am
by Postmann
Urgs ... this works:
Code: Select all
mov ax, 32768
or al, [BUS]
shl eax, 16
mov ax, [DEV]
shl ax, 11
cli
mov dx, 0x0CF8
out dx, eax
mov dx, 0x0CFC
in eax, dx
mov [RESULT], eax
sti
I guess I shouldn't try my stuff with DosBox anymore. It works with a virtual FreeDOS-machine though and with my own kernel. Thanks anyway.
Re: PCI Enumeration can't find any devices [SOLVED]
Posted: Sun Jul 09, 2017 9:43 am
by SpyderTL
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.
Re: PCI Enumeration can't find any devices
Posted: Sun Jul 09, 2017 9:46 am
by BrightLight
Postmann wrote:Code: Select all
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.