mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-09 11:16:47 +00:00
bug: AP处理器发生异常时无法正确处理
This commit is contained in:
parent
5ea38e3b53
commit
32b8a163bb
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include "glib.h"
|
#include "glib.h"
|
||||||
|
|
||||||
#define CPU_NUM 8
|
#define MAX_CPU_NUM 32 // 操作系统支持的最大处理器数量
|
||||||
|
|
||||||
// cpu支持的最大cpuid指令的基础主功能号
|
// cpu支持的最大cpuid指令的基础主功能号
|
||||||
uint Cpu_cpuid_max_Basic_mop;
|
uint Cpu_cpuid_max_Basic_mop;
|
||||||
@ -53,3 +53,9 @@ void cpu_cpuid(uint mop, uint sop, uint *eax, uint*ebx, uint*ecx, uint*edx)
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
void cpu_init(void);
|
void cpu_init(void);
|
||||||
|
|
||||||
|
struct cpu_core_info
|
||||||
|
{
|
||||||
|
uint64_t stack_start; // 栈基地址
|
||||||
|
uint64_t tss_vaddr; // tss地址
|
||||||
|
}cpu_core_info[MAX_CPU_NUM];
|
@ -16,6 +16,7 @@
|
|||||||
#define cli() __asm__ __volatile__("cli\n\t" :: \
|
#define cli() __asm__ __volatile__("cli\n\t" :: \
|
||||||
: "memory") //关闭外部中断
|
: "memory") //关闭外部中断
|
||||||
#define nop() __asm__ __volatile__("nop\n\t")
|
#define nop() __asm__ __volatile__("nop\n\t")
|
||||||
|
#define hlt() __asm__ __volatile__("hlt\n\t")
|
||||||
|
|
||||||
//内存屏障
|
//内存屏障
|
||||||
#define io_mfence() __asm__ __volatile__("mfence\n\t" :: \
|
#define io_mfence() __asm__ __volatile__("mfence\n\t" :: \
|
||||||
|
@ -80,7 +80,7 @@ bool acpi_get_MADT(const struct acpi_system_description_table_header_t *_iter_da
|
|||||||
//*(struct acpi_Multiple_APIC_Description_Table_t *)_data = *(struct acpi_Multiple_APIC_Description_Table_t *)_iter_data;
|
//*(struct acpi_Multiple_APIC_Description_Table_t *)_data = *(struct acpi_Multiple_APIC_Description_Table_t *)_iter_data;
|
||||||
// 返回MADT的虚拟地址
|
// 返回MADT的虚拟地址
|
||||||
*(ul *)_data = (ul)_iter_data;
|
*(ul *)_data = (ul)_iter_data;
|
||||||
acpi_madt_vaddr = _iter_data;
|
acpi_madt_vaddr = (ul)_iter_data;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,6 +102,46 @@ void apic_io_apic_init()
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化AP处理器的Local apic
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void apic_init_ap_core_local_apic()
|
||||||
|
{
|
||||||
|
kinfo("Initializing AP-core's local apic...");
|
||||||
|
uint eax, edx;
|
||||||
|
// 启用xAPIC 和x2APIC
|
||||||
|
__asm__ __volatile__("movq $0x1b, %%rcx \n\t" // 读取IA32_APIC_BASE寄存器
|
||||||
|
"rdmsr \n\t"
|
||||||
|
"bts $10, %%rax \n\t"
|
||||||
|
"bts $11, %%rax \n\t"
|
||||||
|
"wrmsr \n\t"
|
||||||
|
"movq $0x1b, %%rcx \n\t"
|
||||||
|
"rdmsr \n\t"
|
||||||
|
: "=a"(eax), "=d"(edx)::"memory");
|
||||||
|
|
||||||
|
// kdebug("After enable xAPIC and x2APIC: edx=%#010x, eax=%#010x", edx, eax);
|
||||||
|
|
||||||
|
// 检测是否成功启用xAPIC和x2APIC
|
||||||
|
if (eax & 0xc00)
|
||||||
|
kinfo("xAPIC & x2APIC enabled!");
|
||||||
|
// 设置SVR寄存器,开启local APIC、禁止EOI广播
|
||||||
|
|
||||||
|
__asm__ __volatile__("movq $0x80f, %%rcx \n\t"
|
||||||
|
"rdmsr \n\t"
|
||||||
|
"bts $8, %%rax \n\t"
|
||||||
|
"bts $12, %%rax \n\t"
|
||||||
|
"movq $0x80f, %%rcx \n\t"
|
||||||
|
"wrmsr \n\t"
|
||||||
|
"movq $0x80f , %%rcx \n\t"
|
||||||
|
"rdmsr \n\t"
|
||||||
|
: "=a"(eax), "=d"(edx)::"memory", "rcx");
|
||||||
|
|
||||||
|
if (eax & 0x100)
|
||||||
|
kinfo("APIC Software Enabled.");
|
||||||
|
if (eax & 0x1000)
|
||||||
|
kinfo("EOI-Broadcast Suppression Enabled.");
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @brief 初始化local apic
|
* @brief 初始化local apic
|
||||||
*
|
*
|
||||||
@ -114,7 +154,7 @@ void apic_local_apic_init()
|
|||||||
|
|
||||||
cpu_cpuid(1, 0, &a, &b, &c, &d);
|
cpu_cpuid(1, 0, &a, &b, &c, &d);
|
||||||
|
|
||||||
//kdebug("CPUID 0x01, eax:%#010lx, ebx:%#010lx, ecx:%#010lx, edx:%#010lx", a, b, c, d);
|
// kdebug("CPUID 0x01, eax:%#010lx, ebx:%#010lx, ecx:%#010lx, edx:%#010lx", a, b, c, d);
|
||||||
|
|
||||||
// 判断是否支持APIC和xAPIC
|
// 判断是否支持APIC和xAPIC
|
||||||
if ((1 << 9) & d)
|
if ((1 << 9) & d)
|
||||||
@ -152,7 +192,7 @@ void apic_local_apic_init()
|
|||||||
"rdmsr \n\t"
|
"rdmsr \n\t"
|
||||||
: "=a"(eax), "=d"(edx)::"memory");
|
: "=a"(eax), "=d"(edx)::"memory");
|
||||||
|
|
||||||
//kdebug("After enable xAPIC and x2APIC: edx=%#010x, eax=%#010x", edx, eax);
|
// kdebug("After enable xAPIC and x2APIC: edx=%#010x, eax=%#010x", edx, eax);
|
||||||
|
|
||||||
// 检测是否成功启用xAPIC和x2APIC
|
// 检测是否成功启用xAPIC和x2APIC
|
||||||
if (eax & 0xc00)
|
if (eax & 0xc00)
|
||||||
@ -174,7 +214,7 @@ void apic_local_apic_init()
|
|||||||
__asm__ __volatile__("movq $0x80f, %%rcx \n\t"
|
__asm__ __volatile__("movq $0x80f, %%rcx \n\t"
|
||||||
"rdmsr \n\t"
|
"rdmsr \n\t"
|
||||||
"bts $8, %%rax \n\t"
|
"bts $8, %%rax \n\t"
|
||||||
"bts $12, %%rax \n\t"
|
// "bts $12, %%rax \n\t"
|
||||||
"movq $0x80f, %%rcx \n\t"
|
"movq $0x80f, %%rcx \n\t"
|
||||||
"wrmsr \n\t"
|
"wrmsr \n\t"
|
||||||
"movq $0x80f , %%rcx \n\t"
|
"movq $0x80f , %%rcx \n\t"
|
||||||
@ -194,7 +234,7 @@ void apic_local_apic_init()
|
|||||||
:
|
:
|
||||||
:"memory");
|
:"memory");
|
||||||
*/
|
*/
|
||||||
//kdebug("After setting SVR: edx=%#010x, eax=%#010x", edx, eax);
|
// kdebug("After setting SVR: edx=%#010x, eax=%#010x", edx, eax);
|
||||||
|
|
||||||
if (eax & 0x100)
|
if (eax & 0x100)
|
||||||
kinfo("APIC Software Enabled.");
|
kinfo("APIC Software Enabled.");
|
||||||
@ -205,12 +245,13 @@ void apic_local_apic_init()
|
|||||||
// Table 10-6. Local APIC Register Address Map Supported by x2APIC
|
// Table 10-6. Local APIC Register Address Map Supported by x2APIC
|
||||||
// 获取 Local APIC ID
|
// 获取 Local APIC ID
|
||||||
// 0x802处是x2APIC ID 位宽32bits 的 Local APIC ID register
|
// 0x802处是x2APIC ID 位宽32bits 的 Local APIC ID register
|
||||||
|
/*
|
||||||
__asm__ __volatile__("movq $0x802, %%rcx \n\t"
|
__asm__ __volatile__("movq $0x802, %%rcx \n\t"
|
||||||
"rdmsr \n\t"
|
"rdmsr \n\t"
|
||||||
: "=a"(eax), "=d"(edx)::"memory");
|
: "=a"(eax), "=d"(edx)::"memory");
|
||||||
|
*/
|
||||||
//kdebug("get Local APIC ID: edx=%#010x, eax=%#010x", edx, eax);
|
// kdebug("get Local APIC ID: edx=%#010x, eax=%#010x", edx, eax);
|
||||||
//kdebug("local_apic_id=%#018lx", *(uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_ID));
|
// kdebug("local_apic_id=%#018lx", *(uint *)(APIC_LOCAL_APIC_VIRT_BASE_ADDR + LOCAL_APIC_OFFSET_Local_APIC_ID));
|
||||||
|
|
||||||
// 获取Local APIC Version
|
// 获取Local APIC Version
|
||||||
// 0x803处是 Local APIC Version register
|
// 0x803处是 Local APIC Version register
|
||||||
|
@ -269,6 +269,13 @@ ul apic_ioapic_read_rte(unsigned char index);
|
|||||||
*/
|
*/
|
||||||
void apic_ioapic_write_rte(unsigned char index, ul value);
|
void apic_ioapic_write_rte(unsigned char index, ul value);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化AP处理器的Local apic
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void apic_init_ap_core_local_apic();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 初始化apic控制器
|
* @brief 初始化apic控制器
|
||||||
*
|
*
|
||||||
|
@ -20,11 +20,10 @@ struct gate_struct
|
|||||||
unsigned char x[16];
|
unsigned char x[16];
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct desc_struct GDT_Table[]; //GDT_Table是head.S中的GDT_Table
|
extern struct desc_struct GDT_Table[]; // GDT_Table是head.S中的GDT_Table
|
||||||
extern struct gate_struct IDT_Table[]; //IDT_Table是head.S中的IDT_Table
|
extern struct gate_struct IDT_Table[]; // IDT_Table是head.S中的IDT_Table
|
||||||
extern unsigned int TSS64_Table[26];
|
extern unsigned int TSS64_Table[26];
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 初始化中段描述符表内的门描述符(每个16B)
|
* @brief 初始化中段描述符表内的门描述符(每个16B)
|
||||||
* @param gate_selector_addr IDT表项的地址
|
* @param gate_selector_addr IDT表项的地址
|
||||||
@ -35,7 +34,7 @@ extern unsigned int TSS64_Table[26];
|
|||||||
|
|
||||||
void set_gate(ul *gate_selector_addr, ul attr, unsigned char ist, ul *code_addr)
|
void set_gate(ul *gate_selector_addr, ul attr, unsigned char ist, ul *code_addr)
|
||||||
{
|
{
|
||||||
ul __d0=0, __d1=0;
|
ul __d0 = 0, __d1 = 0;
|
||||||
ul tmp_code_addr = *code_addr;
|
ul tmp_code_addr = *code_addr;
|
||||||
__d0 = attr << 40; //设置P、DPL、Type
|
__d0 = attr << 40; //设置P、DPL、Type
|
||||||
|
|
||||||
@ -52,14 +51,16 @@ void set_gate(ul *gate_selector_addr, ul attr, unsigned char ist, ul *code_addr)
|
|||||||
|
|
||||||
__d1 = (0xffffffff & tmp_code_addr); //设置段内偏移[63:32]
|
__d1 = (0xffffffff & tmp_code_addr); //设置段内偏移[63:32]
|
||||||
|
|
||||||
|
|
||||||
*gate_selector_addr = __d0;
|
*gate_selector_addr = __d0;
|
||||||
*(gate_selector_addr + 1) = __d1;
|
*(gate_selector_addr + 1) = __d1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_tss_descriptor(unsigned int n, void *addr)
|
||||||
|
{
|
||||||
|
|
||||||
|
*(unsigned long *)(GDT_Table + n) = (103UL & 0xffff) | (((unsigned long)addr & 0xffff) << 16) | (((unsigned long)addr >> 16 & 0xff) << 32) | ((unsigned long)0x89 << 40) | ((103UL >> 16 & 0xf) << 48) | (((unsigned long)addr >> 24 & 0xff) << 56); /////89 is attribute
|
||||||
|
*(unsigned long *)(GDT_Table + n + 1) = ((unsigned long)addr >> 32 & 0xffffffff) | 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief 加载任务状态段寄存器
|
* @brief 加载任务状态段寄存器
|
||||||
@ -69,7 +70,7 @@ void set_gate(ul *gate_selector_addr, ul attr, unsigned char ist, ul *code_addr)
|
|||||||
#define load_TR(n) \
|
#define load_TR(n) \
|
||||||
do \
|
do \
|
||||||
{ \
|
{ \
|
||||||
__asm__ __volatile__("ltr %%ax" ::"a"(n << 3)); \
|
__asm__ __volatile__("ltr %%ax" ::"a"((n)<< 3)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -81,7 +82,7 @@ void set_gate(ul *gate_selector_addr, ul attr, unsigned char ist, ul *code_addr)
|
|||||||
*/
|
*/
|
||||||
void set_intr_gate(unsigned int n, unsigned char ist, void *addr)
|
void set_intr_gate(unsigned int n, unsigned char ist, void *addr)
|
||||||
{
|
{
|
||||||
set_gate((ul*)(IDT_Table + n), 0x8E, ist, (ul*)(&addr)); // p=1,DPL=0, type=E
|
set_gate((ul *)(IDT_Table + n), 0x8E, ist, (ul *)(&addr)); // p=1,DPL=0, type=E
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -93,7 +94,7 @@ void set_intr_gate(unsigned int n, unsigned char ist, void *addr)
|
|||||||
*/
|
*/
|
||||||
void set_trap_gate(unsigned int n, unsigned char ist, void *addr)
|
void set_trap_gate(unsigned int n, unsigned char ist, void *addr)
|
||||||
{
|
{
|
||||||
set_gate((ul*)(IDT_Table + n), 0x8F, ist, (ul*)(&addr)); // p=1,DPL=0, type=F
|
set_gate((ul *)(IDT_Table + n), 0x8F, ist, (ul *)(&addr)); // p=1,DPL=0, type=F
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -105,7 +106,7 @@ void set_trap_gate(unsigned int n, unsigned char ist, void *addr)
|
|||||||
*/
|
*/
|
||||||
void set_system_trap_gate(unsigned int n, unsigned char ist, void *addr)
|
void set_system_trap_gate(unsigned int n, unsigned char ist, void *addr)
|
||||||
{
|
{
|
||||||
set_gate((ul*)(IDT_Table + n), 0xEF, ist, (ul*)(&addr)); // p=1,DPL=3, type=F
|
set_gate((ul *)(IDT_Table + n), 0xEF, ist, (ul *)(&addr)); // p=1,DPL=3, type=F
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -381,7 +381,7 @@ switch_seg:
|
|||||||
|
|
||||||
.quad entry64
|
.quad entry64
|
||||||
|
|
||||||
.global entry64
|
|
||||||
entry64:
|
entry64:
|
||||||
|
|
||||||
movq $0x10, %rax
|
movq $0x10, %rax
|
||||||
@ -590,7 +590,7 @@ GDT_Table:
|
|||||||
.quad 0x0000f20000000000 // 6 用户64位数据段描述符 0x30
|
.quad 0x0000f20000000000 // 6 用户64位数据段描述符 0x30
|
||||||
.quad 0x00cf9a000000ffff // 7 内核32位代码段描述符 0x38
|
.quad 0x00cf9a000000ffff // 7 内核32位代码段描述符 0x38
|
||||||
.quad 0x00cf92000000ffff // 8 内核32位数据段描述符 0x40
|
.quad 0x00cf92000000ffff // 8 内核32位数据段描述符 0x40
|
||||||
.fill 10, 8, 0 // 10-11 TSS(跳过了第9段) 重复十次填充8字节的空间,赋值为0
|
.fill 100, 8, 0 // 10-11 TSS(跳过了第9段) 重复十次填充8字节的空间,赋值为0 长模式下,每个TSS长度为128bit
|
||||||
GDT_END:
|
GDT_END:
|
||||||
|
|
||||||
GDT_POINTER:
|
GDT_POINTER:
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include "mm/slab.h"
|
#include "mm/slab.h"
|
||||||
#include "process/process.h"
|
#include "process/process.h"
|
||||||
#include "syscall/syscall.h"
|
#include "syscall/syscall.h"
|
||||||
|
#include "smp/smp.h"
|
||||||
|
|
||||||
#include "driver/multiboot2/multiboot2.h"
|
#include "driver/multiboot2/multiboot2.h"
|
||||||
#include "driver/acpi/acpi.h"
|
#include "driver/acpi/acpi.h"
|
||||||
@ -148,9 +149,12 @@ void system_initialize()
|
|||||||
load_TR(10); // 加载TR寄存器
|
load_TR(10); // 加载TR寄存器
|
||||||
ul tss_item_addr = 0x7c00;
|
ul tss_item_addr = 0x7c00;
|
||||||
|
|
||||||
set_TSS64(_stack_start, _stack_start, _stack_start, tss_item_addr, tss_item_addr,
|
set_TSS64((ul)TSS64_Table, _stack_start, _stack_start, tss_item_addr, tss_item_addr,
|
||||||
tss_item_addr, tss_item_addr, tss_item_addr, tss_item_addr, tss_item_addr);
|
tss_item_addr, tss_item_addr, tss_item_addr, tss_item_addr, tss_item_addr);
|
||||||
|
|
||||||
|
cpu_core_info[0].stack_start = _stack_start;
|
||||||
|
cpu_core_info[0].tss_vaddr = (ul)TSS64_Table;
|
||||||
|
|
||||||
// 初始化中断描述符表
|
// 初始化中断描述符表
|
||||||
sys_vector_init();
|
sys_vector_init();
|
||||||
|
|
||||||
@ -161,6 +165,9 @@ void system_initialize()
|
|||||||
// 初始化中断模块
|
// 初始化中断模块
|
||||||
irq_init();
|
irq_init();
|
||||||
|
|
||||||
|
smp_init();
|
||||||
|
|
||||||
|
hlt();
|
||||||
// 先初始化系统调用模块
|
// 先初始化系统调用模块
|
||||||
syscall_init();
|
syscall_init();
|
||||||
|
|
||||||
@ -171,12 +178,12 @@ void system_initialize()
|
|||||||
pci_init();
|
pci_init();
|
||||||
ahci_init();
|
ahci_init();
|
||||||
|
|
||||||
smp_init();
|
|
||||||
// test_slab();
|
// test_slab();
|
||||||
// test_mm();
|
// test_mm();
|
||||||
|
|
||||||
// 再初始化进程模块。顺序不能调转
|
// 再初始化进程模块。顺序不能调转
|
||||||
// process_init();
|
// process_init();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//操作系统内核从这里开始执行
|
//操作系统内核从这里开始执行
|
||||||
|
@ -154,7 +154,7 @@ struct thread_struct initial_thread;
|
|||||||
// 初始化 初始进程的union ,并将其链接到.data.init_proc段内
|
// 初始化 初始进程的union ,并将其链接到.data.init_proc段内
|
||||||
union proc_union initial_proc_union __attribute__((__section__(".data.init_proc_union"))) = {INITIAL_PROC(initial_proc_union.pcb)};
|
union proc_union initial_proc_union __attribute__((__section__(".data.init_proc_union"))) = {INITIAL_PROC(initial_proc_union.pcb)};
|
||||||
|
|
||||||
struct process_control_block *initial_proc[CPU_NUM] = {&initial_proc_union.pcb, 0};
|
struct process_control_block *initial_proc[MAX_CPU_NUM] = {&initial_proc_union.pcb, 0};
|
||||||
|
|
||||||
struct mm_struct initial_mm = {0};
|
struct mm_struct initial_mm = {0};
|
||||||
struct thread_struct initial_thread =
|
struct thread_struct initial_thread =
|
||||||
@ -211,7 +211,7 @@ struct tss_struct
|
|||||||
.io_map_base_addr = 0 \
|
.io_map_base_addr = 0 \
|
||||||
}
|
}
|
||||||
// 为每个核心初始化初始进程的tss
|
// 为每个核心初始化初始进程的tss
|
||||||
struct tss_struct initial_tss[CPU_NUM] = {[0 ... CPU_NUM - 1] = INITIAL_TSS};
|
struct tss_struct initial_tss[MAX_CPU_NUM] = {[0 ... MAX_CPU_NUM - 1] = INITIAL_TSS};
|
||||||
|
|
||||||
// 获取当前的pcb
|
// 获取当前的pcb
|
||||||
struct process_control_block *get_current_pcb()
|
struct process_control_block *get_current_pcb()
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
#include "smp.h"
|
#include "smp.h"
|
||||||
#include "../common/kprint.h"
|
#include "../common/kprint.h"
|
||||||
#include "../driver/interrupt/apic/apic.h"
|
#include "../driver/interrupt/apic/apic.h"
|
||||||
|
#include "../exception/gate.h"
|
||||||
extern void apic_local_apic_init();
|
#include "../common/cpu.h"
|
||||||
|
#include "../mm/slab.h"
|
||||||
|
#include "../process/process.h"
|
||||||
|
|
||||||
static struct acpi_Processor_Local_APIC_Structure_t *proc_local_apic_structs[MAX_SUPPORTED_PROCESSOR_NUM];
|
static struct acpi_Processor_Local_APIC_Structure_t *proc_local_apic_structs[MAX_SUPPORTED_PROCESSOR_NUM];
|
||||||
static uint32_t total_processor_num = 0;
|
static uint32_t total_processor_num = 0;
|
||||||
|
int current_starting_cpu = 0;
|
||||||
|
|
||||||
void smp_init()
|
void smp_init()
|
||||||
{
|
{
|
||||||
@ -17,21 +20,44 @@ void smp_init()
|
|||||||
for (int i = 0; i < total_processor_num; ++i)
|
for (int i = 0; i < total_processor_num; ++i)
|
||||||
proc_local_apic_structs[i] = (struct acpi_Processor_Local_APIC_Structure_t *)(tmp_vaddr[i]);
|
proc_local_apic_structs[i] = (struct acpi_Processor_Local_APIC_Structure_t *)(tmp_vaddr[i]);
|
||||||
|
|
||||||
for (int i = 0; i < total_processor_num; ++i)
|
|
||||||
{
|
|
||||||
kdebug("[core %d] acpi processor UID=%d, APIC ID=%d, flags=%#010lx", i, proc_local_apic_structs[i]->ACPI_Processor_UID, proc_local_apic_structs[i]->ACPI_ID, proc_local_apic_structs[i]->flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
//*(uchar *)0x20000 = 0xf4; // 在内存的0x20000处写入HLT指令(AP处理器会执行物理地址0x20000的代码)
|
//*(uchar *)0x20000 = 0xf4; // 在内存的0x20000处写入HLT指令(AP处理器会执行物理地址0x20000的代码)
|
||||||
// 将引导程序复制到物理地址0x20000处
|
// 将引导程序复制到物理地址0x20000处
|
||||||
memcpy((unsigned char *)0x20000, _apu_boot_start, (unsigned long)&_apu_boot_end - (unsigned long)&_apu_boot_start);
|
memcpy((unsigned char *)0x20000, _apu_boot_start, (unsigned long)&_apu_boot_end - (unsigned long)&_apu_boot_start);
|
||||||
|
wrmsr(0x830, 0xc4500); // init IPI
|
||||||
|
|
||||||
|
struct INT_CMD_REG icr_entry;
|
||||||
|
icr_entry.dest_mode = DEST_PHYSICAL;
|
||||||
|
icr_entry.deliver_status = IDLE;
|
||||||
|
icr_entry.res_1 = 0;
|
||||||
|
icr_entry.level = ICR_LEVEL_DE_ASSERT;
|
||||||
|
icr_entry.trigger = EDGE_TRIGGER;
|
||||||
|
icr_entry.res_2 = 0;
|
||||||
|
icr_entry.res_3 = 0;
|
||||||
|
|
||||||
|
for (int i = 1; i < total_processor_num; ++i) // i从1开始,不初始化bsp
|
||||||
|
{
|
||||||
|
current_starting_cpu = i;
|
||||||
|
kdebug("[core %d] acpi processor UID=%d, APIC ID=%d, flags=%#010lx", i, proc_local_apic_structs[i]->ACPI_Processor_UID, proc_local_apic_structs[i]->ACPI_ID, proc_local_apic_structs[i]->flags);
|
||||||
|
// 为每个AP处理器分配栈空间、tss空间
|
||||||
|
cpu_core_info[i].stack_start = (uint64_t)kmalloc(STACK_SIZE, 0) + STACK_SIZE;
|
||||||
|
cpu_core_info[i].tss_vaddr = (uint64_t)kmalloc(128, 0);
|
||||||
|
|
||||||
|
set_tss_descriptor(10 + (i * 2), (void *)(cpu_core_info[i].tss_vaddr));
|
||||||
|
set_TSS64(cpu_core_info[i].tss_vaddr, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start, cpu_core_info[i].stack_start);
|
||||||
|
kdebug("GDT Table %#018lx, \t %#018lx", GDT_Table[10 + i * 2], GDT_Table[10 + i * 2 + 1]);
|
||||||
|
|
||||||
|
icr_entry.vector = 0x20;
|
||||||
|
icr_entry.deliver_mode = ICR_Start_up;
|
||||||
|
icr_entry.dest_shorthand = ICR_No_Shorthand;
|
||||||
|
icr_entry.destination.x2apic_destination = current_starting_cpu;
|
||||||
|
|
||||||
// 先init ipi, 然后连续发送两次start-up IPI
|
// 先init ipi, 然后连续发送两次start-up IPI
|
||||||
// x2APIC下,ICR寄存器地址为0x830
|
// x2APIC下,ICR寄存器地址为0x830
|
||||||
// xAPIC下则为0xfee00300(31-0) 0xfee00310 (63-32)
|
// xAPIC下则为0xfee00300(31-0) 0xfee00310 (63-32)
|
||||||
wrmsr(0x830, 0xc4500); // init IPI
|
|
||||||
wrmsr(0x830, 0xc4620); // start-up IPI
|
wrmsr(0x830, *(ul *)&icr_entry); // start-up IPI
|
||||||
wrmsr(0x830, 0xc4620); // start-up IPI
|
wrmsr(0x830, *(ul *)&icr_entry); // start-up IPI
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,7 +67,10 @@ void smp_init()
|
|||||||
void smp_ap_start()
|
void smp_ap_start()
|
||||||
{
|
{
|
||||||
ksuccess("AP core successfully started!");
|
ksuccess("AP core successfully started!");
|
||||||
kinfo("Initializing AP's local apic...");
|
kdebug("current=%d", current_starting_cpu);
|
||||||
apic_local_apic_init();
|
load_TR(10 + current_starting_cpu * 2);
|
||||||
while(1);
|
apic_init_ap_core_local_apic();
|
||||||
|
int a =1/0; // 在这儿会出现异常,cs fs gs ss寄存器会被改变
|
||||||
|
|
||||||
|
hlt();
|
||||||
}
|
}
|
@ -4,7 +4,7 @@
|
|||||||
#include "../driver/acpi/acpi.h"
|
#include "../driver/acpi/acpi.h"
|
||||||
#include "../driver/interrupt/apic/apic.h"
|
#include "../driver/interrupt/apic/apic.h"
|
||||||
|
|
||||||
#define MAX_SUPPORTED_PROCESSOR_NUM 1024 // 操作系统支持的最大处理器数量
|
#define MAX_SUPPORTED_PROCESSOR_NUM 1024
|
||||||
|
|
||||||
extern uchar _apu_boot_start[];
|
extern uchar _apu_boot_start[];
|
||||||
extern uchar _apu_boot_end[];
|
extern uchar _apu_boot_end[];
|
||||||
|
2
run.sh
2
run.sh
@ -93,7 +93,7 @@ if [ $flag_can_run -eq 1 ]; then
|
|||||||
bochs -q -f ${bochsrc} -rc ./tools/bochsinit
|
bochs -q -f ${bochsrc} -rc ./tools/bochsinit
|
||||||
else
|
else
|
||||||
qemu-system-x86_64 -cdrom ${iso} -m 512M -smp 2,cores=2,threads=1,sockets=1 \
|
qemu-system-x86_64 -cdrom ${iso} -m 512M -smp 2,cores=2,threads=1,sockets=1 \
|
||||||
-monitor stdio -s -S -cpu IvyBridge --enable-kvm \
|
-monitor stdio -d cpu_reset,guest_errors -s -S -cpu IvyBridge --enable-kvm \
|
||||||
-drive id=disk,file=bin/disk.img,if=none \
|
-drive id=disk,file=bin/disk.img,if=none \
|
||||||
-device ahci,id=ahci \
|
-device ahci,id=ahci \
|
||||||
-device ide-hd,drive=disk,bus=ahci.0 \
|
-device ide-hd,drive=disk,bus=ahci.0 \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user