Browse Source

支持多核启动并初始化AP核的Local APIC

fslongjin 3 years ago
parent
commit
d9c7ddec66
4 changed files with 39 additions and 6 deletions
  1. 2 2
      kernel/driver/disk/ahci/ahci.c
  2. 17 4
      kernel/head.S
  3. 4 0
      kernel/smp/apu_boot.S
  4. 16 0
      kernel/smp/smp.c

+ 2 - 2
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));

+ 17 - 4
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

+ 4 - 0
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
 
 

+ 16 - 0
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);
 }