Send IPI won't cause an interrupt

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
nifanfa
Member
Member
Posts: 104
Joined: Tue Aug 17, 2021 10:40 am
Libera.chat IRC: visitor
Location: CN
Contact:

Send IPI won't cause an interrupt

Post by nifanfa »

Hi! and Here is my code. But no matter what vector i send to apic_id 1 it still won't get any interrupt. but the IDT is working. i can devide zero to get isr0
https://github.com/nifanfa/MOOS/blob/6c ... IC.cs#L109
https://github.com/nifanfa/MOOS/blob/6c ... SMP.cs#L42
Last edited by nifanfa on Wed Jun 08, 2022 5:57 am, edited 1 time in total.
nifanfa
Member
Member
Posts: 104
Joined: Tue Aug 17, 2021 10:40 am
Libera.chat IRC: visitor
Location: CN
Contact:

Re: Send IPI won't cause an interrupt

Post by nifanfa »

apic_id 1 is core 1. and it is valid
Octocontrabass
Member
Member
Posts: 5563
Joined: Mon Mar 25, 2013 7:01 pm

Re: Send IPI won't cause an interrupt

Post by Octocontrabass »

I think you're a little confused about how hexadecimal works.

It looks like you're using QEMU. Have you tried using the "info registers" and "info lapic" commands in QEMU's monitor to check if the AP is configured correctly?
nifanfa
Member
Member
Posts: 104
Joined: Tue Aug 17, 2021 10:40 am
Libera.chat IRC: visitor
Location: CN
Contact:

Re: Send IPI won't cause an interrupt

Post by nifanfa »

Octocontrabass wrote:I think you're a little confused about how hexadecimal works.

It looks like you're using QEMU. Have you tried using the "info registers" and "info lapic" commands in QEMU's monitor to check if the AP is configured correctly?
Hey Octocontrabass!
now it works fine on qemu. but it doesn't work on VMware or real hardware. it still confused me
nifanfa
Member
Member
Posts: 104
Joined: Tue Aug 17, 2021 10:40 am
Libera.chat IRC: visitor
Location: CN
Contact:

Re: Send IPI won't cause an interrupt

Post by nifanfa »

Code: Select all

using MOOS.Misc;

namespace MOOS.Driver
{
    public static unsafe partial class LocalAPIC
    {
        private const int LAPIC_ID = 0x0020;
        private const int LAPIC_VER = 0x0030;
        private const int LAPIC_TPR = 0x0080;
        private const int LAPIC_APR = 0x0090;
        private const int LAPIC_PPR = 0x00a0;
        private const int LAPIC_EOI = 0x00b0;
        private const int LAPIC_RRD = 0x00c0;
        private const int LAPIC_LDR = 0x00d0;
        private const int LAPIC_DFR = 0x00e0;
        private const int LAPIC_SVR = 0x00f0;
        private const int LAPIC_ISR = 0x0100;
        private const int LAPIC_TMR = 0x0180;
        private const int LAPIC_IRR = 0x0200;
        private const int LAPIC_ESR = 0x0280;
        private const int LAPIC_ICRLO = 0x0300;
        private const int LAPIC_ICRHI = 0x0310;
        private const int LAPIC_TIMER = 0x0320;
        private const int LAPIC_THERMAL = 0x0330;
        private const int LAPIC_PERF = 0x0340;
        private const int LAPIC_LINT0 = 0x0350;
        private const int LAPIC_LINT1 = 0x0360;
        private const int LAPIC_ERROR = 0x0370;
        private const int LAPIC_TICR = 0x0380;
        private const int LAPIC_TCCR = 0x0390;
        private const int LAPIC_TDCR = 0x03e0;

        private const int ICR_FIXED = 0x00000000;
        private const int ICR_LOWEST = 0x00000100;
        private const int ICR_SMI = 0x00000200;
        private const int ICR_NMI = 0x00000400;
        private const int ICR_INIT = 0x00000500;
        private const int ICR_STARTUP = 0x00000600;

        private const int ICR_PHYSICAL = 0x00000000;
        private const int ICR_LOGICAL = 0x00000800;

