PCI Enumeration can't find any devices

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.
Post Reply
Postmann
Posts: 17
Joined: Wed Jul 05, 2017 9:39 pm
Libera.chat IRC: Postmann

PCI Enumeration can't find any devices

Post 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.
User avatar
~
Member
Member
Posts: 1228
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

Re: PCI Enumeration can't find any devices

Post by ~ »

Why do you use 32768 as the first value in AX?
Last edited by ~ on Wed Jul 05, 2017 10:04 pm, edited 1 time in total.
Postmann
Posts: 17
Joined: Wed Jul 05, 2017 9:39 pm
Libera.chat IRC: Postmann

Re: PCI Enumeration can't find any devices

Post by Postmann »

I was trying something I found here:
https://www.waste.org/~winkles/hardware/pci.htm
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: PCI Enumeration can't find any devices

Post 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
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.
User avatar
~
Member
Member
Posts: 1228
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

Re: PCI Enumeration can't find any devices

Post 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.
Attachments
PCI.zip
Chris Giese PCI code in assembly.
(7.55 KiB) Downloaded 91 times
Postmann
Posts: 17
Joined: Wed Jul 05, 2017 9:39 pm
Libera.chat IRC: Postmann

Re: PCI Enumeration can't find any devices

Post 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.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: PCI Enumeration can't find any devices

Post 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
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.
Postmann
Posts: 17
Joined: Wed Jul 05, 2017 9:39 pm
Libera.chat IRC: Postmann

Re: PCI Enumeration can't find any devices

Post 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
LtG
Member
Member
Posts: 384
Joined: Thu Aug 13, 2015 4:57 pm

Re: PCI Enumeration can't find any devices

Post 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..
ggodw000
Member
Member
Posts: 396
Joined: Wed Nov 18, 2015 3:04 pm
Location: San Jose San Francisco Bay Area
Contact:

Re: PCI Enumeration can't find any devices

Post by ggodw000 »

hire a detective :D
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
Postmann
Posts: 17
Joined: Wed Jul 05, 2017 9:39 pm
Libera.chat IRC: Postmann

Re: PCI Enumeration can't find any devices

Post 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. :oops:
User avatar
SpyderTL
Member
Member
Posts: 1074
Joined: Sun Sep 19, 2010 10:05 pm

Re: PCI Enumeration can't find any devices [SOLVED]

Post 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.
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
User avatar
BrightLight
Member
Member
Posts: 901
Joined: Sat Dec 27, 2014 9:11 am
Location: Maadi, Cairo, Egypt
Contact:

Re: PCI Enumeration can't find any devices

Post 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.
You know your OS is advanced when you stop using the Intel programming guide as a reference.
Post Reply