浏览代码

fix blk and add test for it

Runji Wang 5 年之前
父节点
当前提交
95002c5475
共有 4 个文件被更改,包括 37 次插入10 次删除
  1. 5 2
      examples/riscv/Makefile
  2. 15 4
      examples/riscv/src/main.rs
  3. 15 4
      src/blk.rs
  4. 2 0
      src/lib.rs

+ 5 - 2
examples/riscv/Makefile

@@ -3,7 +3,7 @@ target := $(arch)imac-unknown-none-elf
 mode := release
 kernel := target/$(target)/$(mode)/riscv
 bin := target/$(target)/$(mode)/kernel.bin
-img := $(bin)
+img := target/$(target)/$(mode)/img
 
 sysroot := $(shell rustc --print sysroot)
 objdump := $(shell find $(sysroot) -name llvm-objdump) --arch-name=$(arch)
@@ -46,7 +46,7 @@ header:
 clean:
 	cargo clean
 
-qemu: $(bin)
+qemu: $(bin) $(img)
 	qemu-system-$(arch) \
 		-machine virt \
 		-nographic \
@@ -55,4 +55,7 @@ qemu: $(bin)
 		-drive file=$(img),if=none,format=raw,id=x0 \
 		-device virtio-blk-device,drive=x0,bus=virtio-mmio-bus.0
 
+$(img):
+	dd if=/dev/zero of=$@ bs=512 count=32
+
 run: build qemu

+ 15 - 4
examples/riscv/src/main.rs

@@ -1,9 +1,12 @@
 #![no_std]
 #![no_main]
+#![deny(warnings)]
 
 #[macro_use]
-extern crate log;
+extern crate alloc;
 #[macro_use]
+extern crate log;
+// #[macro_use]
 extern crate opensbi_rt;
 
 use device_tree::util::SliceRead;
@@ -67,7 +70,15 @@ fn virtio_probe(node: &Node) {
 
 fn virtio_blk(header: &'static mut VirtIOHeader) {
     let mut blk = VirtIOBlk::new(header).expect("failed to create blk driver");
-    let mut buf = [0u8; 512];
-    blk.read_block(0, &mut buf);
-    unimplemented!()
+    let mut input = vec![0xffu8; 512];
+    let mut output = vec![0; 512];
+    for i in 0..32 {
+        for x in input.iter_mut() {
+            *x = i as u8;
+        }
+        blk.write_block(i, &input).expect("failed to write");
+        blk.read_block(i, &mut output).expect("failed to read");
+        assert_eq!(input, output);
+    }
+    info!("virtio-blk test finished");
 }

+ 15 - 4
src/blk.rs

@@ -69,7 +69,7 @@ impl VirtIOBlk<'_> {
         self.queue.get()?;
         match resp.status {
             RespStatus::Ok => Ok(()),
-            _ => panic!("{:?}", resp.status),
+            _ => Err(Error::IoError),
         }
     }
 
@@ -90,7 +90,7 @@ impl VirtIOBlk<'_> {
         self.queue.get()?;
         match resp.status {
             RespStatus::Ok => Ok(()),
-            _ => panic!("{:?}", resp.status),
+            _ => Err(Error::IoError),
         }
     }
 }
@@ -100,6 +100,16 @@ impl VirtIOBlk<'_> {
 struct BlkConfig {
     /// Number of 512 Bytes sectors
     capacity: Volatile<u64>,
+    size_max: Volatile<u32>,
+    seg_max: Volatile<u32>,
+    cylinders: Volatile<u16>,
+    heads: Volatile<u8>,
+    sectors: Volatile<u8>,
+    blk_size: Volatile<u32>,
+    physical_block_exp: Volatile<u8>,
+    alignment_offset: Volatile<u8>,
+    min_io_size: Volatile<u16>,
+    opt_io_size: Volatile<u32>,
     // ... ignored
 }
 
@@ -127,18 +137,19 @@ enum ReqType {
     WriteZeroes = 13,
 }
 
-#[repr(u32)]
+#[repr(u8)]
 #[derive(Debug, Eq, PartialEq)]
 enum RespStatus {
     Ok = 0,
     IoErr = 1,
     Unsupported = 2,
+    _NotReady = 3,
 }
 
 impl Default for BlkResp {
     fn default() -> Self {
         BlkResp {
-            status: RespStatus::Unsupported,
+            status: RespStatus::_NotReady,
         }
     }
 }

+ 2 - 0
src/lib.rs

@@ -69,4 +69,6 @@ pub enum Error {
     InvalidParam,
     /// Failed to alloc DMA memory.
     DmaError,
+    /// I/O Error
+    IoError,
 }