mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 15:08:21 +00:00
smp: nmi ipi support
This commit is contained in:
@@ -284,7 +284,7 @@ void arch_apic_sendipi(uint8_t cpu, uint8_t vec, uint8_t dest, uint8_t mode, uin
|
|||||||
while (readlapic(APIC_REG_ICR_LO) & APIC_REG_ICR_LO_STATUS) CPU_PAUSE();
|
while (readlapic(APIC_REG_ICR_LO) & APIC_REG_ICR_LO_STATUS) CPU_PAUSE();
|
||||||
|
|
||||||
writelapic(APIC_REG_ICR_HI, (uint32_t)cpu << 24);
|
writelapic(APIC_REG_ICR_HI, (uint32_t)cpu << 24);
|
||||||
writelapic(APIC_REG_ICR_LO, vec | (level << 14) | (mode << 15) | (dest << 18));
|
writelapic(APIC_REG_ICR_LO, vec | (level << 8) | (mode << 11) | (dest << 18) | (1 << 14));
|
||||||
}
|
}
|
||||||
|
|
||||||
void arch_apic_init() {
|
void arch_apic_init() {
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ void arch_mmu_tlbshootdown(void *page) {
|
|||||||
mmupage = page;
|
mmupage = page;
|
||||||
remaining = arch_smp_cpusawake - 1;
|
remaining = arch_smp_cpusawake - 1;
|
||||||
|
|
||||||
arch_smp_sendipi(NULL, &_cpu()->isr[0xfe], ARCH_SMP_IPI_OTHERCPUS);
|
arch_smp_sendipi(NULL, &_cpu()->isr[0xfe], ARCH_SMP_IPI_OTHERCPUS, true);
|
||||||
|
|
||||||
while (__atomic_load_n(&remaining, __ATOMIC_SEQ_CST)) CPU_PAUSE();
|
while (__atomic_load_n(&remaining, __ATOMIC_SEQ_CST)) CPU_PAUSE();
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <arch/gdt.h>
|
#include <arch/gdt.h>
|
||||||
#include <arch/idt.h>
|
#include <arch/idt.h>
|
||||||
#include <kernel/cmdline.h>
|
#include <kernel/cmdline.h>
|
||||||
|
#include <arch/smp.h>
|
||||||
|
|
||||||
static volatile struct limine_smp_request smprequest = {
|
static volatile struct limine_smp_request smprequest = {
|
||||||
.id = LIMINE_SMP_REQUEST
|
.id = LIMINE_SMP_REQUEST
|
||||||
@@ -13,11 +14,19 @@ static volatile struct limine_smp_request smprequest = {
|
|||||||
// set to 1 because of the bsp
|
// set to 1 because of the bsp
|
||||||
size_t arch_smp_cpusawake = 1;
|
size_t arch_smp_cpusawake = 1;
|
||||||
|
|
||||||
|
// for panic. if the nosmp argument is given to the kernel, this is what the APs will jump to
|
||||||
|
static void cpuwakeuphalt(struct limine_smp_info *info) {
|
||||||
|
asm("cli");
|
||||||
|
for (;;) CPU_HALT();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void cpuwakeup(struct limine_smp_info *info) {
|
static void cpuwakeup(struct limine_smp_info *info) {
|
||||||
cpu_set((cpu_t *)info->extra_argument);
|
cpu_set((cpu_t *)info->extra_argument);
|
||||||
|
|
||||||
arch_gdt_reload();
|
arch_gdt_reload();
|
||||||
arch_idt_reload();
|
arch_idt_reload();
|
||||||
|
interrupt_register(0xfd, (void *)cpuwakeuphalt, NULL, IPL_IGNORE);
|
||||||
dpc_init();
|
dpc_init();
|
||||||
arch_mmu_apswitch();
|
arch_mmu_apswitch();
|
||||||
vmm_apinit();
|
vmm_apinit();
|
||||||
@@ -30,16 +39,16 @@ static void cpuwakeup(struct limine_smp_info *info) {
|
|||||||
sched_apentry();
|
sched_apentry();
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the nosmp argument is given to the kernel, this is what the APs will jump to
|
void arch_smp_sendipi(cpu_t *targcpu, isr_t *isr, int target, bool nmi) {
|
||||||
static void cpuwakeuphalt(struct limine_smp_info *info) {
|
arch_apic_sendipi(targcpu ? targcpu->id : 0, INTERRUPT_IDTOVECTOR(isr->id), target, nmi ? APIC_MODE_NMI : 0, 0);
|
||||||
for (;;) CPU_HALT();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void arch_smp_sendipi(cpu_t *targcpu, isr_t *isr, int target) {
|
void arch_smp_haltallothers() {
|
||||||
arch_apic_sendipi(targcpu ? targcpu->id : 0, INTERRUPT_IDTOVECTOR(isr->id), target, 0, 1);
|
arch_smp_sendipi(NULL, &_cpu()->isr[0xfd], ARCH_SMP_IPI_OTHERCPUS, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void arch_smp_wakeup() {
|
void arch_smp_wakeup() {
|
||||||
|
interrupt_register(0xfd, (void *)cpuwakeuphalt, NULL, IPL_IGNORE);
|
||||||
struct limine_smp_response *response = smprequest.response;
|
struct limine_smp_response *response = smprequest.response;
|
||||||
if (response == NULL) {
|
if (response == NULL) {
|
||||||
// TODO try to detect the other processors manually
|
// TODO try to detect the other processors manually
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#ifndef _APIC_H
|
#ifndef _APIC_H
|
||||||
#define _APIC_H
|
#define _APIC_H
|
||||||
|
|
||||||
|
#define APIC_MODE_NMI 4
|
||||||
|
|
||||||
void arch_apic_timerinit();
|
void arch_apic_timerinit();
|
||||||
void arch_apic_init();
|
void arch_apic_init();
|
||||||
void arch_apic_initap();
|
void arch_apic_initap();
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
extern size_t arch_smp_cpusawake;
|
extern size_t arch_smp_cpusawake;
|
||||||
|
|
||||||
void arch_smp_wakeup();
|
void arch_smp_wakeup();
|
||||||
void arch_smp_sendipi(cpu_t *targcpu, isr_t *isr, int target);
|
void arch_smp_sendipi(cpu_t *targcpu, isr_t *isr, int target, bool nmi);
|
||||||
|
void arch_smp_haltallothers();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user