make FDT handling more sane
This commit is contained in:
@@ -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) {
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
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 {
|
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]
|
||||||
|
|||||||
Reference in New Issue
Block a user