示例#1
0
        /// <summary>
        /// Parses the MADT
        /// </summary>
        /// <param name="madt">The MADT</param>
        private static void parseMADT(MADT *madt)
        {
            m_madt = madt;
            LocalApic.SetLocalControllerAddress(madt->LocalControllerAddress);

            m_intSourceOverrides = new ISAOverride[16];
            for (uint i = 0; i < 16; i++)
            {
                m_intSourceOverrides[i].GSI      = i;
                m_intSourceOverrides[i].Polarity = IOApic.IOAPIC_REDIR_POLARITY_HIGH;
                m_intSourceOverrides[i].Trigger  = IOApic.IOAPIC_REDIR_TRIGGER_EDGE;
            }

            // After the flags field, the rest of the table contains a variable length of records
            uint current = (uint)madt + (uint)sizeof(MADT);
            uint end     = current + madt->Header.Length - (uint)sizeof(MADT);

            while (current < end)
            {
                ApicEntryHeader *   header = (ApicEntryHeader *)current;
                ApicEntryHeaderType type   = (ApicEntryHeaderType)header->Type;

                switch (type)
                {
                case ApicEntryHeaderType.LOCAL_APIC:
                    ApicLocalApic *localAPIC = (ApicLocalApic *)(current + sizeof(ApicEntryHeader));
                    Console.Write("[ACPI] Found CPU ");
                    Console.WriteNum(localAPIC->ProcessorID);
                    Console.Write('\n');
                    break;

                case ApicEntryHeaderType.IO_APIC:
                    ApicIOApic *IOApicStruct = (ApicIOApic *)(current + sizeof(ApicEntryHeader));

                    Console.Write("[ACPI] Found IO APIC at ");
                    Console.WriteHex(IOApicStruct->IOAPICAddress);
                    Console.Write('\n');

                    IOApic IOApic = new IOApic(IOApicStruct->IOAPIC_ID, (void *)IOApicStruct->IOAPICAddress, IOApicStruct->GlobalSystemInterruptBase);
                    IOApicManager.Add(IOApic);

                    break;

                case ApicEntryHeaderType.INTERRUPT_SOURCE_OVERRIDE:
                    ApicInterruptSourceOverride *intSourceOverride = (ApicInterruptSourceOverride *)(current + sizeof(ApicEntryHeader));

                    m_intSourceOverrides[intSourceOverride->IRQSource].GSI      = intSourceOverride->GlobalSystemInterrupt;
                    m_intSourceOverrides[intSourceOverride->IRQSource].Polarity = (uint)(intSourceOverride->Flags & 0x3);
                    m_intSourceOverrides[intSourceOverride->IRQSource].Trigger  = (uint)((intSourceOverride->Flags >> 2) & 0x3);

                    break;
                }

                current += header->Length;
            }
        }
示例#2
0
        /// <summary>
        /// IRQ handler
        /// </summary>
        /// <param name="regsPtr">Pointer to registers</param>
        public static unsafe void Handler(Regs *regsPtr)
        {
            int irqNum = regsPtr->IntNum;

            if (handlers[irqNum] != null)
            {
                // Loop through handlers to see who has sent interrupt
                for (int i = 0; i < IRQ_MAX_SHARING; i++)
                {
                    if (handlers[irqNum][i] == null || handlers[irqNum][i]())
                    {
                        break;
                    }
                }
            }

            LocalApic.SendEOI();
        }