Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement APIC #2288

Open
wants to merge 47 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
8ea9ca8
Update ACPI parsing
valentinbreiz Jun 10, 2022
c2feeee
Parse local APIC + Add Local APIC class
valentinbreiz Jun 10, 2022
8b021bd
Add local APIC timer
valentinbreiz Jun 10, 2022
ebb4439
Rename APIC file + Add disable PIC method
valentinbreiz Jun 10, 2022
b62855e
Add IO APIC
valentinbreiz Jun 10, 2022
c39a897
Move from PIC to APIC
valentinbreiz Jun 11, 2022
438421a
ACPI parse fix + IOAPIC fix + Add MMIO class
valentinbreiz Jun 11, 2022
dcc7815
Boot fix
valentinbreiz Jun 11, 2022
f8750c5
Fix SetEntry
valentinbreiz Jun 11, 2022
59ce89f
Remove APICTimer for now + move APIC to MemoryGroup
valentinbreiz Jun 11, 2022
b77b01f
Fix build
valentinbreiz Jun 11, 2022
3271625
Update MMIO class + Update IO APIC + Remove IO APIC MMIO Group
valentinbreiz Jun 12, 2022
a776f78
Delete Local APIC MMIO Group + Update Local APIC
valentinbreiz Jun 12, 2022
1667b3b
Remove PIC init since it's already done in CosmosAssembler + Better b…
valentinbreiz Jun 12, 2022
09ba3be
Remove useless EOI + Useless PIT timer
valentinbreiz Jun 12, 2022
d75016d
Change PIT from IRQ0 to IRQ2 + Set APIC Timer to IRQ0
valentinbreiz Jun 12, 2022
882f516
Add Local APIC ID in SetEntry
valentinbreiz Jun 12, 2022
d810ce4
Merge branch 'master' into feature/apic
MishaTy Jun 12, 2022
965f3ed
Fix IRQ conflict between PIT and ATAPI
valentinbreiz Jun 12, 2022
562a314
Fix IRQ conflict between PIT and PS/2 Mouse 🤡
valentinbreiz Jun 12, 2022
2e66c2e
Add MSI detection to PCI device + Fix PIT again (forgot to commit fil…
valentinbreiz Jun 13, 2022
cc48ad2
implement reboot [broken]
MishaTy Jun 13, 2022
dec48ec
Merge branch 'master' into feature/apic
MishaTy Jun 13, 2022
2322aea
Move ACPI + Add AML Parser + DSDT Header
valentinbreiz Jun 13, 2022
96c1291
Add plug for InitOrdinalCasingPage + Parse AML + Get Opcode name (ref…
valentinbreiz Jun 13, 2022
0f73e24
Parse IRQ Routing Tables using AML + Hardparse S5
valentinbreiz Jun 15, 2022
410fa5e
Put IRQ routing in list
valentinbreiz Jun 15, 2022
ba8b53f
Add multi CPU detection + Comment AMDPCNETII IRQ Init
valentinbreiz Jun 15, 2022
9eb6e10
Merge branch 'master' into feature/apic
valentinbreiz Jun 18, 2022
fce9907
"Fix" IRQ routing for PCI devices
valentinbreiz Jun 19, 2022
0dadc0b
Update comment
valentinbreiz Jun 19, 2022
78d9068
Update ACPILib with last @MishaTY changes
valentinbreiz Jun 19, 2022
5e613bc
Remove AML parser for now
valentinbreiz Jun 19, 2022
f784f02
Merge branch 'master' into feature/apic
valentinbreiz Jun 20, 2022
7ad7ea6
Merge branch 'master' into feature/apic
MishaTy Jun 23, 2022
350ad86
Merge branch 'master' into feature/apic
MishaTy Jul 2, 2022
5a3ce4c
Merge branch 'master' into feature/apic
valentinbreiz Jul 16, 2022
e9175bf
Merge branch 'master' into feature/apic
valentinbreiz Sep 28, 2022
fc6c627
Merge branch 'master' into feature/apic
valentinbreiz Oct 24, 2022
3ab0253
ACPI Fixes + Hardcode IO APIC / Local APIC addresses if no ACPI detected
valentinbreiz Oct 24, 2022
ebd674b
Merge branch 'master' into feature/apic
valentinbreiz Jan 2, 2023
61b4411
Fix change to static IO Ports
quajak Jan 5, 2023
ac4b2de
Merge branch 'master' into feature/apic
MishaTy Jan 22, 2023
8f9976a
Merge branch 'master' into feature/apic
valentinbreiz Dec 26, 2023
84d8564
🐛 Fix conflicts
valentinbreiz Dec 26, 2023
757da7b
🐛 Fix boot (NRE on PS/2 keyboard)
valentinbreiz Dec 26, 2023
bda39ef
🐛 Fix IRQ handling
valentinbreiz Dec 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
877 changes: 644 additions & 233 deletions source/Cosmos.Core/ACPI.cs

Large diffs are not rendered by default.

52 changes: 27 additions & 25 deletions source/Cosmos.Core/INTs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ public static void SetIRQMaskState(byte aIRQLine, bool aDoMask)
/// <param name="aIrqNo">IRQ index.</param>
/// <param name="aHandler">IRQ handler.</param>
public static void SetIrqHandler(byte aIrqNo, IRQDelegate aHandler) {
IOAPIC.SetEntry((uint)aIrqNo + 0x20);
SetIntHandler((byte)(0x20 + aIrqNo), aHandler);
}

Expand All @@ -303,13 +304,7 @@ public static void SetIRQMaskState(byte aIRQLine, bool aDoMask)
/// </summary>
/// <param name="aContext">A IEQ context.</param>
public static void HandleInterrupt_Default(ref IRQContext aContext) {
if (aContext.Interrupt >= 0x20 && aContext.Interrupt <= 0x2F) {
if (aContext.Interrupt >= 0x28) {
Global.PIC.EoiSlave();
} else {
Global.PIC.EoiMaster();
}
}
LocalAPIC.EndOfInterrupt();
}

/// <summary>
Expand All @@ -327,12 +322,12 @@ public static void SetIRQMaskState(byte aIRQLine, bool aDoMask)
#region Default Interrupt Handlers

/// <summary>
/// IRQ 0 - System timer. Reserved for the system. Cannot be changed by a user.
/// IRQ 0 - System (APIC) timer. Reserved for the system. Cannot be changed by a user.
/// </summary>
/// <param name="aContext">IRQ context.</param>
public static void HandleInterrupt_20(ref IRQContext aContext) {
IRQ(0x20, ref aContext);
Global.PIC.EoiMaster();
LocalAPIC.EndOfInterrupt();
}

//public static IRQDelegate IRQ01;
Expand All @@ -343,43 +338,43 @@ public static void SetIRQMaskState(byte aIRQLine, bool aDoMask)
public static void HandleInterrupt_21(ref IRQContext aContext) {

IRQ(0x21, ref aContext);
Global.PIC.EoiMaster();
LocalAPIC.EndOfInterrupt();
}

public static void HandleInterrupt_22(ref IRQContext aContext) {

IRQ(0x22, ref aContext);
Global.PIC.EoiMaster();
LocalAPIC.EndOfInterrupt();
}
public static void HandleInterrupt_23(ref IRQContext aContext) {

IRQ(0x23, ref aContext);
Global.PIC.EoiMaster();
LocalAPIC.EndOfInterrupt();
}
public static void HandleInterrupt_24(ref IRQContext aContext) {

IRQ(0x24, ref aContext);
Global.PIC.EoiMaster();
LocalAPIC.EndOfInterrupt();
}
public static void HandleInterrupt_25(ref IRQContext aContext) {
IRQ(0x25, ref aContext);
Global.PIC.EoiMaster();
LocalAPIC.EndOfInterrupt();
}
public static void HandleInterrupt_26(ref IRQContext aContext) {

IRQ(0x26, ref aContext);
Global.PIC.EoiMaster();
LocalAPIC.EndOfInterrupt();
}
public static void HandleInterrupt_27(ref IRQContext aContext) {

IRQ(0x27, ref aContext);
Global.PIC.EoiMaster();
LocalAPIC.EndOfInterrupt();
}

public static void HandleInterrupt_28(ref IRQContext aContext) {

IRQ(0x28, ref aContext);
Global.PIC.EoiSlave();
LocalAPIC.EndOfInterrupt();
}

/// <summary>
Expand All @@ -388,7 +383,7 @@ public static void SetIRQMaskState(byte aIRQLine, bool aDoMask)
/// <param name="aContext">IRQ context.</param>
public static void HandleInterrupt_29(ref IRQContext aContext) {
IRQ(0x29, ref aContext);
Global.PIC.EoiSlave();
LocalAPIC.EndOfInterrupt();
}

/// <summary>
Expand All @@ -397,7 +392,7 @@ public static void SetIRQMaskState(byte aIRQLine, bool aDoMask)
/// <param name="aContext">IRQ context.</param>
public static void HandleInterrupt_2A(ref IRQContext aContext) {
IRQ(0x2A, ref aContext);
Global.PIC.EoiSlave();
LocalAPIC.EndOfInterrupt();
}

/// <summary>
Expand All @@ -406,19 +401,26 @@ public static void SetIRQMaskState(byte aIRQLine, bool aDoMask)
/// <param name="aContext">IRQ context.</param>
public static void HandleInterrupt_2B(ref IRQContext aContext) {
IRQ(0x2B, ref aContext);
Global.PIC.EoiSlave();
LocalAPIC.EndOfInterrupt();
}

/// <summary>
/// IRQ 12 - PS/2 Mouse. Reserved for the system.
/// </summary>
/// <param name="aContext">IRQ context.</param>
public static void HandleInterrupt_2C(ref IRQContext aContext) {

IRQ(0x2C, ref aContext);
Global.PIC.EoiSlave();
LocalAPIC.EndOfInterrupt();
}


/// <summary>
/// IRQ 13 - (Added for PIT Timer).
/// </summary>
/// <param name="aContext">IRQ context.</param>
public static void HandleInterrupt_2D(ref IRQContext aContext) {
IRQ(0x2D, ref aContext);
Global.PIC.EoiSlave();
LocalAPIC.EndOfInterrupt();
}

/// <summary>
Expand All @@ -427,7 +429,7 @@ public static void SetIRQMaskState(byte aIRQLine, bool aDoMask)
/// <param name="aContext">IRQ context.</param>
public static void HandleInterrupt_2E(ref IRQContext aContext) {
IRQ(0x2E, ref aContext);
Global.PIC.EoiSlave();
LocalAPIC.EndOfInterrupt();
}

/// <summary>
Expand All @@ -436,7 +438,7 @@ public static void SetIRQMaskState(byte aIRQLine, bool aDoMask)
/// <param name="aContext">IRQ context.</param>
public static void HandleInterrupt_2F(ref IRQContext aContext) {
IRQ(0x2F, ref aContext);
Global.PIC.EoiSlave();
LocalAPIC.EndOfInterrupt();
}

public static event IRQDelegate Interrupt30;
Expand Down
110 changes: 110 additions & 0 deletions source/Cosmos.Core/IOAPIC.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Cosmos.Core.MemoryGroup;

namespace Cosmos.Core
{
/// <summary>
/// Local APIC class.
/// </summary>
public unsafe partial class IOAPIC
{
public const byte IOREGSEL = 0x00;
public const byte IOWIN = 0x10;

//IO APIC Registers
public const byte IOAPICID = 0x00;
public const byte IOAPICVER = 0x01;
public const byte IOAPICARB = 0x02;
public const byte IOREDTBL = 0x10;

/// <summary>
/// IO APIC Base Address.
/// </summary>
private static uint Address = 0;

/// <summary>
/// Initialize local APIC.
/// </summary>
public static void Initialize()
{
if (ACPI.IOAPIC == null)
{
//TODO: Fix ACPI tables on Bochs
//No APIC detected, hardcode APIC address
Address = 0xFEC00000;
}
else
{
Address = ACPI.IOAPIC->IOApicAddress;
}

Global.debugger.Send("IO APIC address:0x" + Address.ToString("X"));

uint x = In(IOAPICVER);
uint count = ((x >> 16) & 0xFF) + 1;

Global.debugger.Send("IO APIC pins:" + count);

//Disable All Entries, Make all interrupts edge triggered and not routed to any CPUs
for (uint i = 0; i < count; ++i)
{
SetEntry((byte)i, (1 << 16) | 0x20 + i);
}

Global.debugger.Send("IO APIC " + GetId() + " Initialized");
}

/// <summary>
/// IO APIC MMIO Out.
/// </summary>
/// <param name="reg">IO APIC Register.</param>
/// <param name="val">Data.</param>
public static void Out(byte reg, uint val)
{
MMIOBase.Write32(Address + IOREGSEL, reg);
MMIOBase.Write32(Address + IOWIN, val);
}

/// <summary>
/// IO APIC MMIO In.
/// </summary>
/// <param name="reg">IO APIC Register.</param>
public static uint In(byte reg)
{
MMIOBase.Write32(Address + IOREGSEL, reg);
return MMIOBase.Read32(Address + IOWIN);
}

/// <summary>
/// Set IO APIC Entry.
/// </summary>
/// <param name="data">Irq ID.</param>
public static void SetEntry(uint irq)
{
SetEntry((byte)ACPI.RemapIRQ(irq - 0x20), irq);
}

/// <summary>
/// Set IO APIC Entry.
/// </summary>
/// <param name="data">Irq ID.</param>
public static void SetEntry(byte index, ulong data)
{
Out((byte)(IOREDTBL + index * 2), (uint)data);
Out((byte)(IOREDTBL + index * 2 + 1), (uint)(data >> 32));
}

/// <summary>
/// Get IO APIC ID.
/// </summary>
/// <returns>byte value.</returns>
public static byte GetId()
{
return (byte)((In(IOAPICID) >> 24) & 0xF0);
}
}
}