ahci内存越界问题修复+ mm的bug修复+在rust中解析acpi table (#384)

* bugfix: 修复了Flusher Drop的时候没有自动刷新TLB的bug

* 解决进程管理未初始化时,trap.c尝试打印pid导致错误的问题

* 设置kmalloc默认强制清0

* 修复ahci驱动的内存越界问题
* 修复mmio buddy忘记归还buddy block的问题
* 新增acpi模块,暂时能解析acpi tables
This commit is contained in:
LoGin
2023-09-17 15:41:01 +08:00
committed by GitHub
parent 1111099746
commit 7ae679ddd6
19 changed files with 234 additions and 92 deletions

View File

@ -5,6 +5,8 @@
#include <mm/mm.h>
#include <mm/mmio.h>
extern void rs_acpi_init(uint64_t rsdp_paddr);
#define acpi_get_RSDT_entry_vaddr(phys_addr) (acpi_description_header_base + (phys_addr)-acpi_RSDT_entry_phys_base) // 获取RSDT entry的虚拟地址
// #define acpi_get_XSDT_entry_vaddr(phys_addr) (ACPI_DESCRIPTION_HEDERS_BASE + (phys_addr)-acpi_XSDT_entry_phys_base) // 获取XSDT entry的虚拟地址
@ -138,6 +140,8 @@ void acpi_init()
multiboot2_iter(multiboot2_get_acpi_new_RSDP, &new_acpi, &reserved);
rsdpv2 = &(new_acpi.rsdp);
rs_acpi_init((uint64_t)rsdpv1);
uint64_t paddr = 0;
// An ACPI-compatible OS must use the XSDT if present
if (rsdpv2->XsdtAddress != 0x00UL)

View File

@ -0,0 +1,24 @@
use crate::{
arch::MMArch,
libs::align::AlignedBox,
mm::{MemoryManagementArch, VirtAddr},
};
use super::AcpiManager;
static mut RSDP_TMP_BOX: Option<AlignedBox<[u8; 4096], 4096>> = None;
#[no_mangle]
unsafe extern "C" fn rs_acpi_init(rsdp_vaddr: u64) {
RSDP_TMP_BOX = Some(AlignedBox::new_zeroed().expect("rs_acpi_init(): failed to alloc"));
let size = core::mem::size_of::<acpi::rsdp::Rsdp>();
let tmp_data = core::slice::from_raw_parts(rsdp_vaddr as usize as *const u8, size);
RSDP_TMP_BOX.as_mut().unwrap()[0..size].copy_from_slice(tmp_data);
let rsdp_paddr = MMArch::virt_2_phys(VirtAddr::new(
RSDP_TMP_BOX.as_ref().unwrap().as_ptr() as usize
))
.unwrap();
AcpiManager::init(rsdp_paddr);
}

View File

@ -1 +1,99 @@
pub mod acpi;
use core::{fmt::Debug, ptr::NonNull};
use acpi::AcpiHandler;
use crate::{
kinfo,
libs::{
align::{page_align_down, page_align_up},
once::Once,
},
mm::{
mmio_buddy::{mmio_pool, MMIOSpaceGuard},
PhysAddr, VirtAddr,
},
};
mod c_adapter;
pub mod old;
extern crate acpi;
static mut __ACPI_TABLE: Option<acpi::AcpiTables<AcpiHandlerImpl>> = None;
#[derive(Debug)]
pub struct AcpiManager;
impl AcpiManager {
pub fn init(rsdp_paddr: PhysAddr) {
static INIT: Once = Once::new();
INIT.call_once(|| {
kinfo!("Initializing Acpi Manager...");
let acpi_table: acpi::AcpiTables<AcpiHandlerImpl> =
unsafe { acpi::AcpiTables::from_rsdp(AcpiHandlerImpl, rsdp_paddr.data()) }
.unwrap_or_else(|e| {
panic!("acpi_init(): failed to parse acpi tables, error: {:?}", e)
});
unsafe {
__ACPI_TABLE = Some(acpi_table);
}
kinfo!("Acpi Manager initialized.");
});
}
#[allow(dead_code)]
pub fn tables() -> Option<&'static acpi::AcpiTables<AcpiHandlerImpl>> {
unsafe { __ACPI_TABLE.as_ref() }
}
}
#[derive(Debug, Clone, Copy)]
pub struct AcpiHandlerImpl;
impl AcpiHandler for AcpiHandlerImpl {
unsafe fn map_physical_region<T>(
&self,
physical_address: usize,
size: usize,
) -> acpi::PhysicalMapping<Self, T> {
let offset = physical_address - page_align_down(physical_address);
let size_fix = page_align_up(size + offset);
let mmio_guard = mmio_pool()
.create_mmio(size_fix)
.expect("AcpiHandlerImpl::map_physical_region(): failed to create mmio");
mmio_guard
.map_phys(PhysAddr::new(page_align_down(physical_address)), size_fix)
.expect("AcpiHandlerImpl::map_physical_region(): failed to map phys");
let virtual_start = mmio_guard.vaddr().data() + offset;
let virtual_start = NonNull::new(virtual_start as *mut T).unwrap();
let result: acpi::PhysicalMapping<AcpiHandlerImpl, T> = acpi::PhysicalMapping::new(
physical_address,
virtual_start,
size,
mmio_guard.size(),
AcpiHandlerImpl,
);
MMIOSpaceGuard::leak(mmio_guard);
return result;
}
fn unmap_physical_region<T>(region: &acpi::PhysicalMapping<Self, T>) {
let mmio_guard = unsafe {
MMIOSpaceGuard::from_raw(
VirtAddr::new(page_align_down(
region.virtual_start().as_ref() as *const T as usize
)),
region.mapped_length(),
true,
)
};
drop(mmio_guard);
}
}

View File

@ -3,7 +3,7 @@ use crate::include::bindings::bindings::acpi_system_description_table_header_t;
use core::ptr::{slice_from_raw_parts_mut, NonNull};
// MCFG表中的Segement配置部分开始位置为44+16*n
#[repr(C, packed)]
pub struct Segement_Configuration_Space {
pub struct SegementConfigurationSpace {
pub base_address: u64,
pub segement_group_number: SegmentGroupNumber,
pub bus_begin: u8,
@ -16,7 +16,7 @@ pub struct Segement_Configuration_Space {
/// @return NonNull<[Segement_Configuration_Space]>
pub fn mcfg_find_segment(
head: NonNull<acpi_system_description_table_header_t>,
) -> NonNull<[Segement_Configuration_Space]> {
) -> NonNull<[SegementConfigurationSpace]> {
let table_length = unsafe { (*head.as_ptr()).Length };
let number_of_segments = ((table_length - 44) / 16) as u16;
NonNull::new(slice_from_raw_parts_mut(