To start multiprocessor along with apic interrupt I have done following.
for bootstrap cpu
1. Disable PIC
2. Initialize ACPI
3. Initialiize GDT , TSS
4. Enable IOAPIC
5. Initialize TSC
6. Initialize APIC Interrupts
7. IOAPIC Route IRQ
8. Initialize Keybooard Interrupt
9. Initialize APIC Timer
Similarly for application cpu
1. Disable PIC
2. Initialize ACPI
3. Initialiize GDT , TSS
4. Enable IOAPIC
5. Initialize TSC
6. Initialize APIC Interrupts
7. Initialize Keybooard Interrupt
8. Initialize APIC Timer
Here my full code:
Code: Select all
cpu_data_t cpu_datas[MAX_CPUS]; // Array indexed by CPU ID (APIC ID)
extern struct limine_smp_response *smp_response;
extern madt_t *madt;
void start_bootstrap_cpu_core() {
printf("\n[Info] Starting bootstrap CPU core...\n");
if (smp_response == NULL) {
printf("[Error] SMP response is null!\n");
return;
}
if (smp_response->cpu_count == 0) {
printf("[Error] No CPUs found!\n");
return;
}
uint32_t bsp_lapic_id = smp_response->bsp_lapic_id;
disable_pic();
init_acpi();
enable_ioapic_mode();
parse_madt(madt);
init_paging();
init_tsc();
gdt_tss_init();
// Enable the Interrupts
init_bootstrap_interrupt(bsp_lapic_id);
init_apic_interrupt();
int_syscall_init();
init_apic_timer(100);
initKeyboard();
// Route IRQs to the bootstrap core no need to route them to other cores
uint32_t bsp_flags = (0 << 8) | (0 << 13) | (0 << 15);
ioapic_route_irq(0, bsp_lapic_id, 32, bsp_flags); // Route IRQ 1 to current LAPIC ID with vector 33
ioapic_route_irq(1, bsp_lapic_id, 33, bsp_flags); // Route IRQ 1 to current LAPIC ID with vector 33
ioapic_route_irq(2, bsp_lapic_id, 34, bsp_flags); // Route IRQ 2 to current LAPIC ID with vector 34
ioapic_route_irq(3, bsp_lapic_id, 35, bsp_flags); // Route IRQ 3 to current LAPIC ID with vector 35
ioapic_route_irq(4, bsp_lapic_id, 36, bsp_flags); // Route IRQ 4 to current LAPIC ID with vector 36
ioapic_route_irq(5, bsp_lapic_id, 37, bsp_flags); // Route IRQ 5 to current LAPIC ID with vector 37
ioapic_route_irq(6, bsp_lapic_id, 38, bsp_flags); // Route IRQ 6 to current LAPIC ID with vector 38
ioapic_route_irq(7, bsp_lapic_id, 39, bsp_flags); // Route IRQ 7 to current LAPIC ID with vector 39
ioapic_route_irq(8, bsp_lapic_id, 40, bsp_flags); // Route IRQ 8 to current LAPIC ID with vector 40
ioapic_route_irq(9, bsp_lapic_id, 41, bsp_flags); // Route IRQ 9 to current LAPIC ID with vector 41
ioapic_route_irq(10, bsp_lapic_id, 42, bsp_flags); // Route IRQ 10 to current LAPIC ID with vector 42
ioapic_route_irq(11, bsp_lapic_id, 43, bsp_flags); // Route IRQ 11 to current LAPIC ID with vector 43
ioapic_route_irq(12, bsp_lapic_id, 44, bsp_flags); // Route IRQ 12 to current LAPIC ID with vector 44
ioapic_route_irq(13, bsp_lapic_id, 45, bsp_flags); // Route IRQ 13 to current LAPIC ID with vector 45
ioapic_route_irq(14, bsp_lapic_id, 46, bsp_flags); // Route IRQ 14 to current LAPIC ID with vector 46
ioapic_route_irq(15, bsp_lapic_id, 47, bsp_flags); // Route IRQ 15 to current LAPIC ID with vector 47
ioapic_route_irq(16, bsp_lapic_id, 48, bsp_flags); // Route IRQ 16 to current LAPIC ID with vector 48
ioapic_route_irq(17, bsp_lapic_id, 49, bsp_flags); // Route IRQ 17 to current LAPIC ID with vector 49
ioapic_route_irq(18, bsp_lapic_id, 50, bsp_flags); // Route IRQ 18 to current LAPIC ID with vector 50
ioapic_route_irq(140, bsp_lapic_id, 172, bsp_flags); // Route IRQ 140 to current LAPIC ID with vector 172
ioapic_route_irq(141, bsp_lapic_id, 173, bsp_flags); // Route IRQ 141 to current LAPIC ID with vector 173
ioapic_route_irq(142, bsp_lapic_id, 174, bsp_flags); // Route IRQ 142 to current LAPIC ID with vector 174
printf(" [-] IOAPIC IRQs routed to BSP core %d\n", bsp_lapic_id);
if(has_fpu()){
enable_fpu_and_sse();
printf(" [-] FPU and SSE enabled for BSP core %d\n", bsp_lapic_id);
}
cpu_datas[bsp_lapic_id].lapic_id = bsp_lapic_id; // Set the LAPIC ID for the bootstrap core
cpu_datas[bsp_lapic_id].smp_info = smp_response->cpus[bsp_lapic_id]; // Set the SMP info for the bootstrap core
cpu_datas[bsp_lapic_id].is_online = 1; // Mark the bootstrap core as online
cpu_datas[bsp_lapic_id].cpu_stack = read_rsp(); // Set the stack pointer for the bootstrap core
asm volatile("sti"); // Enable interrupts
printf("[Info] Bootstrap CPU %d initialized...\n\n", bsp_lapic_id);
}
void target_cpu_task(struct limine_smp_info *smp_info) {
if(smp_info == NULL){
printf("[Error] SMP INFO is null!\n");
return;
}
uint32_t core_id = smp_info->lapic_id;
cpu_datas[core_id].lapic_id = core_id;
cpu_datas[core_id].smp_info = smp_info;
disable_pic();
// setting cr3 for this core
init_core_paging(core_id);
// Initialize the stack for this core
uint64_t cpu_stack = (uint64_t)kmalloc_a(STACK_SIZE, 1); // Allocate stack for this core
if(cpu_stack == 0) {
printf("[Error] Failed to allocate stack for CPU %d\n", core_id);
return;
}
uint64_t cpu_stack_top = cpu_stack + STACK_SIZE; // Set the stack pointer to the top of the allocated stack
cpu_datas[core_id].cpu_stack = cpu_stack_top; // Set the stack pointer to the top of the allocated stack
set_rsp(cpu_stack_top); // Set the stack pointer for this core
// Initialize GDT and TSS for this core
init_gdt_tss_in_cpu(core_id);
// Initialize interrupts for this core
init_core_interrupt(core_id);
// Initialize APIC for this
init_apic_interrupt();
// if(has_fpu()){
// enable_fpu_and_sse();
// }
init_apic_timer(100);
cpu_datas[core_id].is_online = 1; // Mark this core as online
printf(" [-] CPU %d (LAPIC ID: %x) is online\n", core_id, core_id);
while(true){
if(core_id == 0 && cpu_datas[core_id].is_online == 1){
// This is the bootstrap core (BSP)
printf(" Hello from CPU %d (BSP)\n", core_id);
for(volatile int i = 0; i < 2000000; i++); // Wait for a while
} else if (core_id == 1 && cpu_datas[core_id].is_online == 1){
printf(" Hello from CPU %d (AP)\n", core_id);
for(volatile int i = 0; i < 1900000; i++); // Wait for a while
} else if (core_id == 2 && cpu_datas[core_id].is_online == 1){
printf(" Hello from CPU %d (AP)\n", core_id);
for(volatile int i = 0; i < 1800000; i++); // Wait for a while
} else if (core_id == 3 && cpu_datas[core_id].is_online == 1){
printf(" Hello from CPU %d (AP)\n", core_id);
for(volatile int i = 0; i < 1700000; i++); // Wait for a while
} else{
continue;
}
}
asm volatile("sti"); // Enable interrupts
// Halt the AP as we have nothing else to do currently
for (;;) {
asm volatile("hlt");
}
}
void start_ap_cpu_cores() {
if (smp_response == NULL) {
printf("[Error] SMP response is null!\n");
return;
}
uint32_t start_id = 1;
uint32_t end_id = smp_response->cpu_count; // Get the number of CPUs from the SMP response
for (uint32_t core = start_id; core < end_id; core++) {
struct limine_smp_info *smp_info = smp_response->cpus[core];
// passing sm_info as argument which will accept as input by target_cpu_task
smp_info->extra_argument = (uint64_t)smp_info;
// Set function to execute on the AP
smp_info->goto_address = (limine_goto_address)target_cpu_task;
for(volatile int i = 0; i < 1000000; i++); // Wait for a while
}
}
// Initializing all CPU cores
void init_all_cpu_cores() {
// Initialize the bootstrap core
start_bootstrap_cpu_core();
// Initialize the application cores
start_ap_cpu_cores();
// Wait for all cores to be online
while (1) {
int all_online = 1;
for (size_t i = 0; i < smp_response->cpu_count; i++) {
if (!cpu_datas[i].is_online) {
all_online = 0;
break;
}
printf(" [-] CPU %d is online\n", i);
}
if (all_online) {
break;
}
}
asm volatile("sti");
printf("[Info] All CPU cores initialized and online.\n");
}
void switch_to_core(uint32_t target_lapic_id) {
if (smp_response == NULL) return;
for (size_t i = 0; i < smp_response->cpu_count; i++) {
struct limine_smp_info *smp_info = smp_response->cpus[i];
if (smp_info->lapic_id == target_lapic_id) {
// Send IPI to the target core
lapic_send_ipi(target_lapic_id, 0x40); // 0x20 is the vector
break;
}
}
printf("[Info] Successfully Switched into CPU %d.\n", target_lapic_id);
}
Code: Select all
[Info] Starting bootstrap CPU core...
[-] PIC Disabled.
[-] ACPI 1.0 is signature and checksum validated
[Error] FADT not found! ACPI status unknown.
[-] Successfully ACPI Enabled
[-] TSC Timer initialized with CPU Frequency 168125 Hz
[-] GDT & TSS initialized.
[-] Successfully Bootstrap CPU 0 Interrupt Initialized.
[-] Interrupt Based System Call initialized!
[-] APIC Timer initialized with 100 ms interval in CPU: 0.
[-] Successfully KEYBOARD initialized.
[-] IOAPIC IRQs routed to BSP core 0
[-] FPU and SSE enabled for BSP core 0
[Info] Bootstrap CPU 0 initialized...
Code: Select all
CPU Reset (CPU 3)
EAX=000f49ee EBX=00000000 ECX=000002ff EDX=00000003
ESI=00000000 EDI=00000000 EBP=00000000 ESP=00006c5c
EIP=000fd0ac EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
CS =0008 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA]
SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA]
LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT
TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy
GDT= 000f6180 00000037
IDT= 000f61be 00000000
CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=00000000 CCD=00000004 CCO=EFLAGS
EFER=0000000000000000
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=0000000000000000 0000000000000000 XMM01=0000000000000000 0000000000000000
XMM02=0000000000000000 0000000000000000 XMM03=0000000000000000 0000000000000000
XMM04=0000000000000000 0000000000000000 XMM05=0000000000000000 0000000000000000
XMM06=0000000000000000 0000000000000000 XMM07=0000000000000000 0000000000000000
0: v=30 e=0000 i=0 cpl=0 IP=0008:ffffffff80003ce3 pc=ffffffff80003ce3 SP=0010:ffff80007ff41e50 env->regs[R_EAX]=0000000000000060
RAX=0000000000000060 RBX=0000000000000000 RCX=0000000000000000 RDX=00000000000003fd
RSI=00000000000002b0 RDI=00000000000003fd RBP=ffff80007ff41e60 RSP=ffff80007ff41e50
R8 =00000000000000ee R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=ffffffff80003ce3 RFL=00000296 [--S-AP-] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 0fffffff 00a09300 DPL=0 DS [-WA]
CS =0008 0000000000000000 0fffffff 00a09a00 DPL=0 CS64 [-R-]
SS =0010 0000000000000000 0fffffff 00a09300 DPL=0 DS [-WA]
DS =0010 0000000000000000 0fffffff 00a09300 DPL=0 DS [-WA]
FS =0010 0000000000000000 0fffffff 00a09300 DPL=0 DS [-WA]
GS =0010 0000000000000000 0fffffff 00a09300 DPL=0 DS [-WA]
LDT=0000 0000000000000000 00000000 00008200 DPL=0 LDT
TR =0028 ffffffff805a8fc0 00000068 00008900 DPL=0 TSS64-avl
GDT= ffffffff805a8f60 00000037
IDT= ffffffff805aa760 00000fff
CR0=80010011 CR2=0000000000000000 CR3=000000007ff31000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000094 CCD=ffff80007ff41e28 CCO=EFLAGS
EFER=0000000000000d00
1: v=30 e=0000 i=0 cpl=0 IP=0008:ffffffff80003d00 pc=ffffffff80003d00 SP=0010:ffff80007ff41e50 env->regs[R_EAX]=000000000000005b
RAX=000000000000005b RBX=0000000000000000 RCX=0000000000000000 RDX=00000000000003f8
RSI=000000000000005b RDI=00000000000003f8 RBP=ffff80007ff41e60 RSP=ffff80007ff41e50
R8 =00000000000000ee R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=ffffffff80003d00 RFL=00000292 [--S-A--] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 0fffffff 00a09300 DPL=0 DS [-WA]
CS =0008 0000000000000000 0fffffff 00a09a00 DPL=0 CS64 [-R-]
SS =0010 0000000000000000 0fffffff 00a09300 DPL=0 DS [-WA]
DS =0010 0000000000000000 0fffffff 00a09300 DPL=0 DS [-WA]
FS =0010 0000000000000000 0fffffff 00a09300 DPL=0 DS [-WA]
GS =0010 0000000000000000 0fffffff 00a09300 DPL=0 DS [-WA]
LDT=0000 0000000000000000 00000000 00008200 DPL=0 LDT
TR =0028 ffffffff805a8fc0 00000068 00008900 DPL=0 TSS64-avl
GDT= ffffffff805a8f60 00000037
IDT= ffffffff805aa760 00000fff
CR0=80010011 CR2=0000000000000000 CR3=000000007ff31000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000090 CCD=ffff80007ff41e38 CCO=EFLAGS
EFER=0000000000000d00
2: v=30 e=0000 i=0 cpl=0 IP=0008:ffffffff80003d00 pc=ffffffff80003d00 SP=0010:ffff80007ff41e50 env->regs[R_EAX]=0000000000000020
RAX=0000000000000020 RBX=0000000000000000 RCX=0000000000000000 RDX=00000000000003f8
RSI=0000000000000020 RDI=00000000000003f8 RBP=ffff80007ff41e60 RSP=ffff80007ff41e50
R8 =00000000000000ee R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=ffffffff80003d00 RFL=00000292 [--S-A--] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 0fffffff 00a09300 DPL=0 DS [-WA]
CS =0008 0000000000000000 0fffffff 00a09a00 DPL=0 CS64 [-R-]
SS =0010 0000000000000000 0fffffff 00a09300 DPL=0 DS [-WA]
DS =0010 0000000000000000 0fffffff 00a09300 DPL=0 DS [-WA]
FS =0010 0000000000000000 0fffffff 00a09300 DPL=0 DS [-WA]
GS =0010 0000000000000000 0fffffff 00a09300 DPL=0 DS [-WA]
LDT=0000 0000000000000000 00000000 00008200 DPL=0 LDT
TR =0028 ffffffff805a8fc0 00000068 00008900 DPL=0 TSS64-avl
GDT= ffffffff805a8f60 00000037
IDT= ffffffff805aa760 00000fff
CR0=80010011 CR2=0000000000000000 CR3=000000007ff31000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000090 CCD=ffff80007ff41e38 CCO=EFLAGS
EFER=0000000000000d00
3: v=30 e=0000 i=0 cpl=0 IP=0008:ffffffff80003d00 pc=ffffffff80003d00 SP=0010:ffff80007ff41e50 env->regs[R_EAX]=0000000000000054
RAX=0000000000000054 RBX=0000000000000000 RCX=0000000000000000 RDX=00000000000003f8
RSI=0000000000000054 RDI=00000000000003f8 RBP=ffff80007ff41e60 RSP=ffff80007ff41e50
R8 =00000000000000ee R9 =0000000000000000 R10=0000000000000000 R11=0000000000000000
R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000
RIP=ffffffff80003d00 RFL=00000292 [--S-A--] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0010 0000000000000000 0fffffff 00a09300 DPL=0 DS [-WA]
CS =0008 0000000000000000 0fffffff 00a09a00 DPL=0 CS64 [-R-]
SS =0010 0000000000000000 0fffffff 00a09300 DPL=0 DS [-WA]
DS =0010 0000000000000000 0fffffff 00a09300 DPL=0 DS [-WA]
FS =0010 0000000000000000 0fffffff 00a09300 DPL=0 DS [-WA]
GS =0010 0000000000000000 0fffffff 00a09300 DPL=0 DS [-WA]
LDT=0000 0000000000000000 00000000 00008200 DPL=0 LDT
TR =0028 ffffffff805a8fc0 00000068 00008900 DPL=0 TSS64-avl
GDT= ffffffff805a8f60 00000037
IDT= ffffffff805aa760 00000fff
CR0=80010011 CR2=0000000000000000 CR3=000000007ff31000 CR4=00000020
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=0000000000000090 CCD=ffff80007ff41e38 CCO=EFLAGS
EFER=0000000000000d00
Where my maiden GitHub Repo .
How could I resolve this issue?