1
0
Fork 0
forked from AbleOS/ableos

progress, i guess

This commit is contained in:
TheOddGarlic 2022-08-09 14:53:25 +03:00
parent 3cb666d26e
commit 148c66eae2
4 changed files with 118 additions and 65 deletions

View file

@ -1,7 +1,8 @@
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, FrameDeallocator, FrameAllocator, FrameDeallocator, Mapper, OffsetPageTable, Page, PageTable, PhysFrame,
Size4KiB,
}, },
PhysAddr, VirtAddr, PhysAddr, VirtAddr,
}; };

View file

@ -1,30 +1,53 @@
/*
* Copyright (c) 2022, Umut İnan Erdoğan <umutinanerdogan@pm.me>
*
* SPDX-License-Identifier: MPL-2.0
*/
use core::num::TryFromIntError;
use x86_64::structures::paging::{FrameAllocator, FrameDeallocator}; use x86_64::structures::paging::{FrameAllocator, FrameDeallocator};
// FIXME: platform agnostic paging stuff // 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 x86_64::VirtAddr;
use crate::arch::memory::BootInfoFrameAllocator; 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 PRDT_START: u64 = 0x_ffff_ffff_0000_0000;
const BUFFER_START: u64 = 0x_ffff_ffff_0000_1000; 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 { pub struct Piix {
device_info: PciDeviceInfo, device_info: PciDeviceInfo,
prdt_frame: Option<PhysFrame>, prdt_frame: Option<PhysFrame>,
buffer_frames: Option<Vec<PhysFrame>>, buffer_frames: Option<Vec<PhysFrame>>,
bmiba: u16,
} }
impl Piix { impl Piix {
// FIXME: make this return a Result
pub fn new(bus: u8, device: u8) -> Option<Self> { pub fn new(bus: u8, device: u8) -> Option<Self> {
let device_info = check_device(bus, device)?; let device_info = check_device(bus, device)?;
trace!("device_info: {device_info}"); trace!("device_info: {device_info}");
let bmiba = device_info.bars[4] & 0xFFFFFFFC;
Some(Self { Some(Self {
device_info, device_info,
prdt_frame: None, prdt_frame: None,
buffer_frames: None, buffer_frames: None,
bmiba: bmiba.try_into().ok()?,
}) })
} }
@ -35,25 +58,29 @@ impl Piix {
) -> 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 buffer_frames = {
let mut frame = frame_allocator.allocate_frame() let mut frame = frame_allocator
.allocate_frame()
.ok_or(MapToError::FrameAllocationFailed)?; .ok_or(MapToError::FrameAllocationFailed)?;
while !frame.start_address().is_aligned(0x10000u64) { while !frame.start_address().is_aligned(0x10000u64) {
unsafe { unsafe {
frame_allocator.deallocate_frame(frame); frame_allocator.deallocate_frame(frame);
} }
frame = frame_allocator.allocate_frame() frame = frame_allocator
.allocate_frame()
.ok_or(MapToError::FrameAllocationFailed)?; .ok_or(MapToError::FrameAllocationFailed)?;
} }
let mut frames = Vec::with_capacity(16); let mut frames = Vec::with_capacity(16);
frames.push(frame); frames.push(frame);
for _ in 0..15 { for _ in 0..15 {
let frame = frame_allocator.allocate_frame() let frame = frame_allocator
.ok_or(MapToError::FrameAllocationFailed)?;; .allocate_frame()
.ok_or(MapToError::FrameAllocationFailed)?;
frames.push(frame); frames.push(frame);
} }
@ -62,67 +89,98 @@ impl Piix {
let flags = Flags::NO_CACHE | Flags::PRESENT | Flags::WRITABLE; let flags = Flags::NO_CACHE | Flags::PRESENT | Flags::WRITABLE;
unsafe { unsafe {
mapper.map_to( mapper
.map_to(
Page::containing_address(VirtAddr::new(PRDT_START)), Page::containing_address(VirtAddr::new(PRDT_START)),
prdt_frame, prdt_frame,
flags, flags,
frame_allocator, frame_allocator,
)?.flush(); )?
.flush();
for (i, frame) in buffer_frames.iter().enumerate() { for (i, frame) in buffer_frames.iter().enumerate() {
mapper.map_to( mapper
.map_to(
Page::containing_address(VirtAddr::new(BUFFER_START + i as u64 * 0x1000)), Page::containing_address(VirtAddr::new(BUFFER_START + i as u64 * 0x1000)),
*frame, *frame,
flags, flags,
frame_allocator, frame_allocator,
)?.flush() )?
.flush()
} }
} }
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); self.buffer_frames = Some(buffer_frames);
Ok(()) Ok(())
} }
pub fn read(&self) { pub fn read(&self) -> Result<(), TryFromIntError> {
// bus master interface base address // prepare PRD table
let bmiba = self.device_info.bars[4] as *mut BusMasterInterface; let prd = PRDT_START as *mut PhysRegionDescriptor;
// bmiba.bmidtpp = prdt; 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)] unsafe {
#[repr(C, packed)] self.stop(false);
struct BusMasterInterface { self.set_read(false);
/// Bus Master IDE Command (primary) self.clear_status(false);
pub bmicp: u8, // (*bmiba).bmidtpp = self.prdt_frame.unwrap().start_address().as_u64().try_into()?;
/// Reserved }
pub _0: u8,
/// Bus Master IDE Status (primary) Ok(())
pub bmisp: u8, }
/// Reserved
pub _1: u8, unsafe fn stop(&self, secondary: bool) {
/// Bus Master IDE Descriptor Table Pointer (primary) let addr = if secondary { BMI_SECONDARY } else { 0 } + self.bmiba + BMIC_OFFSET;
pub bmidtpp: u32, let mut bmic = Port::<u8>::new(addr).read();
/// Bus Master IDE Command (secondary) // stop ongoing transfer
pub bmics: u8, bmic &= !1;
/// Reserved // write the new bmic
pub _2: u8, Port::<u8>::new(addr).write(bmic);
/// Bus Master IDE Status (secondary) }
pub bmiss: u8,
/// Reserved unsafe fn set_read(&self, secondary: bool) {
pub _3: u8, let addr = if secondary { BMI_SECONDARY } else { 0 } + self.bmiba + BMIC_OFFSET;
/// Bus Master IDE Descriptor Table Pointer (secondary) let mut bmic = Port::<u8>::new(addr).read();
pub bmidtps: u32, // mark bit 3 as 0 (read)
bmic &= !(1 << 3);
// write the new bmic
Port::<u8>::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::<u8>::new(addr).read();
// mark bit 3 as 1 (write)
bmic |= 1 << 3;
// write the new bmic
Port::<u8>::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::<u8>::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::<u8>::new(addr).write(bmis);
}
} }
#[repr(C, packed)] #[repr(C, packed)]
struct PhysRegionDescriptor { struct PhysRegionDescriptor {
/// Pointer to the data buffer /// Pointer to the data buffer
pub data_buffer: u32, 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, pub byte_count: u16,
/// Reserved byte /// Reserved byte
pub _0: u8, pub _0: u8,

View file

@ -12,9 +12,7 @@ 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};
use crate::{ use crate::{boot_conf::KernelConfig, scratchpad, systeminfo::RELEASE_TYPE, TERM};
boot_conf::KernelConfig, scratchpad, systeminfo::RELEASE_TYPE, TERM,
};
use crate::{filesystem, hardware}; use crate::{filesystem, hardware};
use kernel::KERNEL_VERSION; use kernel::KERNEL_VERSION;
use spin::Lazy; use spin::Lazy;
@ -54,7 +52,9 @@ pub fn kernel_main(
// FIXME: unhardcode this and do device discovery // FIXME: unhardcode this and do device discovery
let mut piix = Piix::new(0, 3).unwrap(); 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();
/* /*

View file

@ -12,11 +12,7 @@ use crate::filesystem::vfs::VFS;
use crate::systeminfo::{KERNEL_VERSION, RELEASE_TYPE}; use crate::systeminfo::{KERNEL_VERSION, RELEASE_TYPE};
use crate::time::fetch_time; use crate::time::fetch_time;
use crate::{ use crate::{
arch::shutdown, arch::shutdown, rhai_shell::KEYBUFF, vterm::VTerm, wasm_jumploader::run_program, KERNEL_STATE,
rhai_shell::KEYBUFF,
vterm::VTerm,
KERNEL_STATE,
wasm_jumploader::run_program,
}; };
use acpi::{AcpiTables, PlatformInfo}; use acpi::{AcpiTables, PlatformInfo};
@ -236,7 +232,7 @@ pub fn command_parser(user: String, command: String) {
"echo" => match conf_args.1.arguments.get("p") { "echo" => match conf_args.1.arguments.get("p") {
Some(path) => echo_file(path.to_string()), Some(path) => echo_file(path.to_string()),
None => println!("No path provided"), None => println!("No path provided"),
} },
"test" => {} "test" => {}
"quit" => shutdown(), "quit" => shutdown(),
"tree" => filesystem::tree("/").unwrap(), "tree" => filesystem::tree("/").unwrap(),
@ -308,9 +304,7 @@ pub fn echo_file(path: String) {
let mut current_path = String::from("/"); let mut current_path = String::from("/");
current_path.push_str(&path); current_path.push_str(&path);
let mut vfs = VFS.lock(); let mut vfs = VFS.lock();
let handle = vfs let handle = vfs.resolve(&current_path).unwrap();
.resolve(&current_path)
.unwrap();
let file = vfs.fs_node(handle).unwrap(); let file = vfs.fs_node(handle).unwrap();
if file.is_dir() { if file.is_dir() {