Skip to content

Commit

Permalink
riscv: register: fix smeh and smel register definitions
Browse files Browse the repository at this point in the history
- always export smel register, but make `read` effective only on 64-bit architectures;
- fix page_size definition on smeh register.

Signed-off-by: Zhouqi Jiang <[email protected]>
  • Loading branch information
luojia65 committed Dec 25, 2024
1 parent 2c4fc74 commit c99ee11
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 32 deletions.
20 changes: 8 additions & 12 deletions xuantie-riscv/src/paging.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,34 @@
//! Paging support.
#[cfg(target_pointer_width = "64")]
use bit_field::BitField;

/// XuanTie extended page table entry.
#[cfg(target_pointer_width = "64")]
/// XuanTie extended 64-bit page table entry.
#[derive(Clone, Copy, Debug)]
#[repr(transparent)]
pub struct Entry {
bits: usize,
bits: u64,
}

#[cfg(target_pointer_width = "64")]
impl Entry {
/// Convert bit representation into page entry, keeping all the bits.
#[inline]
pub const fn from_bits(bits: usize) -> Entry {
pub const fn from_bits(bits: u64) -> Entry {
Entry { bits }
}
/// Returns the raw value of the entry.
#[inline]
pub const fn bits(&self) -> usize {
pub const fn bits(&self) -> u64 {
self.bits
}
/// Set physical page number.
#[inline]
pub fn set_ppn(&mut self, ppn: usize) {
pub fn set_ppn(&mut self, ppn: u64) {
assert!(ppn <= (1 << (28 + 1)));
self.bits |= ppn << 10;
}
/// Get physical page number.
#[inline]
pub fn ppn(&self) -> usize {
pub fn ppn(&self) -> u64 {
self.bits.get_bits(10..38)
}
/// Insert entry flags, setting corresponding bits to one.
Expand Down Expand Up @@ -65,10 +62,9 @@ impl Entry {
}
}

#[cfg(target_pointer_width = "64")]
bitflags::bitflags! {
/// XuanTie page table entry flags.
pub struct Flags: usize {
/// XuanTie 64-bit page table entry flags.
pub struct Flags: u64 {
/// Valid.
const VALID = 1 << 0;
/// Read.
Expand Down
2 changes: 0 additions & 2 deletions xuantie-riscv/src/register.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ pub mod sxstatus; // 0x5C0 // 0x5C3
// Extended supervisor virtual memory registers
// pub mod smir; // 0x9C0
pub mod smeh;
// Only enable smel when 64-bit, as it would contain a page table entry
#[cfg(target_pointer_width = "64")]
pub mod smel; // 0x9C1 // 0x9C2
// pub mod smcir; // 0x9C3

Expand Down
29 changes: 16 additions & 13 deletions xuantie-riscv/src/register/smeh.rs
Original file line number Diff line number Diff line change
@@ -1,37 +1,40 @@
//! smeh, supervisor memory entry high register
//! smeh, supervisor memory entry high register.
use bit_field::BitField;

/// smeh register
/// smeh register.
#[derive(Clone, Copy, Debug)]
pub struct Smeh {
bits: usize,
}

/// Page size
/// Page size.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum PageSize {
Page4K = 0,
Page2M = 1,
Page1G = 2,
/// 4-KiB page.
Page4K = 1,
/// 2-MiB page.
Page2M = 2,
/// 1-GiB page.
Page1G = 4,
}

impl Smeh {
/// Get address space number
/// Get address space number.
#[inline]
pub fn asid(&self) -> u16 {
self.bits.get_bits(0..=15) as u16
}
/// Get page size
/// Get page size.
#[inline]
pub fn page_size(&self) -> PageSize {
match self.bits.get_bits(16..=17) {
0 => PageSize::Page4K,
1 => PageSize::Page2M,
2 => PageSize::Page1G,
match self.bits.get_bits(16..=18) {
1 => PageSize::Page4K,
2 => PageSize::Page2M,
4 => PageSize::Page1G,
_ => unreachable!(),
}
}
/// Get virtual page number
/// Get virtual page number.
#[inline]
pub fn vpn(&self) -> usize {
self.bits.get_bits(19..=45)
Expand Down
24 changes: 19 additions & 5 deletions xuantie-riscv/src/register/smel.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
//! smel, supervisor memory entry low register
//! smel, supervisor memory entry low register.
use crate::paging::Entry;
use core::arch::asm;

/// Reads the smel register
/// Reads the smel register.
///
/// The `xuantie-riscv`` crate assumes that the `smel` register is available only on
/// 64-bit Xuantie architectures. Attempting to read the smel register on non-64-bit
/// architectures using this function will result in an `unimplemented!` panic.
#[inline]
pub fn read() -> Entry {
let bits: usize;
unsafe { asm!("csrr {}, 0x9C1", out(reg) bits) }
Entry::from_bits(bits)
match () {
// Only enable smel when 64-bit, as it would contain a page table entry
#[cfg(target_pointer_width = "64")]
() => {
let bits: usize;
unsafe { asm!("csrr {}, 0x9C1", out(reg) bits) }
Entry::from_bits(bits as u64)
}
#[cfg(not(target_pointer_width = "64"))]
() => {
unimplemented!()
}
}
}

0 comments on commit c99ee11

Please sign in to comment.