starting fs working and FDT is actually a tree now
This commit is contained in:
@@ -8,7 +8,7 @@ rustflags = [
|
|||||||
"-C", "link-arg=-Tsrc/arch/riscv64/link.ld",
|
"-C", "link-arg=-Tsrc/arch/riscv64/link.ld",
|
||||||
"-C", "link-arg=--omagic",
|
"-C", "link-arg=--omagic",
|
||||||
]
|
]
|
||||||
runner = "qemu-system-riscv64 -nographic -semihosting -cpu rv64 -machine virt -bios none -smp 4 -m 1G -kernel"
|
runner = "qemu-system-riscv64 -nographic -semihosting -cpu rv64 -machine virt -bios none -smp 4 -m 1G -drive file=test.raw,format=raw -kernel"
|
||||||
|
|
||||||
[unstable]
|
[unstable]
|
||||||
build-std = ["core", "compiler_builtins", "alloc"]
|
build-std = ["core", "compiler_builtins", "alloc"]
|
||||||
|
|||||||
@@ -53,24 +53,27 @@ pub mod mtvec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub mod mcause {
|
pub mod mcause {
|
||||||
use core::mem::transmute;
|
use core::mem::{size_of, transmute};
|
||||||
|
|
||||||
|
const VIRT: usize = 1 << (size_of::<usize>() - 1);
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
#[repr(usize)]
|
||||||
pub enum MCause {
|
pub enum MCause {
|
||||||
// interrupt = 1
|
// interrupt = 1
|
||||||
SupervisorSoftwareInterrupt = (1 << 63) | 1,
|
SupervisorSoftwareInterrupt = VIRT | 1,
|
||||||
VirtualSupervisorSoftwareInterrupt = (1 << 63) | 2,
|
VirtualSupervisorSoftwareInterrupt = VIRT | 2,
|
||||||
MachineSoftwareInterrupt = (1 << 63) | 3,
|
MachineSoftwareInterrupt = VIRT | 3,
|
||||||
|
|
||||||
SupervisorTimerInterrupt = (1 << 63) | 5,
|
SupervisorTimerInterrupt = VIRT | 5,
|
||||||
VirtualSupervisorTimerInterrupt = (1 << 63) | 6,
|
VirtualSupervisorTimerInterrupt = VIRT | 6,
|
||||||
MachineTimerInterrupt = (1 << 63) | 7,
|
MachineTimerInterrupt = VIRT | 7,
|
||||||
|
|
||||||
SupervisorExternalInterrupt = (1 << 63) | 9,
|
SupervisorExternalInterrupt = VIRT | 9,
|
||||||
VirtualSupervisorExternalInterrupt = (1 << 63) | 10,
|
VirtualSupervisorExternalInterrupt = VIRT | 10,
|
||||||
MachineExternalInterrupt = (1 << 63) | 11,
|
MachineExternalInterrupt = VIRT | 11,
|
||||||
|
|
||||||
SupervisorGuestExternalInterrupt = (1 << 63) | 12,
|
SupervisorGuestExternalInterrupt = VIRT | 12,
|
||||||
|
|
||||||
// interrupt = 0
|
// interrupt = 0
|
||||||
InstructionAddrMisaligned = 0,
|
InstructionAddrMisaligned = 0,
|
||||||
|
|||||||
@@ -37,7 +37,8 @@ unsafe extern "C" fn _start() -> ! {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn to_supervisor() {
|
#[naked]
|
||||||
|
pub unsafe extern "C" fn to_supervisor() {
|
||||||
asm!(
|
asm!(
|
||||||
"li t0, (1 << 8) | (1 << 5)",
|
"li t0, (1 << 8) | (1 << 5)",
|
||||||
"csrw sstatus, t0",
|
"csrw sstatus, t0",
|
||||||
@@ -52,6 +53,7 @@ pub unsafe fn to_supervisor() {
|
|||||||
"csrw sepc, t0",
|
"csrw sepc, t0",
|
||||||
"sfence.vma",
|
"sfence.vma",
|
||||||
"sret",
|
"sret",
|
||||||
|
options(noreturn)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ impl Uart {
|
|||||||
impl fmt::Write for Uart {
|
impl fmt::Write for Uart {
|
||||||
fn write_str(&mut self, s: &str) -> fmt::Result {
|
fn write_str(&mut self, s: &str) -> fmt::Result {
|
||||||
for b in s.as_bytes() {
|
for b in s.as_bytes() {
|
||||||
|
#[allow(clippy::while_immutable_condition)]
|
||||||
while unsafe { *(self.base as *mut i32) } < 0 {}
|
while unsafe { *(self.base as *mut i32) } < 0 {}
|
||||||
unsafe { *(self.base as *mut i32) = *b as i32 }
|
unsafe { *(self.base as *mut i32) = *b as i32 }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
// garbage .1% finished FDT implementation
|
// garbage .1% finished FDT implementation
|
||||||
|
|
||||||
use alloc::format;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
println,
|
println,
|
||||||
util::bits::{u32_from_bytes, Be},
|
util::bits::{u32_from_bytes, Be},
|
||||||
@@ -80,7 +78,7 @@ impl Debug for Prop {
|
|||||||
|
|
||||||
impl Prop {
|
impl Prop {
|
||||||
pub fn full_len(&self) -> usize {
|
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],
|
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 struct NodeIter {
|
||||||
pub pos: &'static [u8],
|
pub pos: &'static [u8],
|
||||||
pub strings: &'static [u8],
|
pub strings: &'static [u8],
|
||||||
@@ -109,13 +96,16 @@ 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> {
|
||||||
let token: Token = Token::from_bytes(self.pos)?;
|
if self.pos.is_empty() {
|
||||||
self.pos = &self.pos[4..];
|
|
||||||
if let Token::End = token {
|
|
||||||
return None;
|
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 name_start = self.pos;
|
||||||
let mut extra = 0;
|
let extra;
|
||||||
'outer: loop {
|
'outer: loop {
|
||||||
let bytes = &self.pos[..4];
|
let bytes = &self.pos[..4];
|
||||||
self.pos = &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_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,
|
||||||
@@ -141,49 +132,66 @@ impl Iterator for NodeIter {
|
|||||||
} else {
|
} 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,
|
name,
|
||||||
props: node_data,
|
props: node_data,
|
||||||
strings: self.strings,
|
strings: self.strings,
|
||||||
};
|
children,
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FDT {
|
impl FDT {
|
||||||
pub fn from_addr(addr: *mut u8) -> Self {
|
pub fn nodes(&self) -> NodeIter {
|
||||||
unsafe {
|
NodeIter {
|
||||||
let header: &Header = transmute(addr);
|
pos: self.nodes,
|
||||||
if header.magic.get() != MAGIC {
|
strings: self.strings,
|
||||||
panic!("fdt magic wrong");
|
}
|
||||||
}
|
}
|
||||||
let data = slice::from_raw_parts(addr as *mut u8, header.totalsize.get() as usize);
|
pub unsafe fn from_addr(addr: *mut u8) -> Self {
|
||||||
Self {
|
let header: &Header = &*(addr as *const Header);
|
||||||
header,
|
if header.magic.get() != MAGIC {
|
||||||
nodes: &data[header.off_dt_struct.get() as usize..],
|
panic!("fdt magic wrong");
|
||||||
strings: &data[header.off_dt_strings.get() as usize..],
|
}
|
||||||
}
|
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 {
|
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");
|
let prop = node.find_prop("reg");
|
||||||
if let Some(prop) = prop {
|
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();
|
let d: [u8; size_of::<FDTMemRange>()] = d.try_into().unwrap();
|
||||||
// just return first one for now
|
return unsafe { transmute::<[u8; 16], FDTMemRange>(d) };
|
||||||
return unsafe { transmute(d) };
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -215,11 +223,11 @@ impl Debug for FDTMemRange {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<Range<*mut u8>> for FDTMemRange {
|
impl From<FDTMemRange> for Range<*mut u8> {
|
||||||
fn into(self) -> Range<*mut u8> {
|
fn from(val: FDTMemRange) -> Self {
|
||||||
Range {
|
Range {
|
||||||
start: self.start(),
|
start: val.start(),
|
||||||
end: self.end(),
|
end: val.end(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -228,27 +236,37 @@ pub struct Node {
|
|||||||
pub name: &'static str,
|
pub name: &'static str,
|
||||||
pub strings: &'static [u8],
|
pub strings: &'static [u8],
|
||||||
pub props: &'static [u8],
|
pub props: &'static [u8],
|
||||||
|
pub children: &'static [u8],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for Node {
|
impl Debug for Node {
|
||||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
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")
|
f.debug_struct("Node")
|
||||||
.field("name", &self.name)
|
.field("name", &self.name)
|
||||||
.field("props", &props)
|
.field("props", &props)
|
||||||
|
.field("children", &children)
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoIterator for &Node {
|
impl Node {
|
||||||
type Item = Prop;
|
pub fn children(&self) -> NodeIter {
|
||||||
type IntoIter = PropIter;
|
NodeIter {
|
||||||
fn into_iter(self) -> Self::IntoIter {
|
pos: self.children,
|
||||||
Self::IntoIter {
|
strings: self.strings,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn props(&self) -> PropIter {
|
||||||
|
PropIter {
|
||||||
pos: self.props,
|
pos: self.props,
|
||||||
strings: self.strings,
|
strings: self.strings,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pub fn find_prop(&self, name: &str) -> Option<Prop> {
|
||||||
|
self.props().find(|p| p.name == name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct PropIter {
|
pub struct PropIter {
|
||||||
@@ -264,7 +282,7 @@ impl Iterator for PropIter {
|
|||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
self.pos = &self.pos[4..];
|
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..];
|
self.pos = &self.pos[PROP_SIZE..];
|
||||||
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);
|
||||||
@@ -273,7 +291,7 @@ impl Iterator for PropIter {
|
|||||||
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 {
|
||||||
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 });
|
return Some(Prop { name, data });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -281,9 +299,3 @@ impl Iterator for PropIter {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Node {
|
|
||||||
pub fn find_prop(&self, name: &str) -> Option<Prop> {
|
|
||||||
self.into_iter().find(|p| p.name == name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
use core::fmt::Arguments;
|
|
||||||
|
|
||||||
|
|
||||||
#[doc(hidden)]
|
|
||||||
pub fn _log(args: Arguments<'_>) {
|
|
||||||
}
|
|
||||||
|
|
||||||
#[macro_export]
|
|
||||||
macro_rules! log {
|
|
||||||
($($arg:tt)*) => ($crate::_log(format_args!($($arg)*)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -15,7 +15,6 @@ extern crate alloc;
|
|||||||
|
|
||||||
pub mod arch;
|
pub mod arch;
|
||||||
pub mod dev;
|
pub mod dev;
|
||||||
pub mod log;
|
|
||||||
pub mod mem;
|
pub mod mem;
|
||||||
pub mod qemu;
|
pub mod qemu;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -41,11 +40,12 @@ pub fn start(info: StartInfo) -> ! {
|
|||||||
|
|
||||||
pub fn main(info: StartInfo) {
|
pub fn main(info: StartInfo) {
|
||||||
println!("we out here vibin");
|
println!("we out here vibin");
|
||||||
|
println!("memory range: {:?}", info.mem_range);
|
||||||
unsafe {
|
unsafe {
|
||||||
ALLOCATOR.init(&info.mem_range);
|
ALLOCATOR.init(&info.mem_range);
|
||||||
}
|
}
|
||||||
for dev in info.dt.into_iter() {
|
for dev in info.dt.nodes() {
|
||||||
println!("{:?}", dev);
|
println!("{:#?}", dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
use core::{mem::MaybeUninit, ops::Deref};
|
|
||||||
|
|
||||||
pub struct LazyConst<T> {
|
|
||||||
value: T,
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
state: u8,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Deref for LazyConst<T> {
|
|
||||||
type Target = T;
|
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
if self.state == 0 {
|
|
||||||
panic!("Lazy const for {} not assigned", core::any::type_name::<T>());
|
|
||||||
}
|
|
||||||
&self.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> LazyConst<T> {
|
|
||||||
pub const fn new() -> Self {
|
|
||||||
unsafe {
|
|
||||||
Self {
|
|
||||||
value: MaybeUninit::zeroed().assume_init(),
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
state: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn init(&self, value: T) {
|
|
||||||
as_mut(self).value = value;
|
|
||||||
#[cfg(debug_assertions)]
|
|
||||||
{
|
|
||||||
as_mut(self).state = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub unsafe fn as_mut<T>(x: &T) -> &mut T {
|
|
||||||
#[allow(invalid_reference_casting)]
|
|
||||||
&mut *((x as *const T) as *mut T)
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
pub mod bits;
|
pub mod bits;
|
||||||
pub mod lazy;
|
|
||||||
pub mod mutex;
|
pub mod mutex;
|
||||||
pub mod spin;
|
pub mod spin;
|
||||||
|
|||||||
BIN
kernel/test.raw
Normal file
BIN
kernel/test.raw
Normal file
Binary file not shown.
Reference in New Issue
Block a user