🆕 从multiboot2获取RSDT结构体

This commit is contained in:
fslongjin 2022-03-13 12:53:32 +08:00
parent e64be7b4df
commit a879bada0a
7 changed files with 115 additions and 23 deletions

View File

@ -2,33 +2,64 @@
#include "../../common/printk.h"
#include "../../common/kprint.h"
#include "../multiboot2/multiboot2.h"
#include "../../mm/mm.h"
static struct acpi_RSDP_t *rsdp;
static struct acpi_RSDP_t *rsdpv1;
static struct acpi_RSDP_2_t *rsdpv2;
static struct acpi_RSDT_Structure_t *rsdt;
static ul acpi_RSDT_offset = 0;
static uint acpi_RSDT_Entry_num = 0;
/**
* @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)
void *_data)
{
}
/**
* @brief acpi模块
*
*
*/
void acpi_init()
{
kinfo("Initializing ACPI...");
struct multiboot_tag_old_acpi_t* tmp1;
// 获取rsdp
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);
multiboot2_iter(multiboot2_get_acpi_old_RSDP, &tmp1, &reserved);
kdebug("RsdtAddress=%#018lx", rsdp->RsdtAddress);
*rsdpv1 = (tmp1.rsdp);
kdebug("Rsdt_phys_Address=%#018lx", rsdpv1->RsdtAddress);
kdebug("RSDP_Revision=%d", rsdpv1->Revision);
// 映射RSDT区域的物理地址到页表
// 暂定字节数为2MB
// 由于页表映射的原因需要清除低21位地址才能填入页表
ul base = rsdpv1->RsdtAddress & (~(0x1fffff));
acpi_RSDT_offset = rsdpv1->RsdtAddress - base;
mm_map_phys_addr(ACPI_RSDT_VIRT_ADDR_BASE, base, PAGE_2M_SIZE, PAGE_KERNEL_PAGE | PAGE_PWT | PAGE_PCD);
kdebug("RSDT mapped!");
struct multiboot_tag_new_acpi_t tmp2;
multiboot2_iter(multiboot2_get_acpi_new_RSDP, &tmp2, &reserved);
*rsdpv2 = tmp2.rsdp;
kdebug("Rsdt_v2_phys_Address=%#018lx", rsdpv2->rsdp1.RsdtAddress);
kdebug("RSDP_v2_Revision=%d", rsdpv2->rsdp1.Revision);
rsdt = ACPI_RSDT_VIRT_ADDR_BASE + acpi_RSDT_offset;
// 计算RSDT Entry的数量
acpi_RSDT_Entry_num = (rsdt->header.Length - 32) / 4;
printk_color(ORANGE, BLACK, "%s\n", rsdt->header.Signature);
printk_color(ORANGE, BLACK, "RSDT Length=%dbytes.\n", rsdt->header.Length);
printk_color(ORANGE, BLACK, "RSDT Entry num=%d\n", acpi_RSDT_Entry_num);
}

View File

