Skip to content

Commit e6bd009

Browse files
graceful AP boot, ensure its done after BSP IDT, and bring up same IDT on all the APs
1 parent 8ffb439 commit e6bd009

File tree

8 files changed

+40
-29
lines changed

8 files changed

+40
-29
lines changed

include/acpi.h

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -128,14 +128,7 @@ typedef struct pci_irq_route {
128128
*
129129
* This function parses the MADT (APIC table) and sets up CPU topology and IOAPIC data.
130130
*/
131-
void init_cores();
132-
133-
/**
134-
* @brief Get an array of Local APIC IDs.
135-
*
136-
* @return Pointer to array of LAPIC IDs (size = get_cpu_count()).
137-
*/
138-
uint8_t* get_lapic_ids();
131+
void init_acpi();
139132

140133
/**
141134
* @brief Get total number of CPUs detected via ACPI.

include/apic.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,3 +117,5 @@ uint32_t get_lapic_id_from_cpu_id(uint8_t cpu_id);
117117
* or 255 if unmapped.
118118
*/
119119
uint8_t get_cpu_id_from_lapic_id(uint32_t lapic_id);
120+
121+
void boot_aps();

include/idt.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ void io_wait(void);
121121
* Message Signalled Interrupts (MSI/MSI-X), associated with
122122
* the specified Local APIC ID.
123123
*
124-
* @param cpu Local APIC ID of the target CPU.
124+
* @param cpu Logical CPU ID of the target CPU.
125125
*
126126
* @return Vector number (64–255) on success,
127127
* -1 if no free vector is available on that CPU.
@@ -139,7 +139,7 @@ int alloc_msi_vector(uint8_t cpu);
139139
* Marks the given MSI vector as available for reuse on the specified
140140
* Local APIC ID.
141141
*
142-
* @param cpu Local APIC ID of the CPU that the vector belongs to.
142+
* @param cpu Logical CPU ID of the CPU that the vector belongs to.
143143
* @param vec The MSI vector to free (64–255).
144144
*
145145
* @warning Behaviour is undefined if freeing a vector that

src/acpi.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <uacpi/uacpi.h>
33
#include <uacpi/namespace.h>
44
#include <uacpi/resources.h>
5+
#include <stdatomic.h>
56
#include "uacpi/context.h"
67

78
volatile struct limine_rsdp_request rsdp_request = {
@@ -11,6 +12,8 @@ volatile struct limine_rsdp_request rsdp_request = {
1112

1213
extern volatile struct limine_smp_request smp_request;
1314

15+
extern atomic_size_t aps_online;
16+
1417
static uint8_t lapic_ids[256] = {0}; // CPU core Local APIC IDs
1518
static uint8_t ioapic_ids[256] = {0}; // CPU core Local APIC IDs
1619
static uint16_t numcore = 0; // number of cores detected
@@ -128,7 +131,7 @@ ioapic_t get_ioapic(uint16_t index) {
128131
return ioapic;
129132
}
130133

131-
void init_cores() {
134+
void init_acpi() {
132135
uint8_t *ptr, *ptr2;
133136
uint32_t len;
134137
uint8_t *rsdt = (uint8_t *) get_sdt_header();
@@ -212,6 +215,13 @@ void init_cores() {
212215
(r->detected_from == FROM_MADT ? "_MADT" : (r->detected_from == FROM_PRT ? "_PRT" : "FALLBACK")));
213216
}
214217
}
218+
for (int i = 0; i < 16; ++i) {
219+
dprintf("IRQ %d maps to GSI %d\n", i, irq_to_gsi(i));
220+
}
221+
rr_flip();
222+
}
223+
224+
void boot_aps() {
215225
if (numcore > 0) {
216226
kprintf("SMP: %d cores, %d IOAPICs\n", numcore, numioapic);
217227
if (!smp_request.response) {
@@ -230,18 +240,18 @@ void init_cores() {
230240
set_lapic_id_for_cpu_id(cpu->processor_id, cpu->lapic_id);
231241
}
232242
if (cpu->lapic_id == smp_request.response->bsp_lapic_id || cpu->processor_id > 254) {
243+
if (cpu->lapic_id == smp_request.response->bsp_lapic_id) {
244+
kprintf("CPU: %d online; ID: %d\n", cpu->processor_id, cpu->lapic_id);
245+
}
233246
// Skip BSP and IDs over 254 (255 is broadcast, 256+ are too big for our array)
234247
continue;
235-
} else if (cpu->lapic_id == smp_request.response->bsp_lapic_id) {
236-
kprintf("CPU: %d online; ID: %d\n", cpu->processor_id, cpu->lapic_id);
237248
}
238249
cpu->goto_address = kmain_ap;
239250
}
251+
while (atomic_load(&aps_online) < limit - 1) {
252+
_mm_pause();
253+
}
240254
}
241-
for (int i = 0; i < 16; ++i) {
242-
dprintf("IRQ %d maps to GSI %d\n", i, irq_to_gsi(i));
243-
}
244-
rr_flip();
245255
}
246256

247257
uint32_t irq_to_gsi(uint8_t irq) {

src/ap.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,27 @@
11
#include <kernel.h>
2+
#include <stdatomic.h>
23

34
volatile struct limine_smp_request smp_request = {
45
.id = LIMINE_SMP_REQUEST,
56
.revision = 0
67
};
78

9+
extern volatile idt_ptr_t idt64;
10+
11+
atomic_size_t aps_online = 0;
12+
813
void kmain_ap(struct limine_smp_info *info)
914
{
15+
// Load the shared IDT
16+
__asm__ volatile("lidtq (%0)" :: "r"(&idt64));
17+
interrupts_on();
18+
1019
kprintf("CPU: %u online; ID: %u\n", info->processor_id, info->lapic_id);
11-
wait_forever();
20+
atomic_fetch_add(&aps_online, 1);
21+
22+
for(;;) {
23+
_mm_pause();
24+
}
1225
/**
1326
* @todo Insert cpu-local scheduler loop here.
1427
* Each AP will run its own list of executing BASIC processes. Accessing

src/apic.c

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,7 @@
44
#define IA32_APIC_BASE_MSR 0x1B
55
#define APIC_BASE_X2APIC_ENABLE (1ULL << 10)
66

7-
static uint64_t saved_lapic = 0;
8-
9-
uint64_t get_lapic_address() {
10-
if (saved_lapic) {
11-
return saved_lapic;
12-
}
7+
uint64_t get_lapic_address() {
138
uint32_t eax, edx;
149
__asm__ volatile (
1510
"rdmsr"
@@ -18,7 +13,6 @@
1813
);
1914
uint64_t result = ((uint64_t)edx << 32) | eax;
2015
result &= 0xFFFFFFFFFFFFF000ULL;
21-
saved_lapic = result;
2216
return result;
2317
}
2418

src/idt.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,6 @@ void init_idt() {
104104
#ifdef USE_IOAPIC
105105
pic_disable();
106106
remap_irqs_to_ioapic();
107-
get_lapic_address();
108107
init_lapic_timer();
109108
#else
110109
pic_enable();

src/init.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,16 +7,16 @@ spinlock_t debug_console_spinlock = 0;
77

88
init_func_t init_funcs[] = {
99
init_heap, validate_limine_page_tables_and_gdt, init_console,
10-
init_cores, init_idt, init_pci, init_realtime_clock,
10+
init_acpi, init_idt, boot_aps, init_pci, init_realtime_clock,
1111
init_devicenames, init_keyboard, init_ide, init_ahci,
1212
init_filesystem, init_iso9660, init_devfs, init_fat32,
1313
init_rtl8139, init_e1000,
1414
NULL,
1515
};
1616

1717
char* init_funcs_names[] = {
18-
"heap", "gdt", "console", "cores",
19-
"idt", "pci", "clock",
18+
"heap", "gdt", "console", "acpi",
19+
"idt", "cpus", "pci", "clock",
2020
"devicenames", "keyboard", "ide", "ahci",
2121
"filesystem", "iso9660", "devfs", "fat32",
2222
"rtl8139", "e1000",

0 commit comments

Comments
 (0)