allocate 16 frames for DMA

This commit is contained in:
TheOddGarlic 2022-08-09 11:11:15 +03:00
parent 6bc74e896c
commit 3cb666d26e
3 changed files with 65 additions and 7 deletions

View file

@ -1,7 +1,7 @@
use bootloader::bootinfo::{MemoryMap, MemoryRegionType}; use bootloader::bootinfo::{MemoryMap, MemoryRegionType};
use x86_64::{ use x86_64::{
structures::paging::{ structures::paging::{
FrameAllocator, Mapper, OffsetPageTable, Page, PageTable, PhysFrame, Size4KiB, FrameAllocator, Mapper, OffsetPageTable, Page, PageTable, PhysFrame, Size4KiB, FrameDeallocator,
}, },
PhysAddr, VirtAddr, PhysAddr, VirtAddr,
}; };
@ -109,3 +109,9 @@ unsafe impl FrameAllocator<Size4KiB> for BootInfoFrameAllocator {
frame frame
} }
} }
impl FrameDeallocator<Size4KiB> for BootInfoFrameAllocator {
unsafe fn deallocate_frame(&mut self, _frame: PhysFrame<Size4KiB>) {
// TODO
}
}

View file

@ -1,14 +1,19 @@
use x86_64::structures::paging::{FrameAllocator, FrameDeallocator};
// FIXME: platform agnostic paging stuff // 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 x86_64::VirtAddr;
use crate::arch::memory::BootInfoFrameAllocator;
use super::{PciDeviceInfo, check_device}; use super::{PciDeviceInfo, check_device};
const PRDT_START: u64 = 0x_ffff_ffff_0000_0000; const PRDT_START: u64 = 0x_ffff_ffff_0000_0000;
const BUFFER_START: u64 = 0x_ffff_ffff_0000_1000;
pub struct Piix { pub struct Piix {
device_info: PciDeviceInfo, device_info: PciDeviceInfo,
prdt_frame: Option<PhysFrame>, prdt_frame: Option<PhysFrame>,
buffer_frames: Option<Vec<PhysFrame>>,
} }
impl Piix { impl Piix {
@ -19,18 +24,41 @@ impl Piix {
Some(Self { Some(Self {
device_info, device_info,
prdt_frame: None, prdt_frame: None,
buffer_frames: None,
}) })
} }
pub fn allocate_dma_frame( pub fn allocate_dma_frame(
&mut self, &mut self,
mapper: &mut impl Mapper<Size4KiB>, mapper: &mut impl Mapper<Size4KiB>,
frame_allocator: &mut impl FrameAllocator<Size4KiB>, frame_allocator: &mut BootInfoFrameAllocator,
) -> Result<(), MapToError<Size4KiB>> { ) -> Result<(), MapToError<Size4KiB>> {
use x86_64::structures::paging::PageTableFlags as Flags; use x86_64::structures::paging::PageTableFlags as Flags;
let prdt_frame = frame_allocator.allocate_frame() let prdt_frame = frame_allocator.allocate_frame()
.ok_or(MapToError::FrameAllocationFailed)?; .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; let flags = Flags::NO_CACHE | Flags::PRESENT | Flags::WRITABLE;
unsafe { unsafe {
@ -39,11 +67,22 @@ impl Piix {
prdt_frame, prdt_frame,
flags, flags,
frame_allocator, 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.prdt_frame = Some(prdt_frame);
self.buffer_frames = Some(buffer_frames);
Ok(()) Ok(())
} }
@ -78,3 +117,15 @@ struct BusMasterInterface {
/// Bus Master IDE Descriptor Table Pointer (secondary) /// Bus Master IDE Descriptor Table Pointer (secondary)
pub bmidtps: u32, 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,
}

View file

@ -8,6 +8,7 @@
use core::sync::atomic::AtomicU64; use core::sync::atomic::AtomicU64;
use crate::arch::memory::BootInfoFrameAllocator;
use crate::arch::{drivers::sysinfo::master, init, sloop}; use crate::arch::{drivers::sysinfo::master, init, sloop};
use crate::devices::pci::piix::Piix; use crate::devices::pci::piix::Piix;
use crate::relib::network::socket::{SimpleSock, Socket}; use crate::relib::network::socket::{SimpleSock, Socket};
@ -19,7 +20,7 @@ use kernel::KERNEL_VERSION;
use spin::Lazy; use spin::Lazy;
// FIXME: platform agnostic paging stuff // 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 // TODO: Change this structure to allow for multiple cores loaded
pub static KERNEL_CONF: Lazy<KernelConfig> = Lazy::new(KernelConfig::new); pub static KERNEL_CONF: Lazy<KernelConfig> = Lazy::new(KernelConfig::new);
@ -27,7 +28,7 @@ pub static KERNEL_CONF: Lazy<KernelConfig> = Lazy::new(KernelConfig::new);
/// The main entry point of the kernel /// The main entry point of the kernel
pub fn kernel_main( pub fn kernel_main(
mut mapper: impl Mapper<Size4KiB>, mut mapper: impl Mapper<Size4KiB>,
mut frame_allocator: impl FrameAllocator<Size4KiB>, mut frame_allocator: BootInfoFrameAllocator,
) -> ! { ) -> ! {
init::init(); init::init();