main.rs 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #![no_std]
  2. #![no_main]
  3. #[macro_use]
  4. extern crate log;
  5. #[macro_use]
  6. extern crate opensbi_rt;
  7. use device_tree::util::SliceRead;
  8. use device_tree::{DeviceTree, Node};
  9. use log::LevelFilter;
  10. use virtio_drivers::{DeviceType, VirtIOBlk, VirtIOHeader};
  11. mod virtio_impl;
  12. #[no_mangle]
  13. extern "C" fn main(_hartid: usize, device_tree_paddr: usize) {
  14. log::set_max_level(LevelFilter::Info);
  15. init_dt(device_tree_paddr);
  16. }
  17. fn init_dt(dtb: usize) {
  18. info!("device tree @ {:#x}", dtb);
  19. struct DtbHeader {
  20. be_magic: u32,
  21. be_size: u32,
  22. }
  23. let header = unsafe { &*(dtb as *const DtbHeader) };
  24. let magic = u32::from_be(header.be_magic);
  25. const DEVICE_TREE_MAGIC: u32 = 0xd00dfeed;
  26. assert_eq!(magic, DEVICE_TREE_MAGIC);
  27. let size = u32::from_be(header.be_size);
  28. let dtb_data = unsafe { core::slice::from_raw_parts(dtb as *const u8, size as usize) };
  29. let dt = DeviceTree::load(dtb_data).expect("failed to parse device tree");
  30. walk_dt_node(&dt.root);
  31. }
  32. fn walk_dt_node(dt: &Node) {
  33. if let Ok(compatible) = dt.prop_str("compatible") {
  34. if compatible == "virtio,mmio" {
  35. virtio_probe(dt);
  36. }
  37. }
  38. for child in dt.children.iter() {
  39. walk_dt_node(child);
  40. }
  41. }
  42. fn virtio_probe(node: &Node) {
  43. if let Some(reg) = node.prop_raw("reg") {
  44. let paddr = reg.as_slice().read_be_u64(0).unwrap();
  45. let size = reg.as_slice().read_be_u64(8).unwrap();
  46. let vaddr = paddr;
  47. info!("walk dt addr={:#x}, size={:#x}", paddr, size);
  48. let header = unsafe { &mut *(vaddr as *mut VirtIOHeader) };
  49. info!(
  50. "Detected virtio device with vendor id {:#X}",
  51. header.vendor_id()
  52. );
  53. info!("Device tree node {:?}", node);
  54. match header.device_type() {
  55. DeviceType::Block => virtio_blk(header),
  56. t => warn!("Unrecognized virtio device: {:?}", t),
  57. }
  58. }
  59. }
  60. fn virtio_blk(header: &'static mut VirtIOHeader) {
  61. let mut blk = VirtIOBlk::new(header).expect("failed to create blk driver");
  62. let mut buf = [0u8; 512];
  63. blk.read_block(0, &mut buf);
  64. unimplemented!()
  65. }