OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 2:18 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: Send IPI won't cause an interrupt
PostPosted: Wed Jun 08, 2022 5:54 am 
Offline
Member
Member

Joined: Tue Aug 17, 2021 10:40 am
Posts: 104
Location: CN
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

_________________
My github: https://github.com/nifanfa


Last edited by nifanfa on Wed Jun 08, 2022 5:57 am, edited 1 time in total.

Top
 Profile  
 
 Post subject: Re: Send IPI won't cause an interrupt
PostPosted: Wed Jun 08, 2022 5:56 am 
Offline
Member
Member

Joined: Tue Aug 17, 2021 10:40 am
Posts: 104
Location: CN
apic_id 1 is core 1. and it is valid

_________________
My github: https://github.com/nifanfa


Top
 Profile  
 
 Post subject: Re: Send IPI won't cause an interrupt
PostPosted: Wed Jun 08, 2022 10:23 am 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
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?


Top
 Profile  
 
 Post subject: Re: Send IPI won't cause an interrupt
PostPosted: Wed Jun 08, 2022 11:16 am 
Offline
Member
Member

Joined: Tue Aug 17, 2021 10:40 am
Posts: 104
Location: CN
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

_________________
My github: https://github.com/nifanfa


Top
 Profile  
 
 Post subject: Re: Send IPI won't cause an interrupt
PostPosted: Wed Jun 08, 2022 11:32 am 
Offline
Member
Member

Joined: Tue Aug 17, 2021 10:40 am
Posts: 104
Location: CN
Code:
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) ;
        }
    }
}

_________________
My github: https://github.com/nifanfa


Top
 Profile  
 
 Post subject: Re: Send IPI won't cause an interrupt
PostPosted: Wed Jun 08, 2022 11:32 am 
Offline
Member
Member

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

_________________
My github: https://github.com/nifanfa


Top
 Profile  
 
 Post subject: Re: Send IPI won't cause an interrupt
PostPosted: Wed Jun 08, 2022 11:27 pm 
Offline
Member
Member

Joined: Tue Aug 17, 2021 10:40 am
Posts: 104
Location: CN
Nvm. problem resolved.

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

_________________
My github: https://github.com/nifanfa


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 59 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group