|
From: Daniel R. <co...@us...> - 2006-05-22 15:18:56
|
Update of /cvsroot/trion/trion v0.2/hal In directory sc8-pr-cvs10.sourceforge.net:/tmp/cvs-serv8777 Modified Files: apic_io.cpp apic_io.hpp apic_local.cpp apic_local.hpp cpu_info.cpp cpu_info.hpp exception.cpp exception.hpp hal_object.hpp idt.cpp interrupt.cpp interrupt.hpp irq.cpp irq.hpp mutex.cpp mutex.hpp ports.hpp Added Files: apic_error.cpp apic_error.hpp Log Message: no message Index: exception.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/exception.hpp,v retrieving revision 1.6 retrieving revision 1.7 diff -C2 -d -r1.6 -r1.7 *** exception.hpp 5 Apr 2006 17:12:00 -0000 1.6 --- exception.hpp 22 May 2006 15:18:49 -0000 1.7 *************** *** 42,73 **** #include "../object/std_types.hpp" #include "hal_object.hpp" #include "interrupt.hpp" ! enum register_id { ! EAX = 7, EBX = 4, ECX = 6, EDX = 5, ! ESI = 1, EDI = 0, ESP = 12, EBP = 2, ! CS = 10, EIP = 9, SS = 13, ! EFLAGS = 11, ERROR_CODE = 8 ! }; class exception : public interrupt { private: - uint exception_number; - bool error_code, handler_running; - uint* stack_pointer; - static bool error_code_map[32], trap_gate_map[32]; ! void PrintAllRegisters(); ! void SetRegisterValue(register_id reg, uint value); ! uint GetRegisterValue(register_id reg); ! void ChangeReturnAddress(ushort selector, uint offset); ! void ChangeStackAddress (ushort selector, uint offset); bool AddHandler (uint number, exception* p_class, method handler); --- 42,76 ---- #include "../object/std_types.hpp" + #include "hal_object.hpp" #include "interrupt.hpp" ! struct segment_registers { ! uint eip, cs; ! uint eflags; ! uint esp, ss; ! }__attribute__ ((__packed__)); ! ! struct general_registers ! { ! uint edi, esi, ebp, ignore; ! uint ebx, edx, ecx, eax; ! ! }__attribute__ ((__packed__)); class exception : public interrupt { private: static bool error_code_map[32], trap_gate_map[32]; ! segment_registers* segment_regs; ! general_registers* general_regs; ! uint exception_number, error_code; ! bool handler_running; ! void PrintAllRegisters(); bool AddHandler (uint number, exception* p_class, method handler); Index: cpu_info.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/cpu_info.cpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** cpu_info.cpp 30 Apr 2006 19:21:34 -0000 1.1 --- cpu_info.cpp 22 May 2006 15:18:48 -0000 1.2 *************** *** 42,46 **** cpu_flags cpu_info::GetProcessorInfo() { ! uint ret = cpuid<EAX>(0x01); return *reinterpret_cast<cpu_flags*>(&ret); } --- 42,46 ---- cpu_flags cpu_info::GetProcessorInfo() { ! uint ret = cpuid<EDX>(0x01); return *reinterpret_cast<cpu_flags*>(&ret); } Index: ports.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/ports.hpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** ports.hpp 13 Apr 2006 20:02:49 -0000 1.2 --- ports.hpp 22 May 2006 15:18:49 -0000 1.3 *************** *** 58,66 **** template<port_size t> uint ReadPort(ushort port_number); ! template<> inline uint ReadPort<BYTE> (ushort p) {uchar r; asm("inb %%dx,%%al ":"=a"(r):"dN"(p)); return r;} template<> inline uint ReadPort<WORD> (ushort p) {ushort r; asm("inw %%dx,%%ax ":"=a"(r):"dN"(p)); return r;} template<> inline uint ReadPort<DWORD>(ushort p) {uint r; asm("ind %%dx,%%eax":"=a"(r):"dN"(p)); return r;} ! template<port_size t> void WritePort(ushort port_number, uint data); template<> inline void WritePort<BYTE> (ushort p, uint v) {asm("outb %%al, %%dx": :"dN"(p), "a"(v));} template<> inline void WritePort<WORD> (ushort p, uint v) {asm("outw %%ax, %%dx": :"dN"(p), "a"(v));} --- 58,66 ---- template<port_size t> uint ReadPort(ushort port_number); ! template<> inline uint ReadPort<BYTE> (ushort p){ uchar r; asm("inb %%dx,%%al ":"=a"(r):"dN"(p)); return r;} template<> inline uint ReadPort<WORD> (ushort p) {ushort r; asm("inw %%dx,%%ax ":"=a"(r):"dN"(p)); return r;} template<> inline uint ReadPort<DWORD>(ushort p) {uint r; asm("ind %%dx,%%eax":"=a"(r):"dN"(p)); return r;} ! template<port_size t> void WritePort(ushort port_number, uint value); template<> inline void WritePort<BYTE> (ushort p, uint v) {asm("outb %%al, %%dx": :"dN"(p), "a"(v));} template<> inline void WritePort<WORD> (ushort p, uint v) {asm("outw %%ax, %%dx": :"dN"(p), "a"(v));} Index: cpu_info.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/cpu_info.hpp,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** cpu_info.hpp 30 Apr 2006 19:21:34 -0000 1.1 --- cpu_info.hpp 22 May 2006 15:18:48 -0000 1.2 *************** *** 81,85 **** class cpu_info { ! private: enum register_id { EAX, EBX, ECX, EDX }; template<register_id r> uint cpuid(uint function); --- 81,85 ---- class cpu_info { ! public: enum register_id { EAX, EBX, ECX, EDX }; template<register_id r> uint cpuid(uint function); *************** *** 103,117 **** template<> inline uint cpu_info::cpuid<cpu_info::EBX>(uint f) { ! uint r; asm("cpuid":"=b"(r):"a"(f):"%eax","%ecx","%edx"); return r; } template<> inline uint cpu_info::cpuid<cpu_info::ECX>(uint f) { ! uint r; asm("cpuid":"=c"(r):"a"(f):"%eax","%ebx","%edx"); return r; } template<> inline uint cpu_info::cpuid<cpu_info::EDX>(uint f) { ! uint r; asm("cpuid":"=d"(r):"a"(f):"%eax","%ebx","%ecx"); return r; } --- 103,117 ---- template<> inline uint cpu_info::cpuid<cpu_info::EBX>(uint f) { ! uint r; asm("cpuid":"=b"(r):"a"(f):"%ecx","%edx"); return r; } template<> inline uint cpu_info::cpuid<cpu_info::ECX>(uint f) { ! uint r; asm("cpuid":"=c"(r):"a"(f):"%ebx","%edx"); return r; } template<> inline uint cpu_info::cpuid<cpu_info::EDX>(uint f) { ! uint r; asm("cpuid":"=d"(r):"a"(f):"%ebx","%ecx"); return r; } Index: hal_object.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/hal_object.hpp,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** hal_object.hpp 7 Apr 2006 17:15:53 -0000 1.4 --- hal_object.hpp 22 May 2006 15:18:49 -0000 1.5 *************** *** 43,52 **** struct hal_object { ! class exception* faults; ! class idt* int_vec; class local_apic* lapic; class ipi* inter; class timer* clock; - class irq_logic* ireq; class mmu* memory; }; --- 43,52 ---- struct hal_object { ! class idt* vector; class local_apic* lapic; + class apic_error* error; + class exception* faults; class ipi* inter; class timer* clock; class mmu* memory; }; --- NEW FILE: apic_error.hpp --- // ----------------------------------------------------------------------- // apic_error.cpp - Handles local apic errors and spurious interrupts // // Author(s) : // Date : MM/DD/2006 // Version : 0.2.0 // Home Page : http://trion.sourceforge.net // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- // Copyright (C) 2006, Trion Development Group Members // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // 3. Neither the name of the Trion Development Group nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // ----------------------------------------------------------------------- #ifndef __HAL__APIC_ERROR__ #define __HAL__APIC_ERROR__ #include "../object/std_types.hpp" #include "interrupt.hpp" class apic_error : public interrupt { private: void InterruptConstructor(hal_object* hal, uchar interrupt_number, uint* esp); void InterruptDestructor (hal_object* hal, uchar interrupt_number, uint* esp); enum error_types { send_checksum = 1, receive_checksum = 2, send_accept = 4, receive_accept = 8, send_vector = 32, receive_vector = 64, illegal_register = 128 }; uint GetErrorCode(); void ClearErrorRegister(); public: apic_error(); void InterruptError(hal_object* hal); void SpuriousInterrupt(hal_object* hal); }; #endif Index: apic_io.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/apic_io.cpp,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** apic_io.cpp 13 Apr 2006 20:00:50 -0000 1.4 --- apic_io.cpp 22 May 2006 15:18:48 -0000 1.5 *************** *** 45,49 **** io_apic::io_apic(uint phys_address) { ! if(phys_address == 0xFEC00000) // First IO APIC in the system { page_base = static_cast<uint*>(heap().CreatePhysicalWindow(0xfec00000)); --- 45,49 ---- io_apic::io_apic(uint phys_address) { ! if(page_base == 0) // First IO APIC in the system { page_base = static_cast<uint*>(heap().CreatePhysicalWindow(0xfec00000)); *************** *** 79,86 **** { ioapic_int interrupt = {0}; ! interrupt.pin_polarity = polarity; ! interrupt.level = level; ! interrupt.mode = mode; ! interrupt.masked = true; SetInterruptFlags(number, interrupt); --- 79,86 ---- { ioapic_int interrupt = {0}; ! interrupt.pin_polarity = polarity; ! interrupt.level = level; ! interrupt.delivery = mode; ! interrupt.masked = true; SetInterruptFlags(number, interrupt); --- NEW FILE: apic_error.cpp --- // ----------------------------------------------------------------------- // apic_error.cpp - Handles local apic errors and spurious interrupts // // Author(s) : // Date : MM/DD/2006 // Version : 0.2.0 // Home Page : http://trion.sourceforge.net // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- // Copyright (C) 2006, Trion Development Group Members // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // 3. Neither the name of the Trion Development Group nor the names of its // contributors may be used to endorse or promote products derived from // this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS // IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED // TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A // PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // ----------------------------------------------------------------------- #include "apic_error.hpp" #include "../loader/console.hpp" apic_error::apic_error() { // Enable the error-interrupt and assign a vector to it uint apic_error_vector = 255 - 0; lapic_lvt lvt = GetLVT(lapic_reg(LVTERR)); lvt.masked = false; lvt.vector = apic_error_vector; SetLVT(lapic_reg(LVTERR), lvt); // Assign a vector to the spurious interupt uint spurious_vector = 255 - 1; WriteRegister(lapic_reg(SIVR), ReadRegister(lapic_reg(SIVR)) | spurious_vector); // Install our two error-handling interrupts AddHandler(apic_error_vector, false, this, (method) &apic_error::InterruptError, false, false); AddHandler(spurious_vector, false, this, (method) &apic_error::SpuriousInterrupt, false, false); ClearErrorRegister(); } void apic_error::InterruptConstructor(hal_object* hal, uchar interrupt_number, uint* esp) { } void apic_error::InterruptDestructor(hal_object* hal, uchar interrupt_number, uint* esp) { } uint apic_error::GetErrorCode() { // Write to the register to update it, then read it out WriteRegister(lapic_reg(ESR), 0); return ReadRegister(lapic_reg(ESR)); } void apic_error::ClearErrorRegister() { // Two sucessive writes clear the error register WriteRegister(lapic_reg(ESR), 0); WriteRegister(lapic_reg(ESR), 0); } void apic_error::InterruptError(hal_object* hal) { cout() << "Panic: A local APIC error was reported (" << GetErrorCode() << ")" << endl; while(true); } void apic_error::SpuriousInterrupt(hal_object* hal) { cout() << "Panic: A spurious interrupt was reported" << endl; while(true); } Index: irq.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/irq.cpp,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** irq.cpp 30 Apr 2006 19:21:34 -0000 1.5 --- irq.cpp 22 May 2006 15:18:49 -0000 1.6 *************** *** 41,132 **** #include "ports.hpp" #include "hal_object.hpp" #include "../loader/console.hpp" ! irq_logic::irq_logic() : handler_running(false) { ! if(boot_hal->lapic->GetPhysicalID() == 0) { ! DisableLegacyPIC(); ! // Detect which buses are installed on the system ! uint number_buses = multiprocessor().GetNumberEntries(TYPE_BUS); ! uint* bus_table = static_cast<uint*>(heap().AllocateMemory(number_buses*sizeof(uint))); ! DetectSystemBuses(bus_table); ! // Walk trough the multiprocessor table and initialize any I/O Apic found ! uint number_apics = multiprocessor().GetNumberEntries(TYPE_IO_APIC); ! apic_table = static_cast<io_apic**>(heap().AllocateMemory(number_apics*sizeof(io_apic*))); ! uint counter = 0; ! for(iterator it = multiprocessor().begin(TYPE_IO_APIC); it != multiprocessor().end(); it++) { ! apic_table[counter] = InitializeIOApic(it, bus_table); ! counter++; } ! // EnableIRQ(1); // Unmask the keyboard IRQ } // Install necessary interrupt handlers ! for(uint i=0x20; i<0x38; i++) { ! AddHandler(i, false, this, (method)&irq_logic::DispatchIRQ, false, false); } } ! void irq_logic::DisableLegacyPIC() { // Before we can diable the ISA PIC we first have to initialize it ! WritePort<BYTE>(0x20, 0x11); // Initialize (16), ICW4 needed (1) WritePort<BYTE>(0xA0, 0x11); ! WritePort<BYTE>(0x21, 0x00); // vector offset master PIC ! WritePort<BYTE>(0xA1, 0x00); // vector offset slave PIC ! WritePort<BYTE>(0x21, 4); // IRQ #2 used for cascading ! WritePort<BYTE>(0xA1, 2); // Set slave ID ! WritePort<BYTE>(0x21, 1); // x86 mode, no auto EOI, etc WritePort<BYTE>(0xA1, 1); // Now mask all of its IRQs ! WritePort<BYTE>(0x21, 0xff); // IRQs 00-07 ! WritePort<BYTE>(0xA1, 0xff); // IRQs 08-15 } ! uint irq_logic::DetectSystemBuses(uint* bus_table) { // In the multiprocessor tables the buses are described by a 6 character ASCII string, // we'll chop the string to a 32bit value, so that it fits into an ordinary dword - uint counter = 0; for(iterator it = multiprocessor().begin(TYPE_BUS); it != multiprocessor().end(); it++) { ! uchar* string = static_cast<SmpConfigBus*>(*it)->TypeString; ! uint buffer = 0; ! ! for(uint i=0; i < 4; i++) { ! buffer <<= 8; ! buffer += string[i]; } - bus_table[counter++] = buffer; } ! return counter; } ! io_apic* irq_logic::InitializeIOApic(iterator it, uint* bus_table) { ! // Spawn an new instance of the apic class for this I/O Apic uint base_address = static_cast<SmpConfigIOApic*>(*it)->BaseAddr; io_apic* apic = new (heap().AllocateMemory(sizeof(io_apic))) io_apic(base_address); ! // Populate the Apic's IRQ redirection entries with default values for(uint i=0; i <= apic->GetMaxRedirect(); i++) { bool irq_type = (i > 15) ? true : false; ! apic->SetInterruptType(i, irq_type, irq_type, ioapic_int::fixed); ! apic->SetInterruptReceiver(i, 0, 0x20 + i, false); } uint counter = 0; --- 41,171 ---- #include "ports.hpp" #include "hal_object.hpp" + #include "../loader/heap_manager.hpp" #include "../loader/console.hpp" ! irq_logic::irq_logic() : instance(0) { ! InitializeLegacyPIC(); ! ! // Detect how many I/O APICs are installed on the system ! uint number_devices = multiprocessor().GetNumberEntries(TYPE_IO_APIC); ! ! device_table = static_cast<irq_dev*>(heap().AllocateMemory(number_devices*sizeof(irq_dev))); ! uint counter = 0; ! ! // Walk through the multiprocessor table and initialize any I/O APIC found ! for(iterator it = multiprocessor().begin(TYPE_IO_APIC); it != multiprocessor().end(); it++) { ! device_table[counter] = InitializeIOApic(it); ! counter++; ! cout() << "Detected an I/O APIC by searching the multiprocessor table" << endl; ! } ! if(number_devices == 0) ! { ! // Some uniprocessor systems don't support the multiprocessor standard although they do ! // have an I/O APIC. If the APIC isn't reported, we might just have to probe for it.. ! io_apic probe(0xfec00000); ! ! if(probe.GetVersion() >= 0x10 && probe.GetVersion() <= 0x20) // sanity check { ! device_table = static_cast<irq_dev*>(heap().AllocateMemory(sizeof(irq_dev))); ! ! SmpConfigIOApic dummy; ! dummy.Type = TYPE_IO_APIC; ! dummy.ApicID = 2; ! dummy.BaseAddr = 0xfec00000; ! ! device_table[0] = InitializeIOApic(iterator(&dummy)); ! number_devices++; ! ! cout() << "Detected an I/O APIC by probing for it" << endl; } ! } ! ! if(number_devices == 0) ! { ! // No APIC found, will use ISA PIC legacy node ! device_table = static_cast<irq_dev*>(heap().AllocateMemory(sizeof(irq_dev))); ! device_table[0].legacy_pic = true; ! device_table[0].number_irqs = 0x10; ! ! number_devices++; ! ! cout() << "Using ISA PIC legacy mode" << endl; } // Install necessary interrupt handlers ! for(uint i=0, k=255-32; i<number_devices; i++) { ! for(uint j=0; j < device_table[i].number_irqs; j++) ! { ! AddHandler(k, false, this, (method)&irq_logic::DispatchIRQ, false, false); ! k--; ! } } } ! void irq_logic::InitializeLegacyPIC() { // Before we can diable the ISA PIC we first have to initialize it ! WritePort<BYTE>(0x20, 0x11); // Initialize (16), ICW4 needed (1) WritePort<BYTE>(0xA0, 0x11); ! WritePort<BYTE>(0x21, 255-47); // vector offset master PIC ! WritePort<BYTE>(0xA1, 255-39); // vector offset slave PIC ! WritePort<BYTE>(0x21, 4); // IRQ #2 used for cascading ! WritePort<BYTE>(0xA1, 2); // Set slave ID ! WritePort<BYTE>(0x21, 1); // x86 mode, no auto EOI, etc WritePort<BYTE>(0xA1, 1); // Now mask all of its IRQs ! WritePort<BYTE>(0x21, 0xff); // IRQs 00-07 ! WritePort<BYTE>(0xA1, 0xff); // IRQs 08-15 } ! uint irq_logic::DetectSystemBus(uint bus_number) { // In the multiprocessor tables the buses are described by a 6 character ASCII string, // we'll chop the string to a 32bit value, so that it fits into an ordinary dword for(iterator it = multiprocessor().begin(TYPE_BUS); it != multiprocessor().end(); it++) { ! if(static_cast<SmpConfigBus*>(*it)->BusID == bus_number) { ! uchar* string = static_cast<SmpConfigBus*>(*it)->TypeString; ! uint hash = 0; ! ! for(uint i=0; i<4; i++) ! { ! hash <<= 8; ! hash += string[i]; ! } ! return hash; } } ! return 0; } ! irq_dev irq_logic::InitializeIOApic(iterator it) { ! // Spawn an new instance of the APIC class for this device uint base_address = static_cast<SmpConfigIOApic*>(*it)->BaseAddr; + + irq_dev* dev = new (heap().AllocateMemory(sizeof(irq_dev))) irq_dev(); io_apic* apic = new (heap().AllocateMemory(sizeof(io_apic))) io_apic(base_address); ! // Populate the APIC's IRQ redirection entries with default values for(uint i=0; i <= apic->GetMaxRedirect(); i++) { bool irq_type = (i > 15) ? true : false; ! apic->SetInterruptType(i, irq_type, irq_type, ioapic_int::lowest); ! apic->SetInterruptReceiver(i, 0xff, 255-32 - i, true); } uint counter = 0; *************** *** 145,221 **** if(!polarity || !edge_level) // Try default values { ! switch(bus_table[irq->SourceID]) { case ISA: polarity = edge_level = false; // High polarity, Edge triggered break; case PCI: polarity = edge_level = true; // Low polarity, Level triggered break; default: ! cout() << "Panic: Unknown bus type (/hal/irg.cpp -> InitializeIOApic)" << endl; while(true); } } ! apic->SetInterruptType(irq->DestIRQ, polarity, edge_level, (ioapic_int::delivery_mode)irq->IntType); ! apic->SetInterruptReceiver(irq->DestIRQ, 0, 0x20 + irq->DestIRQ, false); } counter++; } ! return apic; } void irq_logic::EnableIRQ(uint number) { ! uint current_max = apic_table[0]->GetMaxRedirect(); ! uint apic_number = 0; while(current_max < number) { ! current_max += apic_table[++apic_number]->GetMaxRedirect(); } ! uint irq_number = apic_table[apic_number]->GetMaxRedirect() - (current_max - number); ! apic_table[apic_number]->MaskInterrupt(irq_number, false); } void irq_logic::DisableIRQ(uint number) { ! uint current_max = apic_table[0]->GetMaxRedirect(); ! uint apic_number = 0; while(current_max < number) { ! current_max += apic_table[++apic_number]->GetMaxRedirect(); } ! uint irq_number = apic_table[apic_number]->GetMaxRedirect() - (current_max - number); ! apic_table[apic_number]->MaskInterrupt(irq_number, true); } void irq_logic::InterruptConstructor(hal_object* hal, uchar interrupt_number, uint* esp) { ! if(handler_running) { ! cout() << endl << "Panic: Nested IRQs aren't yet supported (/hal/irq.cpp)" << endl; while(true); } ! ! irq_number = interrupt_number; ! stack_pointer = esp; ! ! handler_running = true; } ! void irq_logic::InterruptDestructor (hal_object* hal, uchar interrupt_number, uint* esp) { ! handler_running = false; ! SignalEOI(); } void irq_logic::DispatchIRQ(hal_object* hal) { ! cout() << (char)ReadPort<BYTE>(0x60); } --- 184,305 ---- if(!polarity || !edge_level) // Try default values { ! switch(DetectSystemBus(irq->SourceID)) { case ISA: + { polarity = edge_level = false; // High polarity, Edge triggered break; + } case PCI: + { polarity = edge_level = true; // Low polarity, Level triggered break; + } default: ! { ! cout() << "Panic: Unknown bus type (/hal/irq.cpp -> InitializeIOApic)" << endl; while(true); + } } } ! apic->SetInterruptType(irq->DestIRQ, polarity, edge_level, ioapic_int::lowest); ! apic->SetInterruptReceiver(irq->DestIRQ, 0xff, 255-32 - irq->DestIRQ, true); } counter++; } ! ! // Store the collected information in a irq_dev class ! dev->legacy_pic = false; ! dev->number_irqs = apic->GetMaxRedirect(); ! dev->device_id = apic->GetApicID(); ! dev->apic = apic; ! ! return *dev; } void irq_logic::EnableIRQ(uint number) { ! uint device_number = 0; ! uint current_max = device_table[device_number].number_irqs; while(current_max < number) { ! current_max += device_table[++device_number].number_irqs; } + uint irq_number = device_table[device_number].number_irqs - (current_max - number); ! if(device_table[device_number].legacy_pic) ! { ! uint irq_mask = ~(1 << irq_number); ! ! WritePort<BYTE>(0x21, ReadPort<BYTE>(0x21) &(irq_mask)); ! WritePort<BYTE>(0xA1, ReadPort<BYTE>(0xA1) &(irq_mask >> 8)); ! } ! else ! { ! device_table[device_number].apic->MaskInterrupt(irq_number, false); ! } } void irq_logic::DisableIRQ(uint number) { ! uint device_number = 0; ! uint current_max = device_table[device_number].number_irqs; while(current_max < number) { ! current_max += device_table[++device_number].number_irqs; } + uint irq_number = device_table[device_number].number_irqs - (current_max - number); ! if(device_table[device_number].legacy_pic) ! { ! uint irq_mask = 1 << irq_number; ! ! WritePort<BYTE>(0x21, ReadPort<BYTE>(0x21) | (irq_mask)); ! WritePort<BYTE>(0xA1, ReadPort<BYTE>(0xA1) | (irq_mask >> 8)); ! } ! else ! { ! device_table[device_number].apic->MaskInterrupt(irq_number, true); ! } ! } ! ! void irq_logic::SignalEOI(uint number) ! { ! if(device_table[0].legacy_pic) ! { ! WritePort<BYTE>(0x20, 0x20); ! WritePort<BYTE>(0xA0, 0x20); ! } } void irq_logic::InterruptConstructor(hal_object* hal, uchar interrupt_number, uint* esp) { ! if(instance != 0) { ! cout() << "Panic: Nested IRQs aren't yet supported" << endl; while(true); } ! instance = reinterpret_cast<irq_data*>(0xFFFFFFFF); } ! void irq_logic::InterruptDestructor(hal_object* hal, uchar interrupt_number, uint* esp) { ! (device_table[0].legacy_pic) ? this->SignalEOI(interrupt_number) : hal->lapic->SignalEOI(); ! instance = reinterpret_cast<irq_data*>(0x00000000); } void irq_logic::DispatchIRQ(hal_object* hal) { ! cout() << (char) ReadPort<BYTE>(0x60); ! } ! ! char irq_logic_reserved[sizeof(irq_logic)]; ! ! irq_logic& irq() ! { ! return (reinterpret_cast<irq_logic&>(irq_logic_reserved)); } Index: exception.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/exception.cpp,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** exception.cpp 13 Apr 2006 20:03:47 -0000 1.7 --- exception.cpp 22 May 2006 15:18:49 -0000 1.8 *************** *** 46,54 **** 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; ! exception::exception() : interrupt() { ! for(uint i=0; i<256; i++) { ! // Install standard handler for all 255 interrupts AddReserved(i, this, (method)&exception::ReservedInterrupt); } --- 46,54 ---- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; ! exception::exception() { ! for(uint i=0; i<0x100; i++) { ! // Install a standard handler for all 256 interrupts AddReserved(i, this, (method)&exception::ReservedInterrupt); } *************** *** 63,105 **** void exception::PrintAllRegisters() { ! cout() << "eax " << GetRegisterValue(register_id(EAX)) << " "; ! cout() << "esi " << GetRegisterValue(register_id(ESI)) << " "; ! cout() << "cs " << GetRegisterValue(register_id(CS )) << endl; ! cout() << "ebx " << GetRegisterValue(register_id(EBX)) << " "; ! cout() << "edi " << GetRegisterValue(register_id(EDI)) << " "; ! cout() << "ss " << GetRegisterValue(register_id(SS )) << endl; ! cout() << "ecx " << GetRegisterValue(register_id(ECX)) << " "; ! cout() << "ebp " << GetRegisterValue(register_id(EBP)) << endl; ! cout() << "edx " << GetRegisterValue(register_id(EDX)) << " "; ! cout() << "esp " << GetRegisterValue(register_id(ESP)) << " "; ! cout() << "eflags " << GetRegisterValue(register_id(EFLAGS)) << endl << endl; ! } ! ! void exception::SetRegisterValue(register_id reg, uint value) ! { ! if(reg > 10 && !error_code) ! reg = register_id(reg + 1); ! ! stack_pointer[reg] = value; ! } ! ! uint exception::GetRegisterValue(register_id reg) ! { ! if(reg > 10 && !error_code) ! reg = register_id(reg + 1); ! ! return stack_pointer[reg]; ! } ! ! void exception::ChangeReturnAddress(ushort selector, uint offset) ! { ! SetRegisterValue(register_id(CS), selector); ! SetRegisterValue(register_id(EIP), offset); ! } ! ! void exception::ChangeStackAddress(ushort selector, uint offset) ! { ! SetRegisterValue(register_id(SS), selector); ! SetRegisterValue(register_id(ESP), offset); } --- 63,77 ---- void exception::PrintAllRegisters() { ! cout() << "eax " << general_regs->eax << " "; ! cout() << "esi " << general_regs->esi << " "; ! cout() << "cs " << segment_regs->cs << endl; ! cout() << "ebx " << general_regs->ebx << " "; ! cout() << "edi " << general_regs->edi << " "; ! cout() << "ss " << segment_regs->ss << endl; ! cout() << "ecx " << general_regs->ecx << " "; ! cout() << "ebp " << general_regs->ebp << endl; ! cout() << "edx " << general_regs->edx << " "; ! cout() << "esp " << segment_regs->esp << " "; ! cout() << "eflags " << segment_regs->eflags << endl << endl; } *************** *** 121,130 **** while(true); } exception_number = interrupt_number; ! error_code = error_code_map[exception_number]; ! stack_pointer = esp; ! handler_running = true; } --- 93,109 ---- while(true); } + handler_running = true; exception_number = interrupt_number; ! error_code = 0; ! general_regs = reinterpret_cast<general_registers*>(&esp[0]); ! segment_regs = reinterpret_cast<segment_registers*>(&esp[8]); ! ! if(error_code_map[exception_number]) ! { ! error_code = esp[8]; ! segment_regs = reinterpret_cast<segment_registers*>(&esp[9]); ! } } *************** *** 140,145 **** PrintAllRegisters(); ! SetRegisterValue(register_id(EDX), 0); ! SetRegisterValue(register_id(EDI), 0x2BADB002); } --- 119,124 ---- PrintAllRegisters(); ! // general_regs->edx = 0; ! // general_regs->edi = 0x2BADB002; } *************** *** 154,158 **** void exception::ReservedInterrupt(hal_object* hal) { ! cout() << endl << "Panic: An unknown exception was reported ("; cout() << exception_number << ")" << endl; --- 133,137 ---- void exception::ReservedInterrupt(hal_object* hal) { ! cout() << endl << "Panic: An unknown exception was reported ("; cout() << exception_number << ")" << endl; Index: apic_io.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/apic_io.hpp,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** apic_io.hpp 30 Apr 2006 19:21:33 -0000 1.5 --- apic_io.hpp 22 May 2006 15:18:48 -0000 1.6 *************** *** 62,66 **** ExtInt = 7 ! } mode : 3; bool dest_logical : 1; bool pending : 1; --- 62,66 ---- ExtInt = 7 ! } delivery : 3; bool dest_logical : 1; bool pending : 1; Index: apic_local.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/apic_local.cpp,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** apic_local.cpp 30 Apr 2006 19:21:33 -0000 1.5 --- apic_local.cpp 22 May 2006 15:18:48 -0000 1.6 *************** *** 39,42 **** --- 39,43 ---- #include "apic_local.hpp" + #include "../loader/heap_manager.hpp" #include "mmu.hpp" *************** *** 50,63 **** local_apic::local_apic() { ! // Check if the processor has a local APIC if(!info().GetProcessorInfo().apic_available) { ! // cout() << "Panic: No local APIC detected" << endl; - only uncomment if exception in main.cpp is disabled while(true); } - // Make sure that its also hardware enabled - info().ModifyLoMSR(0x1B, ~0x800, 0x800); - // Get the local APIC's base address from the MSR uint address = info().ReadLoMSR(0x1B) &0xFFFFF000; --- 51,67 ---- local_apic::local_apic() { ! if(boot_hal->lapic != 0) ! return; ! ! // Make sure that the local APIC is hardware enabled ! info().ModifyLoMSR(0x1B, ~0x800, 0x800); ! ! // Check if it's (now) reported by CPUID if(!info().GetProcessorInfo().apic_available) { ! cout() << "Your system doesn't meet the minimum requirements (local APIC)" << endl; while(true); } // Get the local APIC's base address from the MSR uint address = info().ReadLoMSR(0x1B) &0xFFFFF000; *************** *** 71,77 **** WriteRegister(lapic_reg(DFR), 0xffffffff); SetLogicalID(1 << GetPhysicalID()); } ! uchar local_apic::GetPhysicalID(void) { return (ReadRegister(lapic_reg(ID)) >> 24) &0x0f; --- 75,83 ---- WriteRegister(lapic_reg(DFR), 0xffffffff); SetLogicalID(1 << GetPhysicalID()); + + SetPriority(0x00); } ! uchar local_apic::GetPhysicalID() { return (ReadRegister(lapic_reg(ID)) >> 24) &0x0f; *************** *** 83,92 **** } ! uchar local_apic::GetVersion(void) ! { ! return ReadRegister(lapic_reg(VERSION)) &0xff; ! } ! ! uchar local_apic::GetLogicalID(void) { return ReadRegister(lapic_reg(LDR)) >> 24; --- 89,93 ---- } ! uchar local_apic::GetLogicalID() { return ReadRegister(lapic_reg(LDR)) >> 24; *************** *** 98,140 **** } ! void local_apic::EnableApic(void) ! { ! WriteRegister(lapic_reg(SIVR), ReadRegister(lapic_reg(SIVR)) | 0x00000100); ! } ! ! void local_apic::DisableApic(void) ! { ! WriteRegister(lapic_reg(SIVR), ReadRegister(lapic_reg(SIVR)) & 0xfffffeff); ! } ! ! /* ! void local_apic::SetErrorVector(unsigned char vector) { ! base[REG_LVTERR] = (base[REG_LVTERR] & 0xffffff00) | vector; } ! void local_apic::MaskError(void) { ! base[REG_LVTERR] |= LVT_MASKED; } ! void local_apic::UnmaskError(void) { ! base[REG_LVTERR] &= ~LVT_MASKED; } ! const int local_apic::ErrorPending(void) { ! return(base[REG_LVTERR] & INT_PENDING); } ! const unsigned int local_apic::GetErrorStatus(void) { ! return(base[REG_ESR]); } ! void local_apic::ClearError(void) { ! WriteRegister(lapic_reg(ESR), 0); } - */ --- 99,129 ---- } ! uchar local_apic::GetVersion() { ! return ReadRegister(lapic_reg(VERSION)) &0xff; } ! uchar local_apic::GetMaxLVT() { ! return (ReadRegister(lapic_reg(VERSION)) << 16) &0xff; } ! void local_apic::SetPriority(uchar priority) { ! WriteRegister(lapic_reg(TPR), priority); } ! void local_apic::EnableApic() { ! WriteRegister(lapic_reg(SIVR), ReadRegister(lapic_reg(SIVR)) | 0x00000100); } ! void local_apic::DisableApic() { ! WriteRegister(lapic_reg(SIVR), ReadRegister(lapic_reg(SIVR)) & 0xfffffeff); } ! void local_apic::SignalEOI() { ! WriteRegister(lapic_reg(EOI), 0); } Index: interrupt.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/interrupt.cpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** interrupt.cpp 7 Apr 2006 17:15:53 -0000 1.2 --- interrupt.cpp 22 May 2006 15:18:49 -0000 1.3 *************** *** 48,52 **** bool interrupt::AddHandler(uint number, bool ignore, interrupt* p_class, method handler, bool error, bool trap) { ! if(number + 1 > boot_hal->int_vec->GetNumberEntries()) return false; --- 48,52 ---- bool interrupt::AddHandler(uint number, bool ignore, interrupt* p_class, method handler, bool error, bool trap) { ! if(number + 1 > boot_hal->vector->GetNumberEntries()) return false; *************** *** 67,74 **** flat flat_destructor = (flat)(p_class->*destructor); ! for(uint i=0; i < boot_hal->int_vec->GetNumberEntries(); i++) { // Seach the IDT for an appropriate interrupt stub ! void* current = boot_hal->int_vec->GetTableEntry(i); if(current != 0) --- 67,74 ---- flat flat_destructor = (flat)(p_class->*destructor); ! for(uint i=0; i < boot_hal->vector->GetNumberEntries(); i++) { // Seach the IDT for an appropriate interrupt stub ! void* current = boot_hal->vector->GetTableEntry(i); if(current != 0) *************** *** 76,80 **** interrupt_stub stub(current); ! if(stub.GetHandlerFunction() == flat_handler && stub.GetHandlerObject() == p_class && stub.GetHalObject() == boot_hal && stub.GetErrorCode() == error) { --- 76,80 ---- interrupt_stub stub(current); ! if(stub.GetHandlerFunction() == flat_handler && stub.GetHandlerObject() == p_class && stub.GetHalObject() == boot_hal && stub.GetErrorCode() == error) { *************** *** 82,86 **** { // Use the already existing interrupt stub (sharing saves memory) ! boot_hal->int_vec->SetTableEntry(number, stub.GetStubAddress(), trap); return true; } --- 82,86 ---- { // Use the already existing interrupt stub (sharing saves memory) ! boot_hal->vector->SetTableEntry(number, stub.GetStubAddress(), trap); return true; } *************** *** 97,101 **** stub->SetErrorCode(error); ! boot_hal->int_vec->SetTableEntry(number, stub->GetStubAddress(), trap); return true; } --- 97,101 ---- stub->SetErrorCode(error); ! boot_hal->vector->SetTableEntry(number, stub->GetStubAddress(), trap); return true; } *************** *** 103,107 **** bool interrupt::RemoveHandler(uint number) { ! boot_hal->int_vec->SetTableEntry(number, 0, false); // Marks entry as unused return true; } --- 103,107 ---- bool interrupt::RemoveHandler(uint number) { ! boot_hal->vector->SetTableEntry(number, 0, false); // Marks entry as unused return true; } *************** *** 118,124 **** while(true); } - - void interrupt::SignalEOI() - { - WriteRegister(lapic_reg(EOI), 0); - } --- 118,119 ---- Index: interrupt.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/interrupt.hpp,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** interrupt.hpp 7 Apr 2006 17:15:53 -0000 1.2 --- interrupt.hpp 22 May 2006 15:18:49 -0000 1.3 *************** *** 45,49 **** #include "apic_local.hpp" ! class interrupt : local_apic { private: --- 45,49 ---- #include "apic_local.hpp" ! class interrupt : public local_apic { private: *************** *** 56,63 **** virtual bool AddHandler(uint number, bool ignore, interrupt* p_class, method handler, bool error, bool trap); virtual bool RemoveHandler(uint number); - - void SignalEOI(); }; #endif --- 56,78 ---- virtual bool AddHandler(uint number, bool ignore, interrupt* p_class, method handler, bool error, bool trap); virtual bool RemoveHandler(uint number); }; + // [ Interrupt Map ] + // + // 240 to 255 <16>: APIC errors, spurious interrupts, etc + // 224 to 239 <16>: Local vectors (apic timer, thermal sensor, etc) + // 160 to 223 <64>: Harware IRQs + // .... + // 000 to 031 <32>: Exceptions + // + // priority = vector_number/16, numerical higher -> more important + // + // - For interrupts that have the same interrupt-priority level, + // the highest vector number wins + // - Exceptions aren't delivered by the local apic, hardcoded vectors + // don't imply a certain priority + // - Hardware IRQs are mapped upside down (IRQ0 = 255, IRQ1 = 254, etc) + // to enforce the intended priorities + #endif Index: idt.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/idt.cpp,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** idt.cpp 5 Apr 2006 17:12:00 -0000 1.3 --- idt.cpp 22 May 2006 15:18:49 -0000 1.4 *************** *** 69,76 **** uchar attributes = (trap_gate) ? 0x6F : 0x6E; ! if(stub != 0) ! { ! attributes |= 0x80; // Set the present flag ! } idt_pointer[interrupt_number*2 + 0] = (reinterpret_cast<uint>(stub) &0x0000FFFF) | (0x08 << 16); --- 69,73 ---- uchar attributes = (trap_gate) ? 0x6F : 0x6E; ! if(stub != 0) attributes |= 0x80; // Set the present flag idt_pointer[interrupt_number*2 + 0] = (reinterpret_cast<uint>(stub) &0x0000FFFF) | (0x08 << 16); Index: apic_local.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/apic_local.hpp,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** apic_local.hpp 30 Apr 2006 19:21:34 -0000 1.5 --- apic_local.hpp 22 May 2006 15:18:48 -0000 1.6 *************** *** 52,57 **** struct lapic_lvt { ! uchar vector : 8; ! enum { fixed = 0, --- 52,57 ---- struct lapic_lvt { ! uchar vector : 8; ! enum delivery_mode { fixed = 0, *************** *** 61,73 **** ExtInt = 7 ! } delivery_mode : 3; ! bool : 1; ! bool pending : 1; ! bool pin_polarity : 1; ! bool remote_irr : 1; ! bool level : 1; ! bool masked : 1; ! bool periodic : 1; ! uint : 14; }; --- 61,73 ---- ExtInt = 7 ! } delivery : 3; ! bool : 1; ! bool pending : 1; ! bool pin_polarity : 1; ! bool remote_irr : 1; ! bool level : 1; ! bool masked : 1; ! bool periodic : 1; ! uint : 14; }; *************** *** 126,130 **** VERSION = 0x0030/4, /**< Local APIC version */ TPR = 0x0080/4, /**< Task priority register */ ! AOR = 0x0090/4, /**< Arbitration priority register */ PPR = 0x00a0/4, /**< Processor priority register */ --- 126,130 ---- VERSION = 0x0030/4, /**< Local APIC version */ TPR = 0x0080/4, /**< Task priority register */ ! APR = 0x0090/4, /**< Arbitration priority register */ PPR = 0x00a0/4, /**< Processor priority register */ *************** *** 154,161 **** inline void WriteRegister(lapic_reg reg, uint data) { base[reg] = data; } ! inline uint ReadRegister(lapic_reg reg) { return base[reg]; } inline void SetLVT(lapic_reg reg, lapic_lvt lvt) { *(reinterpret_cast<lapic_lvt*>(&base[reg])) = lvt; } ! inline void SetESR(lapic_esr esr) { *(reinterpret_cast<lapic_esr*>(&base[lapic_reg(ESR)])) = esr; } inline void SetICR(lapic_icr icr) { *(reinterpret_cast<lapic_icr*>(&base[lapic_reg(ICR0)])) = icr; } --- 154,161 ---- inline void WriteRegister(lapic_reg reg, uint data) { base[reg] = data; } ! inline uint ReadRegister (lapic_reg reg) { return base[reg]; } inline void SetLVT(lapic_reg reg, lapic_lvt lvt) { *(reinterpret_cast<lapic_lvt*>(&base[reg])) = lvt; } ! inline void SetESR(lapic_esr esr) { *(reinterpret_cast<lapic_esr*>(&base[lapic_reg(ESR)])) = esr; } inline void SetICR(lapic_icr icr) { *(reinterpret_cast<lapic_icr*>(&base[lapic_reg(ICR0)])) = icr; } *************** *** 165,180 **** public: ! local_apic(void); ! uchar GetPhysicalID(void); void SetPhysicalID(uchar id); ! uchar GetLogicalID(void); void SetLogicalID(uchar id); ! uchar GetVersion(void); ! void EnableApic(void); ! void DisableApic(void); }; --- 165,186 ---- public: ! local_apic(); ! uchar GetPhysicalID(); void SetPhysicalID(uchar id); ! uchar GetLogicalID(); void SetLogicalID(uchar id); ! uchar GetVersion(); ! uchar GetMaxLVT(); ! // protected: ! void SetPriority(uchar priority); ! ! void EnableApic(); ! void DisableApic(); ! ! void SignalEOI(); }; Index: mutex.cpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/mutex.cpp,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** mutex.cpp 5 Apr 2006 17:12:00 -0000 1.4 --- mutex.cpp 22 May 2006 15:18:49 -0000 1.5 *************** *** 51,59 **** void mutex::EnterMutex(void) { ! asm volatile ("start: \n" ! "cli \n" "lock btsl $0, %[key] \n" "jnc ready \n" - /*"sti \n"*/ "jmp start \n" "ready:" : : [key] "m" (key)); --- 51,58 ---- void mutex::EnterMutex(void) { ! asm("start: \n" "lock btsl $0, %[key] \n" + "pause \n" // Replace me with a more fancy MONITOR/MWAIT algorithm.. "jnc ready \n" "jmp start \n" "ready:" : : [key] "m" (key)); *************** *** 62,66 **** void mutex::ExitMutex(void) { ! asm volatile ("movl $0, %[key] \n" ! /*"sti"*/ : : [key] "m" (key)); } --- 61,64 ---- void mutex::ExitMutex(void) { ! asm("movl $0, %[key] \n" : : [key] "m" (key)); } Index: mutex.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/mutex.hpp,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** mutex.hpp 5 Apr 2006 17:12:00 -0000 1.4 --- mutex.hpp 22 May 2006 15:18:49 -0000 1.5 *************** *** 43,55 **** class mutex { ! private: ! volatile unsigned long key; ! public: ! mutex(void); ! ~mutex(void); ! void EnterMutex(void); ! void ExitMutex(void); }; --- 43,55 ---- class mutex { ! private: ! volatile unsigned long key; ! public: ! mutex(void); ! ~mutex(void); ! void EnterMutex(void); ! void ExitMutex(void); }; Index: irq.hpp =================================================================== RCS file: /cvsroot/trion/trion v0.2/hal/irq.hpp,v retrieving revision 1.5 retrieving revision 1.6 diff -C2 -d -r1.5 -r1.6 *** irq.hpp 13 Apr 2006 20:00:51 -0000 1.5 --- irq.hpp 22 May 2006 15:18:49 -0000 1.6 *************** *** 41,71 **** #define __HAL__IRQ_LOGIC__ - //#include <task.hpp> #include "../object/std_types.hpp" #include "../loader/mp_detect.hpp" #include "interrupt.hpp" #include "apic_io.hpp" ! class irq_logic : public interrupt { ! private: ! // static htask dispatch_table[16][10]; ! uint irq_number; ! uint* stack_pointer; ! bool handler_running; static const uint ISA = 0x49534120; static const uint PCI = 0x50434920; ! io_apic** apic_table; ! void DisableLegacyPIC(); ! uint DetectSystemBuses(uint* bus_table); ! io_apic* InitializeIOApic(iterator it, uint* bus_table); void InterruptConstructor(hal_object* hal, uchar interrupt_number, uint* esp); void InterruptDestructor (hal_object* hal, uchar interrupt_number, uint* esp); public: irq_logic(); --- 41,89 ---- #define __HAL__IRQ_LOGIC__ #include "../object/std_types.hpp" #include "../loader/mp_detect.hpp" #include "interrupt.hpp" #include "apic_io.hpp" + #include "mutex.hpp" ! #include "exception.hpp" // register structures are defined there for the moment.. ! ! struct irq_data { ! segment_registers* segment_regs; ! general_registers* general_regs; ! uint irq_number; ! ! irq_data* next; ! }; + struct irq_dev + { + bool legacy_pic; + uint number_irqs, device_id; + + io_apic* apic; + }; + + class irq_logic : public interrupt, public mutex + { + private: static const uint ISA = 0x49534120; static const uint PCI = 0x50434920; ! irq_data* instance; ! irq_dev* device_table; ! void InitializeLegacyPIC(); ! uint DetectSystemBus(uint bus_number); ! ! irq_dev InitializeIOApic(iterator it); void InterruptConstructor(hal_object* hal, uchar interrupt_number, uint* esp); void InterruptDestructor (hal_object* hal, uchar interrupt_number, uint* esp); + void DispatchIRQ(hal_object* hal); + public: irq_logic(); *************** *** 74,79 **** void DisableIRQ(uint number); ! void DispatchIRQ(hal_object* hal); }; #endif --- 92,100 ---- void DisableIRQ(uint number); ! void SignalEOI (uint number); }; + extern char irq_logic_reserved[]; + irq_logic& irq(); + #endif |