From b89eb2aa8f23feec5093360e77a48fdda758f953 Mon Sep 17 00:00:00 2001 From: YdrMaster Date: Fri, 1 Jul 2022 17:29:45 +0800 Subject: [PATCH 1/6] refactor: update dtbwalker to 0.1.3 for early qemu Signed-off-by: YdrMaster --- .vscode/settings.json | 2 +- Cargo.lock | 8 +++--- rustsbi-qemu/Cargo.toml | 2 +- rustsbi-qemu/src/device_tree.rs | 9 +++++-- test-kernel/Cargo.toml | 2 +- test-kernel/src/main.rs | 48 ++++++++++++++++++--------------- 6 files changed, 40 insertions(+), 31 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 31d70de..ba8d691 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -6,7 +6,7 @@ "rust.all_targets": false, // For Rust Analyzer plugin users: "rust-analyzer.cargo.target": "riscv64imac-unknown-none-elf", - "rust-analyzer.checkOnSave.enable": false, + "rust-analyzer.checkOnSave.allTargets": false, // Other settings // For clap "rust-analyzer.procMacro.attributes.enable": true, diff --git a/Cargo.lock b/Cargo.lock index 17b2209..228f11b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -69,9 +69,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87eba3c8c7f42ef17f6c659fc7416d0f4758cd3e58861ee63c5fa4a4dde649e4" +checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" dependencies = [ "os_str_bytes", ] @@ -83,9 +83,9 @@ source = "git+https://github.com/YdrMaster/command-ext.git?rev=a8a48c0#a8a48c09b [[package]] name = "dtb-walker" -version = "0.1.1" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2d3436390f4c683088dcc20a45eddf3e1e3dbde62e9d2d09348876a6170e04d" +checksum = "bc3a45c340447805972e5f53bf10e7118d8333bfb779f9c0ba7ec6ea30d40cd8" [[package]] name = "embedded-hal" diff --git a/rustsbi-qemu/Cargo.toml b/rustsbi-qemu/Cargo.toml index 9121d08..294f1a5 100644 --- a/rustsbi-qemu/Cargo.toml +++ b/rustsbi-qemu/Cargo.toml @@ -11,5 +11,5 @@ riscv = "0.8" spin = "0.9" r0 = "1" uart_16550 = "0.2" -dtb-walker = "0.1.1" +dtb-walker = "0.1.3" qemu-exit = "3.0" diff --git a/rustsbi-qemu/src/device_tree.rs b/rustsbi-qemu/src/device_tree.rs index 00060f1..8d2d726 100644 --- a/rustsbi-qemu/src/device_tree.rs +++ b/rustsbi-qemu/src/device_tree.rs @@ -27,7 +27,7 @@ impl Display for StringInline { /// 解析设备树。 pub(crate) fn parse(opaque: usize) -> BoardInfo { - use dtb_walker::{Dtb, DtbObj, Property, WalkOperation::*}; + use dtb_walker::{Dtb, DtbObj, HeaderError as E, Property, WalkOperation::*}; const CPUS: &[u8] = b"cpus"; const MEMORY: &[u8] = b"memory"; const SOC: &[u8] = b"soc"; @@ -44,7 +44,12 @@ pub(crate) fn parse(opaque: usize) -> BoardInfo { test: 0..0, clint: 0..0, }; - let dtb = unsafe { Dtb::from_raw_parts(opaque as _) }.unwrap(); + let dtb = unsafe { + Dtb::from_raw_parts_filtered(opaque as _, |e| { + matches!(e, E::Misaligned(4) | E::LastCompVersion(16)) + }) + } + .unwrap(); ans.dtb.end += dtb.total_size(); dtb.walk(|path, obj| match obj { DtbObj::SubNode { name } => { diff --git a/test-kernel/Cargo.toml b/test-kernel/Cargo.toml index 45f8fd1..910580c 100644 --- a/test-kernel/Cargo.toml +++ b/test-kernel/Cargo.toml @@ -13,4 +13,4 @@ riscv = "0.8" spin = "0.9" r0 = "1" uart_16550 = "0.2" -dtb-walker = "0.1.1" +dtb-walker = "0.1.3" diff --git a/test-kernel/src/main.rs b/test-kernel/src/main.rs index ad2bae9..a6fda7f 100644 --- a/test-kernel/src/main.rs +++ b/test-kernel/src/main.rs @@ -260,31 +260,35 @@ struct BoardInfo { } fn parse_smp(dtb_pa: usize) -> BoardInfo { - use dtb_walker::{Dtb, DtbObj, Property, WalkOperation::*}; + use dtb_walker::{Dtb, DtbObj, HeaderError as E, Property, WalkOperation::*}; let mut ans = BoardInfo { smp: 0, uart: 0 }; - unsafe { Dtb::from_raw_parts(dtb_pa as _) } - .unwrap() - .walk(|path, obj| match obj { - DtbObj::SubNode { name } => { - if path.last().is_empty() && (name == b"cpus" || name == b"soc") { - StepInto - } else if path.last() == b"cpus" && name.starts_with(b"cpu@") { - ans.smp += 1; - StepOver - } else if path.last() == b"soc" && name.starts_with(b"uart") { - StepInto - } else { - StepOver - } + unsafe { + Dtb::from_raw_parts_filtered(dtb_pa as _, |e| { + matches!(e, E::Misaligned(4) | E::LastCompVersion(16)) + }) + } + .unwrap() + .walk(|path, obj| match obj { + DtbObj::SubNode { name } => { + if path.last().is_empty() && (name == b"cpus" || name == b"soc") { + StepInto + } else if path.last() == b"cpus" && name.starts_with(b"cpu@") { + ans.smp += 1; + StepOver + } else if path.last() == b"soc" && name.starts_with(b"uart") { + StepInto + } else { + StepOver } - DtbObj::Property(Property::Reg(mut reg)) => { - if path.last().starts_with(b"uart") { - ans.uart = reg.next().unwrap().start; - } - StepOut + } + DtbObj::Property(Property::Reg(mut reg)) => { + if path.last().starts_with(b"uart") { + ans.uart = reg.next().unwrap().start; } - DtbObj::Property(_) => StepOver, - }); + StepOut + } + DtbObj::Property(_) => StepOver, + }); ans } From 6743ca431ba1784d6a9dbc5dd8e401ce923b007b Mon Sep 17 00:00:00 2001 From: YdrMaster Date: Sat, 2 Jul 2022 12:02:36 +0800 Subject: [PATCH 2/6] refactor(xtask): update command-ext for qemu Signed-off-by: YdrMaster --- Cargo.lock | 5 ++++- xtask/Cargo.toml | 2 +- xtask/src/main.rs | 30 +++++------------------------- 3 files changed, 10 insertions(+), 27 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 228f11b..159c707 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -79,7 +79,10 @@ dependencies = [ [[package]] name = "command-ext" version = "0.1.0" -source = "git+https://github.com/YdrMaster/command-ext.git?rev=a8a48c0#a8a48c09bd9c1a08f39cb63e5e5963020bdbc20f" +source = "git+https://github.com/YdrMaster/command-ext.git?rev=f25befb#f25befb0b5a58e3e75fb3a891d6cc5969a13d93c" +dependencies = [ + "lazy_static", +] [[package]] name = "dtb-walker" diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index 3d08c71..0fb65cf 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -11,4 +11,4 @@ publish = false [dependencies] clap = { version = "~3.1", features = ["derive"] } lazy_static = "1.4" -command-ext = { git = "https://github.com/YdrMaster/command-ext.git", rev = "a8a48c0" } +command-ext = { git = "https://github.com/YdrMaster/command-ext.git", rev = "f25befb" } diff --git a/xtask/src/main.rs b/xtask/src/main.rs index d455a85..5b13bb7 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -2,9 +2,8 @@ extern crate clap; use clap::Parser; -use command_ext::{BinUtil, Cargo, CommandExt, Ext}; +use command_ext::{BinUtil, Cargo, CommandExt, Qemu}; use std::{ - ffi::OsString, fs, path::{Path, PathBuf}, }; @@ -168,32 +167,13 @@ struct QemuArgs { } impl QemuArgs { - fn find_qemu(&self) -> OsString { - let name = if cfg!(target_os = "windows") { - format!("qemu-system-{}.exe", self.build.arch()) - } else { - format!("qemu-system-{}", self.build.arch()) - }; - if let Some(path) = &self.qemu_dir { - let target = PathBuf::from(path).join(&name); - if target.is_file() { - return target.into_os_string(); - } - } - #[cfg(target_os = "windows")] - { - let target = PathBuf::from(r"C:\Program Files\qemu").join(&name); - if target.is_file() { - return target.into_os_string(); - } - } - OsString::from(name) - } - fn run(mut self) { self.build.kernel.get_or_insert_with(|| "test".into()); self.build.make(); - Ext::new(self.find_qemu()) + if let Some(p) = &self.qemu_dir { + Qemu::search_at(p); + } + Qemu::system(self.build.arch()) .args(&["-machine", "virt"]) .arg("-bios") .arg(self.build.dir().join("rustsbi-qemu.bin")) From 72f39f9e9da98b2a868ced1ef23f45de950a0bd9 Mon Sep 17 00:00:00 2001 From: YdrMaster Date: Sun, 10 Jul 2022 15:59:19 +0800 Subject: [PATCH 3/6] build: update rustsbi Signed-off-by: YdrMaster --- Cargo.lock | 17 +++++++++-------- rustsbi-qemu/Cargo.toml | 4 +++- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 159c707..70f96d3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -102,9 +102,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" +checksum = "607c8a29735385251a339424dd462993c0fed8fa09d378f259377df08c126022" [[package]] name = "heck" @@ -241,11 +241,11 @@ dependencies = [ [[package]] name = "rustsbi" -version = "0.2.2" -source = "git+https://github.com/YdrMaster/rustsbi.git?rev=bd3c092#bd3c0924874acd21a92099a00ae6983abefe0d8d" +version = "0.3.0-alpha.1" +source = "git+https://github.com/rustsbi/rustsbi?rev=af60b02#af60b0211ff0354f618ed437beca471ef49a0f61" dependencies = [ "riscv", - "sbi-spec 0.1.0 (git+https://github.com/rustsbi/sbi-spec.git?rev=9d728bb)", + "sbi-spec 0.0.1", ] [[package]] @@ -272,13 +272,14 @@ name = "sbi-rt" version = "0.1.0" source = "git+https://github.com/rustsbi/sbi-rt.git?rev=72b607c#72b607ce7536ce6f3181e230955aeb0bc6a22564" dependencies = [ - "sbi-spec 0.1.0 (git+https://github.com/rustsbi/sbi-spec.git?rev=a0fd76b)", + "sbi-spec 0.1.0", ] [[package]] name = "sbi-spec" -version = "0.1.0" -source = "git+https://github.com/rustsbi/sbi-spec.git?rev=9d728bb#9d728bbbb3aed4bad3f65413ca666a77ecbfda1b" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9052abf4e5360c78094e445e2c8f7975481c45094e068230b7a1860709289cee" [[package]] name = "sbi-spec" diff --git a/rustsbi-qemu/Cargo.toml b/rustsbi-qemu/Cargo.toml index 294f1a5..dd05173 100644 --- a/rustsbi-qemu/Cargo.toml +++ b/rustsbi-qemu/Cargo.toml @@ -6,7 +6,9 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -rustsbi = { git = "https://github.com/YdrMaster/rustsbi.git", rev = "bd3c092" } +rustsbi = { git = "https://github.com/rustsbi/rustsbi", rev = "af60b02", features = [ + "legacy", +] } riscv = "0.8" spin = "0.9" r0 = "1" From 4284643bb21f6513e2b81ef85bc537c8477c61d7 Mon Sep 17 00:00:00 2001 From: YdrMaster Date: Thu, 21 Jul 2022 07:45:31 +0800 Subject: [PATCH 4/6] build: update deps - Updating dtb-walker v0.1.3 -> v0.2.0-alpha.3 - Updating hashbrown v0.12.2 -> v0.12.3 - Updating os_str_bytes v6.1.0 -> v6.2.0 - Updating rustversion v1.0.7 -> v1.0.8 - Updating spin v0.9.3 -> v0.9.4 - Updating unicode-ident v1.0.1 -> v1.0.2 - Updating x86_64 v0.14.9 -> v0.14.10 Signed-off-by: YdrMaster --- Cargo.lock | 28 ++++++++++++++-------------- rustsbi-qemu/Cargo.toml | 2 +- rustsbi-qemu/src/device_tree.rs | 30 +++++++++++++++--------------- test-kernel/Cargo.toml | 2 +- test-kernel/src/main.rs | 12 ++++++------ 5 files changed, 37 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 70f96d3..dc0b07f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -86,9 +86,9 @@ dependencies = [ [[package]] name = "dtb-walker" -version = "0.1.3" +version = "0.2.0-alpha.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc3a45c340447805972e5f53bf10e7118d8333bfb779f9c0ba7ec6ea30d40cd8" +checksum = "9404d41caa1aa659f7be44d5a902e318c0672900822fe9ca41d9e38c14b52332" [[package]] name = "embedded-hal" @@ -102,9 +102,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.12.2" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "607c8a29735385251a339424dd462993c0fed8fa09d378f259377df08c126022" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" [[package]] name = "heck" @@ -170,9 +170,9 @@ checksum = "546c37ac5d9e56f55e73b677106873d9d9f5190605e41a856503623648488cae" [[package]] name = "os_str_bytes" -version = "6.1.0" +version = "6.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa" +checksum = "648001efe5d5c0102d8cea768e348da85d90af8ba91f0bea908f157951493cd4" [[package]] name = "proc-macro-error" @@ -263,9 +263,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.7" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0a5f7c728f5d284929a1cccb5bc19884422bfe6ef4d6c409da2c41838983fcf" +checksum = "24c8ad4f0c00e1eb5bc7614d236a7f1300e3dbd76b68cac8e06fb00b015ad8d8" [[package]] name = "sbi-rt" @@ -294,9 +294,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" [[package]] name = "spin" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c530c2b0d0bf8b69304b39fe2001993e267461948b890cd037d8ad4293fa1a0d" +checksum = "7f6002a767bff9e83f8eeecf883ecb8011875a21ae8da43bffb817a57e78cc09" dependencies = [ "lock_api", ] @@ -358,9 +358,9 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" +checksum = "15c61ba63f9235225a22310255a29b806b907c9b8c964bcbd0a2c70f3f2deea7" [[package]] name = "version_check" @@ -413,9 +413,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "x86_64" -version = "0.14.9" +version = "0.14.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958cd5cb28e720db2f59ee9dc4235b5f82a183d079fb0e6caf43ad074cfdc66a" +checksum = "100555a863c0092238c2e0e814c1096c1e5cf066a309c696a87e907b5f8c5d69" dependencies = [ "bit_field", "bitflags", diff --git a/rustsbi-qemu/Cargo.toml b/rustsbi-qemu/Cargo.toml index dd05173..6ceaf88 100644 --- a/rustsbi-qemu/Cargo.toml +++ b/rustsbi-qemu/Cargo.toml @@ -13,5 +13,5 @@ riscv = "0.8" spin = "0.9" r0 = "1" uart_16550 = "0.2" -dtb-walker = "0.1.3" +dtb-walker = "=0.2.0-alpha.3" qemu-exit = "3.0" diff --git a/rustsbi-qemu/src/device_tree.rs b/rustsbi-qemu/src/device_tree.rs index 8d2d726..86d8dce 100644 --- a/rustsbi-qemu/src/device_tree.rs +++ b/rustsbi-qemu/src/device_tree.rs @@ -27,13 +27,13 @@ impl Display for StringInline { /// 解析设备树。 pub(crate) fn parse(opaque: usize) -> BoardInfo { - use dtb_walker::{Dtb, DtbObj, HeaderError as E, Property, WalkOperation::*}; - const CPUS: &[u8] = b"cpus"; - const MEMORY: &[u8] = b"memory"; - const SOC: &[u8] = b"soc"; - const UART: &[u8] = b"uart"; - const TEST: &[u8] = b"test"; - const CLINT: &[u8] = b"clint"; + use dtb_walker::{Dtb, DtbObj, HeaderError as E, Property, Str, WalkOperation::*}; + const CPUS: &str = "cpus"; + const MEMORY: &str = "memory"; + const SOC: &str = "soc"; + const UART: &str = "uart"; + const TEST: &str = "test"; + const CLINT: &str = "clint"; let mut ans = BoardInfo { dtb: opaque..opaque, @@ -51,35 +51,35 @@ pub(crate) fn parse(opaque: usize) -> BoardInfo { } .unwrap(); ans.dtb.end += dtb.total_size(); - dtb.walk(|path, obj| match obj { + dtb.walk(|ctx, obj| match obj { DtbObj::SubNode { name } => { - let current = path.last(); - if current.is_empty() { - if name == CPUS || name == SOC || name.starts_with(MEMORY) { + let current = ctx.name(); + if ctx.is_root() { + if name == Str::from(CPUS) || name == Str::from(SOC) || name.starts_with(MEMORY) { StepInto } else { StepOver } - } else if current == SOC { + } else if current == Str::from(SOC) { if name.starts_with(UART) || name.starts_with(TEST) || name.starts_with(CLINT) { StepInto } else { StepOver } } else { - if current == CPUS && name.starts_with(b"cpu@") { + if current == Str::from(CPUS) && name.starts_with("cpu@") { ans.smp += 1; } StepOver } } - DtbObj::Property(Property::Model(model)) if path.last().is_empty() => { + DtbObj::Property(Property::Model(model)) if ctx.is_root() => { ans.model.0 = model.as_bytes().len(); ans.model.1[..ans.model.0].copy_from_slice(model.as_bytes()); StepOver } DtbObj::Property(Property::Reg(mut reg)) => { - let node = path.last(); + let node = ctx.name(); if node.starts_with(UART) { ans.uart = reg.next().unwrap(); StepOut diff --git a/test-kernel/Cargo.toml b/test-kernel/Cargo.toml index 910580c..634e5f8 100644 --- a/test-kernel/Cargo.toml +++ b/test-kernel/Cargo.toml @@ -13,4 +13,4 @@ riscv = "0.8" spin = "0.9" r0 = "1" uart_16550 = "0.2" -dtb-walker = "0.1.3" +dtb-walker = "=0.2.0-alpha.3" diff --git a/test-kernel/src/main.rs b/test-kernel/src/main.rs index a6fda7f..2529c29 100644 --- a/test-kernel/src/main.rs +++ b/test-kernel/src/main.rs @@ -260,7 +260,7 @@ struct BoardInfo { } fn parse_smp(dtb_pa: usize) -> BoardInfo { - use dtb_walker::{Dtb, DtbObj, HeaderError as E, Property, WalkOperation::*}; + use dtb_walker::{Dtb, DtbObj, HeaderError as E, Property, Str, WalkOperation::*}; let mut ans = BoardInfo { smp: 0, uart: 0 }; unsafe { @@ -269,21 +269,21 @@ fn parse_smp(dtb_pa: usize) -> BoardInfo { }) } .unwrap() - .walk(|path, obj| match obj { + .walk(|ctx, obj| match obj { DtbObj::SubNode { name } => { - if path.last().is_empty() && (name == b"cpus" || name == b"soc") { + if ctx.is_root() && (name == Str::from("cpus") || name == Str::from("soc")) { StepInto - } else if path.last() == b"cpus" && name.starts_with(b"cpu@") { + } else if ctx.name() == Str::from("cpus") && name.starts_with("cpu@") { ans.smp += 1; StepOver - } else if path.last() == b"soc" && name.starts_with(b"uart") { + } else if ctx.name() == Str::from("soc") && name.starts_with("uart") { StepInto } else { StepOver } } DtbObj::Property(Property::Reg(mut reg)) => { - if path.last().starts_with(b"uart") { + if ctx.name().starts_with("uart") { ans.uart = reg.next().unwrap().start; } StepOut From 7e177b36cfc7f0e075c8df062fc0b54e5466479b Mon Sep 17 00:00:00 2001 From: YdrMaster Date: Thu, 21 Jul 2022 13:04:56 +0800 Subject: [PATCH 5/6] =?UTF-8?q?fix:=20=E6=AD=A3=E7=A1=AE=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=20timer=20interrupt=20delegate?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: YdrMaster --- rustsbi-qemu/src/clint.rs | 2 ++ test-kernel/src/main.rs | 18 ++++++++++++++---- test-kernel/src/test.rs | 32 +++++++++++++++++++++++++++++--- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/rustsbi-qemu/src/clint.rs b/rustsbi-qemu/src/clint.rs index 4f8147d..228d937 100644 --- a/rustsbi-qemu/src/clint.rs +++ b/rustsbi-qemu/src/clint.rs @@ -55,6 +55,8 @@ impl Timer for Clint { #[inline] fn set_timer(&self, time_value: u64) { unsafe { + riscv::register::mip::clear_stimer(); + riscv::register::mie::set_mtimer(); ((self.base as *mut u8).offset(0x4000) as *mut u64) .add(hart_id()) .write_volatile(time_value); diff --git a/test-kernel/src/main.rs b/test-kernel/src/main.rs index 2529c29..7696575 100644 --- a/test-kernel/src/main.rs +++ b/test-kernel/src/main.rs @@ -6,7 +6,7 @@ use core::arch::asm; use riscv::register::{ - scause::Trap, + scause::{Interrupt, Trap}, sepc, stvec::{self, TrapMode}, }; @@ -84,7 +84,10 @@ extern "C" fn primary_rust_main(hartid: usize, dtb_pa: usize) -> ! { test::sbi_ins_emulation(); unsafe { stvec::write(start_trap as usize, TrapMode::Direct) }; - test::trap_delegate(hartid); + test::trap_execption_delegate(hartid); + + unsafe { riscv::register::sstatus::set_sie() }; + test::trap_interrupt_delegate(hartid); test::hsm(hartid, smp); @@ -97,9 +100,16 @@ extern "C" fn rust_trap_exception(trap_frame: &mut TrapFrame) { let cause = scause::read().cause(); let expected = unsafe { core::mem::take(&mut EXPECTED[trap_frame.tp]) }; - if Some(cause) == expected { - sepc::write(sepc::read().wrapping_add(4)); + match cause { + Trap::Exception(_) => { + sepc::write(sepc::read().wrapping_add(4)); + } + Trap::Interrupt(Interrupt::SupervisorTimer) => { + sbi_rt::set_timer(u64::MAX); + } + _ => {} + } } else { panic!("[test-kernel] SBI test FAILED due to unexpected trap {cause:?}"); } diff --git a/test-kernel/src/test.rs b/test-kernel/src/test.rs index 33d8631..0b868d9 100644 --- a/test-kernel/src/test.rs +++ b/test-kernel/src/test.rs @@ -1,4 +1,6 @@ -pub(crate) fn base_extension() { +use crate::EXPECTED; + +pub(crate) fn base_extension() { println!( " [test-kernel] Testing base extension" @@ -55,8 +57,7 @@ pub(crate) fn sbi_ins_emulation() { } } -pub(crate) fn trap_delegate(hartid: usize) { - use crate::EXPECTED; +pub(crate) fn trap_execption_delegate(hartid: usize) { use core::arch::asm; use riscv::register::scause::{Exception, Trap}; @@ -78,6 +79,31 @@ pub(crate) fn trap_delegate(hartid: usize) { ); } +pub(crate) fn trap_interrupt_delegate(hartid: usize) { + use core::arch::asm; + use riscv::register::{ + scause::{Interrupt, Trap}, + sie, time, + }; + + println!( + " +[test-kernel] Testing trap delegate +[test-kernel] Set timer +1s" + ); + unsafe { + sie::set_stimer(); + EXPECTED[hartid] = Some(Trap::Interrupt(Interrupt::SupervisorTimer)); + } + sbi_rt::set_timer(time::read64() + (10 << 20)); + + unsafe { riscv::asm::wfi() }; + println!( + "\ +[test-kernel] Timer interrupt delegate success" + ); +} + /// 所有副核:启动 -> 不可恢复休眠 -> 唤醒 -> 可恢复休眠 -> 唤醒 -> 关闭。 pub(crate) fn hsm(hartid: usize, smp: usize) { use sbi_rt::SbiRet; From 62bee3553133cdcc7d85b971bbef97728dfa78eb Mon Sep 17 00:00:00 2001 From: YdrMaster Date: Thu, 21 Jul 2022 16:42:30 +0800 Subject: [PATCH 6/6] =?UTF-8?q?style:=20=E6=95=B4=E7=90=86=20execute?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit fix: panic 时以 system failure 退出 Signed-off-by: YdrMaster --- rustsbi-qemu/src/execute.rs | 79 ++++++++++++++++--------------------- rustsbi-qemu/src/main.rs | 8 ++-- test-kernel/src/test.rs | 1 - 3 files changed, 38 insertions(+), 50 deletions(-) diff --git a/rustsbi-qemu/src/execute.rs b/rustsbi-qemu/src/execute.rs index 946d5b8..99b6f26 100644 --- a/rustsbi-qemu/src/execute.rs +++ b/rustsbi-qemu/src/execute.rs @@ -1,5 +1,6 @@ use crate::{clint, hart_id, qemu_hsm::QemuHsm, Supervisor}; -use riscv::register::{mstatus, mtval, scause, sepc, stval, stvec}; +use core::arch::asm; +use riscv::register::*; #[repr(usize)] pub(crate) enum Operation { @@ -8,9 +9,6 @@ pub(crate) enum Operation { } pub(crate) fn execute_supervisor(hsm: &QemuHsm, supervisor: Supervisor) -> Operation { - use core::arch::asm; - use riscv::register::{medeleg, mie}; - unsafe { mstatus::set_mpp(mstatus::MPP::Supervisor); mstatus::set_mie(); @@ -24,7 +22,6 @@ pub(crate) fn execute_supervisor(hsm: &QemuHsm, supervisor: Supervisor) -> Opera asm!("csrw mideleg, {}", in(reg) usize::MAX); asm!("csrw medeleg, {}", in(reg) usize::MAX); mstatus::clear_mie(); - medeleg::clear_illegal_instruction(); medeleg::clear_supervisor_env_call(); medeleg::clear_machine_env_call(); @@ -35,56 +32,32 @@ pub(crate) fn execute_supervisor(hsm: &QemuHsm, supervisor: Supervisor) -> Opera hsm.record_current_start_finished(); loop { - use riscv::register::{ - mcause::{self, Exception as E, Interrupt as I, Trap as T}, - mip, - }; + use mcause::{Exception as E, Interrupt as I, Trap as T}; unsafe { m_to_s(&mut ctx) }; match mcause::read().cause() { T::Interrupt(I::MachineTimer) => unsafe { + // set timer 同时打开中断,响应后即可关闭 mie::clear_mtimer(); + // 转发给 supervisor mip::clear_mtimer(); mip::set_stimer(); }, - T::Interrupt(I::MachineSoft) => { + T::Interrupt(I::MachineSoft) => unsafe { + // 响应中断,清除中断标记 crate::clint::get().clear_soft(hart_id()); - unsafe { - mip::clear_msoft(); - mip::set_ssoft(); - } - } + // 转发给 supervisor + mip::clear_msoft(); + mip::set_ssoft(); + }, T::Exception(E::SupervisorEnvCall) => { if let Some(op) = ctx.handle_ecall() { return op; } } - T::Exception(E::IllegalInstruction) => { - use riscv::register::scause::{Exception as E, Trap as T}; - - // let instruction = mtval::read(); - // 尝试修正或代理指令 - // TODO 需要排查 qemu 哪些版本需要代理哪些指令? - // TODO 标准 20191213 的表 24.3 列出了一些特殊的 CSR,SBI 软件负责将它们模拟出来,但 Qemu6.0+ 似乎不需要模拟 time - // const OPCODE_MASK: usize = (1 << 7) - 1; - // const REG_MASK: usize = (1 << 5) - 1; - // const OPCODE_CSR: usize = 0b1110011; - // const CSR_TIME: usize = 0xc01; - // if let OPCODE_CSR = instruction & OPCODE_MASK { - // if instruction >> 20 == CSR_TIME { - // match (instruction >> 7) & REG_MASK { - // 0 => {} - // rd => *ctx.x_mut(rd) = crate::clint::get().get_mtime() as _, - // } - // continue; - // } - // } - - ctx.do_transfer_trap(T::Exception(E::IllegalInstruction)); - } - // TODO 可以修复非原子的非对齐访存 - t => panic!("unsupported trap: {t:?}"), + // TODO 可以修复非原子的非对齐访存? + t => ctx.trap_stop(t), } } } @@ -107,7 +80,7 @@ impl Context { mepc: supervisor.start_addr, }; - unsafe { core::arch::asm!("csrr {}, mstatus", out(reg) ctx.mstatus) }; + unsafe { asm!("csrr {}, mstatus", out(reg) ctx.mstatus) }; *ctx.a_mut(0) = hart_id(); *ctx.a_mut(1) = supervisor.opaque; @@ -188,6 +161,7 @@ impl Context { None } + #[allow(unused)] fn do_transfer_trap(&mut self, cause: scause::Trap) { unsafe { // 向 S 转发陷入 @@ -213,12 +187,29 @@ impl Context { mstatus::set_spie(); mstatus::clear_sie(); } - core::arch::asm!("csrr {}, mstatus", out(reg) self.mstatus); + asm!("csrr {}, mstatus", out(reg) self.mstatus); // 设置返回地址,返回到 S // TODO Vectored stvec? self.mepc = stvec::read().address(); } } + + fn trap_stop(&self, trap: mcause::Trap) -> ! { + println!( + " +----------------------------- +> trap: {trap:?} +> mstatus: {:#018x} +> mepc: {:#018x} +> mtval: {:#018x} +----------------------------- +", + self.mstatus, + self.mepc, + mtval::read() + ); + panic!("stopped with unsupported trap") + } } /// M 态转到 S 态。 @@ -230,7 +221,7 @@ impl Context { /// 实际 x0(zero) 和 x2(sp) 不需要保存在这里。 #[naked] unsafe extern "C" fn m_to_s(ctx: &mut Context) { - core::arch::asm!( + asm!( r" .altmacro .macro SAVE_M n @@ -298,7 +289,7 @@ unsafe extern "C" fn m_to_s(ctx: &mut Context) { #[naked] #[link_section = ".text.trap_handler"] unsafe extern "C" fn s_to_m() { - core::arch::asm!( + asm!( r" .altmacro .macro SAVE_S n diff --git a/rustsbi-qemu/src/main.rs b/rustsbi-qemu/src/main.rs index 117ea55..5cbb46a 100644 --- a/rustsbi-qemu/src/main.rs +++ b/rustsbi-qemu/src/main.rs @@ -40,16 +40,14 @@ struct Supervisor { #[cfg_attr(not(test), panic_handler)] fn panic(info: &core::panic::PanicInfo) -> ! { use rustsbi::{ - spec::srst::{RESET_REASON_NO_REASON, RESET_TYPE_SHUTDOWN}, + spec::srst::{RESET_REASON_SYSTEM_FAILURE, RESET_TYPE_SHUTDOWN}, Reset, }; // 输出的信息大概是“[rustsbi-panic] hart 0 panicked at ...” println!("[rustsbi-panic] hart {} {info}", hart_id()); println!("[rustsbi-panic] system shutdown scheduled due to RustSBI panic"); - qemu_test::get().system_reset(RESET_TYPE_SHUTDOWN, RESET_REASON_NO_REASON); - loop { - core::hint::spin_loop(); - } + qemu_test::get().system_reset(RESET_TYPE_SHUTDOWN, RESET_REASON_SYSTEM_FAILURE); + unreachable!() } /// 入口。 diff --git a/test-kernel/src/test.rs b/test-kernel/src/test.rs index 0b868d9..c4052e3 100644 --- a/test-kernel/src/test.rs +++ b/test-kernel/src/test.rs @@ -80,7 +80,6 @@ pub(crate) fn trap_execption_delegate(hartid: usize) { } pub(crate) fn trap_interrupt_delegate(hartid: usize) { - use core::arch::asm; use riscv::register::{ scause::{Interrupt, Trap}, sie, time,