From 9a8b93848acb039ddb59a628d3cbcc62156eb8ad Mon Sep 17 00:00:00 2001 From: Bryan McShea Date: Wed, 24 Apr 2024 21:37:47 -0400 Subject: [PATCH] make FDT handling more sane --- kernel/src/arch/riscv64/csr.rs | 4 ++-- kernel/src/arch/riscv64/init.rs | 2 +- kernel/src/arch/riscv64/paging.rs | 9 +++------ kernel/src/dev/fdt.rs | 27 ++++++++++++++++++++++++--- kernel/src/dev/mem.rs | 16 +++++----------- kernel/src/dev/mod.rs | 1 + kernel/src/dev/pci.rs | 14 ++++++++++++++ kernel/src/main.rs | 4 +--- 8 files changed, 51 insertions(+), 26 deletions(-) create mode 100644 kernel/src/dev/pci.rs diff --git a/kernel/src/arch/riscv64/csr.rs b/kernel/src/arch/riscv64/csr.rs index b229802..1abc783 100644 --- a/kernel/src/arch/riscv64/csr.rs +++ b/kernel/src/arch/riscv64/csr.rs @@ -134,9 +134,9 @@ pub mod satp { } pub fn read() -> Satp { let satp = unsafe { csrr!("satp") }; - let mode = unsafe { transmute(bits!(satp;60,63)) }; + let mode = unsafe { transmute::(bits!(satp;60,63)) }; let asid = bits!(satp;44,59); - let ppn = unsafe { transmute(bits!(satp;0,43) << 12) }; + let ppn = (bits!(satp;0,43) << 12) as *mut Table; Satp { mode, asid, ppn } } pub fn write(satp: Satp) { diff --git a/kernel/src/arch/riscv64/init.rs b/kernel/src/arch/riscv64/init.rs index 14ddec2..8bbda9f 100644 --- a/kernel/src/arch/riscv64/init.rs +++ b/kernel/src/arch/riscv64/init.rs @@ -65,7 +65,7 @@ pub unsafe fn init() -> ! { } interrupts::init(); let fdt = FDT::from_addr(dt_addr); - let raw_mem_range = fdt.mem_range(); + let raw_mem_range = fdt.mem_range().expect("we lost guys"); let heap_start = paging::init(raw_mem_range.end()); let heap_mem = Range { start: heap_start, diff --git a/kernel/src/arch/riscv64/paging.rs b/kernel/src/arch/riscv64/paging.rs index d65f778..1542b0d 100644 --- a/kernel/src/arch/riscv64/paging.rs +++ b/kernel/src/arch/riscv64/paging.rs @@ -27,7 +27,7 @@ impl Entry { } pub fn set_addr(&mut self, addr: usize) { self.clear(); - self.0 |= addr as usize >> 2; + self.0 |= addr >> 2; self.0 |= 0b1110; self.set_valid(true); } @@ -94,8 +94,7 @@ pub fn init(mem_end: *mut u8) -> *mut u8 { asid: 0, ppn: lvl2, }); - let table_end = lvl0_arr.as_ptr().add(lvl0_arr.len()) as *mut u8; - table_end + lvl0_arr.as_ptr().add(lvl0_arr.len()) as *mut u8 } } @@ -104,13 +103,11 @@ pub fn virt_to_physical(table: &Table, addr: usize) -> usize { let ppn1 = bits!(addr;21,29); let ppn0 = bits!(addr;12,20); let offset = bits!(addr;0,11); - // let satp = csr::satp::read(); unsafe { let lvl2 = table as *const Table; let lvl1 = (*lvl2).entries[ppn2].get_table(); let lvl0 = (*lvl1).entries[ppn1].get_table(); let base = (*lvl0).entries[ppn0].get_addr(); - let addr = base + offset; - addr + base + offset } } diff --git a/kernel/src/dev/fdt.rs b/kernel/src/dev/fdt.rs index cadc5e4..2efb579 100644 --- a/kernel/src/dev/fdt.rs +++ b/kernel/src/dev/fdt.rs @@ -69,6 +69,9 @@ impl FDT { strings: self.strings, } } + pub fn root(&self) -> Option { + self.nodes().next() + } pub unsafe fn from_addr(addr: *mut u8) -> Self { let header: &Header = &*(addr as *const Header); if header.magic.get() != MAGIC { @@ -111,7 +114,7 @@ impl Node { } } pub fn child(&self, name: &str) -> Option { - self.children().find(|c| c.name == name) + self.children().find(|c| c.name() == name) } pub fn props(&self) -> PropIter { PropIter { @@ -122,6 +125,12 @@ impl Node { pub fn prop(&self, name: &str) -> Option { self.props().find(|p| p.name == name) } + pub fn name(&self) -> &str { + self.name.split_once('@').map(|(name, _)| name).unwrap_or(self.name) + } + pub fn address(&self) -> Option<&str> { + self.name.split_once('@').map(|(_, addr)| Some(addr)).unwrap_or(None) + } } pub struct Prop { @@ -152,17 +161,21 @@ pub struct PropIter { impl Iterator for PropIter { type Item = Prop; fn next(&mut self) -> Option { + // make sure this is a prop let token: Token = Token::from_bytes(self.pos)?; let Token::Prop = token else { return None; }; self.pos = &self.pos[4..]; + // get raw info let prop: &RawProp = unsafe { &*(self.pos.as_ptr() as *const RawProp) }; self.pos = &self.pos[PROP_SIZE..]; + // get data let plen = prop.len.get() as usize; let len = (plen + (TOKEN_SIZE - 1)) & !(TOKEN_SIZE - 1); let data = &self.pos[..len]; self.pos = &self.pos[len..]; + // get name let name_start = &self.strings[prop.nameoff.get() as usize..]; for (i, c) in name_start.iter().enumerate() { if *c == 0 { @@ -176,6 +189,8 @@ impl Iterator for PropIter { } pub struct NodeIter { + // I should make a type called ByteCursor or something for this + // so dealing with it is not cursed and dependent on data type pub pos: &'static [u8], pub strings: &'static [u8], } @@ -183,6 +198,7 @@ pub struct NodeIter { impl Iterator for NodeIter { type Item = Node; fn next(&mut self) -> Option { + // first make sure this is actually a node if self.pos.is_empty() { return None; } @@ -191,6 +207,7 @@ impl Iterator for NodeIter { return None; }; self.pos = &self.pos[4..]; + // then get the name let name_start = self.pos; let extra; 'outer: loop { @@ -205,6 +222,7 @@ impl Iterator for NodeIter { } 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"); + // then props let node_start = self.pos; let node_data = if let Some(prop) = (PropIter { strings: self.strings, @@ -219,6 +237,7 @@ impl Iterator for NodeIter { } else { &[] }; + // then children let children = match Token::from_bytes(self.pos) { Some(Token::EndNode | Token::End) => { self.pos = &self.pos[4..]; @@ -230,19 +249,21 @@ impl Iterator for NodeIter { pos: children, strings: self.strings, }; + // skip children bytes 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)"), + _ => panic!("wut du heeeeeal (toaken)"), } children } _ => { - println!("WARNING: token stuff yeah?"); + println!("WARNING: token stuff XD"); &[] } }; + // done Some(Node { name, props: node_data, diff --git a/kernel/src/dev/mem.rs b/kernel/src/dev/mem.rs index d069d99..abcd9e2 100644 --- a/kernel/src/dev/mem.rs +++ b/kernel/src/dev/mem.rs @@ -9,17 +9,11 @@ use crate::util::bits::Be; use super::fdt::FDT; impl FDT { - pub fn mem_range(&self) -> FDTMemRange { - let root = self.nodes().next().unwrap(); - if let Some(node) = root.children().find(|n| n.name.starts_with("memory@")) { - if let Some(prop) = node.prop("reg") { - if let Some(d) = prop.data.chunks(size_of::()).next() { - let d: [u8; size_of::()] = d.try_into().unwrap(); - return unsafe { transmute::<[u8; 16], FDTMemRange>(d) }; - } - } - } - panic!("failed to get memory range"); + pub fn mem_range(&self) -> Option { + let reg = self.root()?.child("memory")?.prop("reg")?; + let data = reg.data.chunks(size_of::()).next()?; + let data: [u8; size_of::()] = data.try_into().unwrap(); + unsafe { Some(transmute::<[u8; 16], FDTMemRange>(data)) } } } diff --git a/kernel/src/dev/mod.rs b/kernel/src/dev/mod.rs index 6668bff..0476720 100644 --- a/kernel/src/dev/mod.rs +++ b/kernel/src/dev/mod.rs @@ -1,3 +1,4 @@ pub mod fdt; pub mod mem; pub mod uart; +pub mod pci; diff --git a/kernel/src/dev/pci.rs b/kernel/src/dev/pci.rs new file mode 100644 index 0000000..884cc4c --- /dev/null +++ b/kernel/src/dev/pci.rs @@ -0,0 +1,14 @@ +use crate::println; + +use super::fdt::FDT; + +impl FDT { + pub fn pci_devs(&self) -> Option<()> { + // for dev in self.nodes() { + // println!("{:#?}", dev); + // } + let node = self.root()?.child("soc")?.child("pci")?; + println!("{:#?}", node); + None + } +} diff --git a/kernel/src/main.rs b/kernel/src/main.rs index 9ade6bf..9c265c4 100644 --- a/kernel/src/main.rs +++ b/kernel/src/main.rs @@ -44,9 +44,7 @@ pub fn main(info: StartInfo) { unsafe { ALLOCATOR.init(&info.mem_range); } - for dev in info.dt.nodes() { - println!("{:#?}", dev); - } + info.dt.pci_devs(); } #[panic_handler]