make FDT handling more sane
This commit is contained in:
@@ -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::<u64, Mode>(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) {
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,6 +69,9 @@ impl FDT {
|
||||
strings: self.strings,
|
||||
}
|
||||
}
|
||||
pub fn root(&self) -> Option<Node> {
|
||||
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<Node> {
|
||||
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<Prop> {
|
||||
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<Self::Item> {
|
||||
// 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<Self::Item> {
|
||||
// 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,
|
||||
|
||||
@@ -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::<FDTMemRange>()).next() {
|
||||
let d: [u8; size_of::<FDTMemRange>()] = d.try_into().unwrap();
|
||||
return unsafe { transmute::<[u8; 16], FDTMemRange>(d) };
|
||||
}
|
||||
}
|
||||
}
|
||||
panic!("failed to get memory range");
|
||||
pub fn mem_range(&self) -> Option<FDTMemRange> {
|
||||
let reg = self.root()?.child("memory")?.prop("reg")?;
|
||||
let data = reg.data.chunks(size_of::<FDTMemRange>()).next()?;
|
||||
let data: [u8; size_of::<FDTMemRange>()] = data.try_into().unwrap();
|
||||
unsafe { Some(transmute::<[u8; 16], FDTMemRange>(data)) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod fdt;
|
||||
pub mod mem;
|
||||
pub mod uart;
|
||||
pub mod pci;
|
||||
|
||||
14
kernel/src/dev/pci.rs
Normal file
14
kernel/src/dev/pci.rs
Normal 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
|
||||
}
|
||||
}
|
||||
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user