From 8b105cb8a7fd66bf669b152c72f31a934b8b6bbf Mon Sep 17 00:00:00 2001 From: TheOddGarlic Date: Tue, 9 Aug 2022 14:53:25 +0300 Subject: [PATCH] progress, i guess --- ableos/src/arch/x86_64/memory.rs | 3 +- ableos/src/devices/pci/piix.rs | 160 +++++++++++++++++++++---------- ableos/src/kmain.rs | 8 +- ableos/src/scratchpad.rs | 12 +-- 4 files changed, 118 insertions(+), 65 deletions(-) diff --git a/ableos/src/arch/x86_64/memory.rs b/ableos/src/arch/x86_64/memory.rs index 35e4fbe2..df43bb38 100644 --- a/ableos/src/arch/x86_64/memory.rs +++ b/ableos/src/arch/x86_64/memory.rs @@ -1,7 +1,8 @@ use bootloader::bootinfo::{MemoryMap, MemoryRegionType}; use x86_64::{ structures::paging::{ - FrameAllocator, Mapper, OffsetPageTable, Page, PageTable, PhysFrame, Size4KiB, FrameDeallocator, + FrameAllocator, FrameDeallocator, Mapper, OffsetPageTable, Page, PageTable, PhysFrame, + Size4KiB, }, PhysAddr, VirtAddr, }; diff --git a/ableos/src/devices/pci/piix.rs b/ableos/src/devices/pci/piix.rs index 5793530d..1bf32e7b 100644 --- a/ableos/src/devices/pci/piix.rs +++ b/ableos/src/devices/pci/piix.rs @@ -1,30 +1,53 @@ +/* + * Copyright (c) 2022, Umut İnan Erdoğan + * + * SPDX-License-Identifier: MPL-2.0 + */ + +use core::num::TryFromIntError; + use x86_64::structures::paging::{FrameAllocator, FrameDeallocator}; // FIXME: platform agnostic paging stuff -use x86_64::structures::paging::{PhysFrame, Size4KiB, mapper::MapToError, Mapper, Page}; +use x86_64::structures::paging::{mapper::MapToError, Mapper, Page, PhysFrame, Size4KiB}; use x86_64::VirtAddr; use crate::arch::memory::BootInfoFrameAllocator; -use super::{PciDeviceInfo, check_device}; +use super::port::Port; +use super::{check_device, PciDeviceInfo}; const PRDT_START: u64 = 0x_ffff_ffff_0000_0000; const BUFFER_START: u64 = 0x_ffff_ffff_0000_1000; +/// Bus Master IDE Command +const BMIC_OFFSET: u16 = 0; +/// Bus Master IDE Status +const BMIS_OFFSET: u16 = 2; +/// Bus Master IDE Descriptor Table Pointer +const BMIDTP_OFFSET: u16 = 4; + +/// Bus Master IDE Secondary Offset +const BMI_SECONDARY: u16 = 8; + pub struct Piix { device_info: PciDeviceInfo, prdt_frame: Option, buffer_frames: Option>, + bmiba: u16, } impl Piix { + // FIXME: make this return a Result pub fn new(bus: u8, device: u8) -> Option { let device_info = check_device(bus, device)?; trace!("device_info: {device_info}"); + let bmiba = device_info.bars[4] & 0xFFFFFFFC; Some(Self { device_info, prdt_frame: None, buffer_frames: None, + bmiba: bmiba.try_into().ok()?, }) } @@ -35,25 +58,29 @@ impl Piix { ) -> Result<(), MapToError> { 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)?; let buffer_frames = { - let mut frame = frame_allocator.allocate_frame() + 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() + 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)?;; + let frame = frame_allocator + .allocate_frame() + .ok_or(MapToError::FrameAllocationFailed)?; frames.push(frame); } @@ -62,67 +89,98 @@ impl Piix { let flags = Flags::NO_CACHE | Flags::PRESENT | Flags::WRITABLE; unsafe { - mapper.map_to( - Page::containing_address(VirtAddr::new(PRDT_START)), - prdt_frame, - flags, - frame_allocator, - )?.flush(); - - for (i, frame) in buffer_frames.iter().enumerate() { - mapper.map_to( - Page::containing_address(VirtAddr::new(BUFFER_START + i as u64 * 0x1000)), - *frame, + mapper + .map_to( + Page::containing_address(VirtAddr::new(PRDT_START)), + 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: {prdt_frame:?}"); - trace!("buffer_frames: {buffer_frames:?}"); self.prdt_frame = Some(prdt_frame); self.buffer_frames = Some(buffer_frames); Ok(()) } - pub fn read(&self) { - // bus master interface base address - let bmiba = self.device_info.bars[4] as *mut BusMasterInterface; - // bmiba.bmidtpp = prdt; - } -} + pub fn read(&self) -> Result<(), TryFromIntError> { + // prepare PRD table + let prd = PRDT_START as *mut PhysRegionDescriptor; + unsafe { + (*prd).data_buffer = self.buffer_frames.as_ref().unwrap()[0] + .start_address() + .as_u64() + .try_into()?; + // we want to read 512 bytes + (*prd).byte_count = 512; + // this is the end of table + (*prd).eot = 1 << 7; + } -#[derive(Copy, Clone, Debug)] -#[repr(C, packed)] -struct BusMasterInterface { - /// Bus Master IDE Command (primary) - pub bmicp: u8, - /// Reserved - pub _0: u8, - /// Bus Master IDE Status (primary) - pub bmisp: u8, - /// Reserved - pub _1: u8, - /// Bus Master IDE Descriptor Table Pointer (primary) - pub bmidtpp: u32, - /// Bus Master IDE Command (secondary) - pub bmics: u8, - /// Reserved - pub _2: u8, - /// Bus Master IDE Status (secondary) - pub bmiss: u8, - /// Reserved - pub _3: u8, - /// Bus Master IDE Descriptor Table Pointer (secondary) - pub bmidtps: u32, + unsafe { + self.stop(false); + self.set_read(false); + self.clear_status(false); + // (*bmiba).bmidtpp = self.prdt_frame.unwrap().start_address().as_u64().try_into()?; + } + + Ok(()) + } + + unsafe fn stop(&self, secondary: bool) { + let addr = if secondary { BMI_SECONDARY } else { 0 } + self.bmiba + BMIC_OFFSET; + let mut bmic = Port::::new(addr).read(); + // stop ongoing transfer + bmic &= !1; + // write the new bmic + Port::::new(addr).write(bmic); + } + + unsafe fn set_read(&self, secondary: bool) { + let addr = if secondary { BMI_SECONDARY } else { 0 } + self.bmiba + BMIC_OFFSET; + let mut bmic = Port::::new(addr).read(); + // mark bit 3 as 0 (read) + bmic &= !(1 << 3); + // write the new bmic + Port::::new(addr).write(bmic); + } + + unsafe fn set_write(&self, secondary: bool) { + let addr = if secondary { BMI_SECONDARY } else { 0 } + self.bmiba + BMIC_OFFSET; + let mut bmic = Port::::new(addr).read(); + // mark bit 3 as 1 (write) + bmic |= 1 << 3; + // write the new bmic + Port::::new(addr).write(bmic); + } + + unsafe fn clear_status(&self, secondary: bool) { + let addr = if secondary { BMI_SECONDARY } else { 0 } + self.bmiba + BMIS_OFFSET; + let mut bmis = Port::::new(addr).read(); + // write 1 to bits 1 (DMA error) and 2 (int status) which clears them + bmis |= 1 << 1 | 1 << 2; + // write the new bmis + Port::::new(addr).write(bmis); + } } #[repr(C, packed)] struct PhysRegionDescriptor { /// Pointer to the data buffer pub data_buffer: u32, - /// Byte count, 64K maximum per PRD transfer + /// Byte count, 64K maximum per PRD transfer. 0 means 64K pub byte_count: u16, /// Reserved byte pub _0: u8, diff --git a/ableos/src/kmain.rs b/ableos/src/kmain.rs index ef24c9c9..0a2ac2e8 100644 --- a/ableos/src/kmain.rs +++ b/ableos/src/kmain.rs @@ -12,9 +12,7 @@ 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}; -use crate::{ - boot_conf::KernelConfig, scratchpad, systeminfo::RELEASE_TYPE, TERM, -}; +use crate::{boot_conf::KernelConfig, scratchpad, systeminfo::RELEASE_TYPE, TERM}; use crate::{filesystem, hardware}; use kernel::KERNEL_VERSION; use spin::Lazy; @@ -54,7 +52,9 @@ pub fn kernel_main( // FIXME: unhardcode this and do device discovery let mut piix = Piix::new(0, 3).unwrap(); - piix.allocate_dma_frame(&mut mapper, &mut frame_allocator).unwrap(); + piix.allocate_dma_frame(&mut mapper, &mut frame_allocator) + .unwrap(); + piix.read().unwrap(); /* diff --git a/ableos/src/scratchpad.rs b/ableos/src/scratchpad.rs index 2ce80e70..045289f5 100644 --- a/ableos/src/scratchpad.rs +++ b/ableos/src/scratchpad.rs @@ -12,11 +12,7 @@ use crate::filesystem::vfs::VFS; use crate::systeminfo::{KERNEL_VERSION, RELEASE_TYPE}; use crate::time::fetch_time; use crate::{ - arch::shutdown, - rhai_shell::KEYBUFF, - vterm::VTerm, - KERNEL_STATE, - wasm_jumploader::run_program, + arch::shutdown, rhai_shell::KEYBUFF, vterm::VTerm, wasm_jumploader::run_program, KERNEL_STATE, }; use acpi::{AcpiTables, PlatformInfo}; @@ -236,7 +232,7 @@ pub fn command_parser(user: String, command: String) { "echo" => match conf_args.1.arguments.get("p") { Some(path) => echo_file(path.to_string()), None => println!("No path provided"), - } + }, "test" => {} "quit" => shutdown(), "tree" => filesystem::tree("/").unwrap(), @@ -308,9 +304,7 @@ pub fn echo_file(path: String) { let mut current_path = String::from("/"); current_path.push_str(&path); let mut vfs = VFS.lock(); - let handle = vfs - .resolve(¤t_path) - .unwrap(); + let handle = vfs.resolve(¤t_path).unwrap(); let file = vfs.fs_node(handle).unwrap(); if file.is_dir() {