make FDT handling more sane

This commit is contained in:
Bryan McShea
2024-04-24 21:37:47 -04:00
parent 826a122241
commit 9a8b93848a
8 changed files with 51 additions and 26 deletions

View File

@@ -134,9 +134,9 @@ pub mod satp {
} }
pub fn read() -> Satp { pub fn read() -> Satp {
let satp = unsafe { csrr!("satp") }; let satp = unsafe { csrr!("satp") };
let mode = unsafe { transmute(bits!(satp;60,63)) }; let mode = unsafe { transmute::<u64, Mode>(bits!(satp;60,63)) };
let asid = bits!(satp;44,59); 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 } Satp { mode, asid, ppn }
} }
pub fn write(satp: Satp) { pub fn write(satp: Satp) {

View File

@@ -65,7 +65,7 @@ pub unsafe fn init() -> ! {
} }
interrupts::init(); interrupts::init();
let fdt = FDT::from_addr(dt_addr); 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_start = paging::init(raw_mem_range.end());
let heap_mem = Range { let heap_mem = Range {
start: heap_start, start: heap_start,

View File

@@ -27,7 +27,7 @@ impl Entry {
} }
pub fn set_addr(&mut self, addr: usize) { pub fn set_addr(&mut self, addr: usize) {
self.clear(); self.clear();
self.0 |= addr as usize >> 2; self.0 |= addr >> 2;
self.0 |= 0b1110; self.0 |= 0b1110;
self.set_valid(true); self.set_valid(true);
} }
@@ -94,8 +94,7 @@ pub fn init(mem_end: *mut u8) -> *mut u8 {
asid: 0, asid: 0,
ppn: lvl2, ppn: lvl2,
}); });
let table_end = lvl0_arr.as_ptr().add(lvl0_arr.len()) as *mut u8; lvl0_arr.as_ptr().add(lvl0_arr.len()) as *mut u8
table_end
} }
} }
@@ -104,13 +103,11 @@ pub fn virt_to_physical(table: &Table, addr: usize) -> usize {
let ppn1 = bits!(addr;21,29); let ppn1 = bits!(addr;21,29);
let ppn0 = bits!(addr;12,20); let ppn0 = bits!(addr;12,20);
let offset = bits!(addr;0,11); let offset = bits!(addr;0,11);
// let satp = csr::satp::read();
unsafe { unsafe {
let lvl2 = table as *const Table; let lvl2 = table as *const Table;
let lvl1 = (*lvl2).entries[ppn2].get_table(); let lvl1 = (*lvl2).entries[ppn2].get_table();
let lvl0 = (*lvl1).entries[ppn1].get_table(); let lvl0 = (*lvl1).entries[ppn1].get_table();
let base = (*lvl0).entries[ppn0].get_addr(); let base = (*lvl0).entries[ppn0].get_addr();
let addr = base + offset; base + offset
addr
} }
} }

View File

