(* * Copyright 2014, General Dynamics C4 Systems * * 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(GD_GPL) *) (* collects lemmas common to the various CSpace branches *) theory CSpaceAcc_C imports "../../refine/$L4V_ARCH/EmptyFail" Ctac_lemmas_C begin (* For resolving schematics *) lemma lift_t_cslift: "cslift x p = Some y \ lift_t c_guard (hrs_mem (t_hrs_' (globals x)), hrs_htd (t_hrs_' (globals x))) p = Some y" by (simp add: hrs_htd_def hrs_mem_def) context kernel begin lemma ccorres_pre_getNotification: assumes cc: "\rv. ccorres r xf (P rv) (P' rv) hs (f rv) c" shows "ccorres r xf (\s. \ntfn. ko_at' ntfn p s \ P ntfn s) ({s'. \ntfn s. (s, s') \ rf_sr \ ko_at' ntfn p s \ s' \ P' ntfn}) hs (getNotification p >>= (\rv. f rv)) c" apply (rule ccorres_guard_imp) apply (rule ccorres_symb_exec_l) defer apply wp[1] apply (rule get_ntfn_sp') apply simp apply assumption defer apply (rule ccorres_guard_imp) apply (rule cc) apply simp apply assumption apply fastforce done lemma ccorres_pre_getCTE: assumes cc: "\rv. ccorres r xf (P rv) (P' rv) hs (f rv) c" shows "ccorres r xf (\s. (\cte. ctes_of s p = Some cte \ P cte s)) {s. \cte'. (cte_lift \\<^sub>m cslift s) (Ptr p) = Some cte' \ cl_valid_cte cte' \ s \ P' (cte_to_H cte') } hs (getCTE p >>= (\rv. f rv)) c" apply (rule ccorres_guard_imp) apply (rule ccorres_symb_exec_l) defer apply wp[1] apply (rule getCTE_sp) apply simp apply assumption apply clarsimp defer apply (rule ccorres_guard_imp) apply (rule cc) apply (simp add: cte_wp_at_ctes_of) apply assumption apply (simp add: cte_wp_at_ctes_of) apply (drule (1) rf_sr_ctes_of_clift) apply clarsimp apply (simp add: c_valid_cte_eq) done lemmas ccorres_getCTE = ccorres_pre_getCTE lemma getCurThread_sp: "\P\ getCurThread \\rv s. ksCurThread s = rv \ P s\" apply wp apply simp done lemma rf_sr_ksCurThread: "(s, s') \ rf_sr \ ksCurThread_' (globals s') = tcb_ptr_to_ctcb_ptr (ksCurThread s)" by (clarsimp simp: rf_sr_def cstate_relation_def Let_def) lemma ccorres_pre_getCurThread: assumes cc: "\rv. ccorres r xf (P rv) (P' rv) hs (f rv) c" shows "ccorres r xf (\s. (\rv. ksCurThread s = rv \ P rv s)) {s. \rv. ksCurThread_' (globals s) = tcb_ptr_to_ctcb_ptr rv \ s \ P' rv } hs (getCurThread >>= (\rv. f rv)) c" apply (rule ccorres_guard_imp) apply (rule ccorres_symb_exec_l) defer apply wp[1] apply (rule getCurThread_sp) apply (clarsimp simp: empty_fail_def getCurThread_def simpler_gets_def) apply assumption apply clarsimp defer apply (rule ccorres_guard_imp) apply (rule cc) apply clarsimp apply assumption apply (clarsimp simp: rf_sr_ksCurThread) done lemma rf_sr_ksDomainTime: "(s, s') \ rf_sr \ ksDomainTime_' (globals s') = ksDomainTime s" by (clarsimp simp: rf_sr_def cstate_relation_def Let_def) lemma ccorres_pre_getDomainTime: assumes cc: "\rv. ccorres r xf (P rv) (P' rv) hs (f rv) c" shows "ccorres r xf (\s. (\rv. ksDomainTime s = rv \ P rv s)) {s. \rv. ksDomainTime_' (globals s) = rv \ s \ P' rv } hs (getDomainTime >>= (\rv. f rv)) c" apply (rule ccorres_guard_imp) apply (rule ccorres_symb_exec_l) defer apply wp[1] apply (simp add: getDomainTime_def) apply (rule gets_sp) apply (clarsimp simp: empty_fail_def getDomainTime_def simpler_gets_def) apply assumption apply clarsimp defer apply (rule ccorres_guard_imp) apply (rule cc) apply clarsimp apply assumption apply (clarsimp simp: rf_sr_ksDomainTime) done lemma rf_sr_ksIdleThread: "(s, s') \ rf_sr \ ksIdleThread_' (globals s') = tcb_ptr_to_ctcb_ptr (ksIdleThread s)" by (clarsimp simp: rf_sr_def cstate_relation_def Let_def) lemma getIdleThread_sp: "\P\ getIdleThread \\rv s. ksIdleThread s = rv \ P s\" by wpsimp lemma ccorres_pre_getIdleThread: assumes cc: "\rv. ccorres r xf (P rv) (P' rv) hs (f rv) c" shows "ccorres r xf (\s. (\rv. ksIdleThread s = rv \ P rv s)) {s. \rv. ksIdleThread_' (globals s) = tcb_ptr_to_ctcb_ptr rv \ s \ P' rv } hs (getIdleThread >>= (\rv. f rv)) c" apply (rule ccorres_guard_imp) apply (rule ccorres_symb_exec_l) defer apply wp[1] apply (rule getIdleThread_sp) apply (clarsimp simp: empty_fail_def getIdleThread_def simpler_gets_def) apply assumption apply clarsimp defer apply (rule ccorres_guard_imp) apply (rule cc) apply clarsimp apply assumption apply (clarsimp simp: rf_sr_ksIdleThread) done lemma cd_wp [wp]: "\\s. P (ksCurDomain s) s\ curDomain \P\" by (unfold curDomain_def, wp) lemma curDomain_sp: "\P\ curDomain \\rv s. ksCurDomain s = rv \ P s\" apply wp apply simp done lemma rf_sr_ksCurDomain: "(s, s') \ rf_sr \ ksCurDomain_' (globals s') = ucast (ksCurDomain s)" by (clarsimp simp: rf_sr_def cstate_relation_def Let_def) lemma ccorres_pre_curDomain: assumes cc: "\rv. ccorres r xf (P rv) (P' rv) hs (f rv) c" shows "ccorres r xf (\s. (\rv. ksCurDomain s = rv \ P rv s)) {s. \rv. ksCurDomain_' (globals s) = ucast rv \ s \ P' rv } hs (curDomain >>= (\rv. f rv)) c" apply (rule ccorres_guard_imp) apply (rule ccorres_symb_exec_l) defer apply wp[1] apply (rule curDomain_sp) apply (clarsimp simp: empty_fail_def curDomain_def simpler_gets_def) apply assumption apply clarsimp defer apply (rule ccorres_guard_imp) apply (rule cc) apply clarsimp apply assumption apply (clarsimp simp: rf_sr_ksCurDomain) done lemma scast_EXCPT_NONE [simp]: "scast EXCEPTION_NONE = EXCEPTION_NONE" unfolding scast_def EXCEPTION_NONE_def by simp lemma pageBitsForSize_spec: "\s. \ \ \s. \pagesize && mask 2 = \pagesize\ Call pageBitsForSize_'proc \ \ret__unsigned_long = of_nat (pageBitsForSize (gen_framesize_to_H \<^bsup>s\<^esup>pagesize)) \" apply vcg apply clarsimp apply (clarsimp simp: pageBitsForSize_def gen_framesize_to_H_def ARMSmallPageBits_def ARMLargePageBits_def ARMSectionBits_def ARMSuperSectionBits_def Kernel_C.ARMSmallPage_def Kernel_C.ARMLargePage_def Kernel_C.ARMSection_def Kernel_C.ARMSuperSection_def) apply (subst (asm) mask_eq_iff_w2p, simp add: word_size) apply simp apply (drule word_less_cases [where y=4]) apply (erule disjE, simp, simp) apply (drule word_less_cases [where y=3]) apply (erule disjE, simp, simp) apply (drule word_less_cases [where y=2]) apply auto done lemma updateMDB_pre_cte_at: "\\s. \ (p \ 0 \ cte_at' p s) \ updateMDB p f \ \_ _. False \" unfolding updateMDB_def Let_def apply simp apply (intro impI) apply (wp getCTE_wp) apply clarsimp done lemma getSlotCap_pre_cte_at: "\\s. \ cte_at' p s \ getSlotCap p \ \_ _. False \" unfolding getSlotCap_def apply simp apply (wp getCTE_wp) apply clarsimp done lemmas ccorres_updateMDB_cte_at = ccorres_guard_from_wp [OF updateMDB_pre_cte_at empty_fail_updateMDB] ccorres_guard_from_wp_bind [OF updateMDB_pre_cte_at empty_fail_updateMDB] lemmas ccorres_getSlotCap_cte_at = ccorres_guard_from_wp [OF getSlotCap_pre_cte_at empty_fail_getSlotCap] ccorres_guard_from_wp_bind [OF getSlotCap_pre_cte_at empty_fail_getSlotCap] lemma wordFromRights_spec: defines "crl s \ (seL4_CapRights_lift \<^bsup>s\<^esup>seL4_CapRights)" shows "\s. \ \ {s} \ret__unsigned_long :== PROC wordFromRights(\seL4_CapRights) \ \ret__unsigned_long = ((capAllowGrant_CL (crl s) << 2) || (capAllowRead_CL (crl s) << 1) || capAllowWrite_CL (crl s)) \" unfolding crl_def apply vcg apply (simp add: word_sle_def word_sless_def) apply (simp add: seL4_CapRights_lift_def shiftr_over_and_dist) apply (simp add: mask_shift_simps) apply (simp add: word_ao_dist2[symmetric]) done lemma errlookup_fault_errstate [simp]: "errlookup_fault (errstate s) = lookup_fault_lift (current_lookup_fault_' (globals s))" unfolding errstate_def by simp lemma errfault_errstate [simp]: "errfault (errstate s) = seL4_Fault_lift (current_fault_' (globals s))" unfolding errstate_def by simp lemma errsyscall_errstate [simp]: "errsyscall (errstate s) = (current_syscall_error_' (globals s))" unfolding errstate_def by simp lemma array_assertion_abs_cnode_ctes: "\s s'. (s, s') \ rf_sr \ (\n. gsCNodes s p = Some n \ n' \ 2 ^ n) \ True \ (x s' = 0 \ array_assertion (cte_Ptr p) n' (hrs_htd (t_hrs_' (globals s'))))" apply (clarsimp, drule(1) rf_sr_gsCNodes_array_assertion) apply (metis array_assertion_shrink_right) done lemmas ccorres_move_array_assertion_cnode_ctes [corres_pre] = ccorres_move_Guard_Seq [OF array_assertion_abs_cnode_ctes] ccorres_move_Guard [OF array_assertion_abs_cnode_ctes] lemma locateSlotCNode_ccorres [corres]: assumes gl: "\v s. globals (xfu v s) = globals s" -- "for state rel. preservation" and fg: "\v s. xf (xfu (\_. v) s) = v" shows "ccorres (\v v'. v' = Ptr v) xf \ {_. cnode = cnode' \ offset = offset'} hs (locateSlotCNode cnode bits offset) (Guard MemorySafety {s. x s = 0 \ array_assertion (cte_Ptr cnode') (unat offset') (hrs_htd (t_hrs_' (globals s)))} (Basic (\s. xfu (\_. cte_Ptr (cnode' + offset' * of_nat (size_of TYPE(cte_C)))) s)))" apply (simp add: locateSlot_conv split del: if_split) apply (rule ccorres_guard_imp2) apply (rule_tac P="cnode = cnode' \ offset = offset'" in ccorres_gen_asm2) apply (rule ccorres_stateAssert) apply (rule ccorres_move_array_assertion_cnode_ctes) apply (rule ccorres_return[where R="\" and R'=UNIV]) apply (rule conseqPre, vcg) apply (clarsimp simp: fg rf_sr_def gl cte_level_bits_def field_simps) apply (clarsimp simp: Collect_const_mem split: option.split_asm) apply (rule unat_le_helper, simp) done lemma locateSlotTCB_ccorres [corres]: assumes gl: "\v s. globals (xfu v s) = globals s" -- "for state rel. preservation" and fg: "\v s. xf (xfu (\_. v) s) = v" shows "ccorres (\v v'. v' = Ptr v) xf \ {_. cnode = cnode' \ offset = offset'} hs (locateSlotTCB cnode offset) (Basic (\s. xfu (\_. Ptr (cnode' + offset' * of_nat (size_of TYPE(cte_C))) :: cte_C ptr) s))" unfolding locateSlot_conv using gl fg apply - apply (simp add: size_of_def split del: if_split) apply (rule ccorres_return) apply (rule conseqPre) apply vcg apply (clarsimp simp: fg objBits_simps cte_level_bits_def) done lemma getSlotCap_h_val_ccorres [corres]: fixes p :: "cstate \ cte_C ptr" assumes gl: "\v s. globals (xfu v s) = globals s" -- "for state rel. preservation" and fg: "\v s. xf (xfu (\_. v) s) = v" shows "ccorres ccap_relation xf \ {s. p s = Ptr a} hs (getSlotCap a) (Basic (\s. xfu (\_. h_val (hrs_mem (t_hrs_' (globals s))) (Ptr &(p s\[''cap_C'']) :: cap_C ptr)) s))" unfolding getSlotCap_def apply (rule ccorres_add_UNIV_Int) apply (cinitlift p) -- "EVIL!" apply simp apply (rule ccorres_guard_imp2) apply (rule ccorres_pre_getCTE) apply (rule_tac R = "\s. ctes_of s a = Some rva" in ccorres_return [where R' = UNIV]) apply vcg apply (clarsimp simp: gl fg cte_wp_at_ctes_of) apply (erule (1) rf_sr_ctes_of_cliftE) apply (clarsimp simp add: typ_heap_simps ccap_relation_def cte_to_H_def cl_valid_cte_def c_valid_cap_def) apply simp done end end