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 {
37
            set info.clock = moved;
38
        }
39
        if old == shutdown {
40
            set info.shutdown = moved;
41
        }
42
    }
43
    for i in budgets..handles.len {
44
        let budget = abi::Handle(handles[i]);
45
        let window = try! sys::queryBudget(budget);
46
        if window.hart == 0 {
47
            let future = try! sys::budgetSplit(budget, window.start + info.timebase * 2);
48
            set handles[i] = *try! sys::budgetBind(future, scheduler, context.context);
49
        } else {
50
            set handles[i] = *try! sys::capabilityTransfer(budget, scheduler, abi::RIGHTS_MASK as u64);
51
        }
52
    }
53
    set info.rootImage = try! sys::capabilityTransfer(info.rootImage, scheduler, abi::RIGHTS_MASK as u64);
54
    set info.schedulerImage = try! sys::capabilityTransfer(info.schedulerImage, scheduler, abi::RIGHTS_MASK as u64);
55
    set info.arguments = try! sys::capabilityTransfer(info.arguments, scheduler, abi::RIGHTS_MASK as u64);
56
    set handles[0] = *authority;
57
    set handles[1] = 0;
58
    try! sys::domainReparent(self, scheduler);
59
    try! sys::domainActivate(scheduler, stackInfo.base + stackInfo.count * 4096,
60
        info as *unsafe opaque, @sizeOf(abi::BootInfo) as u64);
61
    sys::exit(0);
62
}