mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-25 14:13:23 +00:00
@ -1,13 +0,0 @@
|
||||
use super::kick_cpu;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rs_kick_cpu(cpu_id: usize) -> usize {
|
||||
return kick_cpu(cpu_id)
|
||||
.map(|_| 0usize)
|
||||
.unwrap_or_else(|e| e.to_posix_errno() as usize);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn rs_smp_init_idle() {
|
||||
crate::smp::init_smp_idle_process();
|
||||
}
|
@ -1,11 +1,9 @@
|
||||
use crate::{
|
||||
arch::{asm::current::current_pcb, interrupt::ipi::send_ipi},
|
||||
arch::interrupt::ipi::send_ipi,
|
||||
exception::ipi::{IpiKind, IpiTarget},
|
||||
mm::INITIAL_PROCESS_ADDRESS_SPACE,
|
||||
syscall::SystemError,
|
||||
};
|
||||
|
||||
pub mod c_adapter;
|
||||
pub mod core;
|
||||
|
||||
pub fn kick_cpu(cpu_id: usize) -> Result<(), SystemError> {
|
||||
@ -15,7 +13,9 @@ pub fn kick_cpu(cpu_id: usize) -> Result<(), SystemError> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
/// 初始化AP核的idle进程
|
||||
pub unsafe fn init_smp_idle_process() {
|
||||
current_pcb().set_address_space(INITIAL_PROCESS_ADDRESS_SPACE());
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rs_kick_cpu(cpu_id: usize) -> usize {
|
||||
return kick_cpu(cpu_id)
|
||||
.map(|_| 0usize)
|
||||
.unwrap_or_else(|e| e.to_posix_errno() as usize);
|
||||
}
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include "ipi.h"
|
||||
|
||||
static void __smp_kick_cpu_handler(uint64_t irq_num, uint64_t param, struct pt_regs *regs);
|
||||
static void __smp__flush_tlb_ipi_handler(uint64_t irq_num, uint64_t param, struct pt_regs *regs);
|
||||
|
||||
static spinlock_t multi_core_starting_lock = {1}; // 多核启动锁
|
||||
|
||||
@ -23,22 +22,13 @@ static uint32_t total_processor_num = 0;
|
||||
static int current_starting_cpu = 0;
|
||||
|
||||
static int num_cpu_started = 1;
|
||||
extern void rs_smp_init_idle();
|
||||
|
||||
// 在head.S中定义的,APU启动时,要加载的页表
|
||||
// 由于内存管理模块初始化的时候,重置了页表,因此我们要把当前的页表传给APU
|
||||
extern uint64_t __APU_START_CR3;
|
||||
|
||||
// kick cpu 功能所使用的中断向量号
|
||||
#define KICK_CPU_IRQ_NUM 0xc8
|
||||
#define FLUSH_TLB_IRQ_NUM 0xc9
|
||||
|
||||
void smp_init()
|
||||
{
|
||||
spin_init(&multi_core_starting_lock); // 初始化多核启动锁
|
||||
// 设置多核启动时,要加载的页表
|
||||
__APU_START_CR3 = (uint64_t)get_CR3();
|
||||
|
||||
ul tmp_vaddr[MAX_SUPPORTED_PROCESSOR_NUM] = {0};
|
||||
|
||||
apic_get_ics(ACPI_ICS_TYPE_PROCESSOR_LOCAL_APIC, tmp_vaddr, &total_processor_num);
|
||||
@ -67,7 +57,6 @@ void smp_init()
|
||||
kdebug("total_processor_num=%d", total_processor_num);
|
||||
// 注册接收kick_cpu功能的处理函数。(向量号200)
|
||||
ipi_regiserIPI(KICK_CPU_IRQ_NUM, NULL, &__smp_kick_cpu_handler, NULL, NULL, "IPI kick cpu");
|
||||
ipi_regiserIPI(FLUSH_TLB_IRQ_NUM, NULL, &__smp__flush_tlb_ipi_handler, NULL, NULL, "IPI flush tlb");
|
||||
|
||||
int core_to_start = 0;
|
||||
// total_processor_num = 3;
|
||||
@ -115,7 +104,7 @@ void smp_init()
|
||||
cpu_core_info[current_starting_cpu].tss_vaddr = (uint64_t)&initial_tss[current_starting_cpu];
|
||||
|
||||
memset(&initial_tss[current_starting_cpu], 0, sizeof(struct tss_struct));
|
||||
// kdebug("core %d, set tss", current_starting_cpu);
|
||||
|
||||
set_tss_descriptor(10 + (current_starting_cpu * 2), (void *)(cpu_core_info[current_starting_cpu].tss_vaddr));
|
||||
io_mfence();
|
||||
set_tss64(
|
||||
@ -127,14 +116,12 @@ void smp_init()
|
||||
cpu_core_info[current_starting_cpu].ist_stack_start);
|
||||
io_mfence();
|
||||
|
||||
// kdebug("core %d, to send start up", current_starting_cpu);
|
||||
// 连续发送两次start-up IPI
|
||||
ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0x20, ICR_Start_up, ICR_No_Shorthand,
|
||||
proc_local_apic_structs[i]->local_apic_id);
|
||||
io_mfence();
|
||||
ipi_send_IPI(DEST_PHYSICAL, IDLE, ICR_LEVEL_DE_ASSERT, EDGE_TRIGGER, 0x20, ICR_Start_up, ICR_No_Shorthand,
|
||||
proc_local_apic_structs[i]->local_apic_id);
|
||||
// kdebug("core %d, send start up ok", current_starting_cpu);
|
||||
}
|
||||
io_mfence();
|
||||
while (num_cpu_started != (core_to_start + 1))
|
||||
@ -143,7 +130,12 @@ void smp_init()
|
||||
kinfo("Cleaning page table remapping...\n");
|
||||
|
||||
// 由于ap处理器初始化过程需要用到0x00处的地址,因此初始化完毕后才取消内存地址的重映射
|
||||
rs_unmap_at_low_addr();
|
||||
uint64_t *global_CR3 = get_CR3();
|
||||
for (int i = 0; i < 256; ++i)
|
||||
{
|
||||
io_mfence();
|
||||
*(ul *)(phys_2_virt(global_CR3) + i) = 0UL;
|
||||
}
|
||||
kdebug("init proc's preempt_count=%ld", current_pcb->preempt_count);
|
||||
kinfo("Successfully cleaned page table remapping!\n");
|
||||
}
|
||||
@ -157,10 +149,8 @@ void smp_ap_start()
|
||||
|
||||
// 切换栈基地址
|
||||
// uint64_t stack_start = (uint64_t)kmalloc(STACK_SIZE, 0) + STACK_SIZE;
|
||||
__asm__ __volatile__("movq %0, %%rbp \n\t" ::"m"(cpu_core_info[current_starting_cpu].stack_start)
|
||||
: "memory");
|
||||
__asm__ __volatile__("movq %0, %%rsp \n\t" ::"m"(cpu_core_info[current_starting_cpu].stack_start)
|
||||
: "memory");
|
||||
__asm__ __volatile__("movq %0, %%rbp \n\t" ::"m"(cpu_core_info[current_starting_cpu].stack_start) : "memory");
|
||||
__asm__ __volatile__("movq %0, %%rsp \n\t" ::"m"(cpu_core_info[current_starting_cpu].stack_start) : "memory");
|
||||
|
||||
ksuccess("AP core %d successfully started!", current_starting_cpu);
|
||||
io_mfence();
|
||||
@ -174,8 +164,7 @@ void smp_ap_start()
|
||||
barrier();
|
||||
current_pcb->state = PROC_RUNNING;
|
||||
current_pcb->flags = PF_KTHREAD;
|
||||
current_pcb->address_space = NULL;
|
||||
rs_smp_init_idle();
|
||||
current_pcb->mm = &initial_mm;
|
||||
|
||||
list_init(¤t_pcb->list);
|
||||
current_pcb->addr_limit = KERNEL_BASE_LINEAR_ADDR;
|
||||
@ -201,9 +190,8 @@ void smp_ap_start()
|
||||
preempt_disable(); // 由于ap处理器的pcb与bsp的不同,因此ap处理器放锁时,需要手动恢复preempt count
|
||||
io_mfence();
|
||||
current_pcb->flags |= PF_NEED_SCHED;
|
||||
|
||||
apic_timer_ap_core_init();
|
||||
sti();
|
||||
apic_timer_ap_core_init();
|
||||
sched();
|
||||
|
||||
while (1)
|
||||
@ -234,12 +222,6 @@ static void __smp_kick_cpu_handler(uint64_t irq_num, uint64_t param, struct pt_r
|
||||
sched();
|
||||
}
|
||||
|
||||
static void __smp__flush_tlb_ipi_handler(uint64_t irq_num, uint64_t param, struct pt_regs *regs)
|
||||
{
|
||||
if (user_mode(regs))
|
||||
return;
|
||||
flush_tlb();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 获取当前全部的cpu数目
|
||||
|
Reference in New Issue
Block a user