|
From: Daniel R. <cos...@gm...> - 2006-05-22 16:18:31
|
Hello Trionists, I finally found some time to fix a number of minor bugs and extended the kernel by some new functionality: - Added (very basic) handling for local APIC errors and spurious interrupts - APIC classes now use logical IDs only - Fixed a small bug that migth have lead to faulty APIC reactivations - Cleaned up the exception class, registers on the stack can now be accessed directly - IRQ class can detect an I/O APIC by probing, support for system that use ISA PIC only - Included support for hyperthreading enabled processors Unfortunately there are still some problems with the logical ID APIC code. As cluster-mode doesn't seem to be supported by modern CPU anymore, I was forced to use the more restrictive flat-mode, that only allows a maximum of 8 processors. Each CPU is assigned a unique 8 bit logical ID that can be calculated by (1 << physical_id). The ID is thus basically a bitmask with each bit representing a processor. If the APIC receives a message it compares (AND operation) its logical ID with the destination ID defined in the message. In case that the result is true the message is accepted and gets handled. All messages sent by the I/O APIC have a destination of 0xff, which basically means that any processors may handle it. As the IRQs are sent with delivery-mode 'lowest' the processors with the lowest privilege-level should take the message. The privilege-level is either determined by the current task-priority, that can be set by software (I however didn't touch it yet..), or by the priority of a pending interrupt that is currently handled. I then ran a test in which the first CPU receives an interrupt and blocks, thus remaining on a high priority-level. One would now expect that the next interrupt is handled by one of the remaining processors, which still run on the lowest privilege-level. Unfortunately this is not what's happening. Any subsequent interrupt is again dispatched to the first processor, which of course can't handle it as it hasn't yet acknowledged its earlier messages. The logical destination code itself however seems to work flawlessly: If I change the IRQ's destination ID to 0xFE the second processor handles it, and if I set it to 0xFB it's the third CPU that gets the message. As I've already spent quite some time location my mistake (without any notable success so far), I was wondering whether it wasn't possible that Bochs just doesn't simulate the details of APIC message delivery mechanism properly. Bochs' APIC support is still somewhat limited, and I've seen similiar things with error-handling, that doesn't seem to get emulated either (the error-handling code however does work on real hardware). Maybe someone could try the code on some multiprocessor or dual-core hardware ? All you would have to do is to hang the code at the _beginning_ of InterruptDestructor() in irq.cpp - if my code works each processor should print its own number, otherwise there's only one number printed after the "You may now type something" statement. Has anybody here already implemented logical APIC IDs before ? regards, cosmo86 I should probably warn you that the CVS address hostname has changed from "cvs.sourceforge.net" to "trion.cvs.sourceforge.net", it took me two days to find it out myself ;) |