From 3cb666d26e4e433c9aff1533a9a04f8430170439 Mon Sep 17 00:00:00 2001 From: TheOddGarlic Date: Tue, 9 Aug 2022 11:11:15 +0300 Subject: [PATCH] allocate 16 frames for DMA --- ableos/src/arch/x86_64/memory.rs | 8 ++++- ableos/src/devices/pci/piix.rs | 59 +++++++++++++++++++++++++++++--- ableos/src/kmain.rs | 5 +-- 3 files changed, 65 insertions(+), 7 deletions(-) diff --git a/ableos/src/arch/x86_64/memory.rs b/ableos/src/arch/x86_64/memory.rs index 338daae0..35e4fbe2 100644 --- a/ableos/src/arch/x86_64/memory.rs +++ b/ableos/src/arch/x86_64/memory.rs @@ -1,7 +1,7 @@ use bootloader::bootinfo::{MemoryMap, MemoryRegionType}; use x86_64::{ structures::paging::{ - FrameAllocator, Mapper, OffsetPageTable, Page, PageTable, PhysFrame, Size4KiB, + FrameAllocator, Mapper, OffsetPageTable, Page, PageTable, PhysFrame, Size4KiB, FrameDeallocator, }, PhysAddr, VirtAddr, }; @@ -109,3 +109,9 @@ unsafe impl FrameAllocator for BootInfoFrameAllocator { frame } } + +impl FrameDeallocator for BootInfoFrameAllocator { + unsafe fn deallocate_frame(&mut self, _frame: PhysFrame) { + // TODO + } +} diff --git a/ableos/src/devices/pci/piix.rs b/ableos/src/devices/pci/piix.rs index 416aa329..5793530d 100644 --- a/ableos/src/devices/pci/piix.rs +++ b/ableos/src/devices/pci/piix.rs @@ -1,14 +1,19 @@ +use x86_64::structures::paging::{FrameAllocator, FrameDeallocator}; // FIXME: platform agnostic paging stuff -use x86_64::structures::paging::{PhysFrame, FrameAllocator, Size4KiB, mapper::MapToError, Mapper, Page}; +use x86_64::structures::paging::{PhysFrame, Size4KiB, mapper::MapToError, Mapper, Page}; use x86_64::VirtAddr; +use crate::arch::memory::BootInfoFrameAllocator; + use super::{PciDeviceInfo, check_device}; const PRDT_START: u64 = 0x_ffff_ffff_0000_0000; +const BUFFER_START: u64 = 0x_ffff_ffff_0000_1000; pub struct Piix { device_info: PciDeviceInfo, prdt_frame: Option, + buffer_frames: Option>, } impl Piix { @@ -19,18 +24,41 @@ impl Piix { Some(Self { device_info, prdt_frame: None, + buffer_frames: None, }) } pub fn allocate_dma_frame( &mut self, mapper: &mut impl Mapper, - frame_allocator: &mut impl FrameAllocator, + frame_allocator: &mut BootInfoFrameAllocator, ) -> Result<(), MapToError> { use x86_64::structures::paging::PageTableFlags as Flags; let prdt_frame = frame_allocator.allocate_frame() .ok_or(MapToError::FrameAllocationFailed)?; + let buffer_frames = { + let mut frame = frame_allocator.allocate_frame() + .ok_or(MapToError::FrameAllocationFailed)?; + while !frame.start_address().is_aligned(0x10000u64) { + unsafe { + frame_allocator.deallocate_frame(frame); + } + + frame = frame_allocator.allocate_frame() + .ok_or(MapToError::FrameAllocationFailed)?; + } + + let mut frames = Vec::with_capacity(16); + frames.push(frame); + for _ in 0..15 { + let frame = frame_allocator.allocate_frame() + .ok_or(MapToError::FrameAllocationFailed)?;; + frames.push(frame); + } + + frames + }; let flags = Flags::NO_CACHE | Flags::PRESENT | Flags::WRITABLE; unsafe { @@ -39,11 +67,22 @@ impl Piix { prdt_frame, flags, frame_allocator, - )?.flush() + )?.flush(); + + for (i, frame) in buffer_frames.iter().enumerate() { + mapper.map_to( + Page::containing_address(VirtAddr::new(BUFFER_START + i as u64 * 0x1000)), + *frame, + flags, + frame_allocator, + )?.flush() + } } - trace!("{prdt_frame:#?}"); + trace!("prdt_frame: {prdt_frame:?}"); + trace!("buffer_frames: {buffer_frames:?}"); self.prdt_frame = Some(prdt_frame); + self.buffer_frames = Some(buffer_frames); Ok(()) } @@ -78,3 +117,15 @@ struct BusMasterInterface { /// Bus Master IDE Descriptor Table Pointer (secondary) pub bmidtps: u32, } + +#[repr(C, packed)] +struct PhysRegionDescriptor { + /// Pointer to the data buffer + pub data_buffer: u32, + /// Byte count, 64K maximum per PRD transfer + pub byte_count: u16, + /// Reserved byte + pub _0: u8, + /// MSB marks end of transfer + pub eot: u8, +} diff --git a/ableos/src/kmain.rs b/ableos/src/kmain.rs index eea56b20..ef24c9c9 100644 --- a/ableos/src/kmain.rs +++ b/ableos/src/kmain.rs @@ -8,6 +8,7 @@ use core::sync::atomic::AtomicU64; +use crate::arch::memory::BootInfoFrameAllocator; use crate::arch::{drivers::sysinfo::master, init, sloop}; use crate::devices::pci::piix::Piix; use crate::relib::network::socket::{SimpleSock, Socket}; @@ -19,7 +20,7 @@ use kernel::KERNEL_VERSION; use spin::Lazy; // FIXME: platform agnostic paging stuff -use x86_64::structures::paging::{Mapper, FrameAllocator, Size4KiB}; +use x86_64::structures::paging::{Mapper, Size4KiB}; // TODO: Change this structure to allow for multiple cores loaded pub static KERNEL_CONF: Lazy = Lazy::new(KernelConfig::new); @@ -27,7 +28,7 @@ pub static KERNEL_CONF: Lazy = Lazy::new(KernelConfig::new); /// The main entry point of the kernel pub fn kernel_main( mut mapper: impl Mapper, - mut frame_allocator: impl FrameAllocator, + mut frame_allocator: BootInfoFrameAllocator, ) -> ! { init::init();