Browse Source

检测处理器核心数量

fslongjin 3 years ago
parent
commit
60dc9f4932

+ 4 - 3
kernel/Makefile

@@ -19,9 +19,9 @@ all: kernel
 	objcopy -I elf64-x86-64 -O elf64-x86-64 -R ".comment" -R ".eh_frame" kernel ../bin/kernel/kernel.elf
 #
 
-kernel: head.o entry.o main.o printk.o trap.o mm.o slab.o irq.o pic.o process.o syscall.o multiboot2.o cpu.o acpi.o ps2_keyboard.o ps2_mouse.o ata.o pci.o ahci.o
+kernel: head.o entry.o main.o printk.o trap.o mm.o slab.o irq.o pic.o process.o syscall.o multiboot2.o cpu.o acpi.o ps2_keyboard.o ps2_mouse.o ata.o pci.o ahci.o smp.o
 	ld -b elf64-x86-64 -z muldefs -o kernel head.o exception/entry.o main.o common/printk.o exception/trap.o exception/irq.o mm/mm.o mm/slab.o process/process.o syscall/syscall.o driver/multiboot2/multiboot2.o \
-	common/cpu.o	\
+	common/cpu.o smp/smp.o 	\
 	driver/acpi/acpi.o driver/interrupt/pic.o driver/keyboard/ps2_keyboard.o driver/mouse/ps2_mouse.o driver/disk/ata.o driver/pci/pci.o driver/disk/ahci/ahci.o \
 	-T link.lds
 
@@ -64,7 +64,8 @@ process.o: process/process.c
 syscall.o: syscall/syscall.c
 	gcc $(CFLAGS) -c syscall/syscall.c -o syscall/syscall.o
 
-
+smp.o: smp/smp.c 
+	gcc $(CFLAGS) -c smp/smp.c  -o smp/smp.o 
 
 cpu.o: common/cpu.c 
 	gcc $(CFLAGS) -c common/cpu.c -o common/cpu.o

+ 1 - 0
kernel/common/glib.h

@@ -7,6 +7,7 @@
 
 //引入对bool类型的支持
 #include <stdbool.h>
+#include <stdint.h>
 
 #define NULL 0
 

+ 5 - 3
kernel/driver/acpi/acpi.c

@@ -22,6 +22,8 @@ static uint acpi_XSDT_Entry_num = 0;
 
 static ul acpi_RSDT_entry_phys_base = 0; // RSDT中的第一个entry所在物理页的基地址
 
+static uint64_t acpi_madt_vaddr = 0;    // MADT的虚拟地址
+
 // static ul acpi_XSDT_entry_phys_base = 0; // XSDT中的第一个entry所在物理页的基地址
 
 /**
@@ -53,7 +55,6 @@ void acpi_iter_SDT(bool (*_fun)(const struct acpi_system_description_table_heade
         {
 
             sdt_header = (struct acpi_system_description_table_header_t *)(acpi_get_RSDT_entry_vaddr((ul)(*(ent + i))));
-          
 
             if (_fun(sdt_header, _data) == true)
                 return;
@@ -79,10 +80,11 @@ 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;
     // 返回MADT的虚拟地址
     *(ul *)_data = (ul)_iter_data;
-
+    acpi_madt_vaddr = _iter_data;
     return true;
 }
 
+
 /**
  * @brief 初始化acpi模块
  *
@@ -138,7 +140,7 @@ void acpi_init()
             mm_map_phys_addr(ACPI_XSDT_DESCRIPTION_HEDERS_BASE + PAGE_2M_SIZE * j, (*(ent + j)) & PAGE_2M_MASK, PAGE_2M_SIZE, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD);
         }
         */
-       // 由于解析XSDT出现问题。暂时只使用Rsdpv2的rsdt,但是这是不符合ACPI规范的!!!
+        // 由于解析XSDT出现问题。暂时只使用Rsdpv2的rsdt,但是这是不符合ACPI规范的!!!
         ul rsdt_phys_base = rsdpv2->rsdp1.RsdtAddress & PAGE_2M_MASK;
         acpi_RSDT_offset = rsdpv2->rsdp1.RsdtAddress - rsdt_phys_base;
         mm_map_phys_addr(ACPI_RSDT_VIRT_ADDR_BASE, rsdt_phys_base, PAGE_2M_SIZE, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD);

