main.rs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  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::*;
  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. #[repr(C)]
  24. struct DtbHeader {
  25. be_magic: u32,
  26. be_size: u32,
  27. }
  28. let header = unsafe { &*(dtb as *const DtbHeader) };
  29. let magic = u32::from_be(header.be_magic);
  30. const DEVICE_TREE_MAGIC: u32 = 0xd00dfeed;
  31. assert_eq!(magic, DEVICE_TREE_MAGIC);
  32. let size = u32::from_be(header.be_size);
  33. let dtb_data = unsafe { core::slice::from_raw_parts(dtb as *const u8, size as usize) };
  34. let dt = DeviceTree::load(dtb_data).expect("failed to parse device tree");
  35. walk_dt_node(&dt.root);
  36. }
  37. fn walk_dt_node(dt: &Node) {
  38. if let Ok(compatible) = dt.prop_str("compatible") {
  39. if compatible == "virtio,mmio" {
  40. virtio_probe(dt);
  41. }
  42. }
  43. for child in dt.children.iter() {
  44. walk_dt_node(child);
  45. }
  46. }
  47. fn virtio_probe(node: &Node) {
  48. if let Some(reg) = node.prop_raw("reg") {
  49. let paddr = reg.as_slice().read_be_u64(0).unwrap();
  50. let size = reg.as_slice().read_be_u64(8).unwrap();
  51. let vaddr = paddr;
  52. info!("walk dt addr={:#x}, size={:#x}", paddr, size);
  53. let header = unsafe { &mut *(vaddr as *mut VirtIOHeader) };
  54. info!(
  55. "Detected virtio device with vendor id {:#X}",
  56. header.vendor_id()
  57. );
  58. info!("Device tree node {:?}", node);
  59. match header.device_type() {
  60. DeviceType::Block => virtio_blk(header),
  61. DeviceType::GPU => virtio_gpu(header),
  62. DeviceType::Input => virtio_input(header),
  63. DeviceType::Network => virtio_net(header),
  64. t => warn!("Unrecognized virtio device: {:?}", t),
  65. }
  66. }
  67. }
  68. fn virtio_blk(header: &'static mut VirtIOHeader) {
  69. let mut blk = VirtIOBlk::new(header).expect("failed to create blk driver");
  70. let mut input = vec![0xffu8; 512];
  71. let mut output = vec![0; 512];
  72. for i in 0..32 {
  73. for x in input.iter_mut() {
  74. *x = i as u8;
  75. }
  76. blk.write_block(i, &input).expect("failed to write");
  77. blk.read_block(i, &mut output).expect("failed to read");
  78. assert_eq!(input, output);
  79. }
  80. info!("virtio-blk test finished");
  81. }
  82. fn virtio_gpu(header: &'static mut VirtIOHeader) {
  83. let mut gpu = VirtIOGpu::new(header).expect("failed to create gpu driver");
  84. let fb = gpu.setup_framebuffer().expect("failed to get fb");
  85. for y in 0..768 {
  86. for x in 0..1024 {
  87. let idx = (y * 1024 + x) * 4;
  88. fb[idx] = x as u8;
  89. fb[idx + 1] = y as u8;
  90. fb[idx + 2] = (x + y) as u8;
  91. }
  92. }
  93. gpu.flush().expect("failed to flush");
  94. info!("virtio-gpu test finished");
  95. }
  96. fn virtio_input(header: &'static mut VirtIOHeader) {
  97. let mut event_buf = [0u64; 32];
  98. let mut _input =
  99. VirtIOInput::new(header, &mut event_buf).expect("failed to create input driver");
  100. // loop {
  101. // input.ack_interrupt().expect("failed to ack");
  102. // info!("mouse: {:?}", input.mouse_xy());
  103. // }
  104. // TODO: handle external interrupt
  105. }
  106. fn virtio_net(header: &'static mut VirtIOHeader) {
  107. let mut net = VirtIONet::new(header).expect("failed to create net driver");
  108. let mut buf = [0u8; 0x100];
  109. let len = net.recv(&mut buf).expect("failed to recv");
  110. info!("recv: {:?}", &buf[..len]);
  111. net.send(&buf[..len]).expect("failed to send");
  112. info!("virtio-net test finished");
  113. }