xref: /DragonOS/kernel/src/arch/riscv64/driver/sbi.rs (revision 2b7818e80e00fcfe4d03533f587cc125ea5e4bec)
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 Jiang pub 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