Problems with PCI

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
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Problems with PCI

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

Post 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/
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post 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
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

I just fixed it. I got confused and told it 0x10 was the code segment, instead of 0x08...
User avatar
~
Member
Member
Posts: 1228
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

Post 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...
User avatar
Kevin McGuire
Member
Member
Posts: 843
Joined: Tue Nov 09, 2004 12:00 am
Location: United States
Contact:

Post 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.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post 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 :D
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post 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.
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post 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.
Post Reply