Skip to content

Commit 5a6a621

Browse files
committed
Bump rustsbi to 0.2.0-alpha.10; use stablized asm macro; update PMP config
1 parent 76c2dcb commit 5a6a621

File tree

3 files changed

+57
-11
lines changed

3 files changed

+57
-11
lines changed

rustsbi-qemu/src/execute.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::feature;
22
use crate::qemu_hsm::{pause, HsmCommand, QemuHsm};
33
use crate::runtime::{MachineTrap, Runtime, SupervisorContext};
44
use core::{
5+
arch::asm,
56
ops::{Generator, GeneratorState},
67
pin::Pin,
78
};

rustsbi-qemu/src/hart_csr_utils.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use alloc::format;
22
use alloc::vec::Vec;
33
use bit_field::BitField;
4+
use core::arch::asm;
45
use riscv::register::{
56
medeleg, mideleg,
67
misa::{self, MXL},

rustsbi-qemu/src/main.rs

Lines changed: 55 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ mod test_device;
2323
use buddy_system_allocator::LockedHeap;
2424
use core::arch::asm;
2525
use core::panic::PanicInfo;
26+
use core::arch::asm;
2627

2728
const PER_HART_STACK_SIZE: usize = 4 * 4096; // 16KiB
2829
const SBI_STACK_SIZE: usize = 8 * PER_HART_STACK_SIZE; // assume 8 cores in QEMU
@@ -156,18 +157,61 @@ fn set_pmp() {
156157
// todo: 根据QEMU的loader device等等,设置这里的权限配置
157158
// read fdt tree value, parse, and calculate proper pmp configuration for this device tree (issue #7)
158159
// integrate with `count_harts`
159-
unsafe {
160-
asm!(
161-
"li {tmp}, ((0x08 << 16) | (0x1F << 8) | (0x1F << 0) )", // 0 = NAPOT,ARWX; 1 = NAPOT,ARWX; 2 = TOR,A;
162-
"csrw 0x3A0, {tmp}",
163-
"li {tmp}, ((0x0000000010001000 >> 2) | 0x3ff)", // 0 = 0x0000000010001000-0x0000000010001fff
164-
"csrw 0x3B0, {tmp}",
165-
"li {tmp}, ((0x0000000080000000 >> 2) | 0x3ffffff)", // 1 = 0x0000000080000000-0x000000008fffffff
166-
"csrw 0x3B1, {tmp}",
167-
"sfence.vma",
168-
tmp = out(reg) _
169-
)
160+
//
161+
// Qemu MMIO config ref: https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c#L46
162+
//
163+
// About PMP:
164+
//
165+
// CSR: pmpcfg0(0x3A0)~pmpcfg15(0x3AF); pmpaddr0(0x3B0)~pmpaddr63(0x3EF)
166+
// pmpcfg packs pmp entries each of which is of 8-bit
167+
// on RV64 only even pmpcfg CSRs(0,2,...,14) are available, each of which contains 8 PMP
168+
// entries
169+
// every pmp entry and its corresponding pmpaddr describe a pmp region
170+
//
171+
// layout of PMP entries:
172+
// ------------------------------------------------------
173+
// 7 | [5:6] | [3:4] | 2 | 1 | 0 |
174+
// L | 0(WARL) | A | X | W | R |
175+
// ------------------------------------------------------
176+
// A = OFF(0), disabled;
177+
// A = TOR(top of range, 1), match address y so that pmpaddr_{i-1}<=y<pmpaddr_i irrespective of
178+
// the value pmp entry i-1
179+
// A = NA4(naturally aligned 4-byte region, 2), only support a 4-byte pmp region
180+
// A = NAPOT(naturally aligned power-of-two region, 3), support a >=8-byte pmp region
181+
// When using NAPOT to match a address range [S,S+L), then the pmpaddr_i should be set to (S>>2)|((L>>2)-1)
182+
let calc_pmpaddr = |start_addr: usize, length: usize| {
183+
(start_addr >> 2) | ((length >> 2) - 1)
170184
};
185+
let mut pmpcfg0: usize = 0;
186+
// pmp region 0: RW, A=NAPOT, address range {0x1000_1000, 0x1000}, VIRT_VIRTIO
187+
// address range {0x1000_0000, 0x100}, VIRT_UART0
188+
// aligned address range {0x1000_0000, 0x2000}
189+
pmpcfg0 |= 0b11011;
190+
let pmpaddr0 = calc_pmpaddr(0x1000_0000, 0x2000);
191+
// pmp region 2: RW, A=NAPOT, address range {0x200_0000, 0x1_0000}, VIRT_CLINT
192+
pmpcfg0 |= 0b11011 << 8;
193+
let pmpaddr1 = calc_pmpaddr(0x200_0000, 0x1_0000);
194+
// pmp region 3: RW, A=NAPOT, address range {0xC00_0000, 0x40_0000}, VIRT_PLIC
195+
// VIRT_PLIC_SIZE = 0x20_0000 + 0x1000 * harts, thus supports up to 512 harts
196+
pmpcfg0 |= 0b11011 << 16;
197+
let pmpaddr2 = calc_pmpaddr(0xC00_0000, 0x40_0000);
198+
// pmp region 4: RWX, A=NAPOT, address range {0x8000_0000, 0x1000_0000}, VIRT_DRAM
199+
pmpcfg0 |= 0b11111 << 24;
200+
let pmpaddr3 = calc_pmpaddr(0x8000_0000, 0x1000_0000);
201+
unsafe {
202+
core::arch::asm!("csrw pmpcfg0, {}",
203+
"csrw pmpaddr0, {}",
204+
"csrw pmpaddr1, {}",
205+
"csrw pmpaddr2, {}",
206+
"csrw pmpaddr3, {}",
207+
"sfence.vma",
208+
in(reg) pmpcfg0,
209+
in(reg) pmpaddr0,
210+
in(reg) pmpaddr1,
211+
in(reg) pmpaddr2,
212+
in(reg) pmpaddr3,
213+
);
214+
}
171215
}
172216

173217
#[naked]

0 commit comments

Comments
 (0)