xref: /DragonOS/kernel/src/arch/riscv64/driver/sbi.rs (revision 701589559f912deb03eb5176d049d9d07fb29447)
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