From d9c7ddec66bbdd67a9750383de586d9fa4b48d73 Mon Sep 17 00:00:00 2001 From: fslongjin Date: Mon, 4 Apr 2022 22:54:36 +0800 Subject: [PATCH] =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=A4=9A=E6=A0=B8=E5=90=AF?= =?UTF-8?q?=E5=8A=A8=E5=B9=B6=E5=88=9D=E5=A7=8B=E5=8C=96AP=E6=A0=B8?= =?UTF-8?q?=E7=9A=84Local=20APIC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/driver/disk/ahci/ahci.c | 4 ++-- kernel/head.S | 21 +++++++++++++++++---- kernel/smp/apu_boot.S | 4 ++++ kernel/smp/smp.c | 16 ++++++++++++++++ 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/kernel/driver/disk/ahci/ahci.c b/kernel/driver/disk/ahci/ahci.c index aa39256c..abc84302 100644 --- a/kernel/driver/disk/ahci/ahci.c +++ b/kernel/driver/disk/ahci/ahci.c @@ -28,11 +28,11 @@ void ahci_init() // 映射ABAR mm_map_phys_addr(AHCI_MAPPING_BASE, ((ul)(((struct pci_device_structure_general_device_t *)(ahci_devs[0]))->BAR5)) & PAGE_2M_MASK, PAGE_2M_SIZE, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD); - kdebug("ABAR mapped!"); + //kdebug("ABAR mapped!"); for (int i = 0; i < count_ahci_devices; ++i) { - kdebug("[%d] class_code=%d, sub_class=%d, progIF=%d, ABAR=%#010lx", i, ahci_devs[i]->Class_code, ahci_devs[i]->SubClass, ahci_devs[i]->ProgIF, ((struct pci_device_structure_general_device_t *)(ahci_devs[i]))->BAR5); + //kdebug("[%d] class_code=%d, sub_class=%d, progIF=%d, ABAR=%#010lx", i, ahci_devs[i]->Class_code, ahci_devs[i]->SubClass, ahci_devs[i]->ProgIF, ((struct pci_device_structure_general_device_t *)(ahci_devs[i]))->BAR5); // 赋值HBA_MEM结构体 ahci_devices[i].dev_struct = ahci_devs[i]; ahci_devices[i].hba_mem = (HBA_MEM *)(cal_HBA_MEM_VIRT_ADDR(i)); diff --git a/kernel/head.S b/kernel/head.S index e51d70a3..1b434c01 100644 --- a/kernel/head.S +++ b/kernel/head.S @@ -381,6 +381,7 @@ switch_seg: .quad entry64 +.global entry64 entry64: movq $0x10, %rax @@ -391,6 +392,12 @@ entry64: movq _stack_start(%rip), %rsp //rsp的地址 + // 分支,判断是否为apu + movq $0x1b, %rcx // 根据IA32_APIC_BASE.BSP[8]标志位判断处理器是否为apu + rdmsr + bt $8, %rax + jnc start_smp + setup_IDT: leaq m_ignore_int(%rip), %rdx // 将ignore_int的地址暂时存到中段描述符的高8B movq $(0x08 << 16), %rax // 设置段选择子。由IDT结构和段选择子结构可知,本行设置段基地址为0x100000,TI=0,RPL=0 @@ -469,6 +476,16 @@ SetUp_TSS64: go_to_kernel: .quad Start_Kernel +start_smp: + movq go_to_smp_kernel(%rip), %rax /* movq address */ + pushq $0x08 + pushq %rax + lretq + +go_to_smp_kernel: + + .quad smp_ap_start + // ==== 异常/中断处理模块 ignore int: 忽略中断 m_ignore_int: // 切换到c语言的ignore_int @@ -597,7 +614,3 @@ IDT_BASE: .quad IDT_Table TSS64_Table: .fill 13, 8, 0 TSS64_END: - -TSS64_POINTER: -TSS64_LIMIT: .word TSS64_END - TSS64_Table - 1 -TSS64_BASE: .quad TSS64_Table \ No newline at end of file diff --git a/kernel/smp/apu_boot.S b/kernel/smp/apu_boot.S index 2114a23c..7652ce55 100644 --- a/kernel/smp/apu_boot.S +++ b/kernel/smp/apu_boot.S @@ -112,6 +112,10 @@ _apu_code64: or $(3 << 9), %ax //set CR4.OSFXSR and CR4.OSXMMEXCPT at the same time movq %rax, %cr4 + // 跳转到地址1MB处执行 + movq $_start64, %rax + jmpq *%rax + hlt diff --git a/kernel/smp/smp.c b/kernel/smp/smp.c index 61426ffc..7f734b11 100644 --- a/kernel/smp/smp.c +++ b/kernel/smp/smp.c @@ -1,5 +1,9 @@ #include "smp.h" #include "../common/kprint.h" +#include "../driver/interrupt/apic/apic.h" + +extern void apic_local_apic_init(); + static struct acpi_Processor_Local_APIC_Structure_t *proc_local_apic_structs[MAX_SUPPORTED_PROCESSOR_NUM]; static uint32_t total_processor_num = 0; @@ -28,4 +32,16 @@ void smp_init() wrmsr(0x830, 0xc4500); // init IPI wrmsr(0x830, 0xc4620); // start-up IPI wrmsr(0x830, 0xc4620); // start-up IPI +} + +/** + * @brief AP处理器启动后执行的第一个函数 + * + */ +void smp_ap_start() +{ + ksuccess("AP core successfully started!"); + kinfo("Initializing AP's local apic..."); + apic_local_apic_init(); + while(1); } \ No newline at end of file