(* * Copyright 2014, NICTA * * This software may be distributed and modified according to the terms of * the GNU General Public License version 2. Note that NO WARRANTY is provided. * See "LICENSE_GPLv2.txt" for details. * * @TAG(NICTA_GPL) *) theory Kernel_DP imports "DSpec.Syscall_D" "SepDSpec.Types_SD" begin (* Bootinfo contructs *) (* BootInfo record. Modelled on the C implementation, though only contains information needed for the booter. *) type_synonym bi_slot_region = "cdl_cptr \ cdl_cptr" record cdl_bootinfo = bi_untypes :: bi_slot_region bi_free_slots :: bi_slot_region (* Bootinfo constants *) definition "seL4_CapNull = (0 :: cdl_cptr)" definition "seL4_CapInitThreadTCB = (1 :: cdl_cptr)" definition "seL4_CapInitThreadCNode = (2 :: cdl_cptr)" definition "seL4_CapInitThreadPD = (3 :: cdl_cptr)" definition "seL4_CapIRQControl = (4 :: cdl_cptr)" definition "seL4_CapASIDControl = (5 :: cdl_cptr)" definition "seL4_CapInitThreadASIDPool = (6 :: cdl_cptr)" definition "seL4_CapIOPort = (7 :: cdl_cptr)" definition "seL4_CapIOSpace = (8 :: cdl_cptr)" definition "seL4_CapBootInfoFrame = (9 :: cdl_cptr)" definition "seL4_CapInitThreadIPCBuffer = (10 :: cdl_cptr)" (* This should be added as an axiom or something. * To be fixed when we have a better schedule story. *) consts root_tcb_id :: cdl_object_id text {* This wrapper lifts monadic operations on the underlying kernel state to monadic operations on the user state. *} definition do_kernel_op :: "(cdl_state, 'a) nondet_monad \ (user_state, 'a) nondet_monad" where "do_kernel_op kop \ do ms \ gets kernel_state; (r, ms') \ select_f (kop ms); modify (\state. state \ kernel_state := ms' \); return r od" (* check error *) definition thread_has_error :: "cdl_object_id \ bool k_monad" where "thread_has_error thread_ptr = do tcb \ get_thread thread_ptr; return (cdl_intent_error (cdl_tcb_intent tcb)) od" definition call_kernel_loop :: "event \ unit k_monad" where "call_kernel_loop ev = do (* Deal with the event. *) whileLoop (\rv s. isLeft rv) (\_. handle_event ev (\ _. do handle_pending_interrupts; throwError PreemptError od) ) (Inl PreemptError); schedule; t \ gets cdl_current_thread; case t of Some thread \ do restart \ has_restart_cap thread; when restart $ set_cap (thread, tcb_pending_op_slot) RunningCap od | None \ return () od" (* Kernel call functions *) definition call_kernel_with_intent :: "cdl_full_intent \bool \ bool k_monad" where "call_kernel_with_intent full_intent check_error = do thread_ptr \ gets_the cdl_current_thread; assert (thread_ptr = root_tcb_id); domain \ gets cdl_current_domain; assert (domain = minBound); update_thread thread_ptr (cdl_tcb_intent_update (\x. full_intent)); call_kernel_loop $ SyscallEvent SysCall; ntptr \ gets_the cdl_current_thread; assert (thread_ptr = ntptr); ndomain \ gets cdl_current_domain; assert (minBound = ndomain); has_error \ thread_has_error thread_ptr; (* capDL will need to be extended to support return types. *) when (check_error) (assert (\ has_error)); return has_error od" definition seL4_TCB_Configure :: "cdl_cptr \ cdl_cptr \ cdl_cptr \ cdl_raw_capdata \ cdl_cptr \ cdl_raw_capdata \ word32 \ cdl_cptr \ bool u_monad" where "seL4_TCB_Configure tcb_cap fault_ep cspace_root cspace_root_data vspace_root vspace_root_data buffer_addr buffer_frame \ do_kernel_op $ call_kernel_with_intent \cdl_intent_op = Some $ TcbIntent $ TcbConfigureIntent fault_ep cspace_root_data vspace_root_data buffer_addr, cdl_intent_error = False, cdl_intent_cap = tcb_cap, cdl_intent_extras = [cspace_root, vspace_root, buffer_frame], cdl_intent_recv_slot = None\ True" definition seL4_TCB_SetIPCBuffer :: "cdl_cptr \ word32 \ cdl_cptr \ bool u_monad" where "seL4_TCB_SetIPCBuffer tcb_cap buffer_addr buffer_frame \ do_kernel_op $ call_kernel_with_intent \cdl_intent_op = Some $ TcbIntent $ TcbSetIPCBufferIntent buffer_addr, cdl_intent_error = False, cdl_intent_cap = tcb_cap, cdl_intent_extras = [buffer_frame], cdl_intent_recv_slot = None\ False" definition seL4_TCB_SetPriority :: "cdl_cptr \ word8 \ bool u_monad" where "seL4_TCB_SetPriority tcb_cap priority \ do_kernel_op $ call_kernel_with_intent \cdl_intent_op = Some $ TcbIntent $ TcbSetPriorityIntent priority, cdl_intent_error = False, cdl_intent_cap = tcb_cap, cdl_intent_extras = [], cdl_intent_recv_slot = None\ False" definition seL4_TCB_SetSpace :: "cdl_cptr \ cdl_cptr \ cdl_cptr \ cdl_raw_capdata \ cdl_cptr \ cdl_raw_capdata \ bool u_monad" where "seL4_TCB_SetSpace tcb_cap fault_ep cspace_root cspace_root_data vspace_root vspace_root_data \ do_kernel_op $ call_kernel_with_intent \cdl_intent_op = Some $ TcbIntent $ TcbSetSpaceIntent fault_ep cspace_root_data vspace_root_data, cdl_intent_error = False, cdl_intent_cap = tcb_cap, cdl_intent_extras = [cspace_root, vspace_root], cdl_intent_recv_slot = None\ False" definition seL4_TCB_Resume :: "cdl_cptr \ bool u_monad" where "seL4_TCB_Resume tcb_cap \ do_kernel_op $ call_kernel_with_intent \cdl_intent_op = Some $ TcbIntent $ TcbResumeIntent, cdl_intent_error = False, cdl_intent_cap = tcb_cap, cdl_intent_extras = [], cdl_intent_recv_slot = None\ True" definition seL4_TCB_WriteRegisters :: "cdl_cptr \ bool \ word8 \ word32 \ cdl_raw_usercontext \ bool u_monad" where "seL4_TCB_WriteRegisters tcb_cap resume_target arch_flags count regs \ do_kernel_op $ call_kernel_with_intent \cdl_intent_op = Some $ TcbIntent $ TcbWriteRegistersIntent resume_target arch_flags count regs, cdl_intent_error = False, cdl_intent_cap = tcb_cap, cdl_intent_extras = [], cdl_intent_recv_slot = None\ False" definition seL4_Untyped_Retype :: "cdl_cptr \ cdl_object_type \ word32 \ cdl_cptr \ word32 \ word32 \ word32 \ word32 \ bool u_monad" where "seL4_Untyped_Retype untyped_cap type size_bits croot node_index node_depth node_offset node_window \ do_kernel_op $ call_kernel_with_intent \cdl_intent_op = Some $ UntypedIntent $ UntypedRetypeIntent type size_bits node_index node_depth node_offset node_window, cdl_intent_error = False, cdl_intent_cap = untyped_cap, cdl_intent_extras = [croot], cdl_intent_recv_slot = None\ False" definition seL4_IRQControl_Get :: "cdl_cptr \ 10 word \ cdl_cptr \ word32 \ word32 \ bool u_monad" where "seL4_IRQControl_Get control_cap irq croot node_index node_depth \ do_kernel_op $ call_kernel_with_intent \cdl_intent_op = Some $ IrqControlIntent $ IrqControlIssueIrqHandlerIntent irq node_index node_depth, cdl_intent_error = False, cdl_intent_cap = control_cap, cdl_intent_extras = [croot], cdl_intent_recv_slot = None\ True" definition seL4_IRQHandler_SetEndpoint :: "cdl_cptr \ cdl_cptr \ bool u_monad" where "seL4_IRQHandler_SetEndpoint handler_cap endpoint_cap \ do_kernel_op $ call_kernel_with_intent \cdl_intent_op = Some $ IrqHandlerIntent $ IrqHandlerSetEndpointIntent, cdl_intent_error = False, cdl_intent_cap = handler_cap, cdl_intent_extras = [endpoint_cap], cdl_intent_recv_slot = None\ True" definition seL4_ASIDPool_Assign :: "cdl_cptr \ cdl_cptr \ bool u_monad" where "seL4_ASIDPool_Assign asid_pool_cap pd \ do_kernel_op $ call_kernel_with_intent \cdl_intent_op = Some $ AsidPoolIntent $ AsidPoolAssignIntent, cdl_intent_error = False, cdl_intent_cap = asid_pool_cap, cdl_intent_extras = [pd], cdl_intent_recv_slot = None\ True" definition seL4_PageTable_Map :: "cdl_cptr \ cdl_cptr \ word32 \ cdl_raw_vmattrs \ bool u_monad" where "seL4_PageTable_Map sel4_page_table sel4_page_directory vaddr vmattribs \ do_kernel_op $ call_kernel_with_intent \cdl_intent_op = Some $ PageTableIntent $ PageTableMapIntent vaddr vmattribs, cdl_intent_error = False, cdl_intent_cap = sel4_page_table, cdl_intent_extras = [sel4_page_directory], cdl_intent_recv_slot = None\ True" definition seL4_Page_Map :: "cdl_cptr \ cdl_cptr \ word32 \ cdl_right set \ cdl_raw_vmattrs \ bool u_monad" where "seL4_Page_Map sel4_page sel4_page_directory vaddr perms vmattribs \ do_kernel_op $ call_kernel_with_intent \cdl_intent_op = Some $ PageIntent $ PageMapIntent vaddr perms vmattribs, cdl_intent_error = False, cdl_intent_cap = sel4_page, cdl_intent_extras = [sel4_page_directory], cdl_intent_recv_slot = None\ True" definition seL4_CNode_Move :: "cdl_cptr \ word32 \ word32 \ cdl_cptr \ word32 \ word32 \ bool u_monad" where "seL4_CNode_Move dest_root dest_index dest_depth src_root src_index src_depth \ do_kernel_op $ call_kernel_with_intent \cdl_intent_op = Some $ CNodeIntent $ CNodeMoveIntent dest_index dest_depth src_index src_depth, cdl_intent_error = False, cdl_intent_cap = dest_root, cdl_intent_extras = [src_root], cdl_intent_recv_slot = None\ False" definition seL4_CNode_Copy :: "cdl_cptr \ word32 \ word32 \ cdl_cptr \ word32 \ word32 \ cdl_right set \ bool u_monad" where "seL4_CNode_Copy dest_root dest_index dest_depth src_root src_index src_depth rights \ do_kernel_op $ call_kernel_with_intent \cdl_intent_op = Some $ CNodeIntent $ CNodeCopyIntent dest_index dest_depth src_index src_depth rights, cdl_intent_error = False, cdl_intent_cap = dest_root, cdl_intent_extras = [src_root], cdl_intent_recv_slot = None\ True" definition seL4_CNode_Mint :: "cdl_cptr \ word32 \ word32 \ cdl_cptr \ word32 \ word32 \ cdl_right set \ cdl_raw_capdata \ bool u_monad" where "seL4_CNode_Mint dest_root dest_index dest_depth src_root src_index src_depth rights data \ do_kernel_op $ call_kernel_with_intent \cdl_intent_op = Some $ CNodeIntent $ CNodeMintIntent dest_index dest_depth src_index src_depth rights data, cdl_intent_error = False, cdl_intent_cap = dest_root, cdl_intent_extras = [src_root], cdl_intent_recv_slot = None\ True" definition seL4_CNode_Mutate :: "cdl_cptr \ word32 \ word32 \ cdl_cptr \ word32 \ word32 \ cdl_raw_capdata \ bool u_monad" where "seL4_CNode_Mutate dest_root dest_index dest_depth src_root src_index src_depth data \ do_kernel_op $ call_kernel_with_intent \cdl_intent_op = Some $ CNodeIntent $ CNodeMutateIntent dest_index dest_depth src_index src_depth data, cdl_intent_error = False, cdl_intent_cap = dest_root, cdl_intent_extras = [src_root], cdl_intent_recv_slot = None\ False" (* End of kernel call funtions *) end