MOS Source Code
Loading...
Searching...
No Matches
madt.c
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2
3#include "mos/misc/panic.h"
4
5#include <mos/syslog/printk.h>
6#include <mos/x86/acpi/acpi.h>
8#include <mos/x86/acpi/madt.h>
10
14
15#define IOAPIC_IRQ_OVERRIDE_MAX 255 // u8 can hold up to 255
17
19{
20 if (irq >= IOAPIC_IRQ_OVERRIDE_MAX)
21 return irq;
22 return ioapic_irq_override[irq];
23}
24
26{
27 if (!x86_acpi_madt)
28 mos_panic("MADT not found");
29
31
32 for (u8 i = 0; i < IOAPIC_IRQ_OVERRIDE_MAX; i++)
33 ioapic_irq_override[i] = i; // Default: no override
34
36 {
37 switch (entry->type)
38 {
39 case 0:
40 {
42 pr_dinfo2(x86_acpi, "MADT entry LAPIC [%p], id=%u, processor=%u, flags=0x%x", (void *) lapic, lapic->apic_id, lapic->processor_id, lapic->flags);
43
44 bool enabled = lapic->flags & 1; // bit 0: processor is enabled
45 bool online_capable = lapic->flags & 2; // bit 1: online-capable
46
47 // If flags bit 0 is set the CPU is able to be enabled, if it is not set you need to check bit 1. If that one is set you can still enable it, if it is not
48 // the CPU can not be enabled and the OS should not try.
49
50 if (!enabled && !online_capable)
51 continue;
52
54 mos_panic("Too many CPUs");
55
57 break;
58 }
59 case 1:
60 {
62 pr_dinfo2(x86_acpi, "MADT entry IOAPIC [%p], id=%u, address=%x, global_irq_base=%u", (void *) ioapic, ioapic->id, ioapic->address,
63 ioapic->global_intr_base);
65 mos_panic("Multiple IOAPICs not supported");
66 x86_ioapic_phyaddr = ioapic->address;
67 x86_lapic_global_base = ioapic->global_intr_base;
68 break;
69 }
70 case 2:
71 {
73 pr_dinfo2(x86_acpi, "MADT entry IOAPIC override [%p], bus=%u, flags=0x%x, 'irq source %u is now global irq %u'", (void *) int_override,
74 int_override->bus_source, int_override->flags, int_override->irq_source, int_override->global_intr);
75
76 if (unlikely(int_override->bus_source != 0))
77 mos_panic("IOAPIC override for non-ISA bus not supported");
78
79 if (unlikely(int_override->irq_source >= IOAPIC_IRQ_OVERRIDE_MAX))
80 mos_panic("IOAPIC override for IRQ >= 255 not supported");
81
82 if (unlikely(ioapic_irq_override[int_override->irq_source] != int_override->irq_source))
83 mos_panic("Multiple IOAPIC overrides for the same IRQ not supported");
84
85 ioapic_irq_override[int_override->irq_source] = int_override->global_intr;
86 break;
87 }
88 case 3:
89 {
91 pr_dinfo2(x86_acpi, "MADT entry IOAPIC NMI [%p], nmi_source=%u, global_irq=%u, flags=0x%x", (void *) int_override, int_override->nmi_source,
92 int_override->global_irq, int_override->flags);
93 pr_dwarn(x86_acpi, "Unhandled MADT entry type 3 (IOAPIC NMI)");
94 break;
95 }
96 case 4:
97 {
99 pr_dinfo2(x86_acpi, "MADT entry LAPIC NMI [%p], processor=%u, flags=0x%x, lint=%u", (void *) nmi, nmi->processor_id, nmi->flags, nmi->lint_number);
100 pr_dwarn(x86_acpi, "Unhandled MADT entry type 4 (LAPIC NMI)");
101 break;
102 }
103 case 5:
104 {
106 pr_dinfo2(x86_acpi, "MADT entry LAPIC address override [%p], address=%llu", (void *) local_apic_nmi, local_apic_nmi->lapic_paddr);
107 pr_dwarn(x86_acpi, "Unhandled MADT entry type 5 (LAPIC address override)");
108 break;
109 }
110 case 9:
111 {
112 acpi_madt_et9_lx2apic_t *local_sapic_override = container_of(entry, acpi_madt_et9_lx2apic_t, header);
113 pr_dinfo2(x86_acpi, "MADT entry local x2 SAPIC override [%p], x2apic_id=%u, flags=0x%x, acpi_id=%u", (void *) local_sapic_override,
114 local_sapic_override->processor_lx2apic_id, local_sapic_override->flags, local_sapic_override->acpi_id);
115 pr_dwarn(x86_acpi, "Unhandled MADT entry type 9 (local x2 SAPIC override)");
116 break;
117 }
118 default:
119 {
120 pr_warn("Strange MADT entry type %u", entry->type);
121 }
122 }
123 }
124
125 pr_dinfo2(x86_lapic, "platform has %u cpu(s)", x86_platform.num_cpus);
126 return;
127}
#define madt_entry_foreach(var, madt)
Definition acpi_types.h:220
#define MOS_MAX_CPU_COUNT
Definition autoconf.h:23
static u32 volatile * ioapic
Definition ioapic.c:53
static u32 ioapic_irq_override[255]
Definition madt.c:16
#define IOAPIC_IRQ_OVERRIDE_MAX
Definition madt.c:15
u32 x86_ioapic_get_irq_override(u32 irq)
Definition madt.c:18
const acpi_madt_t * x86_acpi_madt
Definition madt.c:11
u32 x86_lapic_global_base
Definition madt.c:13
void madt_parse_table()
Definition madt.c:25
ptr_t x86_ioapic_phyaddr
Definition madt.c:12
#define unlikely(x)
Definition mos_global.h:40
#define container_of(ptr, type, member)
Definition mos_global.h:50
#define mos_panic(fmt,...)
Definition panic.h:55
#define NULL
Definition pb_syshdr.h:46
#define pr_warn(fmt,...)
Definition printk.h:38
#define pr_dinfo2(feat, fmt,...)
Definition printk.h:27
#define pr_dwarn(feat, fmt,...)
Definition printk.h:30
unsigned int u32
Definition types.h:21
unsigned long ptr_t
Definition types.h:25
unsigned char u8
Definition types.h:19
mos_platform_info_t x86_platform