progress, i guess
This commit is contained in:
parent
3cb666d26e
commit
148c66eae2
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
Page::containing_address(VirtAddr::new(PRDT_START)),
|
.map_to(
|
||||||
prdt_frame,
|
Page::containing_address(VirtAddr::new(PRDT_START)),
|
||||||
flags,
|
prdt_frame,
|
||||||
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,
|
|
||||||
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: {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,
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
||||||
|
|
|
@ -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(¤t_path).unwrap();
|
||||||
.resolve(¤t_path)
|
|
||||||
.unwrap();
|
|
||||||
let file = vfs.fs_node(handle).unwrap();
|
let file = vfs.fs_node(handle).unwrap();
|
||||||
|
|
||||||
if file.is_dir() {
|
if file.is_dir() {
|
||||||
|
|
Loading…
Reference in a new issue