@ -25,6 +25,8 @@
// 0x10-0x7f Reserved. OSPM skips structures of the reserved type.
// 0x80-0xff Reserved for OEM use
#define ACPI_RSDT_VIRT_ADDR_BASE 0xffff80000a000000UL
struct acpi_RSDP_t
{
unsigned char Signature[8];

View File

@ -2,7 +2,7 @@
#include "assert.h"
#include "../../common/glib.h"
#include"../../common/kprint.h"
#include "../../common/kprint.h"
uintptr_t boot_info_addr;
unsigned int multiboot2_magic;
unsigned int boot_info_size;
@ -115,8 +115,9 @@ bool multiboot2_get_acpi_old_RSDP(const struct iter_data_t *_iter_data, void *da
{
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;
}

View File

@ -8,6 +8,7 @@
#include "stdint.h"
#include "stdbool.h"
#include "../../common/boot_info.h"
#include "../acpi/acpi.h"
/// @see Multiboot2 Specification version 2.0.pdf
// 启动后,在 32 位内核进入点,机器状态如下:
@ -358,13 +359,15 @@ struct multiboot_tag_smbios_t
struct multiboot_tag_old_acpi_t
{
struct multiboot_tag_t tag_t;
uint8_t rsdp[0];
//uint8_t rsdp[0];
struct acpi_RSDP_t rsdp;
};
struct multiboot_tag_new_acpi_t
{
struct multiboot_tag_t tag_t;
uint8_t rsdp[0];
//uint8_t rsdp[0];
struct acpi_RSDP_2_t rsdp;
};
struct multiboot_tag_network_t
@ -420,7 +423,7 @@ static bool multiboot2_init(void);
* @param _data
*/
void multiboot2_iter(bool (*_fun)(const struct iter_data_t *, void *, unsigned int *),
void *_data, unsigned int *count);
void *_data, unsigned int *count);
/**
* @brief multiboot2协议提供的内存区域信息
@ -451,20 +454,20 @@ bool multiboot2_get_Framebuffer_info(const struct iter_data_t *_iter_data, void
/**
* @brief acpi旧版RSDP
*
*
* @param _iter_data
* @param _data old RSDP的结构体指针
* @param reserved
* @return uint8_t*
* @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
* @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);

View File

@ -152,6 +152,7 @@ void system_initialize()
// 初始化内存管理单元
mm_init();
acpi_init();
// 初始化中断模块
irq_init();
@ -160,7 +161,6 @@ void system_initialize()
cpu_init();
acpi_init();
// test_slab();
// test_mm();

View File

@ -526,4 +526,50 @@ void init_frame_buffer()
set_pos_VBE_FB_addr((uint*)fb_virt_addr);
flush_tlb();
kinfo("VBE frame buffer successfully Re-mapped!");
}
/**
* @brief
*
* @param virt_addr_start
* @param phys_addr_start
* @param length
*/
void mm_map_phys_addr(ul virt_addr_start, ul phys_addr_start, ul length, ul flags)
{
global_CR3 = get_CR3();
// 计算帧缓冲区的线性地址对应的pml4页表项的地址
ul *tmp = phys_2_virt((ul *)((ul)global_CR3 & (~0xfffUL)) + ((virt_addr_start >> PAGE_GDT_SHIFT) & 0x1ff));
if (*tmp == 0)
{
ul *virt_addr = kmalloc(PAGE_4K_SIZE, 0);
set_pml4t(tmp, mk_pml4t(virt_2_phys(virt_addr), PAGE_KERNEL_PGT));
}
tmp = phys_2_virt((ul *)(*tmp & (~0xfffUL)) + ((virt_addr_start >> PAGE_1G_SHIFT) & 0x1ff));
if (*tmp == 0)
{
ul *virt_addr = kmalloc(PAGE_4K_SIZE, 0);
set_pdpt(tmp, mk_pdpt(virt_2_phys(virt_addr), PAGE_KERNEL_DIR));
}
ul *tmp1;
// 初始化2M物理页
int js = 0;
for (ul i = 0; i < (length); i += PAGE_2M_SIZE)
{
// 计算当前2M物理页对应的pdt的页表项的物理地址
tmp1 = phys_2_virt((ul *)(*tmp & (~0xfffUL)) + (((ul)(virt_addr_start + i) >> PAGE_2M_SHIFT) & 0x1ff));
// 页面写穿,禁止缓存
set_pdt(tmp1, mk_pdt((ul)phys_addr_start+i, flags));
++js;
}
kdebug("js=%d", js);
flush_tlb();
}

View File

@ -339,6 +339,15 @@ void page_table_init();
/**
* @brief VBE帧缓存区的地址重新映射
* 0xffff800003000000
* 0xffff800008000000
*/
void init_frame_buffer();
void init_frame_buffer();
/**
* @brief
*
* @param virt_addr_start
* @param phys_addr_start
* @param length
*/
void mm_map_phys_addr(ul virt_addr_start, ul phys_addr_start, ul length, ul flags);