+ 0 - 9
kernel/driver/acpi/acpi.h

@@ -162,15 +162,6 @@ void acpi_iter_SDT(bool (*_fun)(const struct acpi_system_description_table_heade
 bool acpi_get_MADT(const struct acpi_system_description_table_header_t *_iter_data, void *_data);
 
 
-/**
- * @brief 迭代器,用于迭代中断控制器结构(Interrupt Controller Structure)(位于ACPI标准文件的Table 5-45)
- * @param  _fun            迭代操作调用的函数
- * @param  _data           数据
- */
-void acpi_iter_Interrupt_Controller_Structure(bool (*_fun)(const struct apic_Interrupt_Controller_Structure_header_t *, void *),
-                   void *_data);
-
-
 
 // 初始化acpi模块
 void acpi_init();

+ 34 - 1
kernel/driver/interrupt/apic/apic.c

@@ -24,7 +24,6 @@ void apic_io_apic_init()
 {
 
     ul madt_addr;
-    kdebug("madt_addr = %#018lx", (ul)madt_addr);
     acpi_iter_SDT(acpi_get_MADT, &madt_addr);
     madt = (struct acpi_Multiple_APIC_Description_Table_t *)madt_addr;
 
@@ -453,4 +452,38 @@ void apic_ioapic_edge_ack(ul irq_num) // 边沿触发
                          "movq 	$0x80b,	%%rcx	\n\t"
                          "wrmsr	\n\t" ::
                              : "memory");
+}
+
+/**
+ * @brief 读取指定类型的 Interrupt Control Structure
+ *
+ * @param type ics的类型
+ * @param ret_vaddr 对应的ICS的虚拟地址数组
+ * @param total 返回数组的元素总个数
+ * @return uint
+ */
+uint apic_get_ics(const uint type, ul *ret_vaddr[], uint *total)
+{
+    void *ent = (void *)(madt) + sizeof(struct acpi_Multiple_APIC_Description_Table_t);
+    struct apic_Interrupt_Controller_Structure_header_t *header = (struct apic_Interrupt_Controller_Structure_header_t *)ent;
+    bool flag = false;
+
+    uint cnt = 0;
+
+    while (header->length > 2)
+    {
+        header = (struct apic_Interrupt_Controller_Structure_header_t *)ent;
+        if (header->type == type)
+        {
+            *(ret_vaddr[cnt++]) = (ul)ent;
+            flag = true;
+        }
+        ent += header->length;
+    }
+
+    *total = cnt;
+    if (!flag)
+        return APIC_E_NOTFOUND;
+    else
+        return APIC_SUCCESS;
 }

+ 16 - 1
kernel/driver/interrupt/apic/apic.h

@@ -5,6 +5,9 @@
 #include "../../../exception/irq.h"
 #include "../../../mm/mm.h"
 
+#define APIC_SUCCESS 0
+#define APIC_E_NOTFOUND 1
+
 #define APIC_IO_APIC_VIRT_BASE_ADDR SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + IO_APIC_MAPPING_OFFSET
 #define APIC_LOCAL_APIC_VIRT_BASE_ADDR SPECIAL_MEMOEY_MAPPING_VIRT_ADDR_BASE + LOCAL_APIC_MAPPING_OFFSET
 
@@ -70,6 +73,8 @@
 // 分频配置寄存器(定时器专用)
 #define LOCAL_APIC_OFFSET_Local_APIC_CLKDIV 0x3e0
 
+
+
 /*
 
 1:	LVT	CMCI
@@ -270,10 +275,20 @@ void apic_ioapic_write_rte(unsigned char index, ul value);
  */
 void apic_init();
 
+/**
+ * @brief 读取指定类型的 Interrupt Control Structure
+ * 
+ * @param type ics的类型
+ * @param ret_vaddr 对应的ICS的虚拟地址数组
+ * @param total 返回数组的元素总个数
+ * @return uint 
+ */
+uint apic_get_ics(const uint type, ul *ret_vaddr[], uint * total);
+
 // =========== 中断控制操作接口 ============
 void apic_ioapic_enable(ul irq_num);
 void apic_ioapic_disable(ul irq_num);
 ul apic_ioapic_install(ul irq_num, void *arg);
 void apic_ioapic_uninstall(ul irq_num);
 void apic_ioapic_level_ack(ul irq_num); // 电平触发
-void apic_ioapic_edge_ack(ul irq_num);  // 边沿触发
+void apic_ioapic_edge_ack(ul irq_num);  // 边沿触发

+ 18 - 18
kernel/main.c

@@ -165,11 +165,13 @@ void system_initialize()
     syscall_init();
 
     cpu_init();
-    //ps2_keyboard_init();
-    //ps2_mouse_init();
-    //ata_init();
+    // ps2_keyboard_init();
+    // ps2_mouse_init();
+    // ata_init();
     pci_init();
     ahci_init();
+
+    smp_init();
     // test_slab();
     // test_mm();
 
@@ -180,9 +182,7 @@ void system_initialize()
 //操作系统内核从这里开始执行
 void Start_Kernel(void)
 {
-
     system_initialize();
-    
 
     /*
     uint64_t buf[100];
@@ -197,21 +197,21 @@ void Start_Kernel(void)
     // show_welcome();
     // test_mm();
 
-/*
-    while (1)
-    {
-        ps2_keyboard_analyze_keycode();
-        struct ps2_mouse_packet_3bytes packet = {0};
-        // struct ps2_mouse_packet_4bytes packet = {0};
-        int errcode = 0;
-        errcode = ps2_mouse_get_packet(&packet);
-        if (errcode == 0)
+    /*
+        while (1)
         {
-            printk_color(GREEN, BLACK, " (Mouse: byte0:%d, x:%3d, y:%3d)\n", packet.byte0, packet.movement_x, packet.movement_y);
-            // printk_color(GREEN, BLACK, " (Mouse: byte0:%d, x:%3d, y:%3d, byte3:%3d)\n", packet.byte0, packet.movement_x, packet.movement_y, (unsigned char)packet.byte3);
+            ps2_keyboard_analyze_keycode();
+            struct ps2_mouse_packet_3bytes packet = {0};
+            // struct ps2_mouse_packet_4bytes packet = {0};
+            int errcode = 0;
+            errcode = ps2_mouse_get_packet(&packet);
+            if (errcode == 0)
+            {
+                printk_color(GREEN, BLACK, " (Mouse: byte0:%d, x:%3d, y:%3d)\n", packet.byte0, packet.movement_x, packet.movement_y);
+                // printk_color(GREEN, BLACK, " (Mouse: byte0:%d, x:%3d, y:%3d, byte3:%3d)\n", packet.byte0, packet.movement_x, packet.movement_y, (unsigned char)packet.byte3);
+            }
         }
-    }
-*/
+    */
     /*
         while (1)
         {

+ 0 - 0
kernel/smp/boot_apu.S


+ 13 - 0
kernel/smp/smp.c

@@ -0,0 +1,13 @@
+#include "smp.h"
+#include "../common/kprint.h"
+static struct acpi_Processor_Local_APIC_Structure_t *proc_local_apic_structs[MAX_SUPPORTED_PROCESSOR_NUM];
+static uint32_t total_processor_num = 0;
+
+void smp_init()
+{
+    ul tmp_vaddr[MAX_SUPPORTED_PROCESSOR_NUM] = {0};
+
+    apic_get_ics(ACPI_ICS_TYPE_PROCESSOR_LOCAL_APIC, &tmp_vaddr, &total_processor_num);
+
+    kdebug("processor num=%d", total_processor_num);
+}

+ 12 - 0
kernel/smp/smp.h

@@ -0,0 +1,12 @@
+#include "../common/glib.h"
+
+#include "../common/asm.h"
+#include "../driver/acpi/acpi.h"
+#include "../driver/interrupt/apic/apic.h"
+
+#define MAX_SUPPORTED_PROCESSOR_NUM 1024    // 操作系统支持的最大处理器数量
+/**
+ * @brief 初始化对称多核处理器
+ *
+ */
+void smp_init();