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
use core::mem::transmute;
use core::ptr::RawPtr;
use core::option::Option;

use kernel::heap;
use kernel::mm;
use kernel::mm::Allocator;
use cpu::mmu::Frame;
use util::bitv;

use rust_core::fail::abort;

pub static mut frames: mm::Alloc = mm::Alloc {
    base: 0x200_000 as *mut u8,
    el_size: 12,
    parent: mm::BuddyAlloc {
        order: 13,
        tree: bitv::Bitv { storage: 0 as *mut u32 }
    }
};

pub struct Phys<T> {
    ptr: *mut T
}

impl<T> Phys<T> {
    pub fn at(offset: uint) -> Phys<T> {
        Phys { ptr: offset as *mut T }
    }

    pub fn as_ptr(&self) -> *mut T {
        match *self {
            Phys { ptr: p } => p
        }
    }
}

impl<T> RawPtr<T> for Phys<T> {
    fn null() -> Phys<T> {
        Phys { ptr: RawPtr::null() }
    }

    fn is_null(&self) -> bool {
        self.ptr.is_null()
    }

    fn to_uint(&self) -> uint {
        self.ptr.to_uint()
    }

    unsafe fn to_option(&self) -> Option<&T> {
        self.ptr.to_option()
    }

    unsafe fn offset(self, n: int) -> Phys<T> {
        Phys { ptr: self.ptr.offset(n) }
    }
}

pub fn init() {
    unsafe {
        frames.parent.tree.storage = heap::zero_alloc::<u32>(1024);
    }
}

pub unsafe fn alloc_frames<T = Frame>(count: uint) -> Phys<T> {
    match frames.alloc(count) {
        (_, 0) => abort(),
        (ptr, _) => Phys { ptr: ptr as *mut T }
    }
}

pub unsafe fn zero_alloc_frames<T = Frame>(count: uint) -> Phys<T> {
    match frames.zero_alloc(count) {
        (_, 0) => abort(),
        (ptr, _) => Phys { ptr: ptr as *mut T }
    }
}

#[inline]
pub unsafe fn free_frames<T>(ptr: Phys<T>) {
    frames.free(ptr.to_uint() as *mut u8);
}