        private const int ICR_IDLE = 0x00000000;
        private const int ICR_SEND_PENDING = 0x00001000;

        private const int ICR_DEASSERT = 0x00000000;
        private const int ICR_ASSERT = 0x00004000;

        private const int ICR_EDGE = 0x00000000;
        private const int ICR_LEVEL = 0x00008000;

        private const int ICR_NO_SHORTHAND = 0x00000000;
        private const int ICR_SELF = 0x00040000;
        private const int ICR_ALL_INCLUDING_SELF = 0x00080000;
        private const int ICR_ALL_EXCLUDING_SELF = 0x000c0000;

        private const int ICR_DESTINATION_SHIFT = 24;

        static uint In(uint reg)
        {
            return MMIO.In32((uint*)(ACPI.MADT->LocalAPICAddress + reg));
        }

        static void Out(uint reg, uint data)
        {
            MMIO.Out32((uint*)(ACPI.MADT->LocalAPICAddress + reg), data);
        }

        public static void EndOfInterrupt()
        {
            Out((uint)LAPIC_EOI, 0);
        }

        public static void Initialize()
        {
            //Enable All Interrupts
            Out((uint)LAPIC_TPR, 0);

            // Logical Destination Mode
            Out((uint)LAPIC_DFR, 0xffffffff);   // Flat mode
            Out((uint)LAPIC_LDR, 0 << 24);   // All cpus use logical id 0

            // Configure Spurious Interrupt Vector Register
            Out((uint)LAPIC_SVR, 0x100 | 0xff);

            if(SMP.ThisCPU == 0)
                Console.WriteLine("[Local APIC] Local APIC initialized");
        }

        public static uint GetId()
        {
            return In((uint)LAPIC_ID) >> 24;
        }

        public static void SendInit(uint apic_id)
        {
            Out((uint)LAPIC_ICRHI, apic_id << ICR_DESTINATION_SHIFT);
            Out((uint)LAPIC_ICRLO, (uint)(ICR_INIT | ICR_PHYSICAL
                | ICR_ASSERT | ICR_EDGE | ICR_NO_SHORTHAND));

            while ((In((uint)LAPIC_ICRLO) & ICR_SEND_PENDING) != 0) ;
        }


        public static void SendInterrupt(uint apic_id, uint vector)
        {
            Out((uint)LAPIC_ICRHI, apic_id << ICR_DESTINATION_SHIFT);
            Out((uint)LAPIC_ICRLO, vector | (uint)ICR_FIXED | (uint)ICR_NO_SHORTHAND);

            while ((In((uint)LAPIC_ICRLO) & ICR_SEND_PENDING) != 0) ;
        }

        public static void SendStartup(uint apic_id, uint vector)
        {
            Out((uint)LAPIC_ICRHI, apic_id << ICR_DESTINATION_SHIFT);
            Out((uint)LAPIC_ICRLO, vector | (uint)ICR_STARTUP
                | (uint)ICR_PHYSICAL | (uint)ICR_ASSERT | (uint)ICR_EDGE | (uint)ICR_NO_SHORTHAND);

            while ((In((uint)LAPIC_ICRLO) & ICR_SEND_PENDING) != 0) ;
        }
    }
}
nifanfa
Member
Member
Posts: 104
Joined: Tue Aug 17, 2021 10:40 am
Libera.chat IRC: visitor
Location: CN
Contact:

Re: Send IPI won't cause an interrupt

Post by nifanfa »

Code: Select all

public static void ApplicationProcessorMain(int Core)
        {
            SSE.enable_sse();
            LocalAPIC.Initialize();
            //Console.WriteLine("Hello from Application Processor");
            for (; ; ) SMP.Take()();
        }
nifanfa
Member
Member
Posts: 104
Joined: Tue Aug 17, 2021 10:40 am
Libera.chat IRC: visitor
Location: CN
Contact:

Re: Send IPI won't cause an interrupt

Post by nifanfa »

Nvm. problem resolved.

It is because that SendIPI can't issue a exception interrupt
Post Reply