test: update hosted tests
This commit is contained in:
+5
-2
@@ -5,12 +5,15 @@ edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[target.'cfg(target_arch = "x86_64")'.dependencies]
|
||||
[target.'cfg(all(target_os = "none", target_arch = "x86_64"))'.dependencies]
|
||||
kernel-arch-x86_64 = { path = "x86_64" }
|
||||
|
||||
[target.'cfg(target_arch = "aarch64")'.dependencies]
|
||||
[target.'cfg(all(target_os = "none", target_arch = "aarch64"))'.dependencies]
|
||||
kernel-arch-aarch64 = { path = "aarch64" }
|
||||
|
||||
[target.'cfg(not(target_os = "none"))'.dependencies]
|
||||
kernel-arch-hosted = { path = "hosted" }
|
||||
|
||||
[dependencies]
|
||||
kernel-arch-interface = { path = "interface" }
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
[package]
|
||||
name = "kernel-arch-hosted"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
kernel-arch-interface = { path = "../interface" }
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
libk-mm-interface = { path = "../../libk/libk-mm/interface" }
|
||||
@@ -0,0 +1,176 @@
|
||||
#![feature(never_type)]
|
||||
use std::{
|
||||
marker::PhantomData,
|
||||
sync::atomic::{AtomicBool, Ordering},
|
||||
};
|
||||
|
||||
use kernel_arch_interface::{
|
||||
cpu::IpiQueue,
|
||||
mem::{
|
||||
DeviceMemoryAttributes, KernelTableManager, PhysicalMemoryAllocator, RawDeviceMemoryMapping,
|
||||
},
|
||||
task::{Scheduler, TaskContext},
|
||||
Architecture,
|
||||
};
|
||||
use libk_mm_interface::{
|
||||
address::PhysicalAddress,
|
||||
process::ProcessAddressSpaceManager,
|
||||
table::{MapAttributes, TableAllocator},
|
||||
};
|
||||
use yggdrasil_abi::{error::Error, process::Signal};
|
||||
|
||||
pub struct ArchitectureImpl;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct KernelTableManagerImpl;
|
||||
|
||||
pub struct ProcessAddressSpaceImpl<TA: TableAllocator>(!, PhantomData<TA>);
|
||||
|
||||
pub struct TaskContextImpl<K: KernelTableManager, PA: PhysicalMemoryAllocator>(
|
||||
!,
|
||||
PhantomData<(K, PA)>,
|
||||
);
|
||||
|
||||
static DUMMY_INTERRUPT_MASK: AtomicBool = AtomicBool::new(true);
|
||||
|
||||
impl Architecture for ArchitectureImpl {
|
||||
type PerCpuData = ();
|
||||
|
||||
fn local_cpu() -> *mut Self::PerCpuData {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
unsafe fn set_local_cpu(_cpu: *mut Self::PerCpuData) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
unsafe fn init_local_cpu<S: Scheduler + 'static>(_id: Option<u32>, _data: Self::PerCpuData) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
unsafe fn init_ipi_queues(_queues: Vec<IpiQueue<Self>>) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn idle_task() -> extern "C" fn(usize) -> ! {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn cpu_count() -> usize {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn cpu_index<S: Scheduler + 'static>() -> u32 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
unsafe fn set_interrupt_mask(mask: bool) -> bool {
|
||||
DUMMY_INTERRUPT_MASK.swap(mask, Ordering::Acquire)
|
||||
}
|
||||
|
||||
fn interrupt_mask() -> bool {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn wait_for_interrupt() {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl KernelTableManager for KernelTableManagerImpl {
|
||||
fn virtualize(_phys: u64) -> usize {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn physicalize(_virt: usize) -> u64 {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
unsafe fn map_device_pages(
|
||||
_base: u64,
|
||||
_count: usize,
|
||||
_attrs: DeviceMemoryAttributes,
|
||||
) -> Result<RawDeviceMemoryMapping<Self>, Error> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
unsafe fn unmap_device_pages(_mapping: &RawDeviceMemoryMapping<Self>) {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<TA: TableAllocator> ProcessAddressSpaceManager<TA> for ProcessAddressSpaceImpl<TA> {
|
||||
const LOWER_LIMIT_PFN: usize = 16;
|
||||
const UPPER_LIMIT_PFN: usize = 1024;
|
||||
|
||||
fn new() -> Result<Self, Error> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
unsafe fn clear(&mut self) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
unsafe fn map_page(
|
||||
&mut self,
|
||||
_address: usize,
|
||||
_physical: PhysicalAddress,
|
||||
_flags: MapAttributes,
|
||||
) -> Result<(), Error> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
unsafe fn unmap_page(&mut self, _address: usize) -> Result<PhysicalAddress, Error> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn translate(&self, _address: usize) -> Result<(PhysicalAddress, MapAttributes), Error> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn as_address_with_asid(&self) -> u64 {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: KernelTableManager, PA: PhysicalMemoryAllocator> TaskContext<K, PA>
|
||||
for TaskContextImpl<K, PA>
|
||||
{
|
||||
const USER_STACK_EXTRA_ALIGN: usize = 0;
|
||||
const SIGNAL_STACK_EXTRA_ALIGN: usize = 0;
|
||||
|
||||
unsafe fn enter(&self) -> ! {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
unsafe fn switch(&self, _from: &Self) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
unsafe fn switch_and_drop(&self, _thread: *const ()) {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn user(
|
||||
_entry: usize,
|
||||
_arg: usize,
|
||||
_cr3: u64,
|
||||
_user_stack_sp: usize,
|
||||
_tls_address: usize,
|
||||
) -> Result<Self, Error> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn kernel(_entry: extern "C" fn(usize) -> !, _arg: usize) -> Result<Self, Error> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn kernel_closure<F: FnOnce() -> ! + Send + 'static>(_f: F) -> Result<Self, Error> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
extern "Rust" fn __signal_process_group(_group_id: u32, _signal: Signal) {
|
||||
unimplemented!()
|
||||
}
|
||||
+3
-1
@@ -20,7 +20,9 @@ macro_rules! absolute_address {
|
||||
}
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(target_arch = "aarch64")] {
|
||||
if #[cfg(any(test, not(target_os = "none")))] {
|
||||
extern crate kernel_arch_hosted as imp;
|
||||
} else if #[cfg(target_arch = "aarch64")] {
|
||||
extern crate kernel_arch_aarch64 as imp;
|
||||
} else if #[cfg(target_arch = "x86_64")] {
|
||||
extern crate kernel_arch_x86_64 as imp;
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
[package]
|
||||
name = "hosted-tests"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
authors = ["Mark Poliakov <mark@alnyan.me>"]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
yggdrasil-abi = { git = "https://git.alnyan.me/yggdrasil/yggdrasil-abi.git" }
|
||||
@@ -1,27 +0,0 @@
|
||||
#![no_std]
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::sync::Arc;
|
||||
use yggdrasil_abi::error::Error;
|
||||
|
||||
#[no_mangle]
|
||||
fn __acquire_irq_guard() -> bool {
|
||||
false
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
fn __release_irq_guard(_: bool) {}
|
||||
|
||||
#[no_mangle]
|
||||
fn __current_thread() -> Arc<()> {
|
||||
Arc::new(())
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
fn __suspend_current(_: &()) -> Result<(), Error> {
|
||||
todo!();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
fn __enqueue(_: &Arc<()>) {}
|
||||
@@ -16,6 +16,3 @@ ygg_driver_block = { path = "../../driver/block/core" }
|
||||
|
||||
log = "0.4.20"
|
||||
futures-util = { version = "0.3.28", default-features = false, features = ["alloc", "async-await"] }
|
||||
|
||||
[dev-dependencies]
|
||||
hosted-tests = { path = "../hosted-tests" }
|
||||
|
||||
+12
-68
@@ -564,11 +564,13 @@ impl FileSet {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use core::{mem::MaybeUninit, str::FromStr};
|
||||
use core::{
|
||||
mem::MaybeUninit,
|
||||
str::FromStr,
|
||||
task::{Context, Poll},
|
||||
};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use libk::sync::IrqSafeSpinlock;
|
||||
use ygg_driver_block::BlockDevice;
|
||||
use yggdrasil_abi::{
|
||||
error::Error,
|
||||
io::{DirectoryEntry, FileType, OpenOptions, SeekFrom},
|
||||
@@ -581,7 +583,7 @@ mod tests {
|
||||
impls::const_value_node,
|
||||
node::{AccessToken, CommonImpl, DirectoryImpl, Node, NodeFlags, NodeRef, RegularImpl},
|
||||
traits::{Read, Seek, Write},
|
||||
InstanceData,
|
||||
FileReadiness, InstanceData,
|
||||
};
|
||||
|
||||
#[test]
|
||||
@@ -808,74 +810,16 @@ mod tests {
|
||||
assert_eq!(&buf[..7], b"l123456");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn block_device() {
|
||||
struct B {
|
||||
data: Arc<IrqSafeSpinlock<Vec<u8>>>,
|
||||
}
|
||||
|
||||
impl BlockDevice for B {
|
||||
fn read(&self, pos: u64, buf: &mut [u8]) -> Result<usize, Error> {
|
||||
let data = self.data.lock();
|
||||
let pos = pos as usize;
|
||||
if pos >= data.len() {
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
let count = core::cmp::min(data.len() - pos, buf.len());
|
||||
buf[..count].copy_from_slice(&data[pos..pos + count]);
|
||||
Ok(count)
|
||||
}
|
||||
|
||||
fn write(&self, pos: u64, buf: &[u8]) -> Result<usize, Error> {
|
||||
let mut data = self.data.lock();
|
||||
let pos = pos as usize;
|
||||
if pos >= data.len() {
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
let count = core::cmp::min(data.len() - pos, buf.len());
|
||||
data[pos..pos + count].copy_from_slice(&buf[..count]);
|
||||
Ok(count)
|
||||
}
|
||||
|
||||
fn size(&self) -> Result<u64, Error> {
|
||||
Ok(self.data.lock().len() as _)
|
||||
}
|
||||
}
|
||||
|
||||
let vec = vec![0; 1024];
|
||||
let state = Arc::new(IrqSafeSpinlock::new(vec));
|
||||
let data = state.clone();
|
||||
let dev = Box::leak(Box::new(B { data }));
|
||||
let mut buf = [0; 512];
|
||||
|
||||
let node = Node::block(dev, NodeFlags::empty());
|
||||
|
||||
let file = node
|
||||
.open(
|
||||
OpenOptions::READ | OpenOptions::WRITE,
|
||||
AccessToken::test_authorized(),
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(file.seek(SeekFrom::End(0)).unwrap(), 1024);
|
||||
assert_eq!(file.write(b"12345").unwrap(), 0);
|
||||
assert_eq!(file.seek(SeekFrom::Start(0)).unwrap(), 0);
|
||||
assert_eq!(file.write(b"12345").unwrap(), 5);
|
||||
assert_eq!(&state.lock()[..6], b"12345\0");
|
||||
|
||||
assert_eq!(file.read(&mut buf).unwrap(), 512);
|
||||
assert_eq!(buf, [0; 512]);
|
||||
assert_eq!(file.seek(SeekFrom::Start(2)).unwrap(), 2);
|
||||
assert_eq!(file.read(&mut buf[..8]).unwrap(), 8);
|
||||
assert_eq!(&buf[..8], b"345\0\0\0\0\0");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn char_device() {
|
||||
struct C;
|
||||
|
||||
impl FileReadiness for C {
|
||||
fn poll_read(&self, _cx: &mut Context<'_>) -> Poll<Result<(), Error>> {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
||||
impl CharDevice for C {
|
||||
fn read(&self, buf: &mut [u8]) -> Result<usize, Error> {
|
||||
buf.fill(b'@');
|
||||
|
||||
+1
-3
@@ -1,6 +1,7 @@
|
||||
//! Virtual filesystem interfaces and driver implementation
|
||||
|
||||
#![cfg_attr(not(test), no_std)]
|
||||
#![cfg_attr(test, allow(unused_imports))]
|
||||
#![allow(clippy::new_ret_no_self, clippy::new_without_default)]
|
||||
#![deny(missing_docs)]
|
||||
#![feature(
|
||||
@@ -12,9 +13,6 @@
|
||||
trait_upcasting
|
||||
)]
|
||||
|
||||
#[cfg(test)]
|
||||
extern crate hosted_tests;
|
||||
|
||||
extern crate alloc;
|
||||
|
||||
pub(crate) mod channel;
|
||||
|
||||
Reference in New Issue
Block a user