PCI questions

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
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

PCI questions

Post by nexos »

Hello,
I am currently making a PCI bus driver. I have a few questions however.
How do I read the PCI BARs? I know they are in the configuration space, but since they are DWORDs, how do read them.
How do I figure out what IO APIC line INTA, INTB, INTC, and INTD are without ACPI?
Do I need to enable PCI IRQs explicitly? If so, how do you do it?
And lastly, how do you work with the PCI Busmastering DMA?
Thanks,
nexos
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
User avatar
bellezzasolo
Member
Member
Posts: 110
Joined: Sun Feb 20, 2011 2:01 pm

Re: PCI questions

Post by bellezzasolo »

nexos wrote:Hello,
I am currently making a PCI bus driver. I have a few questions however.
How do I read the PCI BARs? I know they are in the configuration space, but since they are DWORDs, how do read them.
How do I figure out what IO APIC line INTA, INTB, INTC, and INTD are without ACPI?
Do I need to enable PCI IRQs explicitly? If so, how do you do it?
And lastly, how do you work with the PCI Busmastering DMA?
Thanks,
nexos
For BARs - Read configuration space as a DWORD.

Figuring out IO APIC lines without ACPI? Basically, you don't. You need an AML interpreter to get the correct mappings.
Or, you take my approach, and just use MSI(X) instead :lol:

For IRQs, you need to unmask bit 10 of Command/Status to enable pinned interrupts. For MSI, it's a bit of the MSI control register.
Set Bits 1 and 2 of Command/Status to enable memory access and bus mastering.

My PCI(E) code
Whoever said you can't do OS development on Windows?
https://github.com/ChaiSoft/ChaiOS
User avatar
iansjack
Member
Member
Posts: 4703
Joined: Sat Mar 31, 2012 3:07 am
Location: Chichester, UK

Re: PCI questions

Post by iansjack »

nexos wrote: How do I read the PCI BARs? I know they are in the configuration space, but since they are DWORDs, how do read them.
I'm not sure that I understand your problem. You just do a dword "in" to %eax.
Octocontrabass
Member
Member
Posts: 5572
Joined: Mon Mar 25, 2013 7:01 pm

Re: PCI questions

Post by Octocontrabass »

nexos wrote:How do I figure out what IO APIC line INTA, INTB, INTC, and INTD are without ACPI?
On ancient hardware (and VMs that can run OSes that work on ancient hardware) you can use the MP tables.
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: PCI questions

Post by nexos »

Thanks for your answers. I now have an understanding of PCI and have decided to use MSI in my Operating System.
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: PCI questions

Post by nexos »

I have managed to make the PCI bus driver, but what is a simple PCI device I can program to test stuff like IRQs, BAR mapping, MSI, and Busmastering?
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
User avatar
bellezzasolo
Member
Member
Posts: 110
Joined: Sun Feb 20, 2011 2:01 pm

Re: PCI questions

Post by bellezzasolo »

nexos wrote:I have managed to make the PCI bus driver, but what is a simple PCI device I can program to test stuff like IRQs, BAR mapping, MSI, and Busmastering?
Dare I say it, xHCI?

Not simple by any means, but it's not hard to test the IRQs and such. A "simple" device descriptor request tests bus mastering.

I'm currently working on an i219[v] driver, because I figure that'll be simpler than implementing a full USB stack for keyboard support, but I haven't tested bus mastering yet. BAR mapping and MSI work though. :D
Whoever said you can't do OS development on Windows?
https://github.com/ChaiSoft/ChaiOS
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: PCI questions

Post by nexos »

So in my BAR obtaining code, it appears that MMIO and IO Space regions are backwards. MMIO regions are set to be IO space and regions, and vice versa. The code that figures whether the BAR represents MMIO looks like this

Code: Select all

INT isMmio = !barLow & 1;
Is that correct?
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
thewrongchristian
Member
Member
Posts: 426
Joined: Tue Apr 03, 2018 2:44 am

Re: PCI questions

Post by thewrongchristian »

nexos wrote:So in my BAR obtaining code, it appears that MMIO and IO Space regions are backwards. MMIO regions are set to be IO space and regions, and vice versa. The code that figures whether the BAR represents MMIO looks like this

Code: Select all

INT isMmio = !barLow & 1;
Is that correct?
The lowest bit of the BAR is 1 if this is an IO address space BAR.

Your code looks like it should work, if barLow is a MMIO address, its LSB will be 0, !barLow LSB will be 1, and so isMmio will be non-zero (true). Have you inverted the test later on by accident?

I would find this test easier, though in the form:

Code: Select all

bool isMmio = (0==(barLow & 1)); 
nexos
Member
Member
Posts: 1081
Joined: Tue Feb 18, 2020 3:29 pm
Libera.chat IRC: nexos

Re: PCI questions

Post by nexos »

I have finished my PCI host controller driver. Thanks for all your help during its development.
nexos
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
Octocontrabass
Member
Member
Posts: 5572
Joined: Mon Mar 25, 2013 7:01 pm

Re: PCI questions

Post by Octocontrabass »

nexos wrote:

Code: Select all

INT isMmio = !barLow & 1;
Is that correct?
You forgot parentheses.

Code: Select all

INT isMmio = !(barLow & 1);
Post Reply