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.
To access a specific register within a device's PCI configuration space, you have to use the device's PCI Segment Group and bus to determine which memory mapped PCI configuration space area to use, and obtain the starting physical address and starting bus number for that memory mapped area. Once you have the correct starting physical address and starting bus number for that memory mapped area you would use the following formula to determine where the (4096-byte) area for a function's PCI configuration space is: Physical_Address = MMIO_Starting_Physical_Address + ( (Bus - MMIO_Starting_Bus) << 20 | Device << 15 | Function << 12 ).
Last edited by Rukog on Tue Aug 24, 2021 3:15 pm, edited 1 time in total.
Klakap wrote:You do not have to use physical address, you can simply use ports 0xCF8 and 0xCFC. Everything is on PCI, driver for PCI will work on PCI express too.
No thanks, I do not wish to use in/out, I prefer the MMIO way.
If you want to use MMIO in PCI, you have to find ACPI table MCFG. So it means that you have to find RSDP, where is pointer to RSDT. RSDT contains pointers to all ACPI tables. You have to search them and figure out of MCFG is here. If yes, you can read MMIO_Starting_Physical_Address from it. But it is not sure that you will find this table on every computer. I think that I/O way is much much easier than this.
Klakap wrote:I think that I/O way is much much easier than this.
True, but PCIe (which is what uses MMIO) became the industry standard in 2005. I have seen many motherboard that have no PCI slots, although I'm not sure if they emulate PCI internally. For this reason, I would prefer the MCFG way. It may be trickier, but you have support of the current industry standard.
"How did you do this?"
"It's very simple — you read the protocol and write the code." - Bill Joy
Projects: NexNix | libnex | nnpkg
Klakap wrote:If you want to use MMIO in PCI, you have to find ACPI table MCFG. So it means that you have to find RSDP, where is pointer to RSDT. RSDT contains pointers to all ACPI tables. You have to search them and figure out of MCFG is here. If yes, you can read MMIO_Starting_Physical_Address from it. But it is not sure that you will find this table on every computer. I think that I/O way is much much easier than this.
I think ive found it, so the RSDT address is 0x5150484B ?
Octocontrabass wrote:If the checksum is correct, that's the RSDP, but you've got the wrong number for the RSDT address. Take another look at the RSDP structure.
Also, you should use the XSDT instead of the RSDT if it's available.
Feelsbad, on Qemu impossible to retrieve the RSDP table descriptor, the checksum is bad and only RSD is showing as signature, it shows its limit real quick
Also the checksum was a success on real machine and the XSDT address is 0x873BE0A0.
Rukog wrote:Feelsbad, on Qemu impossible to retrieve the RSDP table descriptor, the checksum is bad and only RSD is showing as signature, it shows its limit real quick
If the signature doesn't match, it's not the RSDP. Did you find anything else that looks like the RSDP?
Rukog wrote:Also the checksum was a success on real machine and the XSDT address is 0x873BE0A0.
Rukog wrote:Feelsbad, on Qemu impossible to retrieve the RSDP table descriptor, the checksum is bad and only RSD is showing as signature, it shows its limit real quick
If the signature doesn't match, it's not the RSDP. Did you find anything else that looks like the RSDP?
Yes because I am dumping the RSDPDesc struct where I store the RSDP found.
Else I am just searching for "RSD " w/o "PTR ", on my real machine it redirects me directly to a good RSDP but not Qemu that redirect me to several RSDP.
Last edited by Rukog on Fri Aug 13, 2021 4:58 pm, edited 1 time in total.
Qemu definitely presents a valid RSDP if you run a machine model that has ACPI support.
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].
As Occontrabass noted, you have to search RSDP in memory from 0xE0000 to 0xFFFFF as first. Only if you can not found RSDP in this memory, you can move to Bios EBDA area. When you found signature ‘RSD PTR ‘ you have to do checksum. If you do not do checksum, once in a while you will found computer with false RSDPs, e.g. Bochs. Checksum is made by adding all 20 bytes of RSDP/36 bytes of XSDP and checking if first byte of result is zero. If yes, you found valid RSDP. From my driver I can provide information that in Bochs is RSDP on address 0xFBB30, in QEMU on 0xF0980, and in Virtualbox on 0xE0000.