refactor: fix all warnings
This commit is contained in:
@@ -83,7 +83,7 @@ extern "C" fn __aa64_bsp_main(fdt_base: usize) -> ! {
|
||||
// Enable MMU
|
||||
virt::enable().expect("Failed to initialize virtual memory");
|
||||
|
||||
let fdt = init_device_tree(fdt_base).expect("Device tree init failed");
|
||||
let _fdt = init_device_tree(fdt_base).expect("Device tree init failed");
|
||||
|
||||
// Most basic machine init: initialize proper debug output
|
||||
// physical memory
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::arch::{machine, intrin};
|
||||
use crate::debug::Level;
|
||||
use crate::dev::irq::{IntController, IrqContext};
|
||||
use crate::mem;
|
||||
use crate::proc::{sched, Process, Thread};
|
||||
use crate::proc::{sched, Thread};
|
||||
use crate::syscall;
|
||||
use cortex_a::registers::{ESR_EL1, FAR_EL1};
|
||||
use libsys::{abi::SystemCall, signal::Signal, error::Errno};
|
||||
|
||||
@@ -1,14 +1,31 @@
|
||||
//! AArch64-specific assembly functions
|
||||
use core::arch::asm;
|
||||
|
||||
/// Disables delievery of IRQs
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Unsafe: requires EL0
|
||||
#[inline(always)]
|
||||
pub unsafe fn irq_disable() {
|
||||
asm!("msr daifset, {bits}", bits = const 2, options(nomem, nostack, preserves_flags));
|
||||
}
|
||||
|
||||
/// Discards an entry related to `addr` from TLB cache
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Unsafe: requires EL0
|
||||
#[inline(always)]
|
||||
pub unsafe fn flush_tlb_virt(addr: usize) {
|
||||
pub unsafe fn flush_tlb_virt(_addr: usize) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// Discards all entries related to `asid` from TLB cache
|
||||
///
|
||||
/// # Safety
|
||||
///
|
||||
/// Only safe to use for known [Process]es and their ASIDs
|
||||
// TODO non-portable
|
||||
#[inline(always)]
|
||||
pub unsafe fn flush_tlb_asid(asid: usize) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
//! aarch64 architecture implementation
|
||||
|
||||
use core::arch::asm;
|
||||
use cortex_a::registers::DAIF;
|
||||
use tock_registers::interfaces::{Readable, Writeable};
|
||||
|
||||
|
||||
@@ -8,13 +8,15 @@ use tock_registers::{
|
||||
|
||||
macro_rules! wrap_msr {
|
||||
($struct_name:ident, $name:ident, $reg:literal, $fields:tt) => {
|
||||
#[allow(missing_docs)]
|
||||
pub struct $struct_name;
|
||||
|
||||
register_bitfields! {
|
||||
u64,
|
||||
#[allow(missing_docs)]
|
||||
pub $name $fields
|
||||
}
|
||||
|
||||
pub struct $struct_name;
|
||||
|
||||
impl Readable for $struct_name {
|
||||
type T = u64;
|
||||
type R = $name::Register;
|
||||
@@ -41,11 +43,11 @@ macro_rules! wrap_msr {
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(missing_docs)]
|
||||
pub const $name: $struct_name = $struct_name;
|
||||
};
|
||||
}
|
||||
|
||||
/// EL1 Architectural Feature Access Control Register
|
||||
wrap_msr!(CpacrEl1, CPACR_EL1, "cpacr_el1", [
|
||||
/// Enable EL0 and EL1 SIMD/FP accesses to EL1
|
||||
FPEN OFFSET(20) NUMBITS(2) [
|
||||
|
||||
@@ -16,6 +16,7 @@ use libsys::{debug::TraceLevel, error::Errno};
|
||||
use core::convert::TryFrom;
|
||||
use core::fmt;
|
||||
|
||||
/// Currently active print level
|
||||
pub static LEVEL: Level = Level::Debug;
|
||||
|
||||
/// Kernel logging levels
|
||||
|
||||
+13
-19
@@ -1,25 +1,14 @@
|
||||
use crate::arch::machine::{self, IrqNumber};
|
||||
use crate::dev::{
|
||||
irq::{IntController, IntSource},
|
||||
serial::SerialDevice,
|
||||
tty::{CharRing, TtyDevice},
|
||||
Device,
|
||||
};
|
||||
use crate::mem::virt::DeviceMemoryIo;
|
||||
use crate::sync::IrqSafeSpinLock;
|
||||
use crate::util::InitOnce;
|
||||
use libsys::{error::Errno, ioctl::IoctlCmd};
|
||||
//! Virtual (pseudo) device implemetation
|
||||
use crate::dev::Device;
|
||||
use core::sync::atomic::{AtomicU32, Ordering};
|
||||
use tock_registers::{
|
||||
interfaces::{ReadWriteable, Readable, Writeable},
|
||||
register_bitfields, register_structs,
|
||||
registers::{ReadOnly, ReadWrite, WriteOnly},
|
||||
};
|
||||
use libsys::{error::Errno, ioctl::IoctlCmd};
|
||||
use vfs::CharDevice;
|
||||
|
||||
/// Pseudorandom number generator device
|
||||
pub struct Random {
|
||||
state: AtomicU32
|
||||
state: AtomicU32,
|
||||
}
|
||||
/// Zero device
|
||||
pub struct Zero;
|
||||
|
||||
impl Device for Random {
|
||||
@@ -53,7 +42,6 @@ impl CharDevice for Random {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Device for Zero {
|
||||
fn name(&self) -> &'static str {
|
||||
"Zero device"
|
||||
@@ -84,10 +72,12 @@ impl CharDevice for Zero {
|
||||
}
|
||||
|
||||
impl Random {
|
||||
/// Initializes PRNG with a seed value
|
||||
pub fn set_state(&self, state: u32) {
|
||||
self.state.store(state, Ordering::Release);
|
||||
}
|
||||
|
||||
/// Returns a single pseudo-random value
|
||||
pub fn read_single(&self) -> u32 {
|
||||
let mut x = self.state.load(Ordering::Acquire);
|
||||
x ^= x << 13;
|
||||
@@ -98,5 +88,9 @@ impl Random {
|
||||
}
|
||||
}
|
||||
|
||||
pub static RANDOM: Random = Random { state: AtomicU32::new(0) };
|
||||
/// Pseudorandom number generator device
|
||||
pub static RANDOM: Random = Random {
|
||||
state: AtomicU32::new(0),
|
||||
};
|
||||
/// Zero device
|
||||
pub static ZERO: Zero = Zero;
|
||||
|
||||
+11
-6
@@ -1,10 +1,10 @@
|
||||
//! Device list pseudo-filesystem
|
||||
use crate::util::InitOnce;
|
||||
use alloc::boxed::Box;
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
use libsys::{stat::FileMode, error::Errno};
|
||||
use vfs::{CharDevice, Vnode, VnodeData, VnodeRef};
|
||||
use core::cell::RefCell;
|
||||
use vfs::CharDevice;
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
use libsys::{error::Errno, stat::FileMode};
|
||||
use vfs::{Vnode, VnodeData, VnodeRef};
|
||||
|
||||
/// Possible character device kinds
|
||||
#[derive(Debug)]
|
||||
@@ -17,7 +17,11 @@ static DEVFS_ROOT: InitOnce<VnodeRef> = InitOnce::new();
|
||||
|
||||
/// Initializes devfs
|
||||
pub fn init() {
|
||||
let node = Vnode::new("", VnodeData::Directory(RefCell::new(None)), Vnode::CACHE_READDIR | Vnode::CACHE_STAT);
|
||||
let node = Vnode::new(
|
||||
"",
|
||||
VnodeData::Directory(RefCell::new(None)),
|
||||
Vnode::CACHE_READDIR | Vnode::CACHE_STAT,
|
||||
);
|
||||
// let node = Vnode::new("", VnodeKind::Directory, Vnode::CACHE_READDIR | Vnode::CACHE_STAT);
|
||||
node.props_mut().mode = FileMode::default_dir();
|
||||
DEVFS_ROOT.init(node);
|
||||
@@ -28,13 +32,14 @@ pub fn root() -> &'static VnodeRef {
|
||||
DEVFS_ROOT.get()
|
||||
}
|
||||
|
||||
/// Adds device `dev` to devfs with `name`
|
||||
pub fn add_named_char_device(dev: &'static dyn CharDevice, name: &str) -> Result<(), Errno> {
|
||||
infoln!("Add char device: {}", name);
|
||||
|
||||
let node = Vnode::new(name, VnodeData::Char(dev), Vnode::CACHE_STAT);
|
||||
// let node = Vnode::new(name, VnodeKind::Char, Vnode::CACHE_STAT);
|
||||
// node.set_data(Box::new(CharDeviceWrapper::new(dev)));
|
||||
node.props_mut().mode = FileMode::from_bits(0o600).unwrap() | FileMode::S_IFCHR;
|
||||
node.props_mut().mode = FileMode::from_bits(0o600).unwrap() | FileMode::S_IFCHR;
|
||||
|
||||
DEVFS_ROOT.get().attach(node);
|
||||
|
||||
|
||||
+47
-27
@@ -1,17 +1,16 @@
|
||||
//! System control/info virtual filesystem
|
||||
use crate::debug::{self, Level};
|
||||
use crate::util::InitOnce;
|
||||
use alloc::boxed::Box;
|
||||
use core::cell::RefCell;
|
||||
use core::fmt::{self, Write};
|
||||
use core::str::FromStr;
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
use fs_macros::auto_inode;
|
||||
use libsys::{
|
||||
error::Errno,
|
||||
stat::{FileMode, OpenFlags, Stat},
|
||||
ioctl::IoctlCmd,
|
||||
stat::{FileMode, OpenFlags, Stat},
|
||||
};
|
||||
use vfs::{CharDevice, Vnode, VnodeCommon, VnodeData, VnodeFile, VnodeRef};
|
||||
use vfs::{Vnode, VnodeCommon, VnodeData, VnodeFile, VnodeRef};
|
||||
|
||||
struct NodeData<R: Fn(&mut [u8]) -> Result<usize, Errno>, W: Fn(&[u8]) -> Result<usize, Errno>> {
|
||||
read_func: R,
|
||||
@@ -59,32 +58,33 @@ impl<R: Fn(&mut [u8]) -> Result<usize, Errno>, W: Fn(&[u8]) -> Result<usize, Err
|
||||
/// Performs filetype-specific request
|
||||
fn ioctl(
|
||||
&mut self,
|
||||
node: VnodeRef,
|
||||
cmd: IoctlCmd,
|
||||
ptr: usize,
|
||||
len: usize,
|
||||
_node: VnodeRef,
|
||||
_cmd: IoctlCmd,
|
||||
_ptr: usize,
|
||||
_len: usize,
|
||||
) -> Result<usize, Errno> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// Retrieves file status
|
||||
fn stat(&mut self, node: VnodeRef) -> Result<Stat, Errno> {
|
||||
fn stat(&mut self, _node: VnodeRef) -> Result<Stat, Errno> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// Reports the size of this filesystem object in bytes
|
||||
fn size(&mut self, node: VnodeRef) -> Result<usize, Errno> {
|
||||
fn size(&mut self, _node: VnodeRef) -> Result<usize, Errno> {
|
||||
todo!()
|
||||
}
|
||||
|
||||
/// Returns `true` if node is ready for an operation
|
||||
fn is_ready(&mut self, node: VnodeRef, write: bool) -> Result<bool, Errno> {
|
||||
fn ready(&mut self, _node: VnodeRef, _write: bool) -> Result<bool, Errno> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
impl<R: Fn(&mut [u8]) -> Result<usize, Errno>, W: Fn(&[u8]) -> Result<usize, Errno>> VnodeFile
|
||||
for NodeData<R, W> {
|
||||
for NodeData<R, W>
|
||||
{
|
||||
fn read(&mut self, _node: VnodeRef, pos: usize, data: &mut [u8]) -> Result<usize, Errno> {
|
||||
if pos != 0 {
|
||||
// TODO handle this
|
||||
@@ -101,10 +101,10 @@ impl<R: Fn(&mut [u8]) -> Result<usize, Errno>, W: Fn(&[u8]) -> Result<usize, Err
|
||||
(self.write_func)(data)
|
||||
}
|
||||
|
||||
fn truncate(&mut self, node: VnodeRef, size: usize) -> Result<(), Errno> {
|
||||
fn truncate(&mut self, _node: VnodeRef, _size: usize) -> Result<(), Errno> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<R: Fn(&mut [u8]) -> Result<usize, Errno>, W: Fn(&[u8]) -> Result<usize, Errno>>
|
||||
NodeData<R, W>
|
||||
{
|
||||
@@ -117,7 +117,6 @@ impl<R: Fn(&mut [u8]) -> Result<usize, Errno>, W: Fn(&[u8]) -> Result<usize, Err
|
||||
}
|
||||
|
||||
static SYSFS_ROOT: InitOnce<VnodeRef> = InitOnce::new();
|
||||
static TEST_COUNTER: AtomicUsize = AtomicUsize::new(0);
|
||||
|
||||
// TODO subdirs
|
||||
fn add_generic_node<R, W>(parent: Option<VnodeRef>, name: &str, mode: FileMode, read: R, write: W)
|
||||
@@ -139,6 +138,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds a node with and `read` and `write` operations
|
||||
pub fn add_read_write_node<R, W>(parent: Option<VnodeRef>, name: &str, read: R, write: W)
|
||||
where
|
||||
R: Fn(&mut [u8]) -> Result<usize, Errno> + 'static,
|
||||
@@ -153,6 +153,7 @@ where
|
||||
)
|
||||
}
|
||||
|
||||
/// Adds `read`-only node
|
||||
pub fn add_read_node<R>(parent: Option<VnodeRef>, name: &str, read: R)
|
||||
where
|
||||
R: Fn(&mut [u8]) -> Result<usize, Errno> + 'static,
|
||||
@@ -166,8 +167,13 @@ where
|
||||
)
|
||||
}
|
||||
|
||||
/// Creates a directory in sysfs structure
|
||||
pub fn add_directory(parent: Option<VnodeRef>, name: &str) -> Result<VnodeRef, Errno> {
|
||||
let node = Vnode::new(name, VnodeData::Directory(RefCell::new(None)), Vnode::CACHE_READDIR | Vnode::CACHE_STAT);
|
||||
let node = Vnode::new(
|
||||
name,
|
||||
VnodeData::Directory(RefCell::new(None)),
|
||||
Vnode::CACHE_READDIR | Vnode::CACHE_STAT,
|
||||
);
|
||||
node.props_mut().mode = FileMode::from_bits(0o500).unwrap() | FileMode::S_IFDIR;
|
||||
|
||||
if let Some(parent) = parent {
|
||||
@@ -179,26 +185,39 @@ pub fn add_directory(parent: Option<VnodeRef>, name: &str) -> Result<VnodeRef, E
|
||||
Ok(node)
|
||||
}
|
||||
|
||||
/// Returns sysfs root node reference
|
||||
pub fn root() -> &'static VnodeRef {
|
||||
SYSFS_ROOT.get()
|
||||
}
|
||||
|
||||
/// Sets up the sysfs tree
|
||||
pub fn init() {
|
||||
let node = Vnode::new("", VnodeData::Directory(RefCell::new(None)), Vnode::CACHE_READDIR | Vnode::CACHE_STAT);
|
||||
let node = Vnode::new(
|
||||
"",
|
||||
VnodeData::Directory(RefCell::new(None)),
|
||||
Vnode::CACHE_READDIR | Vnode::CACHE_STAT,
|
||||
);
|
||||
node.props_mut().mode = FileMode::default_dir();
|
||||
SYSFS_ROOT.init(node);
|
||||
|
||||
let debug_dir = add_directory(None, "debug").unwrap();
|
||||
|
||||
add_read_write_node(Some(debug_dir.clone()), "level", |buf| {
|
||||
let mut writer = BufferWriter::new(buf);
|
||||
write!(&mut writer, "{}\n", debug::LEVEL as u32).map_err(|_| Errno::InvalidArgument)?;
|
||||
Ok(writer.count())
|
||||
}, |buf| {
|
||||
let s = core::str::from_utf8(buf).map_err(|_| Errno::InvalidArgument)?;
|
||||
let value = u32::from_str(s).map_err(|_| Errno::InvalidArgument).and_then(Level::try_from)?;
|
||||
todo!()
|
||||
});
|
||||
add_read_write_node(
|
||||
Some(debug_dir),
|
||||
"level",
|
||||
|buf| {
|
||||
let mut writer = BufferWriter::new(buf);
|
||||
writeln!(&mut writer, "{}", debug::LEVEL as u32).map_err(|_| Errno::InvalidArgument)?;
|
||||
Ok(writer.count())
|
||||
},
|
||||
|buf| {
|
||||
let s = core::str::from_utf8(buf).map_err(|_| Errno::InvalidArgument)?;
|
||||
let _value = u32::from_str(s)
|
||||
.map_err(|_| Errno::InvalidArgument)
|
||||
.and_then(Level::try_from)?;
|
||||
todo!()
|
||||
},
|
||||
);
|
||||
|
||||
add_read_node(None, "uptime", |buf| {
|
||||
use crate::arch::machine;
|
||||
@@ -206,7 +225,8 @@ pub fn init() {
|
||||
|
||||
let mut writer = BufferWriter::new(buf);
|
||||
let time = machine::local_timer().timestamp()?;
|
||||
write!(&mut writer, "{} {}\n", time.as_secs(), time.subsec_nanos()).map_err(|_| Errno::InvalidArgument)?;
|
||||
writeln!(&mut writer, "{} {}", time.as_secs(), time.subsec_nanos())
|
||||
.map_err(|_| Errno::InvalidArgument)?;
|
||||
Ok(writer.count())
|
||||
});
|
||||
}
|
||||
|
||||
@@ -37,8 +37,6 @@ pub mod sync;
|
||||
pub mod syscall;
|
||||
pub mod util;
|
||||
|
||||
use core::arch::asm;
|
||||
|
||||
#[panic_handler]
|
||||
fn panic_handler(pi: &core::panic::PanicInfo) -> ! {
|
||||
unsafe {
|
||||
|
||||
@@ -28,6 +28,7 @@ pub fn kernel_end_phys() -> usize {
|
||||
}
|
||||
|
||||
// TODO cross-platform variant
|
||||
/// Returns `true` if `virt` address is accessible for requested operation
|
||||
#[inline(always)]
|
||||
pub fn is_el0_accessible(virt: usize, write: bool) -> bool {
|
||||
use core::arch::asm;
|
||||
|
||||
@@ -4,6 +4,9 @@ use crate::sync::IrqSafeSpinLock;
|
||||
use core::mem;
|
||||
use libsys::{error::Errno, mem::memcpy};
|
||||
|
||||
/// # Safety
|
||||
///
|
||||
/// Unsafe to implement because of direct memory manipulation
|
||||
pub unsafe trait Manager {
|
||||
fn alloc_page(&mut self, pu: PageUsage) -> Result<usize, Errno>;
|
||||
fn alloc_contiguous_pages(&mut self, pu: PageUsage, count: usize) -> Result<usize, Errno>;
|
||||
|
||||
+14
-4
@@ -1,7 +1,10 @@
|
||||
//! Process file descriptors and I/O context
|
||||
use alloc::collections::BTreeMap;
|
||||
use libsys::{error::Errno, stat::{FileDescriptor, UserId, GroupId}};
|
||||
use vfs::{FileRef, Ioctx, VnodeRef, VnodeData};
|
||||
use libsys::{
|
||||
error::Errno,
|
||||
stat::{FileDescriptor, GroupId, UserId},
|
||||
};
|
||||
use vfs::{FileRef, Ioctx, VnodeRef};
|
||||
|
||||
/// Process I/O context. Contains file tables, root/cwd info etc.
|
||||
pub struct ProcessIo {
|
||||
@@ -74,7 +77,11 @@ impl ProcessIo {
|
||||
}
|
||||
|
||||
/// Clones a file descriptor into an available slot or, if specified, requested one
|
||||
pub fn duplicate_file(&mut self, src: FileDescriptor, dst: Option<FileDescriptor>) -> Result<FileDescriptor, Errno> {
|
||||
pub fn duplicate_file(
|
||||
&mut self,
|
||||
src: FileDescriptor,
|
||||
dst: Option<FileDescriptor>,
|
||||
) -> Result<FileDescriptor, Errno> {
|
||||
let file_ref = self.file(src)?;
|
||||
if let Some(dst) = dst {
|
||||
let idx = u32::from(dst);
|
||||
@@ -91,7 +98,10 @@ impl ProcessIo {
|
||||
|
||||
/// Returns [File] struct referred to by file descriptor `idx`
|
||||
pub fn file(&mut self, fd: FileDescriptor) -> Result<FileRef, Errno> {
|
||||
self.files.get(&u32::from(fd)).cloned().ok_or(Errno::InvalidFile)
|
||||
self.files
|
||||
.get(&u32::from(fd))
|
||||
.cloned()
|
||||
.ok_or(Errno::InvalidFile)
|
||||
}
|
||||
|
||||
/// Returns [Ioctx] structure reference of this I/O context
|
||||
|
||||
@@ -10,7 +10,6 @@ use crate::proc::{
|
||||
};
|
||||
use crate::sync::IrqSafeSpinLock;
|
||||
use alloc::{rc::Rc, vec::Vec};
|
||||
use core::arch::asm;
|
||||
use core::sync::atomic::{AtomicU32, Ordering};
|
||||
use libsys::{
|
||||
error::Errno,
|
||||
@@ -463,10 +462,12 @@ impl Process {
|
||||
Ok(base + offset)
|
||||
}
|
||||
|
||||
/// Returns the process's address space ID
|
||||
pub fn asid(&self) -> usize {
|
||||
(self.id().asid() as usize) << 48
|
||||
}
|
||||
|
||||
/// Flushes TLB cache for the process address space
|
||||
pub fn invalidate_tlb(&self) {
|
||||
unsafe {
|
||||
intrin::flush_tlb_asid(self.asid());
|
||||
|
||||
@@ -5,7 +5,6 @@ use crate::arch::intrin;
|
||||
use core::alloc::Layout;
|
||||
use libsys::error::Errno;
|
||||
use crate::proc::Process;
|
||||
use core::arch::asm;
|
||||
|
||||
// TODO _mut() versions checking whether pages are actually writable
|
||||
|
||||
|
||||
@@ -251,7 +251,8 @@ fn _syscall(num: SystemCall, args: &[usize]) -> Result<usize, Errno> {
|
||||
let at_fd = FileDescriptor::from_i32(args[0] as i32)?;
|
||||
let path = arg::str_ref(args[1], args[2])?;
|
||||
let mode = FileMode::from_bits(args[3] as u32).ok_or(Errno::InvalidArgument)?;
|
||||
let flags = args[4] as u32;
|
||||
// TODO honor this option
|
||||
let _flags = args[4] as u32;
|
||||
|
||||
let proc = Process::current();
|
||||
let mut io = proc.io.lock();
|
||||
|
||||
Reference in New Issue
Block a user