Page 1 of 1
Problems with PCI
Posted: Wed Apr 11, 2007 5:15 pm
by pcmattman
I've implemented a version of the code here:
http://www.gelato.unsw.edu.au/lxr/sourc ... i/pcbios.c.
It works perfectly except for two things - inline assembly blocks which throw GPFs:
Block 1:
Code: Select all
__asm__("lcall *(%%edi); cld"
: "=a" (returnCode),
"=b" (address),
"=c" (length),
"=d" (entry)
: "0" (service),
"1" (0),
"D" (&bios32Indirect));
Block 2:
Code: Select all
__asm__ __volatile__(
"lcall *(%%edi); cld\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:"
: "=d" (signature),
"=a" (eax),
"=b" (ebx),
"=c" (ecx)
: "1" (PCIBIOS_BIOS_PRESENT),
"D" (&pciIndirect)
: "memory");
If these blocks are commented out I can detect all PCI devices and it works perfectly (in Bochs, anyway). The problem is that these blocks are pretty much validation - so they are necessary (especially the first block).
Posted: Wed Apr 11, 2007 5:42 pm
by ~
Are you relying on the PCI BIOS functions?
Why don't you try direct PCI access (if you haven't yet)?, maybe that works better for you.
Try this link, and look for the C/GCC examples that show how to access the PCI devices without BIOS, and to detect the presence of a PCI controller:
http://my.execpc.com/~geezer/
Posted: Wed Apr 11, 2007 5:44 pm
by pcmattman
I would prefer to use what I'm using now because it is already implemented into my OS, it's just these two blocks that don't work.
Bochs log at time of GPF is:
Code: Select all
00029214760e[CPU0 ] check_cs: not a valid code segment !
00060438000p[WGUI ] >>PANIC<< POWER button turned off.
00060438000i[SYS ] Last time is 1176335711
00060438000i[CPU0 ] protected mode
00060438000i[CPU0 ] CS.d_b = 32 bit
00060438000i[CPU0 ] SS.d_b = 32 bit
00060438000i[CPU0 ] | EAX=00107000 EBX=00130000 ECX=000b840c EDX=000003d5
00060438000i[CPU0 ] | ESP=0018b0f8 EBP=0018b130 ESI=0002be8f EDI=00143a78
00060438000i[CPU0 ] | IOPL=0 id vip vif ac vm rf nt of df if tf sf zf af pf cf
00060438000i[CPU0 ] | SEG selector base limit G D
00060438000i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00060438000i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 000fffff 1 1
00060438000i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00060438000i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00060438000i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 000fffff 1 1
00060438000i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00060438000i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 000fffff 1 1
00060438000i[CPU0 ] | EIP=0010718d (0010718d)
00060438000i[CPU0 ] | CR0=0x00000011 CR1=0 CR2=0x00000000
00060438000i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00060438000i[CPU0 ] >> jmp .+0xfffffffe (0x0010718d) : EBFE
00060438000i[ ] restoring default signal behavior
00060438000i[CTRL ] quit_sim called with exit code 1
Posted: Wed Apr 11, 2007 5:49 pm
by pcmattman
I just fixed it. I got confused and told it 0x10 was the code segment, instead of 0x08...
Posted: Wed Apr 11, 2007 5:57 pm
by ~
That wasn't even a bug, but a plain error.......
I don't know if this applies here but... I used to face that kind of "basic" errors because I used direct values to specify things like the GDT selectors.
But I found that one good way to finish with that kind of things, once and for all, was to use %define to have one only constant and, if I ever tried to change it, my code wouldn't suffer because it wasn't necessary anymore to modify all of the occurences, and to remember all of them in the first place.
In any case, it demonstrates once again that writing down things allows one to think about them twice and fix errors twice as fast also...
Posted: Wed Apr 11, 2007 5:59 pm
by Kevin McGuire
I tried going that route, and found out that Bochs does not support the PCI BIOS service. I think I tried Qemu too and it was the same situation.
Once you query for the service $PCI it will return a error meaning the service could not be found. I actually stepped through the BIOS code with Bochs and confirmed this.
I directly accessed the PCI bus using I/O:
http://kmcguire.jouleos.galekus.com/pci ... ource.html
As for other topics such as IRQ routing I have no idea, yet.
Posted: Wed Apr 11, 2007 6:00 pm
by pcmattman
I was considering including a define, something like CODESEG but that would mean I would have to modify quite a lot of files.
I have made this mistake before, so I just have to remember next time. If I ask something like this please remind me of the code segment
Posted: Wed Apr 11, 2007 6:24 pm
by mystran
Do not fear making modifications. The earlier you modify something, the easier it's going to be. The more you fear making modifications, the later you will do them, and that'll only make them more painful. Just make sure you're using some relatively decent version control system, so you can easily roll back to your starting point (or compare the old code with the new code) if your modifications don't work right away.
I'm pretty sure that kills far too many project.
Posted: Wed Apr 11, 2007 6:28 pm
by pcmattman
The last modification I made took a week to get back to a buildable system.
On the other hand, I think implementing #defines for all my segments will save me a LOT of problems later, especially since I seem to mix the code segment with the other segments a lot lately.