@@ -69,6 +69,9 @@ impl FDT {
strings: self.strings, strings: self.strings,
} }
} }
pub fn root(&self) -> Option<Node> {
self.nodes().next()
}
pub unsafe fn from_addr(addr: *mut u8) -> Self { pub unsafe fn from_addr(addr: *mut u8) -> Self {
let header: &Header = &*(addr as *const Header); let header: &Header = &*(addr as *const Header);
if header.magic.get() != MAGIC { if header.magic.get() != MAGIC {
@@ -111,7 +114,7 @@ impl Node {
} }
} }
pub fn child(&self, name: &str) -> Option<Node> { pub fn child(&self, name: &str) -> Option<Node> {
self.children().find(|c| c.name == name) self.children().find(|c| c.name() == name)
} }
pub fn props(&self) -> PropIter { pub fn props(&self) -> PropIter {
PropIter { PropIter {
@@ -122,6 +125,12 @@ impl Node {
pub fn prop(&self, name: &str) -> Option<Prop> { pub fn prop(&self, name: &str) -> Option<Prop> {
self.props().find(|p| p.name == name) 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 { pub struct Prop {
@@ -152,17 +161,21 @@ pub struct PropIter {
impl Iterator for PropIter { impl Iterator for PropIter {
type Item = Prop; type Item = Prop;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
// make sure this is a prop
let token: Token = Token::from_bytes(self.pos)?; let token: Token = Token::from_bytes(self.pos)?;
let Token::Prop = token else { let Token::Prop = token else {
return None; return None;
}; };
self.pos = &self.pos[4..]; self.pos = &self.pos[4..];
// get raw info
let prop: &RawProp = unsafe { &*(self.pos.as_ptr() as *const RawProp) }; let prop: &RawProp = unsafe { &*(self.pos.as_ptr() as *const RawProp) };
self.pos = &self.pos[PROP_SIZE..]; self.pos = &self.pos[PROP_SIZE..];
// get data
let plen = prop.len.get() as usize; let plen = prop.len.get() as usize;
let len = (plen + (TOKEN_SIZE - 1)) & !(TOKEN_SIZE - 1); let len = (plen + (TOKEN_SIZE - 1)) & !(TOKEN_SIZE - 1);
let data = &self.pos[..len]; let data = &self.pos[..len];
self.pos = &self.pos[len..]; self.pos = &self.pos[len..];
// get name
let name_start = &self.strings[prop.nameoff.get() as usize..]; let name_start = &self.strings[prop.nameoff.get() as usize..];
for (i, c) in name_start.iter().enumerate() { for (i, c) in name_start.iter().enumerate() {
if *c == 0 { if *c == 0 {
@@ -176,6 +189,8 @@ impl Iterator for PropIter {
} }
pub struct NodeIter { 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 pos: &'static [u8],
pub strings: &'static [u8], pub strings: &'static [u8],
} }
@@ -183,6 +198,7 @@ pub struct NodeIter {
impl Iterator for NodeIter { impl Iterator for NodeIter {
type Item = Node; type Item = Node;
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
// first make sure this is actually a node
if self.pos.is_empty() { if self.pos.is_empty() {
return None; return None;
} }
@@ -191,6 +207,7 @@ impl Iterator for NodeIter {
return None; return None;
}; };
self.pos = &self.pos[4..]; self.pos = &self.pos[4..];
// then get the name
let name_start = self.pos; let name_start = self.pos;
let extra; let extra;
'outer: loop { '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]) 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"); .expect("har har har har har har har har har har. RAAAAAAAAAAAAAAAAAAAAAAAA");
// then props
let node_start = self.pos; let node_start = self.pos;
let node_data = if let Some(prop) = (PropIter { let node_data = if let Some(prop) = (PropIter {
strings: self.strings, strings: self.strings,
@@ -219,6 +237,7 @@ impl Iterator for NodeIter {
} else { } else {
&[] &[]
}; };
// then children
let children = match Token::from_bytes(self.pos) { let children = match Token::from_bytes(self.pos) {
Some(Token::EndNode | Token::End) => { Some(Token::EndNode | Token::End) => {
self.pos = &self.pos[4..]; self.pos = &self.pos[4..];
@@ -230,19 +249,21 @@ impl Iterator for NodeIter {
pos: children, pos: children,
strings: self.strings, strings: self.strings,
}; };
// skip children bytes
for _ in iter.by_ref() {} for _ in iter.by_ref() {}
self.pos = iter.pos; self.pos = iter.pos;
match Token::from_bytes(self.pos) { match Token::from_bytes(self.pos) {
Some(Token::EndNode | Token::End) => self.pos = &self.pos[4..], Some(Token::EndNode | Token::End) => self.pos = &self.pos[4..],
_ => panic!("wut du heeeeell (toaken)"), _ => panic!("wut du heeeeeal (toaken)"),
} }
children children
} }
_ => { _ => {
println!("WARNING: token stuff yeah?"); println!("WARNING: token stuff XD");
&[] &[]
} }
}; };
// done
Some(Node { Some(Node {
name, name,
props: node_data, props: node_data,

View File

@@ -9,17 +9,11 @@ use crate::util::bits::Be;
use super::fdt::FDT; use super::fdt::FDT;
impl FDT { impl FDT {
pub fn mem_range(&self) -> FDTMemRange { pub fn mem_range(&self) -> Option<FDTMemRange> {
let root = self.nodes().next().unwrap(); let reg = self.root()?.child("memory")?.prop("reg")?;
if let Some(node) = root.children().find(|n| n.name.starts_with("memory@")) { let data = reg.data.chunks(size_of::<FDTMemRange>()).next()?;
if let Some(prop) = node.prop("reg") { let data: [u8; size_of::<FDTMemRange>()] = data.try_into().unwrap();
if let Some(d) = prop.data.chunks(size_of::<FDTMemRange>()).next() { unsafe { Some(transmute::<[u8; 16], FDTMemRange>(data)) }
let d: [u8; size_of::<FDTMemRange>()] = d.try_into().unwrap();
return unsafe { transmute::<[u8; 16], FDTMemRange>(d) };
}
}
}
panic!("failed to get memory range");
} }
} }

View File

@@ -1,3 +1,4 @@
pub mod fdt; pub mod fdt;
pub mod mem; pub mod mem;
pub mod uart; pub mod uart;
pub mod pci;

14
kernel/src/dev/pci.rs Normal file
View File

@@ -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
}
}

View File

@@ -44,9 +44,7 @@ pub fn main(info: StartInfo) {
unsafe { unsafe {
ALLOCATOR.init(&info.mem_range); ALLOCATOR.init(&info.mem_range);
} }
for dev in info.dt.nodes() { info.dt.pci_devs();
println!("{:#?}", dev);
}
} }
#[panic_handler] #[panic_handler]