Browse Source

:new: 创建了acpi模块

fslongjin 3 years ago
parent
commit
e64be7b4df

+ 2 - 1
README.md

@@ -10,8 +10,9 @@
 
 GCC>=8.0
 
-bochs==2.7
+qemu==6.2
 
+grub==2.06
 
 
 ## 如何运行?

+ 7 - 4
kernel/Makefile

@@ -20,10 +20,10 @@ all: kernel
 # cp 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
+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
 	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	\
-	driver/interrupt/pic.o	\
+	driver/acpi/acpi.o driver/interrupt/pic.o 	\
 	-T link.lds
 
 head.o: head.S
@@ -72,10 +72,10 @@ cpu.o: common/cpu.c
 
 # 驱动程序
 # 中断处理芯片的驱动程序
-ifeq ($(PIC), _INTR_8259A_))
+ifeq ($(PIC), _INTR_8259A_)
 pic.o: driver/interrupt/8259A/8259A.c
 	gcc $(CFLAGS) -c driver/interrupt/8259A/8259A.c -o driver/interrupt/pic.o
-else ifeq($(PIC), _INTR_APIC_)
+else
 pic.o: driver/interrupt/apic/apic.c
 	gcc $(CFLAGS) -c driver/interrupt/apic/apic.c -o driver/interrupt/pic.o
 endif
@@ -83,5 +83,8 @@ endif
 multiboot2.o: driver/multiboot2/multiboot2.c 
 	gcc $(CFLAGS) -c driver/multiboot2/multiboot2.c  -o driver/multiboot2/multiboot2.o
 
+acpi.o: driver/acpi/acpi.c 
+	gcc $(CFLAGS) -c driver/acpi/acpi.c  -o driver/acpi/acpi.o
+
 clean: 
 	rm -rf $(GARBAGE)

+ 34 - 0
kernel/driver/acpi/acpi.c

@@ -0,0 +1,34 @@
+#include "acpi.h"
+#include "../../common/printk.h"
+#include "../../common/kprint.h"
+#include "../multiboot2/multiboot2.h"
+
+static struct acpi_RSDP_t *rsdp;
+/**
+ * @brief 迭代器,用于迭代描述符头(位于ACPI标准文件的Table 5-29)
+ * @param  _fun            迭代操作调用的函数
+ * @param  _data           数据
+ */
+void acpi_iter_SDT(bool (*_fun)(const struct acpi_iter_SDT_header_t *, void *),
+               void *_data)
+{
+
+}
+
+/**
+ * @brief 初始化acpi模块
+ * 
+ */
+void acpi_init()
+{
+    kinfo("Initializing ACPI...");
+    struct multiboot_tag_old_acpi_t* tmp1;
+    int reserved;
+    kdebug("yyyy");
+    multiboot2_iter(multiboot2_get_acpi_old_RSDP, tmp1, &reserved);
+    kdebug("1");
+    *rsdp = *(struct acpi_RSDP_t*)(tmp1->rsdp);
+
+    kdebug("RsdtAddress=%#018lx", rsdp->RsdtAddress);
+
+}

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

