// SPDX-License-Identifier: MPL-2.0 #ifndef SH_LIB_AP_H #define SH_LIB_AP_H #include "std/status.h" #include "std/type.h" #include "memory/memory.h" #include "irq/gdt.h" #include "irq/idt.h" #include "devs/apic/lapic.h" #define SH_AP_AP_TRAMPOLINE 0x7000 #define SH_AP_GDT_32_PA 0x8000 #define SH_AP_BOOTSTRAP_PA 0x9000 #define SH_AP_TRAMPOLINE_PAYLOAD 0xA000 #define SH_AP_STATE_PENDING 0x00 #define SH_AP_STATE_NO_LAPIC 0x01 #define SH_AP_STATE_OK 0x02 // Fill the 32 bits GDT used by AP trampoline SH_STATUS sh_ap_load_gdt_32(); // AP boostrap structure, shared with each AP #pragma pack(1) typedef struct { sh_page_PHYSICAL_ADDRESS lapic_base_pa; sh_page_VIRTUAL_ADDRESS c_entry_point_va; sh_page_PHYSICAL_ADDRESS page_table_pa; sh_page_VIRTUAL_ADDRESS cpu_struct_base_area; sh_page_VIRTUAL_ADDRESS shared_gdt_64_va; sh_gdt_GDTR gdt_64_gdtr; sh_idt_IDT *idt; } sh_ap_AP_BOOTSTRAP; #pragma pack() // Per-CPU structure, one for each AP #pragma pack(1) typedef struct { sh_uint64 cpu_id; sh_uint32 bytes_outputed; sh_bool timer_state; char *temp_buffer; sh_uint64 temp_buffer_size; } sh_ap_PER_CPU; #pragma pack() // CPU structure, one for each AP #pragma pack(1) typedef struct { sh_page_VIRTUAL_ADDRESS c_entry_point_stack_top_va; sh_uint32 lapic_id; // just for the tranpoline to confirm it has found his own struct sh_uint16 tss_selector; sh_ap_PER_CPU *per_cpu; } sh_ap_CPU_STRUCT; #pragma pack() // Allocate each sets of stacks for each TSS and each C stack, create each TSS entry, create global GDT64, create the CPU structure area, create and fill each CPU structure, create the AP bootstrap structure and place it correctly SH_STATUS sh_ap_prepare_for_smp_launch(sh_lapic_DEVICE **lapic_dev_array,sh_uint64 max_lapic_id,sh_uint64 expected_lapic_found,sh_conf_BOOT_CONFIG *boot_config,sh_idt_IDT *idt); // AP C entry point void sh_ap_entry_point(); // Start AP boot procedure SH_STATUS sh_ap_start_ap_boot_procedure(sh_conf_BOOT_CONFIG *boot_config); #endif