@@ -112,13 +112,15 @@ static HSM: Once<qemu_hsm::QemuHsm> = Once::new();
112
112
113
113
/// rust 入口。
114
114
extern "C" fn rust_main ( _hartid : usize , opaque : usize ) {
115
+ use core:: sync:: atomic:: { AtomicBool , Ordering :: AcqRel } ;
116
+
115
117
unsafe { set_mtcev ( early_trap as _ ) } ;
116
118
117
119
#[ link_section = ".bss.uninit" ]
118
- static BOARD_INFO : Once < device_tree :: BoardInfo > = Once :: new ( ) ;
120
+ static GENESIS : AtomicBool = AtomicBool :: new ( false ) ;
119
121
120
122
// 全局初始化过程
121
- BOARD_INFO . call_once ( || {
123
+ if ! GENESIS . swap ( true , AcqRel ) {
122
124
// 清零 bss 段
123
125
zero_bss ( ) ;
124
126
// 初始化堆和分配器
@@ -158,12 +160,11 @@ extern "C" fn rust_main(_hartid: usize, opaque: usize) {
158
160
dtb = opaque,
159
161
firmware = entry as usize ,
160
162
) ;
161
- board_info
162
- } ) ;
163
+ }
163
164
164
165
let hsm = HSM . wait ( ) ;
165
166
if let Some ( supervisor) = hsm. take_supervisor ( ) {
166
- set_pmp ( BOARD_INFO . wait ( ) ) ;
167
+ set_pmp ( ) ;
167
168
hsm. record_current_start_finished ( ) ;
168
169
execute:: execute_supervisor ( supervisor) ;
169
170
}
@@ -208,85 +209,14 @@ fn init_heap() {
208
209
}
209
210
210
211
/// 设置 PMP。
211
- ///
212
- /// FIXME 最好能实现一个排序+合并连续区域的复杂算法,尽量将地址段配置为 NAPOT 以节省 PMP 段,不过全部 TOR 也够用了
213
- fn set_pmp ( board_info : & device_tree:: BoardInfo ) {
214
- use riscv:: register:: {
215
- pmpaddr0, pmpaddr1, pmpaddr10, pmpaddr11, pmpaddr12, pmpaddr13, pmpaddr14, pmpaddr15,
216
- pmpaddr2, pmpaddr3, pmpaddr4, pmpaddr5, pmpaddr6, pmpaddr7, pmpaddr8, pmpaddr9, pmpcfg0,
217
- pmpcfg2,
218
- } ;
219
-
220
- let memory = & board_info. memory ;
221
- let rtc = & board_info. rtc ;
222
- let uart = & board_info. uart ;
223
- let test = & board_info. test ;
224
- let pci = & board_info. pci ;
225
- let clint = & board_info. clint ;
226
- let plic = & board_info. plic ;
227
-
228
- let mut pmpcfg0 = PmpCfg :: ZERO ;
229
- // rtc
230
- pmpcfg0. set_next ( 0 ) ;
231
- pmpaddr0:: write ( rtc. start >> 2 ) ;
232
- pmpcfg0. set_next ( 0b1011 ) ;
233
- pmpaddr1:: write ( rtc. end >> 2 ) ;
234
- // uart
235
- pmpcfg0. set_next ( 0 ) ;
236
- pmpaddr2:: write ( uart. start >> 2 ) ;
237
- pmpcfg0. set_next ( 0b1011 ) ;
238
- pmpaddr3:: write ( uart. end >> 2 ) ;
239
- // test
240
- pmpcfg0. set_next ( 0 ) ;
241
- pmpaddr4:: write ( test. start >> 2 ) ;
242
- pmpcfg0. set_next ( 0b1011 ) ;
243
- pmpaddr5:: write ( test. end >> 2 ) ;
244
- // pci
245
- pmpcfg0. set_next ( 0 ) ;
246
- pmpaddr6:: write ( pci. start >> 2 ) ;
247
- pmpcfg0. set_next ( 0b1011 ) ;
248
- pmpaddr7:: write ( pci. end >> 2 ) ;
249
- // cfg
250
- pmpcfg0:: write ( pmpcfg0. bits ( ) ) ;
251
-
252
- let mut pmpcfg2 = PmpCfg :: ZERO ;
253
- // clint
254
- pmpcfg2. set_next ( 0 ) ;
255
- pmpaddr8:: write ( clint. start >> 2 ) ;
256
- pmpcfg2. set_next ( 0b1011 ) ;
257
- pmpaddr9:: write ( clint. end >> 2 ) ;
258
- // plic
259
- pmpcfg2. set_next ( 0 ) ;
260
- pmpaddr10:: write ( plic. start >> 2 ) ;
261
- pmpcfg2. set_next ( 0b1011 ) ;
262
- pmpaddr11:: write ( plic. end >> 2 ) ;
263
- // virtio_mmio
264
- pmpcfg2. set_next ( 0 ) ;
265
- pmpaddr12:: write ( 0x1000_1000 >> 2 ) ;
266
- pmpcfg2. set_next ( 0b1011 ) ;
267
- pmpaddr13:: write ( 0x1000_9000 >> 2 ) ;
268
- // memory
269
- pmpcfg2. set_next ( 0 ) ;
270
- pmpaddr14:: write ( SUPERVISOR_ENTRY >> 2 ) ;
271
- pmpcfg2. set_next ( 0b1111 ) ;
272
- pmpaddr15:: write ( memory. end >> 2 ) ;
273
- // cfg
274
- pmpcfg2:: write ( pmpcfg2. bits ( ) ) ;
275
- }
276
-
277
- struct PmpCfg ( usize , usize ) ;
278
-
279
- impl PmpCfg {
280
- const ZERO : Self = Self ( 0 , 0 ) ;
281
-
282
- fn set_next ( & mut self , value : u8 ) {
283
- self . 0 |= ( value as usize ) << self . 1 ;
284
- self . 1 += 8 ;
285
- }
286
-
287
- fn bits ( & self ) -> usize {
288
- self . 0
212
+ fn set_pmp ( ) {
213
+ use riscv:: register:: { pmpaddr0, pmpaddr1, pmpcfg0, Permission , Range } ;
214
+ unsafe {
215
+ pmpcfg0:: set_pmp ( 0 , Range :: NAPOT , Permission :: RWX , false ) ;
216
+ pmpcfg0:: set_pmp ( 1 , Range :: NAPOT , Permission :: NONE , false ) ;
289
217
}
218
+ pmpaddr0:: write ( usize:: MAX ) ;
219
+ pmpaddr1:: write ( ( entry as usize >> 2 ) | 0x10_0000 >> 2 ) ;
290
220
}
291
221
292
222
#[ inline( always) ]
0 commit comments