From c99ee11cb6b7ae27d38c585cd82a7549506a0ce7 Mon Sep 17 00:00:00 2001 From: Zhouqi Jiang Date: Wed, 25 Dec 2024 08:00:20 +0800 Subject: [PATCH] riscv: register: fix smeh and smel register definitions - 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 --- xuantie-riscv/src/paging.rs | 20 ++++++++------------ xuantie-riscv/src/register.rs | 2 -- xuantie-riscv/src/register/smeh.rs | 29 ++++++++++++++++------------- xuantie-riscv/src/register/smel.rs | 24 +++++++++++++++++++----- 4 files changed, 43 insertions(+), 32 deletions(-) diff --git a/xuantie-riscv/src/paging.rs b/xuantie-riscv/src/paging.rs index b1644e0..c72e72e 100644 --- a/xuantie-riscv/src/paging.rs +++ b/xuantie-riscv/src/paging.rs @@ -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. @@ -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. diff --git a/xuantie-riscv/src/register.rs b/xuantie-riscv/src/register.rs index bc661d3..1becece 100644 --- a/xuantie-riscv/src/register.rs +++ b/xuantie-riscv/src/register.rs @@ -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 diff --git a/xuantie-riscv/src/register/smeh.rs b/xuantie-riscv/src/register/smeh.rs index b0f5e9b..dc601d1 100644 --- a/xuantie-riscv/src/register/smeh.rs +++ b/xuantie-riscv/src/register/smeh.rs @@ -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) diff --git a/xuantie-riscv/src/register/smel.rs b/xuantie-riscv/src/register/smel.rs index b0f2571..3f4a377 100644 --- a/xuantie-riscv/src/register/smel.rs +++ b/xuantie-riscv/src/register/smel.rs @@ -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!() + } + } }