main.rs 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #![no_std]
  2. #![no_main]
  3. #![deny(warnings)]
  4. #[macro_use]
  5. extern crate alloc;
  6. #[macro_use]
  7. extern crate log;
  8. // #[macro_use]
  9. extern crate opensbi_rt;
  10. use device_tree::util::SliceRead;
  11. use device_tree::{DeviceTree, Node};
  12. use log::LevelFilter;
  13. use virtio_drivers::{DeviceType, VirtIOBlk, VirtIOGpu, VirtIOHeader};
  14. mod virtio_impl;
  15. #[no_mangle]
  16. extern "C" fn main(_hartid: usize, device_tree_paddr: usize) {
  17. log::set_max_level(LevelFilter::Info);
  18. init_dt(device_tree_paddr);
  19. info!("test end");
  20. }
  21. fn init_dt(dtb: usize) {
  22. info!("device tree @ {:#x}", dtb);
  23. struct DtbHeader {
  24. be_magic: u32,
  25. be_size: u32,
  26. }
  27. let header = unsafe { &*(dtb as *const DtbHeader) };
  28. let magic = u32::from_be(header.be_magic);
  29. const DEVICE_TREE_MAGIC: u32 = 0xd00dfeed;
  30. assert_eq!(magic, DEVICE_TREE_MAGIC);
  31. let size = u32::from_be(header.be_size);
  32. let dtb_data = unsafe { core::slice::from_raw_parts(dtb as *const u8, size as usize) };
  33. let dt = DeviceTree::load(dtb_data).expect("failed to parse device tree");
  34. walk_dt_node(&dt.root);
  35. }
  36. fn walk_dt_node(dt: &Node) {
  37. if let Ok(compatible) = dt.prop_str("compatible") {
  38. if compatible == "virtio,mmio" {
  39. virtio_probe(dt);
  40. }
  41. }
  42. for child in dt.children.iter() {
  43. walk_dt_node(child);
  44. }
  45. }
  46. fn virtio_probe(node: &Node) {
  47. if let Some(reg) = node.prop_raw("reg") {
  48. let paddr = reg.as_slice().read_be_u64(0).unwrap();
  49. let size = reg.as_slice().read_be_u64(8).unwrap();
  50. let vaddr = paddr;
  51. info!("walk dt addr={:#x}, size={:#x}", paddr, size);
  52. let header = unsafe { &mut *(vaddr as *mut VirtIOHeader) };
  53. info!(
  54. "Detected virtio device with vendor id {:#X}",
  55. header.vendor_id()
  56. );
  57. info!("Device tree node {:?}", node);
  58. match header.device_type() {
  59. DeviceType::Block => virtio_blk(header),
  60. DeviceType::GPU => virtio_gpu(header),
  61. t => warn!("Unrecognized virtio device: {:?}", t),
  62. }
  63. }
  64. }
  65. fn virtio_blk(header: &'static mut VirtIOHeader) {
  66. let mut blk = VirtIOBlk::new(header).expect("failed to create blk driver");
  67. let mut input = vec![0xffu8; 512];
  68. let mut output = vec![0; 512];
  69. for i in 0..32 {
  70. for x in input.iter_mut() {
  71. *x = i as u8;
  72. }
  73. blk.write_block(i, &input).expect("failed to write");
  74. blk.read_block(i, &mut output).expect("failed to read");
  75. assert_eq!(input, output);
  76. }
  77. info!("virtio-blk test finished");
  78. }
  79. fn virtio_gpu(header: &'static mut VirtIOHeader) {
  80. let mut blk = VirtIOGpu::new(header).expect("failed to create blk driver");
  81. let fb = blk.setup_framebuffer().expect("failed to get fb");
  82. for y in 0..768 {
  83. for x in 0..1024 {
  84. let idx = (y * 1024 + x) * 4;
  85. fb[idx] = x as u8;
  86. fb[idx + 1] = y as u8;
  87. fb[idx + 2] = (x + y) as u8;
  88. }
  89. }
  90. blk.flush().expect("failed to flush");
  91. info!("virtio-gpu test finished");
  92. }