mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-21 00:06:32 +00:00
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:
@ -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)
|
||||
|
24
kernel/src/driver/acpi/c_adapter.rs
Normal file
24
kernel/src/driver/acpi/c_adapter.rs
Normal 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);
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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(
|
Reference in New Issue
Block a user