@@ -0,0 +1,164 @@
+/**
+ * 解析acpi信息的模块
+ **/
+
+#pragma once
+
+#include "../../common/glib.h"
+
+#define ACPI_ICS_TYPE_PROCESSOR_LOCAL_APIC 0
+#define ACPI_ICS_TYPE_IO_APIC 1
+#define ACPI_ICS_TYPE_INTERRUPT_SOURCE_OVERRIDE 2
+#define ACPI_ICS_TYPE_NMI_SOURCE 3
+#define ACPI_ICS_TYPE_LOCAL_APIC_NMI 4
+#define ACPI_ICS_TYPE_LOCAL_APIC_ADDRESS_OVERRIDE 5
+#define ACPI_ICS_TYPE_IO_SAPIC 6
+#define ACPI_ICS_TYPE_LOCAL_SAPIC 7
+#define ACPI_ICS_TYPE_PLATFORM_INTERRUPT_SOURCES 8
+#define ACPI_ICS_TYPE_PROCESSOR_LOCAL_x2APIC 9
+#define ACPI_ICS_TYPE_PROCESSOR_LOCAL_x2APIC_NMI 0xA
+#define ACPI_ICS_TYPE_PROCESSOR_GICC 0xB
+#define ACPI_ICS_TYPE_PROCESSOR_GICD 0xC
+#define ACPI_ICS_TYPE_PROCESSOR_GIC_MSI_Frame 0xD
+#define ACPI_ICS_TYPE_PROCESSOR_GICR 0xE
+#define ACPI_ICS_TYPE_PROCESSOR_GIC_ITS 0xF
+// 0x10-0x7f Reserved. OSPM skips structures of the reserved type.
+// 0x80-0xff Reserved for OEM use
+
+struct acpi_RSDP_t
+{
+    unsigned char Signature[8];
+    unsigned char Checksum;
+    unsigned char OEMID[6];
+
+    unsigned char Revision;
+
+    // 32bit physical address of the RSDT
+    uint RsdtAddress;
+};
+
+struct acpi_RSDP_2_t
+{
+    struct acpi_RSDP_t rsdp1;
+
+    // fields below are only valid when the revision value is 2 or above
+    // 表的长度(单位:字节)从offset=0开始算
+    uint Length;
+    // 64bit的XSDT的物理地址
+    ul XsdtAddress;
+    unsigned char ExtendedChecksum; // 整个表的checksum,包括了之前的checksum区域
+
+    unsigned char Reserved[3];
+};
+
+struct acpi_system_description_table_header_t
+{
+    // The ascii string representation of the table header.
+    unsigned char Signature[4];
+    // 整个表的长度(单位:字节),包括了header,从偏移量0处开始
+    uint Length;
+    // The revision of the  structure corresponding to the signature field for this table.
+    unsigned char Revision;
+    // The entire table, including the checksum field, must add to zero to be considered valid.
+    char Checksum;
+
+    unsigned char OEMID[6];
+    unsigned char OEM_Table_ID[8];
+    uint OEMRevision;
+    uint CreatorID;
+    uint CreatorRevision;
+};
+
+// =========== MADT结构,其中Signature为APIC ============
+struct acpi_Multiple_APIC_Description_Table_t
+{
+    struct acpi_system_description_table_header_t header;
+
+    // 32bit的,每个处理器可访问的local中断控制器的物理地址
+    uint Local_Interrupt_Controller_Address;
+
+    // Multiple APIC flags, 详见 ACPI Specification Version 6.3, Table 5-44
+    uint flags;
+
+    void *Interrupt_Controller_Structure;
+};
+
+struct apic_Interrupt_Controller_Structure_header_t
+{
+    unsigned char type;
+    unsigned char length;
+};
+
+struct acpi_Processor_Local_APIC_Structure_t
+{
+    // type=0
+    struct apic_Interrupt_Controller_Structure_header_t header;
+    unsigned char ACPI_Processor_UID;
+    // 处理器的local apic id
+    unsigned char ACPI_ID;
+    //详见 ACPI Specification Version 6.3, Table 5-47
+    uint flags;
+};
+
+struct acpi_Processor_IO_APIC_Structure_t
+{
+    // type=1
+    struct apic_Interrupt_Controller_Structure_header_t header;
+    unsigned char IO_APIC_ID;
+    unsigned char Reserved;
+    // 32bit的IO APIC物理地址 (每个IO APIC都有一个独立的物理地址)
+    uint IO_APIC_Address;
+    // 当前IO APIC的全局系统中断向量号起始值
+    // The number of intr inputs is determined by the IO APIC's Max Redir Entry register.
+    uint Global_System_Interrupt_Base;
+};
+
+// =========== RSDT 结构 =============
+struct acpi_RSDT_Structure_t
+{
+    // 通过RSDT的header->Length可以计算出entry的数量n
+    // n = (length - 32)/4
+    struct acpi_system_description_table_header_t header;
+
+    // 一个包含了n个32bit物理地址的数组,指向了其他的description headers
+    uint *Entry;
+};
+
+// =========== XSDT 结构 =============
+struct acpi_XSDT_Structure_t
+{
+    // 通过RSDT的header->Length可以计算出entry的数量n
+    // n = (length - 32)/8
+    struct acpi_system_description_table_header_t header;
+
+    // 一个包含了n个64bit物理地址的数组,指向了其他的description headers
+    ul *Entry;
+};
+
+// 要被迭代的系统描述表的开头的sign
+struct acpi_iter_SDT_header_t
+{
+    unsigned char Signature[8];
+};
+
+/**
+ * @brief 迭代器,用于迭代描述符头(位于ACPI标准文件的Table 5-29)
+ * @param  _fun            迭代操作调用的函数
+ * @param  _data           数据
+ */
+void acpi_iter_SDT(bool (*_fun)(const struct acpi_iter_SDT_header_t *, void *),
+                            void *_data);
+
+/**
+ * @brief 获取MADT信息
+ *
+ * @param _iter_data 要被迭代的信息的结构体
+ * @param _data 返回信息的结构体指针
+ * @param count 返回数组的长度
+ * @return true
+ * @return false
+ */
+bool acpi_get_MADT(const struct acpi_iter_SDT_header_t *_iter_data, void *_data);
+
+// 初始化acpi模块
+void acpi_init();

