refactor: remove address crate

This commit is contained in:
2021-10-12 23:59:12 +03:00
parent 7121e502df
commit fdb4f4e8e9
5 changed files with 0 additions and 569 deletions
-9
View File
@@ -1,9 +0,0 @@
[package]
name = "address"
version = "0.1.0"
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
error = { path = "../error" }
View File
-16
View File
@@ -1,16 +0,0 @@
//! Type-safe wrappers for different address kinds
#![no_std]
#![feature(step_trait, const_fn_trait_bound, const_trait_impl, const_panic)]
#[cfg(test)]
#[macro_use]
extern crate std;
#[deny(missing_docs)]
pub mod phys;
pub mod virt;
trait Address {}
pub use phys::PhysicalAddress;
pub use virt::{AddressSpace, NoTrivialConvert, TrivialConvert, VirtualAddress};
-183
View File
@@ -1,183 +0,0 @@
//! Module for handling physical memory addresses
use crate::{AddressSpace, TrivialConvert, VirtualAddress};
use core::convert::TryFrom;
use core::fmt;
use core::iter::Step;
use core::ops::{Add, AddAssign, Sub, SubAssign};
/// Wrapper struct for representing a physical address
#[repr(transparent)]
#[derive(PartialEq, PartialOrd, Copy, Clone)]
pub struct PhysicalAddress(usize);
// Arithmetic
impl const Add<usize> for PhysicalAddress {
type Output = Self;
#[inline(always)]
fn add(self, rhs: usize) -> Self {
// Will panic on overflow
Self::from(self.0 + rhs)
}
}
impl<A: Into<usize>> AddAssign<A> for PhysicalAddress {
#[inline(always)]
fn add_assign(&mut self, rhs: A) {
// Will panic on overflow
*self = Self::from(self.0 + rhs.into());
}
}
impl const Sub<usize> for PhysicalAddress {
type Output = Self;
#[inline(always)]
fn sub(self, rhs: usize) -> Self {
Self::from(self.0 - rhs)
}
}
impl SubAssign<usize> for PhysicalAddress {
#[inline(always)]
fn sub_assign(&mut self, rhs: usize) {
*self = Self::from(self.0 - rhs);
}
}
// Construction
impl const From<usize> for PhysicalAddress {
fn from(p: usize) -> Self {
Self(p)
}
}
#[cfg(target_pointer_width = "64")]
impl const From<u64> for PhysicalAddress {
fn from(p: u64) -> Self {
Self(p as usize)
}
}
impl PhysicalAddress {
/// Computes a signed difference between `start` and `end`
/// addresses. Will panic if the result cannot be represented due to
/// overflow.
#[inline(always)]
pub fn diff(start: PhysicalAddress, end: PhysicalAddress) -> isize {
if end >= start {
isize::try_from(end.0 - start.0).expect("Address subtraction overflowed")
} else {
-isize::try_from(start.0 - end.0).expect("Address subtraction overflowed")
}
}
/// Computes a signed difference between `start` and `end`, does not check for
/// overflow condition.
///
/// # Safety
///
/// Does not check for signed integer overflow.
#[inline(always)]
pub unsafe fn diff_unchecked(start: PhysicalAddress, end: PhysicalAddress) -> isize {
end.0 as isize - start.0 as isize
}
/// Returns `true` if the address is page-aligned
#[inline(always)]
pub const fn is_paligned(self) -> bool {
self.0 & 0xFFF == 0
}
/// Returns the index of the 4K page containing the address
#[inline(always)]
pub const fn page_index(self) -> usize {
self.0 >> 12
}
}
// Trivial conversion PhysicalAddress -> VirtualAddress
impl<T: AddressSpace + TrivialConvert> const From<PhysicalAddress> for VirtualAddress<T> {
fn from(p: PhysicalAddress) -> Self {
VirtualAddress::from(p.0 + T::OFFSET)
}
}
impl const From<PhysicalAddress> for usize {
#[inline(always)]
fn from(p: PhysicalAddress) -> Self {
p.0 as usize
}
}
#[cfg(target_pointer_width = "64")]
impl const From<PhysicalAddress> for u64 {
#[inline(always)]
fn from(p: PhysicalAddress) -> Self {
p.0 as u64
}
}
// Formatting
impl fmt::Debug for PhysicalAddress {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "<phys {:#018x}>", self.0)
}
}
// Step
impl Step for PhysicalAddress {
#[inline]
fn steps_between(_p0: &Self, _p1: &Self) -> Option<usize> {
todo!()
}
#[inline]
fn forward_checked(p: Self, steps: usize) -> Option<Self> {
p.0.checked_add(steps).map(Self::from)
}
#[inline]
fn backward_checked(p: Self, steps: usize) -> Option<Self> {
p.0.checked_sub(steps).map(Self::from)
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{AddressSpace, NoTrivialConvert, TrivialConvert, VirtualAddress};
#[derive(Copy, Clone, PartialEq, PartialOrd)]
struct S0;
impl AddressSpace for S0 {
const NAME: &'static str = "S0";
const OFFSET: usize = 0x8000;
const LIMIT: usize = Self::OFFSET + 0x4000;
}
impl TrivialConvert for S0 {}
#[derive(Copy, Clone, PartialEq, PartialOrd)]
struct S1;
impl AddressSpace for S1 {
const NAME: &'static str = "S1";
const OFFSET: usize = 0;
const LIMIT: usize = 0;
}
impl NoTrivialConvert for S1 {}
#[test]
fn test_virt_convert_valid() {
let p0 = PhysicalAddress::from(0x1234usize);
assert_eq!(
VirtualAddress::<S0>::from(p0),
VirtualAddress::<S0>::from(0x9234usize)
);
}
#[test]
#[should_panic]
fn test_virt_convert_invalid() {
let p0 = PhysicalAddress::from(0x4321usize);
let _v = VirtualAddress::<S0>::from(p0);
}
}
-361
View File
@@ -1,361 +0,0 @@
use super::PhysicalAddress;
use core::convert::TryFrom;
use core::fmt;
use core::iter::Step;
use core::marker::PhantomData;
use core::ops::{Add, AddAssign, Neg, Sub, SubAssign};
pub trait AddressSpace: Copy + Clone + PartialEq + PartialOrd {
const NAME: &'static str;
const OFFSET: usize;
const LIMIT: usize;
}
pub trait NoTrivialConvert {}
pub trait TrivialConvert {}
#[repr(transparent)]
#[derive(Copy, Clone, PartialOrd, PartialEq)]
pub struct VirtualAddress<Kind: AddressSpace>(usize, PhantomData<Kind>);
// Arithmetic
impl<T: AddressSpace> Add<usize> for VirtualAddress<T> {
type Output = Self;
#[inline(always)]
fn add(self, rhs: usize) -> Self {
// Will panic on overflow
Self::from(self.0 + rhs)
}
}
impl<T: AddressSpace> AddAssign<usize> for VirtualAddress<T> {
#[inline(always)]
fn add_assign(&mut self, rhs: usize) {
// Will panic on overflow
*self = Self::from(self.0 + rhs);
}
}
impl<T: AddressSpace> Sub<usize> for VirtualAddress<T> {
type Output = Self;
#[inline(always)]
fn sub(self, rhs: usize) -> Self {
// Will panic on underflow
Self::from(self.0 - rhs)
}
}
impl<T: AddressSpace> SubAssign<usize> for VirtualAddress<T> {
#[inline(always)]
fn sub_assign(&mut self, rhs: usize) {
// Will panic on underflow
*self = Self::from(self.0 - rhs);
}
}
// Trivial conversion VirtualAddress -> PhysicalAddress
impl<T: AddressSpace + TrivialConvert> From<VirtualAddress<T>> for PhysicalAddress {
#[inline(always)]
fn from(virt: VirtualAddress<T>) -> Self {
assert!(virt.0 < T::LIMIT);
PhysicalAddress::from(virt.0 - T::OFFSET)
}
}
// Formatting
impl<T: AddressSpace> fmt::Debug for VirtualAddress<T> {
#[inline]
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "<{} {:#018x}>", T::NAME, self.0)
}
}
impl<T: AddressSpace> VirtualAddress<T> {
#[inline(always)]
pub const fn null() -> Self {
Self(0, PhantomData)
}
pub fn try_subtract(self, p: usize) -> Option<Self> {
let (res, overflow) = self.0.overflowing_sub(p);
if overflow || res < T::OFFSET || res >= T::LIMIT {
None
} else {
Some(Self(res, PhantomData))
}
}
#[inline]
pub fn diff(start: Self, end: Self) -> isize {
if end >= start {
isize::try_from(end.0 - start.0).expect("Address subtraction overflowed")
} else {
-isize::try_from(start.0 - end.0).expect("Address subtraction overflowed")
}
}
#[inline(always)]
pub fn try_diff(start: Self, end: Self) -> Option<isize> {
if end >= start {
isize::try_from(end.0 - start.0).ok()
} else {
isize::try_from(start.0 - end.0).map(Neg::neg).ok()
}
}
#[inline(always)]
pub unsafe fn as_slice_mut<U>(self, count: usize) -> &'static mut [U] {
core::slice::from_raw_parts_mut(self.0 as *mut _, count)
}
#[inline(always)]
pub fn as_mut_ptr<U>(self) -> *mut U {
self.0 as *mut U
}
#[inline(always)]
pub fn as_ptr<U>(self) -> *const U {
self.0 as *const U
}
#[inline(always)]
pub unsafe fn as_mut<U>(self) -> Option<&'static mut U> {
(self.0 as *mut U).as_mut()
}
#[inline(always)]
pub unsafe fn from_ptr<U>(r: *const U) -> Self {
Self::from(r as usize)
}
#[inline(always)]
pub unsafe fn from_ref<U>(r: &U) -> Self {
Self(r as *const U as usize, PhantomData)
}
}
// Step
impl<T: AddressSpace> Step for VirtualAddress<T> {
#[inline]
fn steps_between(_p0: &Self, _p1: &Self) -> Option<usize> {
todo!()
}
#[inline]
fn forward_checked(p: Self, steps: usize) -> Option<Self> {
p.0.checked_add(steps).map(Self::from)
}
#[inline]
fn backward_checked(p: Self, steps: usize) -> Option<Self> {
p.0.checked_sub(steps).map(Self::from)
}
}
// Conversion into VirtualAddress
impl<T: AddressSpace> const From<usize> for VirtualAddress<T> {
#[inline(always)]
fn from(p: usize) -> Self {
if T::LIMIT > 0 {
assert!(p >= T::OFFSET && p < T::LIMIT);
}
Self(p, PhantomData)
}
}
#[cfg(target_pointer_width = "64")]
impl<T: AddressSpace> From<u64> for VirtualAddress<T> {
#[inline(always)]
fn from(p: u64) -> Self {
Self::from(p as usize)
}
}
// Conversion from VirtualAddress
impl<T: AddressSpace> From<VirtualAddress<T>> for usize {
#[inline(always)]
fn from(p: VirtualAddress<T>) -> Self {
p.0
}
}
#[cfg(target_pointer_width = "64")]
impl<T: AddressSpace> From<VirtualAddress<T>> for u64 {
#[inline(always)]
fn from(p: VirtualAddress<T>) -> Self {
p.0 as u64
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::PhysicalAddress;
#[derive(Copy, Clone, PartialEq, PartialOrd)]
struct S0;
impl AddressSpace for S0 {
const NAME: &'static str = "S0";
const OFFSET: usize = 0x8000;
const LIMIT: usize = Self::OFFSET + 0x4000;
}
impl TrivialConvert for S0 {}
#[derive(Copy, Clone, PartialEq, PartialOrd)]
struct S1;
impl AddressSpace for S1 {
const NAME: &'static str = "S1";
const OFFSET: usize = 0;
const LIMIT: usize = 0;
}
impl NoTrivialConvert for S1 {}
#[test]
fn test_trivial_construct_valid() {
for i in 0x8000usize..0xC000 {
VirtualAddress::<S0>::from(i);
}
}
#[test]
#[should_panic]
fn test_trivial_construct_invalid_0() {
let _v = VirtualAddress::<S0>::from(0x1234usize);
}
#[test]
#[should_panic]
fn test_trivial_construct_invalid_1() {
let _v = VirtualAddress::<S0>::from(0xD123usize);
}
#[test]
fn test_trivial_convert() {
let v0 = VirtualAddress::<S0>::from(0x8123usize);
assert_eq!(PhysicalAddress::from(v0), PhysicalAddress::from(0x123usize));
}
#[test]
fn test_add_valid() {
let v0 = VirtualAddress::<S0>::from(0x8100usize);
assert_eq!(VirtualAddress::<S0>::from(0x8223usize), v0 + 0x123usize);
}
#[test]
#[should_panic]
fn test_add_overflow() {
let v0 = VirtualAddress::<S0>::from(0x8100usize);
let _v = v0 - 0xF123usize;
}
#[test]
fn test_subtract_valid() {
let v0 = VirtualAddress::<S0>::from(0x8100usize);
assert_eq!(VirtualAddress::<S0>::from(0x8023usize), v0 - 0xDDusize);
}
#[test]
#[should_panic]
fn test_subtract_overflow() {
let v0 = VirtualAddress::<S0>::from(0x8100usize);
let _v = v0 - 0x1234usize;
}
#[test]
fn test_try_subtract() {
let v0 = VirtualAddress::<S0>::from(0x8100usize);
assert_eq!(v0.try_subtract(0x1234usize), None);
assert_eq!(
v0.try_subtract(0x12usize),
Some(VirtualAddress::<S0>::from(0x80EEusize))
);
}
#[test]
fn test_add_assign_valid() {
let mut v0 = VirtualAddress::<S0>::from(0x8100usize);
v0 += 0x123usize;
assert_eq!(v0, VirtualAddress::<S0>::from(0x8223usize));
}
#[test]
fn test_sub_assign_valid() {
let mut v0 = VirtualAddress::<S0>::from(0x8321usize);
v0 -= 0x123usize;
assert_eq!(v0, VirtualAddress::<S0>::from(0x81FEusize));
}
#[test]
#[should_panic]
fn test_sub_assign_overflow() {
let mut v0 = VirtualAddress::<S0>::from(0x8321usize);
v0 -= 0x1234usize;
}
#[test]
#[should_panic]
fn test_add_assign_overflow() {
let mut v0 = VirtualAddress::<S0>::from(0x8321usize);
v0 += 0xF234usize;
}
#[test]
fn test_format() {
let v0 = VirtualAddress::<S0>::from(0x8123usize);
assert_eq!(&format!("{:?}", v0), "<S0 0x0000000000008123>");
}
#[test]
fn test_diff() {
let v0 = VirtualAddress::<S0>::from(0x8123usize);
let v1 = VirtualAddress::<S0>::from(0x8321usize);
// Ok
assert_eq!(VirtualAddress::diff(v0, v1), 510);
assert_eq!(VirtualAddress::diff(v1, v0), -510);
assert_eq!(VirtualAddress::diff(v0, v0), 0);
assert_eq!(VirtualAddress::diff(v1, v1), 0);
}
#[test]
#[should_panic]
fn test_diff_overflow() {
let v0 = VirtualAddress::<S1>::from(0usize);
let v1 = VirtualAddress::<S1>::from(usize::MAX);
let _v = VirtualAddress::diff(v0, v1);
}
#[test]
fn test_step() {
let mut count = 0;
for _ in VirtualAddress::<S0>::from(0x8000usize)..VirtualAddress::<S0>::from(0x8300usize) {
count += 1;
}
assert_eq!(count, 0x300);
let mut count = 0;
for _ in (VirtualAddress::<S0>::from(0x8000usize)..VirtualAddress::<S0>::from(0x8300usize))
.step_by(0x100)
{
count += 1;
}
assert_eq!(count, 3);
let mut count = 0;
for _ in
(VirtualAddress::<S0>::from(0x8000usize)..VirtualAddress::<S0>::from(0x8300usize)).rev()
{
count += 1;
}
assert_eq!(count, 0x300);
let mut count = 0;
for _ in (VirtualAddress::<S0>::from(0x8000usize)..VirtualAddress::<S0>::from(0x8300usize))
.rev()
.step_by(0x100)
{
count += 1;
}
assert_eq!(count, 3);
}
}