diff --git a/kernel/.cargo/config.toml b/kernel/.cargo/config.toml index 24f54fa..7c4343d 100644 --- a/kernel/.cargo/config.toml +++ b/kernel/.cargo/config.toml @@ -8,7 +8,7 @@ rustflags = [ "-C", "link-arg=-Tsrc/arch/riscv64/link.ld", "-C", "link-arg=--omagic", ] -runner = "qemu-system-riscv64 -nographic -semihosting -cpu rv64 -machine virt -bios none -smp 4 -m 1G -kernel" +runner = "qemu-system-riscv64 -nographic -semihosting -cpu rv64 -machine virt -bios none -smp 4 -m 1G -drive file=test.raw,format=raw -kernel" [unstable] build-std = ["core", "compiler_builtins", "alloc"] diff --git a/kernel/src/arch/riscv64/csr.rs b/kernel/src/arch/riscv64/csr.rs index 3bab1c8..b229802 100644 --- a/kernel/src/arch/riscv64/csr.rs +++ b/kernel/src/arch/riscv64/csr.rs @@ -53,24 +53,27 @@ pub mod mtvec { } pub mod mcause { - use core::mem::transmute; + use core::mem::{size_of, transmute}; + + const VIRT: usize = 1 << (size_of::() - 1); #[derive(Debug)] + #[repr(usize)] pub enum MCause { // interrupt = 1 - SupervisorSoftwareInterrupt = (1 << 63) | 1, - VirtualSupervisorSoftwareInterrupt = (1 << 63) | 2, - MachineSoftwareInterrupt = (1 << 63) | 3, + SupervisorSoftwareInterrupt = VIRT | 1, + VirtualSupervisorSoftwareInterrupt = VIRT | 2, + MachineSoftwareInterrupt = VIRT | 3, - SupervisorTimerInterrupt = (1 << 63) | 5, - VirtualSupervisorTimerInterrupt = (1 << 63) | 6, - MachineTimerInterrupt = (1 << 63) | 7, + SupervisorTimerInterrupt = VIRT | 5, + VirtualSupervisorTimerInterrupt = VIRT | 6, + MachineTimerInterrupt = VIRT | 7, - SupervisorExternalInterrupt = (1 << 63) | 9, - VirtualSupervisorExternalInterrupt = (1 << 63) | 10, - MachineExternalInterrupt = (1 << 63) | 11, + SupervisorExternalInterrupt = VIRT | 9, + VirtualSupervisorExternalInterrupt = VIRT | 10, + MachineExternalInterrupt = VIRT | 11, - SupervisorGuestExternalInterrupt = (1 << 63) | 12, + SupervisorGuestExternalInterrupt = VIRT | 12, // interrupt = 0 InstructionAddrMisaligned = 0, diff --git a/kernel/src/arch/riscv64/init.rs b/kernel/src/arch/riscv64/init.rs index 72c2010..14ddec2 100644 --- a/kernel/src/arch/riscv64/init.rs +++ b/kernel/src/arch/riscv64/init.rs @@ -37,7 +37,8 @@ unsafe extern "C" fn _start() -> ! { ); } -pub unsafe fn to_supervisor() { +#[naked] +pub unsafe extern "C" fn to_supervisor() { asm!( "li t0, (1 << 8) | (1 << 5)", "csrw sstatus, t0", @@ -52,6 +53,7 @@ pub unsafe fn to_supervisor() { "csrw sepc, t0", "sfence.vma", "sret", + options(noreturn) ); } diff --git a/kernel/src/arch/riscv64/qemu.rs b/kernel/src/arch/riscv64/qemu.rs index c9b5d53..b5dd54e 100644 --- a/kernel/src/arch/riscv64/qemu.rs +++ b/kernel/src/arch/riscv64/qemu.rs @@ -22,6 +22,7 @@ impl Uart { impl fmt::Write for Uart { fn write_str(&mut self, s: &str) -> fmt::Result { for b in s.as_bytes() { + #[allow(clippy::while_immutable_condition)] while unsafe { *(self.base as *mut i32) } < 0 {} unsafe { *(self.base as *mut i32) = *b as i32 } } diff --git a/kernel/src/dev/fdt.rs b/kernel/src/dev/fdt.rs index 22901e8..7222241 100644 --- a/kernel/src/dev/fdt.rs +++ b/kernel/src/dev/fdt.rs @@ -1,7 +1,5 @@ // garbage .1% finished FDT implementation -use alloc::format; - use crate::{ println, util::bits::{u32_from_bytes, Be}, @@ -80,7 +78,7 @@ impl Debug for Prop { impl Prop { pub fn full_len(&self) -> usize { - return PROP_SIZE + self.data.len(); + PROP_SIZE + self.data.len() } } @@ -90,17 +88,6 @@ pub struct FDT { pub strings: &'static [u8], } -impl IntoIterator for &FDT { - type Item = Node; - type IntoIter = NodeIter; - fn into_iter(self) -> Self::IntoIter { - Self::IntoIter { - pos: self.nodes, - strings: self.strings, - } - } -} - pub struct NodeIter { pub pos: &'static [u8], pub strings: &'static [u8], @@ -109,13 +96,16 @@ pub struct NodeIter { impl Iterator for NodeIter { type Item = Node; fn next(&mut self) -> Option { - let token: Token = Token::from_bytes(self.pos)?; - self.pos = &self.pos[4..]; - if let Token::End = token { + if self.pos.is_empty() { return None; } + let token: Token = Token::from_bytes(self.pos)?; + let Token::BeginNode = token else { + return None; + }; + self.pos = &self.pos[4..]; let name_start = self.pos; - let mut extra = 0; + let extra; 'outer: loop { let bytes = &self.pos[..4]; self.pos = &self.pos[4..]; @@ -126,7 +116,8 @@ impl Iterator for NodeIter { } } } - let name = unsafe { transmute(&name_start[..name_start.len() - self.pos.len() - extra]) }; + let name = core::str::from_utf8(&name_start[..name_start.len() - self.pos.len() - extra]) + .expect("har har har har har har har har har har. RAAAAAAAAAAAAAAAAAAAAAAAA"); let node_start = self.pos; let node_data = if let Some(prop) = (PropIter { strings: self.strings, @@ -141,49 +132,66 @@ impl Iterator for NodeIter { } else { &[] }; - let node = Node { + let children = match Token::from_bytes(self.pos) { + Some(Token::EndNode | Token::End) => { + self.pos = &self.pos[4..]; + &[] + } + Some(Token::BeginNode) => { + let children = self.pos; + let mut iter = Self { + pos: children, + strings: self.strings, + }; + for _ in iter.by_ref() {} + self.pos = iter.pos; + match Token::from_bytes(self.pos) { + Some(Token::EndNode | Token::End) => self.pos = &self.pos[4..], + _ => panic!("wut du heeeeell (toaken)"), + } + children + } + _ => { + println!("WARNING: token stuff yeah?"); + &[] + } + }; + Some(Node { name, props: node_data, strings: self.strings, - }; - loop { - if let Some(token) = Token::from_bytes(self.pos) { - if let Token::EndNode = token { - self.pos = &self.pos[4..]; - } else { - break; - } - } else { - break; - } - } - Some(node) + children, + }) } } impl FDT { - pub fn from_addr(addr: *mut u8) -> Self { - unsafe { - let header: &Header = transmute(addr); - if header.magic.get() != MAGIC { - panic!("fdt magic wrong"); - } - let data = slice::from_raw_parts(addr as *mut u8, header.totalsize.get() as usize); - Self { - header, - nodes: &data[header.off_dt_struct.get() as usize..], - strings: &data[header.off_dt_strings.get() as usize..], - } + pub fn nodes(&self) -> NodeIter { + NodeIter { + pos: self.nodes, + strings: self.strings, + } + } + pub unsafe fn from_addr(addr: *mut u8) -> Self { + let header: &Header = &*(addr as *const Header); + if header.magic.get() != MAGIC { + panic!("fdt magic wrong"); + } + let data = slice::from_raw_parts(addr, header.totalsize.get() as usize); + Self { + header, + nodes: &data[header.off_dt_struct.get() as usize..], + strings: &data[header.off_dt_strings.get() as usize..], } } pub fn mem_range(&self) -> FDTMemRange { - if let Some(node) = self.into_iter().find(|n| n.name.starts_with("memory@")) { + let root = self.nodes().next().unwrap(); + if let Some(node) = root.children().find(|n| n.name.starts_with("memory@")) { let prop = node.find_prop("reg"); if let Some(prop) = prop { - for d in prop.data.chunks(size_of::()) { + if let Some(d) = prop.data.chunks(size_of::()).next() { let d: [u8; size_of::()] = d.try_into().unwrap(); - // just return first one for now - return unsafe { transmute(d) }; + return unsafe { transmute::<[u8; 16], FDTMemRange>(d) }; } } } @@ -215,11 +223,11 @@ impl Debug for FDTMemRange { } } -impl Into> for FDTMemRange { - fn into(self) -> Range<*mut u8> { +impl From for Range<*mut u8> { + fn from(val: FDTMemRange) -> Self { Range { - start: self.start(), - end: self.end(), + start: val.start(), + end: val.end(), } } } @@ -228,27 +236,37 @@ pub struct Node { pub name: &'static str, pub strings: &'static [u8], pub props: &'static [u8], + pub children: &'static [u8], } impl Debug for Node { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { - let props: alloc::vec::Vec<_> = self.into_iter().map(|p| format!("{:?}", p)).collect(); + let props: alloc::vec::Vec<_> = self.props().collect(); + let children: alloc::vec::Vec<_> = self.children().collect(); f.debug_struct("Node") .field("name", &self.name) .field("props", &props) + .field("children", &children) .finish() } } -impl IntoIterator for &Node { - type Item = Prop; - type IntoIter = PropIter; - fn into_iter(self) -> Self::IntoIter { - Self::IntoIter { +impl Node { + pub fn children(&self) -> NodeIter { + NodeIter { + pos: self.children, + strings: self.strings, + } + } + pub fn props(&self) -> PropIter { + PropIter { pos: self.props, strings: self.strings, } } + pub fn find_prop(&self, name: &str) -> Option { + self.props().find(|p| p.name == name) + } } pub struct PropIter { @@ -264,7 +282,7 @@ impl Iterator for PropIter { return None; }; self.pos = &self.pos[4..]; - let prop: &RawProp = unsafe { transmute(self.pos.as_ptr()) }; + let prop: &RawProp = unsafe { &*(self.pos.as_ptr() as *const RawProp) }; self.pos = &self.pos[PROP_SIZE..]; let plen = prop.len.get() as usize; let len = (plen + (TOKEN_SIZE - 1)) & !(TOKEN_SIZE - 1); @@ -273,7 +291,7 @@ impl Iterator for PropIter { let name_start = &self.strings[prop.nameoff.get() as usize..]; for (i, c) in name_start.iter().enumerate() { if *c == 0 { - let name: &str = unsafe { transmute(&name_start[..i]) }; + let name: &str = core::str::from_utf8(&name_start[..i]).expect("uhhhhh"); return Some(Prop { name, data }); } } @@ -281,9 +299,3 @@ impl Iterator for PropIter { None } } - -impl Node { - pub fn find_prop(&self, name: &str) -> Option { - self.into_iter().find(|p| p.name == name) - } -} diff --git a/kernel/src/log.rs b/kernel/src/log.rs deleted file mode 100644 index 1252b35..0000000 --- a/kernel/src/log.rs +++ /dev/null @@ -1,12 +0,0 @@ -use core::fmt::Arguments; - - -#[doc(hidden)] -pub fn _log(args: Arguments<'_>) { -} - -#[macro_export] -macro_rules! log { - ($($arg:tt)*) => ($crate::_log(format_args!($($arg)*))); -} - diff --git a/kernel/src/main.rs b/kernel/src/main.rs index 8bc9178..9ade6bf 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -15,7 +15,6 @@ extern crate alloc; pub mod arch; pub mod dev; -pub mod log; pub mod mem; pub mod qemu; #[cfg(test)] @@ -41,11 +40,12 @@ pub fn start(info: StartInfo) -> ! { pub fn main(info: StartInfo) { println!("we out here vibin"); + println!("memory range: {:?}", info.mem_range); unsafe { ALLOCATOR.init(&info.mem_range); } - for dev in info.dt.into_iter() { - println!("{:?}", dev); + for dev in info.dt.nodes() { + println!("{:#?}", dev); } } diff --git a/kernel/src/util/lazy.rs b/kernel/src/util/lazy.rs deleted file mode 100644 index 7ee6333..0000000 --- a/kernel/src/util/lazy.rs +++ /dev/null @@ -1,44 +0,0 @@ -use core::{mem::MaybeUninit, ops::Deref}; - -pub struct LazyConst { - value: T, - #[cfg(debug_assertions)] - state: u8, -} - -impl Deref for LazyConst { - type Target = T; - - fn deref(&self) -> &Self::Target { - #[cfg(debug_assertions)] - if self.state == 0 { - panic!("Lazy const for {} not assigned", core::any::type_name::()); - } - &self.value - } -} - -impl LazyConst { - pub const fn new() -> Self { - unsafe { - Self { - value: MaybeUninit::zeroed().assume_init(), - #[cfg(debug_assertions)] - state: 0, - } - } - } - - pub unsafe fn init(&self, value: T) { - as_mut(self).value = value; - #[cfg(debug_assertions)] - { - as_mut(self).state = 1; - } - } -} - -pub unsafe fn as_mut(x: &T) -> &mut T { - #[allow(invalid_reference_casting)] - &mut *((x as *const T) as *mut T) -} diff --git a/kernel/src/util/mod.rs b/kernel/src/util/mod.rs index 4348fa2..c3594e1 100644 --- a/kernel/src/util/mod.rs +++ b/kernel/src/util/mod.rs @@ -1,4 +1,3 @@ pub mod bits; -pub mod lazy; pub mod mutex; pub mod spin; diff --git a/kernel/test.raw b/kernel/test.raw new file mode 100644 index 0000000..4fce05a Binary files /dev/null and b/kernel/test.raw differ