1 /// 向控制台打印字符串。 2 /// 3 /// 该函数接受一个字节切片 `s` 作为输入,并迭代切片中的每个字节 `c`。 4 /// 然后调用 `sbi_rt::console_write_byte` 函数,将 `c` 的值作为参数传递给它。 5 /// 6 /// # 安全性 7 /// 8 /// 这个函数是安全的,因为对SBI环境的操作不涉及不安全内存的访问操作。 9 /// 10 /// # 参数 11 /// 12 /// * `s` - 表示要打印的字符串的字节切片。 13 /// 14 /// # 示例 15 /// 16 /// ``` 17 /// let message = b"Hello, World!"; 18 /// console_putstr(message); 19 /// ``` 20 pub fn console_putstr(s: &[u8]) { 21 if SbiDriver::extensions().contains(SBIExtensions::CONSOLE) { 22 for c in s { 23 sbi_rt::console_write_byte(*c); 24 } 25 return; 26 } else { 27 for c in s { 28 #[allow(deprecated)] 29 sbi_rt::legacy::console_putchar(*c as usize); 30 } 31 } 32 } 33 34 bitflags! { 35 pub struct SBIExtensions: u64 { 36 /// RISC-V SBI Base extension. 37 const BASE = 1 << 0; 38 /// Timer programmer extension. 39 const TIME = 1 << 1; 40 /// Inter-processor Interrupt extension. 41 const SPI = 1 << 2; 42 /// Remote Fence extension. 43 const RFENCE = 1 << 3; 44 /// Hart State Monitor extension. 45 const HSM = 1 << 4; 46 /// System Reset extension. 47 const RESET = 1 << 5; 48 /// Performance Monitoring Unit extension. 49 const PMU = 1 << 6; 50 /// Debug Console extension. 51 const CONSOLE = 1 << 7; 52 /// System Suspend extension. 53 const SUSPEND = 1 << 8; 54 /// SBI CPPC extension. 55 const CPPC = 1 << 9; 56 /// Nested Acceleration extension. 57 const NACL = 1 << 10; 58 /// Steal-time Accounting extension. 59 const STA = 1 << 11; 60 } 61 } 62 63 static mut EXTENSIONS: SBIExtensions = SBIExtensions::empty(); 64 65 #[derive(Debug)] 66 pub struct SbiDriver; 67 68 impl SbiDriver { 69 #[inline(never)] 70 pub fn early_init() { 71 unsafe { 72 EXTENSIONS = Self::probe_extensions(); 73 } 74 } 75 76 /// 获取probe得到的SBI扩展信息。 77 pub fn extensions() -> &'static SBIExtensions { 78 unsafe { &EXTENSIONS } 79 } 80 81 fn probe_extensions() -> SBIExtensions { 82 let mut extensions = SBIExtensions::empty(); 83 if sbi_rt::probe_extension(sbi_rt::Base).is_available() { 84 extensions |= SBIExtensions::BASE; 85 } 86 if sbi_rt::probe_extension(sbi_rt::Timer).is_available() { 87 extensions |= SBIExtensions::TIME; 88 } 89 90 if sbi_rt::probe_extension(sbi_rt::Ipi).is_available() { 91 extensions |= SBIExtensions::SPI; 92 } 93 94 if sbi_rt::probe_extension(sbi_rt::Fence).is_available() { 95 extensions |= SBIExtensions::RFENCE; 96 } 97 98 if sbi_rt::probe_extension(sbi_rt::Hsm).is_available() { 99 extensions |= SBIExtensions::HSM; 100 } 101 102 if sbi_rt::probe_extension(sbi_rt::Reset).is_available() { 103 extensions |= SBIExtensions::RESET; 104 } 105 106 if sbi_rt::probe_extension(sbi_rt::Pmu).is_available() { 107 extensions |= SBIExtensions::PMU; 108 } 109 110 if sbi_rt::probe_extension(sbi_rt::Console).is_available() { 111 extensions |= SBIExtensions::CONSOLE; 112 } 113 114 if sbi_rt::probe_extension(sbi_rt::Suspend).is_available() { 115 extensions |= SBIExtensions::SUSPEND; 116 } 117 118 if sbi_rt::probe_extension(sbi_rt::Cppc).is_available() { 119 extensions |= SBIExtensions::CPPC; 120 } 121 122 if sbi_rt::probe_extension(sbi_rt::Nacl).is_available() { 123 extensions |= SBIExtensions::NACL; 124 } 125 126 if sbi_rt::probe_extension(sbi_rt::Sta).is_available() { 127 extensions |= SBIExtensions::STA; 128 } 129 130 return extensions; 131 } 132 } 133