From 60dc9f4932d3a5e975ee6dfef87f2add6ec00781 Mon Sep 17 00:00:00 2001 From: fslongjin Date: Mon, 4 Apr 2022 18:42:22 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A3=80=E6=B5=8B=E5=A4=84=E7=90=86=E5=99=A8?= =?UTF-8?q?=E6=A0=B8=E5=BF=83=E6=95=B0=E9=87=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kernel/Makefile | 7 +++--- kernel/common/glib.h | 1 + kernel/driver/acpi/acpi.c | 8 ++++--- kernel/driver/acpi/acpi.h | 9 -------- kernel/driver/interrupt/apic/apic.c | 35 +++++++++++++++++++++++++++- kernel/driver/interrupt/apic/apic.h | 17 +++++++++++++- kernel/main.c | 36 ++++++++++++++--------------- kernel/smp/boot_apu.S | 0 kernel/smp/smp.c | 13 +++++++++++ kernel/smp/smp.h | 12 ++++++++++ 10 files changed, 103 insertions(+), 35 deletions(-) create mode 100644 kernel/smp/boot_apu.S create mode 100644 kernel/smp/smp.c create mode 100644 kernel/smp/smp.h diff --git a/kernel/Makefile b/kernel/Makefile index 0480116b..c559f3e4 100644 --- a/kernel/Makefile +++ b/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 diff --git a/kernel/common/glib.h b/kernel/common/glib.h index 9ca4291c..c7a59bd6 100644 --- a/kernel/common/glib.h +++ b/kernel/common/glib.h @@ -7,6 +7,7 @@ //引入对bool类型的支持 #include +#include #define NULL 0 diff --git a/kernel/driver/acpi/acpi.c b/kernel/driver/acpi/acpi.c index 416ff436..9fe5c0ba 100644 --- a/kernel/driver/acpi/acpi.c +++ b/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); diff --git a/kernel/driver/acpi/acpi.h b/kernel/driver/acpi/acpi.h index 3ce7fec6..2ae3a21f 100644 --- a/kernel/driver/acpi/acpi.h +++ b/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(); \ No newline at end of file diff --git a/kernel/driver/interrupt/apic/apic.c b/kernel/driver/interrupt/apic/apic.c index 59b9a94e..c12b1924 100644 --- a/kernel/driver/interrupt/apic/apic.c +++ b/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; } \ No newline at end of file diff --git a/kernel/driver/interrupt/apic/apic.h b/kernel/driver/interrupt/apic/apic.h index 00373a83..cbc7f92f 100644 --- a/kernel/driver/interrupt/apic/apic.h +++ b/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); // 边沿触发 \ No newline at end of file +void apic_ioapic_edge_ack(ul irq_num); // 边沿触发 diff --git a/kernel/main.c b/kernel/main.c index c136692c..af5657fd 100644 --- a/kernel/main.c +++ b/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) { diff --git a/kernel/smp/boot_apu.S b/kernel/smp/boot_apu.S new file mode 100644 index 00000000..e69de29b diff --git a/kernel/smp/smp.c b/kernel/smp/smp.c new file mode 100644 index 00000000..02e848dc --- /dev/null +++ b/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); +} \ No newline at end of file diff --git a/kernel/smp/smp.h b/kernel/smp/smp.h new file mode 100644 index 00000000..0810433b --- /dev/null +++ b/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();