123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392 |
- use core::{
- cmp::Ordering,
- fmt::{self, Debug, Formatter},
- ops::{Add, RangeBounds, Sub},
- };
- #[repr(C)]
- #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
- pub struct PAddr(pub usize);
- #[repr(C)]
- #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
- pub struct VAddr(pub usize);
- #[repr(C)]
- #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
- pub struct PFN(pub usize);
- #[repr(C)]
- #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
- pub struct VPN(pub usize);
- const PAGE_SIZE: usize = 4096;
- const PAGE_SIZE_BITS: usize = 12;
- const USER_SPACE_MEMORY_TOP: VAddr = VAddr(0x8000_0000_0000);
- impl From<PAddr> for usize {
- fn from(v: PAddr) -> Self {
- v.0
- }
- }
- impl From<PFN> for usize {
- fn from(v: PFN) -> Self {
- v.0
- }
- }
- impl From<VAddr> for usize {
- fn from(v: VAddr) -> Self {
- v.0
- }
- }
- impl From<VPN> for usize {
- fn from(v: VPN) -> Self {
- v.0
- }
- }
- impl From<usize> for PAddr {
- fn from(v: usize) -> Self {
- Self(v)
- }
- }
- impl From<usize> for PFN {
- fn from(v: usize) -> Self {
- Self(v)
- }
- }
- impl From<usize> for VAddr {
- fn from(v: usize) -> Self {
- Self(v)
- }
- }
- impl From<usize> for VPN {
- fn from(v: usize) -> Self {
- Self(v)
- }
- }
- impl From<VPN> for VAddr {
- fn from(v: VPN) -> Self {
- Self(v.0 << PAGE_SIZE_BITS)
- }
- }
- impl From<VAddr> for VPN {
- fn from(v: VAddr) -> Self {
- assert_eq!(v.page_offset(), 0);
- v.floor_vpn()
- }
- }
- impl From<PAddr> for PFN {
- fn from(v: PAddr) -> Self {
- assert_eq!(v.page_offset(), 0);
- v.floor_pfn()
- }
- }
- impl From<PFN> for PAddr {
- fn from(v: PFN) -> Self {
- Self(v.0 << PAGE_SIZE_BITS)
- }
- }
- impl PAddr {
- pub fn floor_pfn(&self) -> PFN {
- PFN(self.0 / PAGE_SIZE)
- }
- pub fn ceil_pfn(&self) -> PFN {
- PFN((self.0 + PAGE_SIZE - 1) / PAGE_SIZE)
- }
- pub fn page_offset(&self) -> usize {
- self.0 & (PAGE_SIZE - 1)
- }
- pub fn is_aligned(&self) -> bool {
- self.page_offset() == 0
- }
- }
- impl PFN {
- pub fn buddy_pfn(&self, order: u32) -> PFN {
- PFN::from(self.0 ^ (1 << order))
- }
- pub fn combined_pfn(&self, buddy_pfn: PFN) -> PFN {
- PFN::from(self.0 & buddy_pfn.0)
- }
- }
- impl VAddr {
- pub const NULL: Self = Self(0);
- pub fn floor_vpn(&self) -> VPN {
- VPN(self.0 / PAGE_SIZE)
- }
- pub fn ceil_vpn(&self) -> VPN {
- VPN((self.0 - 1 + PAGE_SIZE) / PAGE_SIZE)
- }
- pub fn page_offset(&self) -> usize {
- self.0 & (PAGE_SIZE - 1)
- }
- pub fn is_aligned(&self) -> bool {
- self.page_offset() == 0
- }
- pub fn is_user(&self) -> bool {
- self.0 != 0 && self < &USER_SPACE_MEMORY_TOP
- }
- pub fn floor(&self) -> Self {
- VAddr(self.0 & !(PAGE_SIZE - 1))
- }
- pub fn ceil(&self) -> Self {
- VAddr((self.0 + (PAGE_SIZE - 1)) & !(PAGE_SIZE - 1))
- }
- }
- impl Sub for VAddr {
- type Output = usize;
- fn sub(self, rhs: Self) -> Self::Output {
- self.0 - rhs.0
- }
- }
- impl Sub<usize> for VAddr {
- type Output = Self;
- fn sub(self, rhs: usize) -> Self::Output {
- VAddr(self.0 - rhs)
- }
- }
- impl Add<usize> for VAddr {
- type Output = Self;
- fn add(self, rhs: usize) -> Self::Output {
- VAddr(self.0 + rhs)
- }
- }
- impl Sub for PAddr {
- type Output = usize;
- fn sub(self, rhs: Self) -> Self::Output {
- self.0 - rhs.0
- }
- }
- impl Sub<usize> for PAddr {
- type Output = Self;
- fn sub(self, rhs: usize) -> Self::Output {
- PAddr(self.0 - rhs)
- }
- }
- impl Add<usize> for PAddr {
- type Output = Self;
- fn add(self, rhs: usize) -> Self::Output {
- PAddr(self.0 + rhs)
- }
- }
- impl Debug for VAddr {
- fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
- write!(f, "VAddr{:#x}", self.0)
- }
- }
- impl Debug for PAddr {
- fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
- write!(f, "PAddr{:#x}", self.0)
- }
- }
- impl Add<usize> for PFN {
- type Output = Self;
- fn add(self, rhs: usize) -> Self::Output {
- PFN(self.0 + rhs)
- }
- }
- impl Sub for PFN {
- type Output = usize;
- fn sub(self, rhs: Self) -> Self::Output {
- self.0 - rhs.0
- }
- }
- impl Sub<usize> for PFN {
- type Output = Self;
- fn sub(self, rhs: usize) -> Self::Output {
- PFN(self.0 - rhs)
- }
- }
- impl Add<usize> for VPN {
- type Output = Self;
- fn add(self, rhs: usize) -> Self::Output {
- VPN(self.0 + rhs)
- }
- }
- impl Sub for VPN {
- type Output = usize;
- fn sub(self, rhs: Self) -> Self::Output {
- self.0 - rhs.0
- }
- }
- impl Sub<usize> for VPN {
- type Output = Self;
- fn sub(self, rhs: usize) -> Self::Output {
- VPN(self.0 - rhs)
- }
- }
- impl Debug for VPN {
- fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
- write!(f, "VPN{:#x}", self.0)
- }
- }
- impl Debug for PFN {
- fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
- write!(f, "PFN{:#x}", self.0)
- }
- }
- #[derive(Clone, Copy)]
- pub struct VRange {
- start: VAddr,
- end: VAddr,
- }
- impl Debug for VRange {
- fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
- write!(f, "[{:?}, {:?})", self.start, self.end)
- }
- }
- impl Eq for VRange {}
- impl PartialOrd for VRange {
- fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
- Some(self.cmp(other))
- }
- }
- impl PartialEq for VRange {
- fn eq(&self, other: &Self) -> bool {
- self.cmp(other) == Ordering::Equal
- }
- }
- /// Any two ranges that have one of them containing the other are considered equal.
- impl Ord for VRange {
- fn cmp(&self, other: &Self) -> Ordering {
- if self.start == other.start {
- return Ordering::Equal;
- }
- if self.end == other.end {
- if self.start == self.end {
- return Ordering::Greater;
- }
- if other.start == other.end {
- return Ordering::Less;
- }
- return Ordering::Equal;
- }
- if self.start < other.start {
- if other.end < self.end {
- return Ordering::Equal;
- } else {
- return Ordering::Less;
- }
- }
- if other.start < self.start {
- if self.end < other.end {
- return Ordering::Equal;
- } else {
- return Ordering::Greater;
- }
- }
- unreachable!()
- }
- }
- impl From<VAddr> for VRange {
- fn from(addr: VAddr) -> Self {
- VRange::new(addr, addr)
- }
- }
- impl VRange {
- pub fn new(start: VAddr, end: VAddr) -> Self {
- assert!(start <= end);
- VRange { start, end }
- }
- #[allow(dead_code)]
- pub fn is_overlapped(&self, other: &Self) -> bool {
- self == other
- }
- pub fn is_user(&self) -> bool {
- self.start < USER_SPACE_MEMORY_TOP && self.end <= USER_SPACE_MEMORY_TOP
- }
- pub fn start(&self) -> VAddr {
- self.start
- }
- pub fn end(&self) -> VAddr {
- self.end
- }
- pub fn len(&self) -> usize {
- self.end.0 - self.start.0
- }
- pub fn shrink(&self, count: usize) -> Self {
- assert!(count <= self.len());
- VRange::new(self.start, self.end - count)
- }
- pub fn grow(&self, count: usize) -> Self {
- VRange::new(self.start, self.end + count)
- }
- pub fn into_range(self) -> impl RangeBounds<Self> {
- if self.len() == 0 {
- VRange::from(self.start())..=VRange::from(self.start())
- } else {
- VRange::from(self.start())..=VRange::from(self.end() - 1)
- }
- }
- }
|