From 0789f4b9eed099cb1533c64cba9042fe295dc993 Mon Sep 17 00:00:00 2001 From: Clo91eaf Date: Wed, 13 Mar 2024 20:28:50 +0800 Subject: [PATCH] Add rvemu crate and rvemu.dts file --- Cargo.lock | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + rvemu.dtb | Bin 0 -> 1598 bytes rvemu.dts | 88 ++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 88 ++++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 278 insertions(+), 3 deletions(-) create mode 100644 rvemu.dtb create mode 100644 rvemu.dts diff --git a/Cargo.lock b/Cargo.lock index df950a9..4c2555f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -96,6 +96,12 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bumpalo" +version = "3.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ff69b9dd49fd426c69a0db9fc04dd934cdb6645ff000864d98f7e2af8830eaa" + [[package]] name = "cc" version = "1.0.79" @@ -263,6 +269,7 @@ dependencies = [ "log", "regex", "rustyline", + "rvemu", ] [[package]] @@ -306,6 +313,15 @@ version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62b02a5381cc465bd3041d84623d0fa3b66738b52b8e2fc3bab8ad63ab032f4a" +[[package]] +name = "js-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29c15563dc2726973df627357ce0c9ddddbea194836909d655df6a75d2cf296d" +dependencies = [ + "wasm-bindgen", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -474,6 +490,18 @@ dependencies = [ "winapi", ] +[[package]] +name = "rvemu" +version = "0.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2cf2d0137e679b050f594199a7fddd31f06a80be7c8dc572cee89fa850e732b" +dependencies = [ + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + [[package]] name = "ryu" version = "1.0.14" @@ -579,6 +607,82 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasm-bindgen" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4be2531df63900aeb2bca0daaaddec08491ee64ceecbee5076636a3b026795a8" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "614d787b966d3989fa7bb98a654e369c762374fd3213d212cfc0251257e747da" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76bc14366121efc8dbb487ab05bcc9d346b3b5ec0eaa76e46594cabbe51762c0" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1f8823de937b71b9460c0c34e25f3da88250760bec0ebac694b49997550d726" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af190c94f2773fdb3729c55b007a722abb5384da03bc0986df4c289bf5567e96" + +[[package]] +name = "web-sys" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77afa9a11836342370f4817622a2f0f418b134426d91a82dfb48f532d2ec13ef" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + [[package]] name = "winapi" version = "0.3.9" diff --git a/Cargo.toml b/Cargo.toml index 0c48bd8..7af2ce4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,3 +15,4 @@ clap = { version = "4.3.11", features = ["derive"] } regex = "1.9.0" eval = "0.4.3" anyhow = "1.0.80" +rvemu = "0.0.11" diff --git a/rvemu.dtb b/rvemu.dtb new file mode 100644 index 0000000000000000000000000000000000000000..47c9f54671a68d8e9b2f850ba5abb28a3ae680bc GIT binary patch literal 1598 zcmah}J#Q2-5cL8H1c(TNz5=;-OFQMBiEl2vxs8{2#0s8Uc+ra}~S z)U^BsT7Cc>HT(p`d-nQn6Ob5b&NK7o%j4Pmw*LF45UbCG5c@)`JjMAKd>_041|`>E zzY*k1ze%TE#~E?>im2a%9QAd`15;QzOJ{{~g@#U|?*s6oJ~lj4RZA4b<%zbc_A-4R zf`>+Hcd(tS+4d~YHjUnty0*Gh2hPo3juyVGKi+OL<0dH2FH86 z=;Wxs68jUFJkA+aRJvh7@?)Xz8hB9KoxSmRltCu>+F=5RRaI!;8M_Pcq9%J_qFA%v zL$7A6>QDOK1rI|0A@f5GHD%LUDxjE?a=!-WMT+>D`0)N5dV<)r${J#cEL-c88BqZx zQXADNG43txVBR${b4;%Iz3cp9+y#7KTGaP*?erC#AN6TArvr#FtKhIxv;-UX?30=8 z?G{ybluO&Kk@vp??6cpqp`Gnw+d)ZD<2I&kT#6-fMwg{B9$EJBg??bxBz*-_=Db4v zAt!`P5|(8g?-%bM&!ke7HuK4TZy}lMCio&?kV1|PoPGx9w194fgSir`eKE%V@7v?O z2ezo1Ql-;w3m8ZG4*us1CbIX%T)q=yW8EK+$DO|DmrF?M8lx|xlXJ(&&k=95C)td|PJrjlf3N z$ZK0!o*QLtDpgrpv1N-ls*|Ozn#>i`Qi)3EsuWZFXJzKt3hQ#+x)kV%SS+7iia?C2 zosgxLr|FSVXRWH`To`pMTv4fMW>wG3Z>BlP>Kv8uk61``=;n<=nats>!zc@ziK=Q- gk8CZfcD?rW; + #size-cells = <0x02>; + compatible = "riscv-virtio"; + model = "riscv-virtio,qemu"; + + chosen { + bootargs = "root=/dev/vda ro console=ttyS0"; + stdout-path = "/uart@10000000"; + }; + + uart@10000000 { + interrupts = <0xa>; + interrupt-parent = <0x03>; + clock-frequency = <0x384000>; + reg = <0x0 0x10000000 0x0 0x100>; + compatible = "ns16550a"; + }; + + virtio_mmio@10001000 { + interrupts = <0x01>; + interrupt-parent = <0x03>; + reg = <0x0 0x10001000 0x0 0x1000>; + compatible = "virtio,mmio"; + }; + + cpus { + #address-cells = <0x01>; + #size-cells = <0x00>; + timebase-frequency = <0x989680>; + + cpu-map { + cluster0 { + core0 { + cpu = <0x01>; + }; + }; + }; + + cpu@0 { + phandle = <0x01>; + device_type = "cpu"; + reg = <0x00>; + status = "okay"; + compatible = "riscv"; + riscv,isa = "rv64imafdcsu"; + mmu-type = "riscv,sv48"; + + interrupt-controller { + #interrupt-cells = <0x01>; + interrupt-controller; + compatible = "riscv,cpu-intc"; + phandle = <0x02>; + }; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0x0 0x8000000>; + }; + + soc { + #address-cells = <0x02>; + #size-cells = <0x02>; + compatible = "simple-bus"; + ranges; + + interrupt-controller@c000000 { + phandle = <0x03>; + riscv,ndev = <0x35>; + reg = <0x00 0xc000000 0x00 0x4000000>; + interrupts-extended = <0x02 0x0b 0x02 0x09>; + interrupt-controller; + compatible = "riscv,plic0"; + #interrupt-cells = <0x01>; + #address-cells = <0x00>; + }; + + clint@2000000 { + interrupts-extended = <0x02 0x03 0x02 0x07>; + reg = <0x00 0x2000000 0x00 0x10000>; + compatible = "riscv,clint0"; + }; + }; +}; \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 49422ae..64cb459 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,87 @@ -use hemu::engine::init::engine_start; +use std::fs::File; +use std::io; +use std::io::prelude::*; +use std::iter::FromIterator; -fn main() { - engine_start(); +use rvemu::bus::DRAM_BASE; +use rvemu::cpu::Cpu; +use rvemu::emulator::Emulator; + +use clap::Parser; + +/// Command line arguments. +#[derive(Parser, Debug)] +#[clap(name = "rvemu: RISC-V emulator", version = "0.0.1", author = "Asami Doi <@d0iasm>")] +struct Args { + /// A kernel ELF image without headers + #[arg(short = 'k', long = "kernel", required = true)] + kernel: String, + + /// A raw disk image + #[arg(short = 'f', long = "file")] + file: Option, + + /// Enables to output debug messages + #[arg(short = 'd', long = "debug")] + debug: bool, + + /// Enables to count each instruction executed + #[clap(short = 'c', long = "count")] + count: bool, +} + +/// Output current registers to the console. +fn dump_registers(cpu: &Cpu) { + println!("-------------------------------------------------------------------------------------------"); + println!("{}", cpu.xregs); + println!("-------------------------------------------------------------------------------------------"); + println!("{}", cpu.fregs); + println!("-------------------------------------------------------------------------------------------"); + println!("{}", cpu.state); + println!("-------------------------------------------------------------------------------------------"); + println!("pc: {:#x}", cpu.pc); +} + +/// Output the count of each instruction executed. +fn dump_count(cpu: &Cpu) { + if cpu.is_count { + println!("==========================================================================================="); + let mut sorted_counter = Vec::from_iter(&cpu.inst_counter); + sorted_counter.sort_by(|&(_, a), &(_, b)| b.cmp(&a)); + for (inst, count) in sorted_counter.iter() { + println!("{}, {}", inst, count); + } + println!("==========================================================================================="); + } +} + +/// Main function of RISC-V emulator for the CLI version. +fn main() -> io::Result<()> { + let args = Args::parse(); + + let mut kernel_file = File::open(args.kernel)?; + let mut kernel_data = Vec::new(); + kernel_file.read_to_end(&mut kernel_data)?; + + let mut img_data = Vec::new(); + if let Some(img_file) = args.file { + File::open(img_file)?.read_to_end(&mut img_data)?; + } + + let mut emu = Emulator::new(); + + emu.initialize_dram(kernel_data); + emu.initialize_disk(img_data); + emu.initialize_pc(DRAM_BASE); + + emu.is_debug = args.debug; + + emu.cpu.is_count = args.count; + + emu.start(); + + dump_registers(&emu.cpu); + dump_count(&emu.cpu); + + Ok(()) }