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