1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
//! Memory management.
//!
//! In general, all memory is directly mapped physical-to-virtual with no protection. All of
//! physical memory is part of a memory pool managed with TLSF. Thread stacks are the only true
//! users of virtual memory, mapped into the top of virtual memory. From `(top of memory) - (thread
//! stack size)` to `(top of physical memory)` is unmapped virtual memory.
//!
//! The advantage of this approach is that allocation of both physical and virtual memory need not
//! be tracked. Only physical memory allocation is tracked, and virtual memory allocation is
//! implicit according to the active thread.

/// Assert that `ptr` is aligned to a `n`-byte boundary.
///
/// `n` must be a power of two.
macro_rules! assert_aligned {
    ($ptr:expr, $n:expr) => (
        unsafe {
            // XXX assumes 64-bit
            assert_eq!(::core::intrinsics::ctpop64($n), 1);
        }
        assert_eq!($ptr as usize & ($n - 1), 0);
    )
}

pub mod phys;
pub mod virt;

use core::{self, fmt, intrinsics, mem, slice};

pub struct PhysPtr<T>(*mut T);

/// Disable virtual memory.
///
/// This is incredibly unsafe. Don't use it unless you **really** know what
/// you're doing.
pub unsafe fn disable_vm() {
    unimplemented!();
}

/// Enable virtual memory.
///
/// This is incredibly unsafe. Don't use it unless you **really** know what
/// you're doing.
pub unsafe fn enable_vm() {
    unimplemented!();
}

/* These functions cannot use intrinsics because intrinsics can lower to calls
 * to these functions. Unbounded recursion.
 *
 * Implementations borrowed from rlibc: https://github.com/alexcrichton/rlibc 
 *
 * Copyright (c) 2014 The Rust Project Developers
 *
 * Permission is hereby granted, free of charge, to any
 * person obtaining a copy of this software and associated
 * documentation files (the "Software"), to deal in the
 * Software without restriction, including without
 * limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of
 * the Software, and to permit persons to whom the Software
 * is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice
 * shall be included in all copies or substantial portions
 * of the Software.
 */
#[no_mangle]
/// Copy n bytes from src to dest. Must not overlap.
pub unsafe extern "C" fn memcpy(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 {
    let mut i = 0;
    while i < n {
        *dest.offset(i as isize) = *src.offset(i as isize);
        i += 1;
    }
    return dest;
}

#[no_mangle]
/// Set the n bytes at s to the value of c, truncated to a byte.
pub unsafe extern "C" fn memset(s: *mut u8, c: u32, n: usize) -> *mut u8 {
    let mut i = 0;
    while i < n {
        *s.offset(i as isize) = c as u8;
        i += 1;
    }
    return s;
}

#[no_mangle]
/// Copy n bytes from dest to src; buffers may overlap.
pub unsafe extern "C" fn memmove(dest: *mut u8, src: *const u8, n: usize) -> *mut u8 {
    if src < dest as *const u8 { // copy from end
        let mut i = n;
        while i != 0 {
            i -= 1;
            *dest.offset(i as isize) = *src.offset(i as isize);
        }
    } else { // copy from beginning
        let mut i = 0;
        while i < n {
            *dest.offset(i as isize) = *src.offset(i as isize);
            i += 1;
        }
    }
    return dest;
}

#[no_mangle]
pub unsafe extern "C" fn memcmp(s1: *const u8, s2: *const u8, n: usize) -> i32 {
    let mut i = 0;
    while i < n {
        let a = *s1.offset(i as isize);
        let b = *s2.offset(i as isize);
        if a != b {
            return a as i32 - b as i32
        }
        i += 1;
    }
    return 0;
}