address.rs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. use core::{
  2. cmp::Ordering,
  3. fmt::{self, Debug, Formatter},
  4. ops::{Add, RangeBounds, Sub},
  5. };
  6. #[repr(C)]
  7. #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
  8. pub struct PAddr(pub usize);
  9. #[repr(C)]
  10. #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
  11. pub struct VAddr(pub usize);
  12. #[repr(C)]
  13. #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
  14. pub struct PFN(pub usize);
  15. #[repr(C)]
  16. #[derive(Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
  17. pub struct VPN(pub usize);
  18. const PAGE_SIZE: usize = 4096;
  19. const PAGE_SIZE_BITS: usize = 12;
  20. const USER_SPACE_MEMORY_TOP: VAddr = VAddr(0x8000_0000_0000);
  21. impl From<PAddr> for usize {
  22. fn from(v: PAddr) -> Self {
  23. v.0
  24. }
  25. }
  26. impl From<PFN> for usize {
  27. fn from(v: PFN) -> Self {
  28. v.0
  29. }
  30. }
  31. impl From<VAddr> for usize {
  32. fn from(v: VAddr) -> Self {
  33. v.0
  34. }
  35. }
  36. impl From<VPN> for usize {
  37. fn from(v: VPN) -> Self {
  38. v.0
  39. }
  40. }
  41. impl From<usize> for PAddr {
  42. fn from(v: usize) -> Self {
  43. Self(v)
  44. }
  45. }
  46. impl From<usize> for PFN {
  47. fn from(v: usize) -> Self {
  48. Self(v)
  49. }
  50. }
  51. impl From<usize> for VAddr {
  52. fn from(v: usize) -> Self {
  53. Self(v)
  54. }
  55. }
  56. impl From<usize> for VPN {
  57. fn from(v: usize) -> Self {
  58. Self(v)
  59. }
  60. }
  61. impl From<VPN> for VAddr {
  62. fn from(v: VPN) -> Self {
  63. Self(v.0 << PAGE_SIZE_BITS)
  64. }
  65. }
  66. impl From<VAddr> for VPN {
  67. fn from(v: VAddr) -> Self {
  68. assert_eq!(v.page_offset(), 0);
  69. v.floor_vpn()
  70. }
  71. }
  72. impl From<PAddr> for PFN {
  73. fn from(v: PAddr) -> Self {
  74. assert_eq!(v.page_offset(), 0);
  75. v.floor_pfn()
  76. }
  77. }
  78. impl From<PFN> for PAddr {
  79. fn from(v: PFN) -> Self {
  80. Self(v.0 << PAGE_SIZE_BITS)
  81. }
  82. }
  83. impl PAddr {
  84. pub fn floor_pfn(&self) -> PFN {
  85. PFN(self.0 / PAGE_SIZE)
  86. }
  87. pub fn ceil_pfn(&self) -> PFN {
  88. PFN((self.0 + PAGE_SIZE - 1) / PAGE_SIZE)
  89. }
  90. pub fn page_offset(&self) -> usize {
  91. self.0 & (PAGE_SIZE - 1)
  92. }
  93. pub fn is_aligned(&self) -> bool {
  94. self.page_offset() == 0
  95. }
  96. }
  97. impl PFN {
  98. pub fn buddy_pfn(&self, order: u32) -> PFN {
  99. PFN::from(self.0 ^ (1 << order))
  100. }
  101. pub fn combined_pfn(&self, buddy_pfn: PFN) -> PFN {
  102. PFN::from(self.0 & buddy_pfn.0)
  103. }
  104. }
  105. impl VAddr {
  106. pub const NULL: Self = Self(0);
  107. pub fn floor_vpn(&self) -> VPN {
  108. VPN(self.0 / PAGE_SIZE)
  109. }
  110. pub fn ceil_vpn(&self) -> VPN {
  111. VPN((self.0 - 1 + PAGE_SIZE) / PAGE_SIZE)
  112. }
  113. pub fn page_offset(&self) -> usize {
  114. self.0 & (PAGE_SIZE - 1)
  115. }
  116. pub fn is_aligned(&self) -> bool {
  117. self.page_offset() == 0
  118. }
  119. pub fn is_user(&self) -> bool {
  120. self.0 != 0 && self < &USER_SPACE_MEMORY_TOP
  121. }
  122. pub fn floor(&self) -> Self {
  123. VAddr(self.0 & !(PAGE_SIZE - 1))
  124. }
  125. pub fn ceil(&self) -> Self {
  126. VAddr((self.0 + (PAGE_SIZE - 1)) & !(PAGE_SIZE - 1))
  127. }
  128. }
  129. impl Sub for VAddr {
  130. type Output = usize;
  131. fn sub(self, rhs: Self) -> Self::Output {
  132. self.0 - rhs.0
  133. }
  134. }
  135. impl Sub<usize> for VAddr {
  136. type Output = Self;
  137. fn sub(self, rhs: usize) -> Self::Output {
  138. VAddr(self.0 - rhs)
  139. }
  140. }
  141. impl Add<usize> for VAddr {
  142. type Output = Self;
  143. fn add(self, rhs: usize) -> Self::Output {
  144. VAddr(self.0 + rhs)
  145. }
  146. }
  147. impl Sub for PAddr {
  148. type Output = usize;
  149. fn sub(self, rhs: Self) -> Self::Output {
  150. self.0 - rhs.0
  151. }
  152. }
  153. impl Sub<usize> for PAddr {
  154. type Output = Self;
  155. fn sub(self, rhs: usize) -> Self::Output {
  156. PAddr(self.0 - rhs)
  157. }
  158. }
  159. impl Add<usize> for PAddr {
  160. type Output = Self;
  161. fn add(self, rhs: usize) -> Self::Output {
  162. PAddr(self.0 + rhs)
  163. }
  164. }
  165. impl Debug for VAddr {
  166. fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
  167. write!(f, "VAddr{:#x}", self.0)
  168. }
  169. }
  170. impl Debug for PAddr {
  171. fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
  172. write!(f, "PAddr{:#x}", self.0)
  173. }
  174. }
  175. impl Add<usize> for PFN {
  176. type Output = Self;
  177. fn add(self, rhs: usize) -> Self::Output {
  178. PFN(self.0 + rhs)
  179. }
  180. }
  181. impl Sub for PFN {
  182. type Output = usize;
  183. fn sub(self, rhs: Self) -> Self::Output {
  184. self.0 - rhs.0
  185. }
  186. }
  187. impl Sub<usize> for PFN {
  188. type Output = Self;
  189. fn sub(self, rhs: usize) -> Self::Output {
  190. PFN(self.0 - rhs)
  191. }
  192. }
  193. impl Add<usize> for VPN {
  194. type Output = Self;
  195. fn add(self, rhs: usize) -> Self::Output {
  196. VPN(self.0 + rhs)
  197. }
  198. }
  199. impl Sub for VPN {
  200. type Output = usize;
  201. fn sub(self, rhs: Self) -> Self::Output {
  202. self.0 - rhs.0
  203. }
  204. }
  205. impl Sub<usize> for VPN {
  206. type Output = Self;
  207. fn sub(self, rhs: usize) -> Self::Output {
  208. VPN(self.0 - rhs)
  209. }
  210. }
  211. impl Debug for VPN {
  212. fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
  213. write!(f, "VPN{:#x}", self.0)
  214. }
  215. }
  216. impl Debug for PFN {
  217. fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
  218. write!(f, "PFN{:#x}", self.0)
  219. }
  220. }
  221. #[derive(Clone, Copy)]
  222. pub struct VRange {
  223. start: VAddr,
  224. end: VAddr,
  225. }
  226. impl Debug for VRange {
  227. fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
  228. write!(f, "[{:?}, {:?})", self.start, self.end)
  229. }
  230. }
  231. impl Eq for VRange {}
  232. impl PartialOrd for VRange {
  233. fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
  234. Some(self.cmp(other))
  235. }
  236. }
  237. impl PartialEq for VRange {
  238. fn eq(&self, other: &Self) -> bool {
  239. self.cmp(other) == Ordering::Equal
  240. }
  241. }
  242. /// Any two ranges that have one of them containing the other are considered equal.
  243. impl Ord for VRange {
  244. fn cmp(&self, other: &Self) -> Ordering {
  245. if self.start == other.start {
  246. return Ordering::Equal;
  247. }
  248. if self.end == other.end {
  249. if self.start == self.end {
  250. return Ordering::Greater;
  251. }
  252. if other.start == other.end {
  253. return Ordering::Less;
  254. }
  255. return Ordering::Equal;
  256. }
  257. if self.start < other.start {
  258. if other.end < self.end {
  259. return Ordering::Equal;
  260. } else {
  261. return Ordering::Less;
  262. }
  263. }
  264. if other.start < self.start {
  265. if self.end < other.end {
  266. return Ordering::Equal;
  267. } else {
  268. return Ordering::Greater;
  269. }
  270. }
  271. unreachable!()
  272. }
  273. }
  274. impl From<VAddr> for VRange {
  275. fn from(addr: VAddr) -> Self {
  276. VRange::new(addr, addr)
  277. }
  278. }
  279. impl VRange {
  280. pub fn new(start: VAddr, end: VAddr) -> Self {
  281. assert!(start <= end);
  282. VRange { start, end }
  283. }
  284. #[allow(dead_code)]
  285. pub fn is_overlapped(&self, other: &Self) -> bool {
  286. self == other
  287. }
  288. pub fn is_user(&self) -> bool {
  289. self.start < USER_SPACE_MEMORY_TOP && self.end <= USER_SPACE_MEMORY_TOP
  290. }
  291. pub fn start(&self) -> VAddr {
  292. self.start
  293. }
  294. pub fn end(&self) -> VAddr {
  295. self.end
  296. }
  297. pub fn len(&self) -> usize {
  298. self.end.0 - self.start.0
  299. }
  300. pub fn shrink(&self, count: usize) -> Self {
  301. assert!(count <= self.len());
  302. VRange::new(self.start, self.end - count)
  303. }
  304. pub fn grow(&self, count: usize) -> Self {
  305. VRange::new(self.start, self.end + count)
  306. }
  307. pub fn into_range(self) -> impl RangeBounds<Self> {
  308. if self.len() == 0 {
  309. VRange::from(self.start())..=VRange::from(self.start())
  310. } else {
  311. VRange::from(self.start())..=VRange::from(self.end() - 1)
  312. }
  313. }
  314. }