kernel/root.rad 2.6 KiB raw
1
//! Initial resource handoff to the user-space scheduler.
2
export mod abi;
3
export mod sys;
4
5
/// Root startup memory supplied by the kernel.
6
record Env: Copy {
7
    /// Writable header and copied resource handles.
8
    argsPointer: *unsafe mut abi::BootInfo,
9
    /// Header size in bytes.
10
    argsSize: u64,
11
    /// Root's event capability.
12
    eventsHandle: u64,
13
    /// Root's event-ring address.
14
    eventsPointer: u64,
15
}
16
17
/// Transfer root's resource bundle and parent duties before normal exit.
18
@default unsafe fn main(env: *Env) -> ! {
19
    assert env.argsSize == @sizeOf(abi::BootInfo) as u64;
20
    let mut info = env.argsPointer;
21
    let self = abi::Handle(info.handles[0]);
22
    let scheduler = try! sys::domainCreate(self, info.schedulerImage);
23
    let context = try! sys::queryContext(scheduler, 0);
24
    let authority = try! sys::capabilityGrant(scheduler, scheduler, abi::RIGHTS_MASK as u64);
25
    let stack = try! sys::pageAllocate(self, 16);
26
    let stackInfo = sys::queryPage(stack);
27
    let sharedStack = try! sys::capabilityTransfer(stack, scheduler, abi::RIGHTS_MASK as u64);
28
    let mut handles = info.handles;
29
    let clock = info.clock;
30
    let shutdown = info.shutdown;
31
    let budgets = 2 + info.devices as u32 + info.interrupts as u32;
32
    for i in 2..budgets {
33
        let old = abi::Handle(handles[i]);
34
        let moved = try! sys::capabilityTransfer(old, scheduler, abi::RIGHTS_MASK as u64);
35
        set handles[i] = *moved;
36
        if old == clock { set info.clock = moved; }
37
        if old == shutdown { set info.shutdown = moved; }
38
    }
39
    for i in budgets..handles.len {
40
        let budget = abi::Handle(handles[i]);
41
        let window = try! sys::queryBudget(budget);
42
        if window.hart == 0 {
43
            let future = try! sys::budgetSplit(budget, window.start + info.timebase * 2);
44
            set handles[i] = *try! sys::budgetBind(future, scheduler, context.context);
45
        } else {
46
            set handles[i] = *try! sys::capabilityTransfer(budget, scheduler, abi::RIGHTS_MASK as u64);
47
        }
48
    }
49
    set info.rootImage = try! sys::capabilityTransfer(info.rootImage, scheduler, abi::RIGHTS_MASK as u64);
50
    set info.schedulerImage = try! sys::capabilityTransfer(info.schedulerImage, scheduler, abi::RIGHTS_MASK as u64);
51
    set info.arguments = try! sys::capabilityTransfer(info.arguments, scheduler, abi::RIGHTS_MASK as u64);
52
    set handles[0] = *authority;
53
    set handles[1] = 0;
54
    try! sys::domainReparent(self, scheduler);
55
    try! sys::domainActivate(scheduler, stackInfo.base + stackInfo.count * 4096,
56
        info as *unsafe opaque, @sizeOf(abi::BootInfo) as u64);
57
    sys::exit(0);
58
}