Recursive pci scan hanging on some PC's?
-
- Member
- Posts: 70
- Joined: Tue Jul 14, 2020 4:01 am
- Libera.chat IRC: clementttttttttt
Recursive pci scan hanging on some PC's?
So I made a recursive pci scanning function, and it's hanging on my computer, but not in qemu, bochs, etc. Additionally, is there anyway to debug pci hangs on real hardware?
Re: Recursive pci scan hanging on some PC's?
Recursive PCI enumeration does not hang PCs.
Recursive PCI enumeration is the only correct strategy to enumerate busses. For configuration mechanisms such as ECAM, non-recursive enumeration does not even work.
Recursive PCI enumeration is the only correct strategy to enumerate busses. For configuration mechanisms such as ECAM, non-recursive enumeration does not even work.
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].
-
- Member
- Posts: 70
- Joined: Tue Jul 14, 2020 4:01 am
- Libera.chat IRC: clementttttttttt
Re: Recursive pci scan hanging on some PC's?
might have make some mistake in the code then. will look at it even more
Re: Recursive pci scan hanging on some PC's?
Do you have a way to output text on the screen?
Re: Recursive pci scan hanging on some PC's?
How so? Unless I'm missing something, this method, which is what I use, is not recursive and works just fine:Korona wrote:Recursive PCI enumeration does not hang PCs.
Recursive PCI enumeration is the only correct strategy to enumerate busses. For configuration mechanisms such as ECAM, non-recursive enumeration does not even work.
Code: Select all
let mut maxsg: u16 = 0;
(0..MAX_SG).for_each(|i| {
if regions.physical_address(i as u16, 0, 0, 0).is_some() {
maxsg += 1;
}
});
for sg in 0u16..maxsg {
for bus in 0..MAX_BUS {
for device in 0..MAX_DEVICE {
for function in 0..MAX_FUNCTION {
// Probe
}
}
}
}
- AndrewAPrice
- Member
- Posts: 2300
- Joined: Mon Jun 05, 2006 11:00 pm
- Location: USA (and Australia)
Re: Recursive pci scan hanging on some PC's?
I can't see your code but feel free to compare against mine for any differences:
https://github.com/AndrewAPrice/Percept ... c#L56-L119
https://github.com/AndrewAPrice/Percept ... c#L56-L119
My OS is Perception.
Re: Recursive pci scan hanging on some PC's?
How do you handle/detect nested/secondary/subordinate buses? Recursion seems to be the natural way to go about it.Ethin wrote: How so? Unless I'm missing something, this method, which is what I use, is not recursive and works just fine:
Re: Recursive pci scan hanging on some PC's?
I don't treat a bridge or bus any differently than any other device. If I can scan it (that is, if the vendor ID isn't 0xFFFF or 0x0000), I add it. For bridges and such, I have this extra bit of handlign code:kzinti wrote:How do you handle/detect nested/secondary/subordinate buses? Recursion seems to be the natural way to go about it.Ethin wrote: How so? Unless I'm missing something, this method, which is what I use, is not recursive and works just fine:
Code: Select all
// Bridge or PCI card bus
secondary_bus: if (read_byte(addr as usize, HEADER_TYPE) & 0x7F)
== 1
|| (read_byte(addr as usize, HEADER_TYPE) & 0x7F) == 2
{
read_byte(addr as usize, SEC_BUS)
} else {
0
},
-
- Member
- Posts: 70
- Joined: Tue Jul 14, 2020 4:01 am
- Libera.chat IRC: clementttttttttt
Re: Recursive pci scan hanging on some PC's?
nevermind, it works now, might have mistyped something somewhere
Re: Recursive pci scan hanging on some PC's?
Okay, that works but that's kind of a hack -- using recursive enumeration you know a priori whether a bus number is valid or not.Ethin wrote:I use a method to check to see if the region I'm accessing in PCIe is actually a region in PCIe space but other than that, this is the code I'm using. Are you saying that this way isn't the right way?
Aside from that, there are situations where non-recursive enumeration truly does not work: for example, on most (all?) ARM devices, the firmware does not allocate bus numbers for you and you have to do it yourself once you see a bridge. The same is true even for x86 if you have a bridge on an expansion card.
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].
Re: Recursive pci scan hanging on some PC's?
Hmm... That definitely seems like a problem. I might switch my code to using the recursive initialization sequence then.Korona wrote:Okay, that works but that's kind of a hack -- using recursive enumeration you know a priori whether a bus number is valid or not.Ethin wrote:I use a method to check to see if the region I'm accessing in PCIe is actually a region in PCIe space but other than that, this is the code I'm using. Are you saying that this way isn't the right way?
Aside from that, there are situations where non-recursive enumeration truly does not work: for example, on most (all?) ARM devices, the firmware does not allocate bus numbers for you and you have to do it yourself once you see a bridge. The same is true even for x86 if you have a bridge on an expansion card.
Re: Recursive pci scan hanging on some PC's?
That method is not recursive, but it will scan a lot of busses that are not actually present. And a lot of functions that are not present. I mean, the code will work, it's just doing a lot of useless nonsense.Ethin wrote:How so? Unless I'm missing something, this method, which is what I use, is not recursive and works just fine:
I would handle that by putting a separate PCI bridge initialization step before the actual enumeration. Besides, if I have to initialize PCI bridges, I will likely also have to initialize PCI BARs, and that is where it gets complicated without knowledge of the system.Korona wrote:Aside from that, there are situations where non-recursive enumeration truly does not work: for example, on most (all?) ARM devices, the firmware does not allocate bus numbers for you and you have to do it yourself once you see a bridge. The same is true even for x86 if you have a bridge on an expansion card.
Carpe diem!
Re: Recursive pci scan hanging on some PC's?
To see all bridges, you have to see all devices anyway, so you can integrate these two kinds of iterations into a single recursive scan.nullplan wrote:I would handle that by putting a separate PCI bridge initialization step before the actual enumeration. Besides, if I have to initialize PCI bridges, I will likely also have to initialize PCI BARs, and that is where it gets complicated without knowledge of the system.
You are correct about the BARs. It is a bit annoying but not too complicated: you get the memory range that the PCI root complex can address from the DTB, you recursively enumerate all BARs behind each bridge, and you allocate enough space for the devices behind each bridge, set up the bridge's MMIO range registers, and finally set up the BARs.
managarm: Microkernel-based OS capable of running a Wayland desktop (Discord: https://discord.gg/7WB6Ur3). My OS-dev projects: [mlibc: Portable C library for managarm, qword, Linux, Sigma, ...] [LAI: AML interpreter] [xbstrap: Build system for OS distributions].
-
- Member
- Posts: 70
- Joined: Tue Jul 14, 2020 4:01 am
- Libera.chat IRC: clementttttttttt
Re: Recursive pci scan hanging on some PC's?
Now it sometime hangs, but sometime works. This doesn't happen on emulators so debugging is very hard. Is there anything like a pci card or smth that shows the register states on real hardware?
Re: Recursive pci scan hanging on some PC's?
Have you taken any steps to debug the issue? Even something as simple as "print EIP when I press a button"? You should be able to see what is going on that way.
Carpe diem!