+ 45 - 9
kernel/driver/multiboot2/multiboot2.c

@@ -2,16 +2,17 @@
 #include "assert.h"
 
 #include "../../common/glib.h"
-
+#include"../../common/kprint.h"
 uintptr_t boot_info_addr;
 unsigned int multiboot2_magic;
 unsigned int boot_info_size;
 
 bool multiboot2_init(void)
 {
-    uintptr_t *addr = (uintptr_t*)boot_info_addr;
-    if(multiboot2_magic != MULTIBOOT2_BOOTLOADER_MAGIC);
-        return false;
+    uintptr_t *addr = (uintptr_t *)boot_info_addr;
+    if (multiboot2_magic != MULTIBOOT2_BOOTLOADER_MAGIC)
+        ;
+    return false;
     // addr+0 处保存了大小
     boot_info_size = *(unsigned int *)addr;
     return true;
@@ -20,12 +21,14 @@ bool multiboot2_init(void)
 void multiboot2_iter(bool (*_fun)(const struct iter_data_t *, void *, unsigned int *),
                      void *data, unsigned int *count)
 {
+
     uintptr_t addr = boot_info_addr;
     // 下一字节开始为 tag 信息
     struct iter_data_t *tag = (struct iter_data_t *)(addr + 8);
     for (; tag->type != MULTIBOOT_TAG_TYPE_END;
          tag = (struct iter_data_t *)((uint8_t *)tag + ALIGN(tag->size, 8)))
     {
+
         if (_fun(tag, data, count) == true)
         {
             return;
@@ -73,13 +76,13 @@ bool multiboot2_get_memory(const struct iter_data_t *_iter_data, void *data, uns
 
 /**
  * @brief 获取VBE信息
- * 
+ *
  * @param _iter_data 要被迭代的信息的结构体
  * @param _data 返回信息的结构体指针
  */
 bool multiboot2_get_VBE_info(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
 {
-    
+
     if (_iter_data->type != MULTIBOOT_TAG_TYPE_VBE)
         return false;
     *(struct multiboot_tag_vbe_t *)data = *(struct multiboot_tag_vbe_t *)_iter_data;
@@ -88,14 +91,47 @@ bool multiboot2_get_VBE_info(const struct iter_data_t *_iter_data, void *data, u
 
 /**
  * @brief 获取帧缓冲区信息
- * 
+ *
  * @param _iter_data 要被迭代的信息的结构体
  * @param _data 返回信息的结构体指针
  */
 bool multiboot2_get_Framebuffer_info(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
 {
-    if(_iter_data->type !=MULTIBOOT_TAG_TYPE_FRAMEBUFFER)
+    if (_iter_data->type != MULTIBOOT_TAG_TYPE_FRAMEBUFFER)
+        return false;
+    *(struct multiboot_tag_framebuffer_info_t *)data = *(struct multiboot_tag_framebuffer_info_t *)_iter_data;
+    return true;
+}
+
+/**
+ * @brief 获取acpi旧版RSDP
+ *
+ * @param _iter_data 要被迭代的信息的结构体
+ * @param _data old RSDP的结构体指针
+ * @param reserved
+ * @return uint8_t*  struct multiboot_tag_old_acpi_t
+ */
+bool multiboot2_get_acpi_old_RSDP(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
+{
+    if (_iter_data->type != MULTIBOOT_TAG_TYPE_ACPI_OLD)
+        return false;
+    kdebug("xxx=%#018lx",((struct multiboot_tag_old_acpi_t *)_iter_data)->rsdp);
+    *(struct multiboot_tag_old_acpi_t *)data = *(struct multiboot_tag_old_acpi_t *)_iter_data;
+    return true;
+}
+
+/**
+ * @brief 获取acpi新版RSDP
+ *
+ * @param _iter_data 要被迭代的信息的结构体
+ * @param _data old RSDP的结构体指针
+ * @param reserved
+ * @return uint8_t*  struct multiboot_tag_old_acpi_t
+ */
+bool multiboot2_get_acpi_new_RSDP(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved)
+{
+    if (_iter_data->type != MULTIBOOT_TAG_TYPE_ACPI_NEW)
         return false;
-    *(struct multiboot_tag_framebuffer_info_t *)data = *(struct multiboot_tag_framebuffer_info_t*)_iter_data;
+    *(struct multiboot_tag_new_acpi_t *)data = *(struct multiboot_tag_new_acpi_t *)_iter_data;
     return true;
 }

+ 21 - 1
kernel/driver/multiboot2/multiboot2.h

@@ -447,4 +447,24 @@ bool multiboot2_get_VBE_info(const struct iter_data_t *_iter_data, void *_data,
  * @param _iter_data 要被迭代的信息的结构体
  * @param _data 返回信息的结构体指针
  */
-bool multiboot2_get_Framebuffer_info(const struct iter_data_t *_iter_data, void *_data, unsigned int *reserved);
+bool multiboot2_get_Framebuffer_info(const struct iter_data_t *_iter_data, void *_data, unsigned int *reserved);
+
+/**
+ * @brief 获取acpi旧版RSDP
+ * 
+ * @param _iter_data 要被迭代的信息的结构体
+ * @param _data old RSDP的结构体指针
+ * @param reserved 
+ * @return uint8_t* 
+ */
+bool multiboot2_get_acpi_old_RSDP(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved);
+
+/**
+ * @brief 获取acpi新版RSDP
+ * 
+ * @param _iter_data 要被迭代的信息的结构体
+ * @param _data old RSDP的结构体指针
+ * @param reserved 
+ * @return uint8_t*  struct multiboot_tag_old_acpi_t
+ */
+bool multiboot2_get_acpi_new_RSDP(const struct iter_data_t *_iter_data, void *data, unsigned int *reserved);

+ 7 - 2
kernel/main.c

@@ -13,6 +13,9 @@
 #include "process/process.h"
 #include "syscall/syscall.h"
 
+#include "driver/multiboot2/multiboot2.h"
+#include "driver/acpi/acpi.h"
+
 unsigned int *FR_address = (unsigned int *)0xb8000; //帧缓存区的地址
 
 struct memory_desc memory_management_struct = {{0}, 0};
@@ -156,9 +159,11 @@ void system_initialize()
     syscall_init();
 
     cpu_init();
-
+    
+    acpi_init();
     // test_slab();
-    test_mm();
+    // test_mm();
+
     //  再初始化进程模块。顺序不能调转
     // process_init();
 }