starting fs working and FDT is actually a tree now

This commit is contained in:
Bryan McShea
2024-04-24 19:59:31 -04:00
parent 7c859ab6c3
commit 13438976a8
10 changed files with 101 additions and 140 deletions

View File

@@ -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<Self::Item> {
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::<FDTMemRange>()) {
if let Some(d) = prop.data.chunks(size_of::<FDTMemRange>()).next() {
let d: [u8; size_of::<FDTMemRange>()] = 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<Range<*mut u8>> for FDTMemRange {
fn into(self) -> Range<*mut u8> {
impl From<FDTMemRange> 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<Prop> {
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<Prop> {
self.into_iter().find(|p| p.name == name)
}
}