|
miniOS
x86_64 hobby kernel with SMP, VFS, and POSIX process model
|
ACPI MADT parsing, AP boot sequence, and per-CPU cpu_t management. More...
Classes | |
| struct | cpu_t |
Macros | |
| #define | MAX_CPUS 8 |
Typedefs | |
| typedef struct cpu_t | cpu_t |
Functions | |
| static cpu_t * | cpu_local (void) |
| void | cpu_enable_sse (void) |
| Enable SSE/SSE2 on the calling CPU. | |
| void | per_cpu_init (uint32_t cpu_id) |
| Initialise per-CPU GDT, TSS, IDT, and GS base for one CPU. | |
| void | acpi_find_madt (uint64_t mb_info_phys) |
| Parse ACPI MADT and populate smp_lapic_ids[]/smp_cpu_count. | |
| void | smp_boot_aps (void) |
| Send INIT-SIPI-SIPI sequence to all non-BSP CPUs. | |
| void | per_cpu_update_rsp0 (uint64_t rsp0) |
| Update this CPU's TSS RSP0 and cpu_t.kstack_top. | |
| void | ap_barrier_checkin (void) |
| Signal that this AP has completed its CPU init. | |
| void | smp_wait_for_aps (void) |
| Block until all APs have checked in at the rendezvous barrier. | |
| void | lapic_timer_init_ap (void) |
| Start LAPIC timer on the calling AP using the BSP-calibrated ICR. | |
Variables | |
| uint32_t | smp_cpu_count |
| uint8_t | smp_lapic_ids [MAX_CPUS] |
| cpu_t | g_cpus [MAX_CPUS] |
| volatile uint32_t | smp_aps_ready |
ACPI MADT parsing, AP boot sequence, and per-CPU cpu_t management.
Declares cpu_t (the per-CPU state block accessed via GS.base), the global g_cpus[] array, and the public API for SMP initialisation: MADT parsing, AP boot, rendezvous barrier, and per-CPU TSS/GDT setup.
| #define MAX_CPUS 8 |
| typedef struct cpu_t cpu_t |
cpu_t - Per-CPU state block; GS.base on each CPU points to this struct.
The first field MUST be a self-pointer at offset 0 (gs:0) so cpu_local() works with a single mov %gs:0, %0 instruction regardless of cpu count. Fields at fixed GS offsets are used by assembly: current_thread at gs:56, kstack_top at gs:64, user_rsp_scratch at gs:72.
| void acpi_find_madt | ( | uint64_t | mb_info_phys | ) |
Parse ACPI MADT and populate smp_lapic_ids[]/smp_cpu_count.
| mb_info_phys | Physical address of the Multiboot 2 information structure (from RDI at boot). |
Locates the RSDP via the Multiboot 2 ACPI tag (or EBDA/BIOS ROM scan fallback), prefers XSDT (RSDP revision >= 2) over RSDT to support memory above 4 GB, walks the SDT entries to find the MADT, then extracts all Processor Local APIC entries (type 0) into smp_lapic_ids[]. Index 0 is always the BSP.


| void ap_barrier_checkin | ( | void | ) |
Signal that this AP has completed its CPU init.
Atomically increments smp_aps_ready. Called by each AP after per_cpu_init() and lapic_timer_init_ap() succeed, immediately before entering the AP idle loop. The BSP polls smp_aps_ready in smp_wait_for_aps() until it reaches smp_cpu_count-1.

| void cpu_enable_sse | ( | void | ) |
Enable SSE/SSE2 on the calling CPU.
Sets CR4.OSFXSR and CR4.OSXMMEXCPT, clears CR0.EM, sets CR0.MP, then executes FNINIT and LDMXCSR 0x1F80 to put the FPU and SSE unit in a known state. Must be called on every CPU (BSP in kernel_main, each AP in ap_entry) before any userspace SSE instruction executes.

|
inlinestatic |

| void lapic_timer_init_ap | ( | void | ) |
Start LAPIC timer on the calling AP using the BSP-calibrated ICR.
Reads lapic_bsp_timer_icr (calibrated by the BSP) and writes it directly to LAPIC_TIMER_ICR, avoiding a second PIT calibration which would cause contention on smp_aps_ready. Sets LVT timer to periodic mode at LAPIC_TIMER_VECTOR. Must be called after LAPIC is software-enabled on AP.
Start LAPIC timer on the calling AP using the BSP-calibrated ICR.
Reads lapic_bsp_timer_icr (calibrated by the BSP) and writes it directly to LAPIC_TIMER_ICR, avoiding a second PIT calibration which would cause contention. Sets LVT timer to periodic mode at LAPIC_TIMER_VECTOR. Called from ap_entry() on each AP after LAPIC software-enable.
| void per_cpu_init | ( | uint32_t | cpu_id | ) |
Initialise per-CPU GDT, TSS, IDT, and GS base for one CPU.
| cpu_id | Logical CPU index (0 = BSP, 1..N-1 = APs). |
Steps performed:


| void per_cpu_update_rsp0 | ( | uint64_t | rsp0 | ) |
Update this CPU's TSS RSP0 and cpu_t.kstack_top.
| rsp0 | New kernel stack top to install in TSS privileged_stack_table[0] and cpu_t.kstack_top (read by syscall_entry via gs:64). |
Must be called whenever the running thread changes (in sched_schedule) and before the first ring-3 entry on any CPU, so that both interrupt- driven (iretq path) and SYSCALL-driven ring-3 to ring-0 transitions use the correct kernel stack for the new thread.


| void smp_boot_aps | ( | void | ) |
Send INIT-SIPI-SIPI sequence to all non-BSP CPUs.
Iterates smp_lapic_ids[1..smp_cpu_count-1], sends INIT IPI, waits 10 ms, sends two SIPI IPIs 200 us apart with vector = TRAMP_BASE >> 12 (0x8). Each AP executes the 16-bit trampoline at physical 0x8000, transitions to 64-bit long mode, and calls ap_entry(). Requires lapic_init() to have run.


| void smp_wait_for_aps | ( | void | ) |
Block until all APs have checked in at the rendezvous barrier.
Spins with PAUSE until smp_aps_ready == smp_cpu_count - 1. Must be called by the BSP after smp_boot_aps() and before the second call to sched_init() (which sets up per-CPU run queues). Guaranteed to return eventually because each AP calls ap_barrier_checkin() exactly once.


|
extern |
|
extern |