compiler/
kernel/
kernel/
tools/
kernel.rad
684 B
mmio.rad
2.5 KiB
root.rad
2.6 KiB
scheduler.rad
1.7 KiB
lib/
scripts/
seed/
sublime/
test/
vim/
.gitignore
336 B
.gitsigners
112 B
CONTRIBUTING
2.1 KiB
LICENSE
1.1 KiB
Makefile
9.2 KiB
README
2.5 KiB
STYLE
2.5 KiB
std.lib
1.5 KiB
std.lib.test
662 B
kernel/root.rad
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 | } |