generated from limine-bootloader/limine-c-template
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
38 additions
and
231 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#include "lock.h" | ||
|
||
void lock(atomic_flag* lock) { | ||
while (atomic_flag_test_and_set_explicit(lock, memory_order_acquire)) { | ||
asm volatile ("pause": : : "memory"); | ||
} | ||
} | ||
|
||
void unlock(atomic_flag* lock) { | ||
atomic_flag_clear_explicit(lock, memory_order_release); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
#ifndef LOCK_H | ||
#define LOCK_H | ||
|
||
#include <stdatomic.h> | ||
|
||
void lock(atomic_flag* lock); | ||
void unlock(atomic_flag* lock); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,107 +1,26 @@ | ||
#include "smp.h" | ||
#include "klibc/alloc.h" | ||
#include "mm/pmm.h" | ||
#include "mm/mm.h" | ||
#include "klibc/memory.h" | ||
#include "gdt/gdt.h" | ||
#include "klibc/lock.h" | ||
#include "klibc/io.h" | ||
#include "klibc/string.h" | ||
#include "devices/apic.h" | ||
#include "firmware/acpi.h" | ||
#include "devices/hpet.h" | ||
#include "config.h" | ||
#include <limine.h> | ||
|
||
extern uintptr_t lapic_base; | ||
extern struct proc_lapic_t** proc_apic_tbl; | ||
extern uint64_t proc_apic_idx; | ||
extern uint64_t lapic_id; | ||
extern struct gdt gdt[FRAZZOS_TOTAL_SEGMENTS]; | ||
extern uint64_t* root_page_dir; | ||
struct limine_smp_request smp_request = { | ||
.id = LIMINE_SMP_REQUEST, | ||
.revision = 0 | ||
}; | ||
|
||
extern char smp_check_flag(); | ||
extern void prepare_ap_trampoline(uint64_t* pm14, volatile uint8_t* stack); | ||
extern unsigned char ap_trampoline[]; | ||
atomic_flag smp_lock = ATOMIC_FLAG_INIT; | ||
|
||
volatile struct ap_stack* cpu_stacks; | ||
|
||
void send_init_ipi(uint8_t apic_id) { | ||
lapic_write_reg(ERROR_STAT_REG, 0); | ||
lapic_write_reg(INTERRUPT_COMMAND_REG_2, (apic_id << 24)); | ||
lapic_write_reg(INTERRUPT_COMMAND_REG_1, INIT_IPI_MSG); | ||
|
||
do { | ||
asm volatile ( | ||
"pause": : : | ||
"memory" | ||
); | ||
} while ((volatile uint32_t)lapic_read_reg(INTERRUPT_COMMAND_REG_1) & (1 << 12)); | ||
|
||
lapic_write_reg(INTERRUPT_COMMAND_REG_2, (apic_id << 24)); | ||
lapic_write_reg(INTERRUPT_COMMAND_REG_1, INIT_IPI_DEASSERT); | ||
|
||
do { | ||
asm volatile ( | ||
"pause": : : | ||
"memory" | ||
); | ||
} while ((volatile uint32_t)lapic_read_reg(INTERRUPT_COMMAND_REG_1) & (1 << 12)); | ||
|
||
wait_10ms(); | ||
} | ||
|
||
int send_startup_ipi(uint8_t apic_id) { | ||
for (uint8_t i = 0; i < 2; i++) { | ||
prepare_ap_trampoline(root_page_dir, &cpu_stacks[apic_id - 1].stack[0]); | ||
lapic_write_reg(ERROR_STAT_REG, 0); | ||
lapic_write_reg(INTERRUPT_COMMAND_REG_2, (apic_id << 24)); | ||
lapic_write_reg(INTERRUPT_COMMAND_REG_1, SIPI_CODE | (TRAMPOLINE_ADDR / PAGE_SIZE)); | ||
|
||
do { | ||
asm volatile ( | ||
"pause": : : | ||
"memory" | ||
); | ||
} while ((volatile uint32_t)lapic_read_reg(INTERRUPT_COMMAND_REG_1) & (1 << 12)); | ||
|
||
if (i == 0) { | ||
for (int i = 0; i < 200; i++) { | ||
usleep(1); | ||
if (smp_check_flag()) { | ||
return 0; | ||
} | ||
} | ||
} else { | ||
for (int i = 0; i < 10000; i++) { | ||
usleep(1); | ||
if (smp_check_flag()) { | ||
return 0; | ||
} | ||
} | ||
} | ||
} | ||
return -1; | ||
} | ||
|
||
void ap_entry() { | ||
kprint("Hello from AP's!\n"); | ||
void ap_entry_point () { | ||
kprint("Hello from APs!\n"); | ||
while (1) {} | ||
} | ||
|
||
void smp_init() { | ||
kprint("[KERNEL] Initilizing APs... "); | ||
cpu_stacks = (volatile struct ap_stack*)phys_to_hh((uintptr_t)pmm_alloc((proc_apic_idx - 1) * sizeof(struct ap_stack))); | ||
char buf[HEX_STRING_MAX]; | ||
kprint(ull_to_hex(buf, (uint64_t)((void*)TRAMPOLINE_ADDR))); | ||
kprint("\n"); | ||
kprint(ull_to_hex(buf, (uint64_t)ap_trampoline)); | ||
kprint("\n"); | ||
memcpy((void*)(TRAMPOLINE_ADDR + KERNEL_VIRT_BASE_ADDR), ap_trampoline, PAGE_SIZE); | ||
for (uint8_t i = 0; i < proc_apic_idx; i++) { | ||
if (i == lapic_id) { | ||
continue; | ||
} | ||
send_init_ipi(i); | ||
send_startup_ipi(i); | ||
atomic_flag* mutex_lock = &smp_lock; | ||
struct limine_smp_response* smp_response = smp_request.response; | ||
for (int i = 1; i < (int)smp_response->cpu_count; i++) { | ||
lock(mutex_lock); | ||
smp_response->cpus[i]->goto_address = ap_entry_point; | ||
unlock(mutex_lock); | ||
} | ||
kprint("Success\n"); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,23 +1,6 @@ | ||
#ifndef SMP_H | ||
#define SMP_H | ||
|
||
#include <stdint.h> | ||
#include "mm/mm.h" | ||
|
||
#define INIT_IPI_MSG 0x00004500 | ||
#define INIT_IPI_DEASSERT 0x00008500 | ||
#define SIPI_CODE 0x600 | ||
|
||
#define TRAMPOLINE_ADDR 0x1000 | ||
|
||
#define AP_STACK_SIZE 32000 | ||
|
||
struct ap_stack { | ||
uint8_t guard_page[PAGE_SIZE] __attribute__((aligned(PAGE_SIZE))); | ||
uint8_t stack[AP_STACK_SIZE] __attribute__((aligned(PAGE_SIZE))); | ||
}; | ||
|
||
void ap_entry(); | ||
void smp_init(); | ||
|
||
#endif |
This file was deleted.
Oops, something went wrong.