(* * 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 Finalise_DR imports KHeap_DR "../invariant-abstract/PDPTEntries_AI" "../../lib/Apply_Trace" begin declare dxo_wp_weak[wp del] lemma trancl_image: assumes inj: "inj_on f (Domain S \ Range S)" shows "trancl ((\(x, y). (f x, f y)) ` S) = (\(x, y). (f x, f y)) ` trancl S" (is "?lhs = ?rhs") apply safe apply (erule trancl.induct) apply clarsimp apply (erule image_eqI[rotated, OF r_into_trancl]) apply simp apply (clarsimp simp: inj_on_iff[OF inj] RangeI[THEN eqset_imp_iff[OF trancl_range, THEN iffD1]] DomainI) apply (erule(1) image_eqI[rotated, OF trancl_into_trancl]) apply simp apply (erule trancl.induct) apply (rule r_into_trancl, erule image_eqI[rotated]) apply simp apply (erule trancl_into_trancl) apply (erule image_eqI[rotated]) apply simp done lemma descendants_of_eqv: assumes cte_at: "mdb_cte_at (swp (cte_wp_at P) s) (cdt s)" and cte_at_p: "cte_at p s" shows "KHeap_D.descendants_of (transform_cslot_ptr p) (transform s) = transform_cslot_ptr ` CSpaceAcc_A.descendants_of p (cdt s)" proof - note inj = transform_cdt_slot_inj_on_mdb_cte_at[OF cte_at] have P: "{(x, y). KHeap_D.is_cdt_parent (transform s) x y} = (\(x, y). (transform_cslot_ptr x, transform_cslot_ptr y)) ` {(x, y). CSpaceAcc_A.is_cdt_parent (cdt s) x y}" apply (simp add: KHeap_D.is_cdt_parent_def CSpaceAcc_A.is_cdt_parent_def) apply (simp add: transform_def transform_cdt_def map_lift_over_eq_Some inj) apply auto done have inj': "inj_on transform_cslot_ptr ({p} \ dom (cdt s) \ ran (cdt s))" using cte_at_p mdb_cte_atD[OF _ cte_at] apply - apply (rule transform_cdt_slot_inj_on_cte_at[where P=\ and s=s]) apply (fastforce simp: cte_wp_at_caps_of_state elim!: ranE) done show ?thesis apply (simp add: KHeap_D.descendants_of_def CSpaceAcc_A.descendants_of_def KHeap_D.cdt_parent_rel_def CSpaceAcc_A.cdt_parent_rel_def) apply (simp add: P) apply (subst trancl_image) apply (rule subset_inj_on[OF inj]) apply (auto simp: KHeap_D.is_cdt_parent_def CSpaceAcc_A.is_cdt_parent_def)[1] apply safe apply (subst(asm) inj_on_iff[OF inj'], simp_all) apply (drule DomainI[THEN eqset_imp_iff[OF trancl_domain, THEN iffD1]]) apply (auto simp: CSpaceAcc_A.is_cdt_parent_def) done qed (* Fast finalise is done in TCB_DR, this file only deals with finalise *) lemma dcorres_unmap_page_empty: "dcorres dc \ \ (PageTableUnmap_D.unmap_page x) (return a)" apply (simp add:PageTableUnmap_D.unmap_page_def) apply (rule corres_symb_exec_l) apply (rule corres_guard_imp) apply (rule_tac x = "[]" in select_pick_corres) apply (clarsimp simp:mapM_x_def sequence_x_def del:hoare_post_taut) prefer 4 apply (rule hoare_post_taut) apply simp_all apply (simp add:exs_valid_def slots_with_def gets_def has_slots_def get_def bind_def return_def ) done lemma dcorres_revoke_cap_no_descendants: "slot' = transform_cslot_ptr slot \ dcorres dc \ (\s. valid_mdb s \ cte_at slot s \ CSpaceAcc_A.descendants_of slot (cdt s) = {}) (revoke_cap_simple slot') (return x)" apply (rule dcorres_revoke_cap_simple_helper) apply (simp add:gets_def) apply (rule dcorres_absorb_get_l) apply (subgoal_tac "(KHeap_D.descendants_of slot' (transform s')) = {}") apply clarsimp apply (rule dcorres_absorb_get_l) apply clarsimp apply (clarsimp simp:descendants_of_eqv valid_mdb_def) done lemma dcorres_revoke_cap_unnecessary: "dcorres dc \ (valid_reply_caps and valid_objs and only_idle and valid_mdb and st_tcb_at (Not \ awaiting_reply) ptr and cte_at (ptr,tcb_cnode_index 2) and not_idle_thread ptr and valid_idle) (revoke_cap_simple (ptr, tcb_replycap_slot)) (return x)" apply (subst transform_tcb_slot_simp[symmetric]) apply (rule corres_guard_imp) apply (rule dcorres_revoke_cap_no_descendants) apply (simp add:transform_tcb_slot_simp[symmetric])+ apply (rule not_waiting_reply_slot_no_descendants) apply simp_all done lemma descendants_exist_in_cdt: "\ a \ descendants_of p (cdt s) \ \ cdt s a \ None" apply (simp add: descendants_of_def cdt_parent_rel_def) apply (frule RangeI[THEN eqset_imp_iff[OF trancl_range, THEN iffD1]]) apply (clarsimp simp: is_cdt_parent_def) done lemma descendants_exist_in_cdl_cdt: "\ a \ KHeap_D.descendants_of p (transform s) \ \ cdl_cdt (transform s) a \ None" apply (simp add: KHeap_D.descendants_of_def KHeap_D.cdt_parent_rel_def) apply (frule RangeI) apply (frule DomainI) apply (clarsimp simp: KHeap_D.is_cdt_parent_def) done lemma cdl_cdt_parent_cte_at_lift: "\ mdb_cte_at (swp (cte_wp_at P) s) (cdt s) ; a \ KHeap_D.descendants_of p (transform s) \ \ (\slot. cte_at slot s \ p = transform_cslot_ptr slot)" apply (simp add:KHeap_D.descendants_of_def KHeap_D.cdt_parent_rel_def) apply (frule DomainI) apply (clarsimp simp:KHeap_D.is_cdt_parent_def) apply (simp add:transform_def transform_cdt_def) apply (clarsimp simp:transform_cdt_slot_inj_on_mdb_cte_at map_lift_over_eq_Some split:if_splits) apply (rule_tac x = ab in exI,rule_tac x = bb in exI) apply (drule(1) mdb_cte_atD) apply (clarsimp simp :cte_wp_at_cte_at) done lemma descendants_not_null_cap: "\ a \ descendants_of p (cdt s); mdb_cte_at (swp (cte_wp_at P) s) (cdt s) \ \ cte_wp_at P a s" apply (drule descendants_exist_in_cdt) apply clarsimp apply (drule(1) mdb_cte_atD) apply simp done lemma descendants_in_cte_wp_set: "mdb_cte_at (swp (cte_wp_at P ) s) (cdt s) \ CSpaceAcc_A.descendants_of p (cdt s) \ Collect (\x. cte_wp_at (P) x s)" by (auto simp:descendants_not_null_cap) lemma ex_in_none_empty_set: "a\{} \ \x. x\a" by auto lemma finite_descendants_if_from_transform: " mdb_cte_at (swp (cte_wp_at P) s) (cdt s) \ finite (KHeap_D.descendants_of x (transform s))" apply (case_tac "KHeap_D.descendants_of x (transform s) = {}") apply simp apply (drule ex_in_none_empty_set) apply clarsimp apply (frule(1) cdl_cdt_parent_cte_at_lift) apply clarsimp apply (frule(1) descendants_of_eqv) apply clarsimp apply (rule finite_imageI) apply (rule finite_subset) apply (rule descendants_in_cte_wp_set) apply simp apply (simp add:cte_wp_at_set_finite) done lemma delete_cdt_slot_shrink_descendants: "\\s. valid_mdb s \ x = cdt s \ slot \ CSpaceAcc_A.descendants_of p x \ x = y \ set_cdt ((\p. if x p = Some slot then x slot else x p)(slot := None)) \\r s. slot \ CSpaceAcc_A.descendants_of p (cdt s) \ CSpaceAcc_A.descendants_of p (cdt s) \ CSpaceAcc_A.descendants_of p y \" apply (clarsimp simp:set_cdt_def get_def put_def bind_def valid_def) apply (rule conjI) apply (subgoal_tac "mdb_empty_abs s") apply (clarsimp simp:mdb_empty_abs.descendants mdb_empty_abs_def vmdb_abs_def)+ done lemma delete_cap_one_shrink_descendants: "\\s. s = pres \ invs s \ slot \ CSpaceAcc_A.descendants_of p (cdt pres) \ cap_delete_one slot \\r s. slot \ CSpaceAcc_A.descendants_of p (cdt s) \ CSpaceAcc_A.descendants_of p (cdt s) \ CSpaceAcc_A.descendants_of p (cdt pres) \" apply (simp add:cap_delete_one_def unless_def) apply wp apply (clarsimp simp add:empty_slot_def) apply (wp dxo_wp_weak) apply simp apply (rule_tac P="\s. valid_mdb s \ cdt s = xa \ cdt pres = xa \ slot \ CSpaceAcc_A.descendants_of p (cdt s) \ mdb_cte_at (swp (cte_wp_at (op\ cap.NullCap)) s) (cdt s)" in hoare_vcg_precond_imp) apply (rule_tac Q ="\r s. (?Q r s) \ (mdb_cte_at (swp (cte_wp_at (op\ cap.NullCap)) s) (cdt s))" in hoare_strengthen_post) apply (rule hoare_vcg_conj_lift) apply (rule delete_cdt_slot_shrink_descendants[where y= "cdt pres" and p = p]) apply (rule_tac Q="\s. mdb_cte_at (swp (cte_wp_at (op\cap.NullCap)) s ) xa" in hoare_vcg_precond_imp) apply (case_tac slot) apply (clarsimp simp:set_cdt_def get_def put_def bind_def valid_def mdb_cte_at_def | rule conjI)+ apply (fastforce,clarsimp,fastforce) apply (assumption) apply clarsimp+ apply (assumption) apply wp apply (rule hoare_vcg_conj_lift[where P="\s. cdt s = cdt pres \ mdb_cte_at (swp (cte_wp_at (op\cap.NullCap)) s) (cdt s)"]) prefer 2 apply (rule hoare_drop_imp) apply wp apply (clarsimp simp:valid_def in_get_cap_cte_wp_at) apply (drule sym) apply clarsimp apply (drule descendants_not_null_cap) apply simp apply (simp add:cte_wp_at_def) apply (wp|simp)+ apply (rule hoare_vcg_conj_lift) apply (rule hoare_strengthen_post[OF invs_mdb_fast_finalise]) apply (clarsimp simp:valid_mdb_def swp_def) apply wp apply (rule hoare_strengthen_post[OF invs_mdb_fast_finalise]) apply (clarsimp simp:valid_mdb_def swp_def) apply wp apply (clarsimp simp:valid_def in_get_cap_cte_wp_at) apply (clarsimp simp:invs_def valid_mdb_def valid_state_def) apply (drule descendants_not_null_cap) apply simp apply (clarsimp simp:cte_wp_at_def) done lemma invs_emptyable_descendants: "\invs s;CSpaceAcc_A.descendants_of slot (cdt s) = {(a, b)}\ \ emptyable (a, b) s" apply (clarsimp simp:emptyable_def) apply (frule reply_slot_not_descendant) apply simp apply fastforce done lemma cap_delete_one_cte_at: "\invs and emptyable sl and cte_at x\ cap_delete_one sl \\_. cte_at x\" apply (simp add:cap_delete_one_def) apply wp apply (clarsimp simp:unless_def when_def | rule conjI)+ apply (wp|clarsimp)+ done lemma caps_of_state_transform_opt_cap_no_idle: "\caps_of_state s p = Some cap; valid_etcbs s\ \ opt_cap (transform_cslot_ptr p) (transform s) = Some (transform_cap cap) \ opt_cap (transform_cslot_ptr p) (transform s) = None" apply (frule caps_of_state_cteD) apply (cases p) apply (erule cte_wp_atE) apply (clarsimp simp: opt_cap_def transform_cslot_ptr_def object_slots_def slots_of_def opt_object_def transform_def transform_objects_def transform_cnode_contents_def well_formed_cnode_n_def restrict_map_def split: option.splits split_if_asm) apply (frule(1) eqset_imp_iff[THEN iffD1, OF _ domI]) apply (simp add: option_map_join_def nat_to_bl_dest) apply (clarsimp simp: cap_installed_at_irq_def valid_irq_node_def obj_at_def is_cap_table_def well_formed_cnode_n_def length_set_helper word_bl.Abs_inverse object_slots_def nat_bl_to_bin_lt2p) apply (frule(1) valid_etcbs_tcb_etcb) apply (clarsimp simp: opt_cap_def transform_cslot_ptr_def slots_of_def opt_object_def restrict_map_def transform_def object_slots_def transform_objects_def valid_irq_node_def obj_at_def is_cap_table_def transform_tcb_def tcb_slot_defs tcb_pending_op_slot_def tcb_cap_cases_def bl_to_bin_tcb_cnode_index bl_to_bin_tcb_cnode_index_le0 split: split_if_asm option.splits) done lemma transform_cap_Null [simp]: "(transform_cap cap = cdl_cap.NullCap) = (cap = cap.NullCap)" apply (cases cap, simp_all) apply (case_tac arch_cap, simp_all) done lemma dcorres_revoke_the_cap_corres: "dcorres dc \ (invs and cte_at slot and valid_etcbs) (revoke_cap_simple (transform_cslot_ptr slot)) (do descs \ gets (CSpaceAcc_A.descendants_of slot \ cdt); when (descs \ {}) (do y \ assert (\a b. descs = {(a, b)}); select descs >>= cap_delete_one od) od)" apply (rule dcorres_revoke_cap_simple_helper) apply (simp add:gets_def) apply (rule dcorres_absorb_get_l) apply (rule dcorres_absorb_get_r) apply (subgoal_tac "finite (KHeap_D.descendants_of (transform_cslot_ptr slot) (transform s'))") apply (clarsimp simp: finite_descendants_if_from_transform valid_mdb_def invs_def valid_state_def descendants_of_eqv) apply (rule dcorres_absorb_get_l) apply (clarsimp simp: when_def assert_def corres_free_fail) apply (subgoal_tac "cte_wp_at (op \ cap.NullCap) (a,b) s'") prefer 2 apply (erule descendants_not_null_cap [rotated]) apply fastforce apply (rule conjI) prefer 2 apply (clarsimp simp: cte_wp_at_caps_of_state) apply (subgoal_tac "a \ idle_thread s'") apply (drule_tac p="(a,b)" in caps_of_state_transform_opt_cap) apply clarsimp apply clarsimp apply clarsimp apply clarsimp apply (erule notE, rule sym) apply (erule (4) valid_idle_has_null_cap) apply clarsimp apply (rule corres_dummy_return_r) apply (rule corres_guard_imp) apply (rule corres_split[OF dcorres_revoke_cap_no_descendants]) apply simp apply (rule delete_cap_simple_corres) apply (wp cap_delete_one_cte_at) apply (rule_tac pres1 = s' and p1 = slot in hoare_strengthen_post[OF delete_cap_one_shrink_descendants]) apply (simp_all add:invs_def valid_state_def valid_mdb_def) apply fastforce apply (rule conjI) apply (rule ccontr) apply (subgoal_tac "cte_wp_at (op\cap.NullCap) (a,b) s") apply (clarsimp simp: cte_wp_at_caps_of_state) apply (drule valid_idle_has_null_cap) apply (simp add:not_idle_thread_def)+ apply (rule invs_emptyable_descendants) apply (simp add:invs_def valid_state_def valid_mdb_def)+ apply (clarsimp simp:finite_descendants_if_from_transform) done lemma valid_aep_after_reomve_slot: "valid_aep (async_ep.WaitingAEP list) s'\ valid_aep (case remove1 ptr list of [] \ async_ep.IdleAEP | a # lista \ async_ep.WaitingAEP (remove1 ptr list)) s'" by (clarsimp simp:valid_aep_def split:async_ep.splits list.split_asm) lemma finalise_ipc_cancel: "dcorres dc \ (not_idle_thread ptr and invs and valid_etcbs) (CSpace_D.ipc_cancel ptr) (ipc_cancel ptr)" apply (simp add:CSpace_D.ipc_cancel_def ipc_cancel_def get_thread_state_def thread_get_def) apply (rule dcorres_gets_the) apply (simp add:opt_object_tcb not_idle_thread_def transform_tcb_def, clarsimp) apply (frule(1) valid_etcbs_get_tcb_get_etcb) apply (clarsimp simp: opt_cap_tcb tcb_pending_op_slot_def tcb_caller_slot_def tcb_cspace_slot_def tcb_ipcbuffer_slot_def tcb_replycap_slot_def tcb_vspace_slot_def assert_opt_def) apply (case_tac "tcb_state obj'") apply (simp_all add:not_idle_thread_def infer_tcb_pending_op_def tcb_pending_op_slot_def[symmetric] tcb_replycap_slot_def[symmetric]) apply (simp add:blocked_ipc_cancel_def) apply (rule corres_guard_imp) apply (rule corres_symb_exec_r) apply (rule corres_symb_exec_r) apply (rule corres_symb_exec_r) apply (rule corres_dummy_return_pl) apply (rule corres_split[ OF _ corres_dummy_set_sync_ep]) apply clarsimp apply (rule corres_dummy_return_pr) apply (rule corres_split [OF _ dcorres_revoke_cap_unnecessary]) apply (simp add:K_bind_def when_def dc_def[symmetric]) apply (rule set_thread_state_corres) apply (wp sts_only_idle sts_st_tcb_at' valid_ep_queue_subset | clarsimp simp:not_idle_thread_def)+ apply (simp add:get_blocking_ipc_endpoint_def | wp)+ apply (clarsimp dest!:get_tcb_rev simp:invs_def ) apply (frule(1) valid_tcb_if_valid_state) apply (clarsimp simp:valid_tcb_def valid_tcb_state_def valid_state_def valid_pspace_def infer_tcb_pending_op_def st_tcb_at_def generates_pending_def obj_at_def dest!:get_tcb_SomeD) apply (rule tcb_at_cte_at_2,clarsimp simp:tcb_at_def dest!:get_tcb_rev,simp) apply (simp add:blocked_ipc_cancel_def) apply (rule corres_guard_imp) apply (rule corres_symb_exec_r) apply (rule corres_symb_exec_r) apply (rule corres_symb_exec_r) apply (rule corres_dummy_return_pl) apply (rule corres_split[ OF _ corres_dummy_set_sync_ep]) apply clarsimp apply (rule corres_dummy_return_pr) apply (rule corres_split [OF _ dcorres_revoke_cap_unnecessary]) unfolding K_bind_def apply (rule set_thread_state_corres) apply (wp sts_only_idle sts_st_tcb_at' valid_ep_queue_subset | clarsimp simp:not_idle_thread_def)+ apply (simp add:get_blocking_ipc_endpoint_def | wp)+ apply (clarsimp dest!:get_tcb_rev simp:invs_def) apply (frule(1) valid_tcb_if_valid_state) apply (clarsimp simp:valid_tcb_def valid_tcb_state_def valid_state_def valid_pspace_def infer_tcb_pending_op_def st_tcb_at_def generates_pending_def obj_at_def dest!:get_tcb_SomeD) apply (rule tcb_at_cte_at_2,clarsimp simp:tcb_at_def dest!:get_tcb_rev,simp) apply (simp add:reply_ipc_cancel_def) apply (rule corres_guard_imp) apply (rule corres_split[OF _ thread_set_fault_corres]) apply (rule corres_symb_exec_r) apply (simp add:when_False revoke_cap_simple.simps ) apply (subst transform_tcb_slot_simp[symmetric]) apply (rule dcorres_revoke_the_cap_corres) apply (wp thread_set_invs_trivial[OF ball_tcb_cap_casesI] thread_set_cte_at|clarsimp)+ apply (clarsimp simp: not_idle_thread_def tcb_at_cte_at_2[unfolded tcb_at_def]) apply (simp add:async_ipc_cancel_def) apply (rule corres_guard_imp) apply (rule_tac Q'="\r. valid_aep r and op=s'" in corres_symb_exec_r) apply (rule corres_symb_exec_r) apply (rule corres_dummy_return_pl) apply (rule corres_split[ OF _ corres_dummy_set_async_ep]) unfolding K_bind_def apply (rule corres_dummy_return_pr) apply (rule corres_split[OF _ dcorres_revoke_cap_unnecessary]) unfolding K_bind_def apply (rule set_thread_state_corres) apply (wp set_aep_valid_objs | clarsimp simp:not_idle_thread_def)+ apply (clarsimp simp:valid_def fail_def return_def split:async_ep.splits)+ apply (clarsimp simp:invs_def) apply (frule(1) valid_tcb_if_valid_state) apply (clarsimp simp:valid_tcb_def tcb_at_cte_at_2 valid_tcb_state_def invs_def valid_state_def valid_pspace_def st_tcb_at_def generates_pending_def obj_at_def infer_tcb_pending_op_def dest!:get_tcb_SomeD) apply (simp add:valid_aep_after_reomve_slot) apply (wp | clarsimp split:async_ep.splits)+ apply (clarsimp simp:invs_def, frule(1) valid_tcb_if_valid_state) apply (clarsimp simp:valid_tcb_def tcb_at_cte_at_2 valid_tcb_state_def invs_def valid_state_def valid_pspace_def st_tcb_at_def generates_pending_def obj_at_def dest!:get_tcb_SomeD) apply (clarsimp, frule(1) valid_etcbs_get_tcb_get_etcb) apply (clarsimp simp:opt_object_tcb opt_cap_tcb) done lemma dcorres_get_irq_slot: "dcorres (\r r'. r = transform_cslot_ptr r') \ \ (gets (CSpace_D.get_irq_slot x)) (KHeap_A.get_irq_slot x)" apply (simp add:gets_def CSpace_D.get_irq_slot_def KHeap_A.get_irq_slot_def) apply (rule dcorres_absorb_get_l) apply (rule dcorres_absorb_get_r) apply (clarsimp simp: return_def transform_def corres_underlying_def transform_cslot_ptr_def) done lemma dcorres_deleting_irq_handler: "dcorres dc \ (invs and valid_etcbs) (CSpace_D.deleting_irq_handler word) (CSpace_A.deleting_irq_handler word)" apply (simp add:CSpace_D.deleting_irq_handler_def CSpace_A.deleting_irq_handler_def) apply (rule corres_guard_imp) apply (rule corres_split[OF _ dcorres_get_irq_slot]) apply (simp, rule delete_cap_simple_corres,simp) apply (rule hoare_vcg_precond_imp [where Q="invs and valid_etcbs"]) apply (wp |clarsimp simp:get_irq_slot_def)+ apply (rule irq_node_image_not_idle) apply (simp add:invs_def valid_state_def)+ done lemma do_machine_op_wp: "\m. \\ms. underlying_memory ms = m\ mop \\rv ms. underlying_memory ms = m\ \ \\ps. transform ps = cs\ do_machine_op mop \\r ps. transform ps = cs\" apply (clarsimp simp:do_machine_op_def gets_def get_def return_def bind_def select_f_def simpler_modify_def) apply (clarsimp simp:valid_def) apply (drule_tac x = "(machine_state s)" in spec) apply (drule_tac x = "(a,b)" in bspec) apply simp apply clarsimp apply (clarsimp simp:transform_def transform_current_thread_def) apply (simp add: transform_objects_def2) done lemmas dmo_dwp = do_machine_op_wp [OF allI] lemma machine_op_lift[wp]: "\\ms. underlying_memory ms = m\ machine_op_lift x \\rv ms. underlying_memory ms = m\" apply (clarsimp simp:machine_rest_lift_def ignore_failure_def machine_op_lift_def) apply wp apply (clarsimp simp:simpler_modify_def valid_def) apply (assumption) apply wp apply clarsimp done lemma invalidateTLB_ASID_underlying_memory[wp]: "\\ms. underlying_memory ms = m\ invalidateTLB_ASID a \\rv ms. underlying_memory ms = m\" apply (clarsimp simp: invalidateTLB_ASID_def, wp) done lemma dsb_underlying_memory[wp]: "\\ms. underlying_memory ms = m\ dsb \\rv ms. underlying_memory ms = m\" apply (clarsimp simp: dsb_def, wp) done lemma invalidate_I_PoU_underlying_memory[wp]: "\\ms. underlying_memory ms = m\ invalidate_I_PoU \\rv ms. underlying_memory ms = m\" apply (clarsimp simp: invalidate_I_PoU_def , wp) done lemma clean_D_PoU_underlying_memory[wp]: "\\ms. underlying_memory ms = m\clean_D_PoU \\rv ms. underlying_memory ms = m\" apply (clarsimp simp: clean_D_PoU_def , wp) done lemma cleanCachesPoU_underlying_memory[wp]: "\\ms. underlying_memory ms = m\ cleanCaches_PoU \\rv ms. underlying_memory ms = m\" apply (clarsimp simp: cleanCaches_PoU_def, wp) done lemma flush_space_dwp[wp]: "\\ps. transform ps = cs\ flush_space x \\r ps. transform ps = cs\" apply (clarsimp simp:flush_space_def) apply (wp|wpc)+ apply (clarsimp split:option.splits) apply (rule do_machine_op_wp) apply clarsimp apply (wp static_imp_wp) apply (rule do_machine_op_wp) apply clarsimp apply wp apply (rule hoare_allI) apply (rule hoare_drop_imp) apply (rule do_machine_op_wp) apply clarsimp apply wp apply (rule hoare_conjI) apply (rule hoare_drop_imp) apply (clarsimp simp:load_hw_asid_def) apply wp apply (clarsimp simp:load_hw_asid_def) apply wp done lemma invalidate_asid_dwp[wp]: "\\ps. transform ps = cs\ invalidate_asid (the (hw_asid_table next_asid)) \\x ps. transform ps = cs\" apply (clarsimp simp:invalidate_asid_def) apply wp apply (clarsimp simp:transform_def transform_objects_def2 transform_current_thread_def transform_cdt_def transform_asid_table_def) done lemma invalidate_asid_entry_dwp[wp]: "\\ps. transform ps = cs\ invalidate_asid_entry x \\r ps. transform ps = cs\" apply (clarsimp simp:invalidate_asid_entry_def) apply wp apply (clarsimp simp:invalidate_asid_def) apply wp apply (clarsimp simp:invalidate_hw_asid_entry_def) apply wp apply (subgoal_tac "transform s = cs") prefer 2 apply (assumption) apply (clarsimp simp:transform_def transform_objects_def2 transform_current_thread_def transform_cdt_def transform_asid_table_def) apply (clarsimp simp:load_hw_asid_def) apply wp apply (clarsimp simp:transform_def transform_objects_def2 transform_current_thread_def transform_cdt_def transform_asid_table_def) done lemma invalidate_hw_asid_entry_dwp[wp]: "\\s. transform s = cs\ invalidate_hw_asid_entry next_asid \\xb a. transform a = cs\" apply (clarsimp simp:invalidate_hw_asid_entry_def) apply wp apply (clarsimp simp:transform_def transform_objects_def2 transform_current_thread_def transform_cdt_def transform_asid_table_def) done lemma set_current_pd_dwp[wp]: " \\ms. underlying_memory ms = m\ setCurrentPD (Platform.addrFromPPtr x) \\rv ms. underlying_memory ms = m\" by (clarsimp simp:setCurrentPD_def,wp) lemma set_hardware_asid_dwp[wp]: " \\ms. underlying_memory ms = m\ setHardwareASID hw_asid \\rv ms. underlying_memory ms = m\" by (clarsimp simp:setHardwareASID_def,wp) lemma store_hardware_asid_dwp[wp]: "\\s. transform s = cs\ store_hw_asid a xa \\xb a. transform a = cs\" apply (clarsimp simp:store_hw_asid_def) apply wp apply (simp add:find_pd_for_asid_assert_def) apply wp apply (simp add:find_pd_for_asid_def) apply (wp|wpc)+ apply (clarsimp simp:transform_def transform_objects_def2 transform_current_thread_def transform_cdt_def transform_asid_table_def) done lemma transform_arch_state: "\ arm_globals_frame (arch_state a) = arm_globals_frame x; arm_asid_table (arch_state a) = arm_asid_table x \ \ transform (a\arch_state := x \) = transform a" by (clarsimp simp:transform_def transform_objects_def2 transform_cdt_def transform_current_thread_def transform_asid_table_def) lemma find_free_hw_asid_dwp[wp]: "\\s. transform s = cs\ find_free_hw_asid \\xa s. transform s = cs\" apply (clarsimp simp:find_free_hw_asid_def) apply (wp|wpc)+ apply (clarsimp simp:transform_arch_state) apply (wp do_machine_op_wp |clarsimp simp:)+ done lemma arch_obj_not_idle: "\valid_idle s;kheap s ptr = Some (ArchObj x )\ \ not_idle_thread ptr s" by (clarsimp simp:not_idle_thread_def valid_idle_def obj_at_def st_tcb_at_def) lemma asid_pool_at_rev: "\ kheap s a = Some (ArchObj (arch_kernel_obj.ASIDPool fun)) \ \ asid_pool_at a s" apply (clarsimp simp:obj_at_def valid_idle_def st_tcb_at_def) apply (clarsimp simp:a_type_def split:arch_kernel_obj.splits Structures_A.kernel_object.split_asm if_splits arch_kernel_object.splits) done lemma asid_pool_not_idle: "\ valid_idle s; asid_pool_at a s \ \ not_idle_thread a s" apply (clarsimp simp:obj_at_def valid_idle_def st_tcb_at_def) apply (clarsimp simp:a_type_def not_idle_thread_def split:arch_kernel_obj.splits Structures_A.kernel_object.split_asm if_splits arch_kernel_object.splits) done lemma opt_object_asid_pool: "\ valid_idle s; kheap s a = Some (ArchObj (arch_kernel_obj.ASIDPool fun)) \ \ opt_object a (transform s) = Some (cdl_object.AsidPool \cdl_asid_pool_caps = transform_asid_pool_contents fun\)" apply (frule asid_pool_at_rev) apply (frule(1) asid_pool_not_idle) apply (clarsimp simp:transform_objects_def opt_object_def transform_def not_idle_thread_def restrict_map_def) done lemma transform_asid_pool_contents_upd: "transform_asid_pool_contents (pool(ucast asid := pd)) = transform_asid_pool_contents pool(snd (transform_asid asid) \ transform_asid_pool_entry pd)" apply (clarsimp simp:transform_asid_pool_contents_def transform_asid_def) apply (rule ext) apply (case_tac x) apply (clarsimp simp:unat_eq_0 unat_map_def) apply (safe | clarsimp)+ apply (safe | clarsimp simp:unat_map_def)+ apply (subst (asm) of_nat_Suc[symmetric]) apply (rule_tac P="Suc nat = unat (ucast asid)" in notE, simp) apply (cut_tac x="Suc nat" and y="unat (ucast asid :: 10 word)" in word_unat.Abs_inject[symmetric, where 'a=10]) apply (simp add:unats_def)+ apply (rule unat_lt2p[where x="ucast asid :: 10 word", simplified]) apply simp done lemma dcorres_set_asid_pool: "\ pool' = pool (ucast asid := pd); slot = snd (transform_asid asid); cap = transform_asid_pool_entry pd \ \ dcorres dc \ (valid_idle and ko_at (ArchObj (arch_kernel_obj.ASIDPool pool)) a) (KHeap_D.set_cap (a, slot) cap) (set_asid_pool a pool')" apply (simp add:KHeap_D.set_cap_def set_asid_pool_def get_object_def gets_the_def gets_def bind_assoc) apply (rule dcorres_absorb_get_l) apply (clarsimp simp:obj_at_def opt_object_asid_pool assert_opt_def has_slots_def) apply (clarsimp simp:KHeap_D.set_object_def simpler_modify_def put_def bind_def corres_underlying_def update_slots_def return_def object_slots_def) apply (clarsimp simp:KHeap_A.set_object_def get_def put_def bind_def return_def) apply (clarsimp simp:transform_def transform_current_thread_def) apply (drule(1) arch_obj_not_idle) apply (rule ext) apply (clarsimp simp:not_idle_thread_def transform_objects_def restrict_map_def map_add_def) apply (rule transform_asid_pool_contents_upd) done lemma dcorres_set_vm_root: "dcorres dc \ \ (return x) (set_vm_root rvd)" apply (clarsimp simp: set_vm_root_def) apply (rule dcorres_symb_exec_r)+ apply (clarsimp simp:catch_def throwError_def) apply (rule corres_dummy_return_r) apply (rule dcorres_symb_exec_r[OF corres_free_return[where P=\ and P'=\]])+ apply wp apply wpc apply (wp do_machine_op_wp | clarsimp)+ apply (rule_tac Q = "\_ s. transform s = cs" in hoare_post_imp) apply simp apply (rule hoare_pre) apply (wp hoare_whenE_wp do_machine_op_wp [OF allI] hoare_drop_imps find_pd_for_asid_inv | wpc | simp add: set_current_asid_def get_hw_asid_def load_hw_asid_def if_apply_def2)+ done lemma dcorres_delete_asid_pool: "dcorres dc \ \ (CSpace_D.delete_asid_pool (transform_asid asid) oid) (ArchVSpace_A.delete_asid_pool asid oid)" apply (simp add:CSpace_D.delete_asid_pool_def ArchVSpace_A.delete_asid_pool_def) apply (rule dcorres_symb_exec_r[where Q'="\rv. \", simplified]) apply (clarsimp simp:gets_def) apply (rule dcorres_absorb_get_r) apply (clarsimp simp:when_def) apply (rule conjI) prefer 2 apply (clarsimp, rule corres_alternate2) apply (clarsimp simp: corres_return) apply clarsimp apply (rule corres_alternate1) apply (rule dcorres_absorb_get_l) apply (rule dcorres_symb_exec_r[where Q'="\rv. \", simplified]) apply (rule dcorres_symb_exec_r[where Q'="\rv. \", simplified]) apply (rule corres_dummy_return_l) apply (rule corres_underlying_split[where r'=dc and P="\rv. \" and P'="\rv. \", simplified]) prefer 2 apply clarsimp apply (rule dcorres_absorb_get_r) apply (rule corres_guard_imp) apply (rule dcorres_set_vm_root) apply clarsimp+ apply (rule corres_guard_imp[where Q=\ and Q'=\, simplified]) apply (clarsimp simp:simpler_modify_def put_def bind_def corres_underlying_def) apply (clarsimp simp:transform_def transform_objects_def transform_cdt_def transform_current_thread_def) apply (clarsimp simp:transform_asid_table_def) apply (rule ext) apply (clarsimp simp:unat_map_def asid_high_bits_of_def transform_asid_table_entry_def transform_asid_def) apply safe apply (drule unat_cong) apply (subst (asm) word_unat.Abs_inverse) apply (clarsimp simp:unats_def unat_ucast)+ apply (rule mapM_wp) apply clarsimp apply wp apply fastforce apply wp apply simp done lemma descendants_of_page: "\valid_mdb s;page_table_at oid s\\ KHeap_D.descendants_of (oid, 0) (transform s) = {}" apply (clarsimp simp:pspace_aligned_def obj_at_def a_type_def) apply (clarsimp split:arch_kernel_obj.split_asm Structures_A.kernel_object.split_asm if_splits) apply (rule ccontr) apply (clarsimp simp:valid_mdb_def dest!:not_emptyI) apply (frule(1) cdl_cdt_parent_cte_at_lift) apply clarsimp apply (simp add:descendants_of_eqv cte_at_cases) apply (clarsimp simp:transform_cslot_ptr_def) done lemma page_table_aligned: "\pspace_aligned s;page_table_at oid s\ \ (oid && ~~ mask pt_bits) = oid" apply (clarsimp simp:pspace_aligned_def obj_at_def a_type_def) apply (clarsimp split:arch_kernel_obj.split_asm Structures_A.kernel_object.split_asm if_splits) apply (drule_tac x = oid in bspec) apply clarsimp apply (clarsimp simp:obj_bits_def arch_kobj_size_def pt_bits_def pageBits_def) apply (simp add:is_aligned_neg_mask_eq) done lemma invalidateTLB_VAASID_underlying_memory[wp]: "\\ms. underlying_memory ms = m\ invalidateTLB_VAASID word \\rv ms. underlying_memory ms = m\" apply (clarsimp simp: invalidateTLB_VAASID_def, wp) done lemma dcorres_flush_page: "dcorres dc \ \ (return x) (flush_page aa a b word)" apply (rule corres_dummy_return_r) apply (rule dcorres_symb_exec_r[OF corres_free_return[where P=\ and P'=\]]) apply wp apply (simp add:flush_page_def) apply wp apply (rule dcorres_to_wp[OF dcorres_set_vm_root]) apply wp apply clarsimp apply (wp do_machine_op_wp, clarsimp) apply (wp) apply (simp add:load_hw_asid_def) apply wp apply (clarsimp simp:set_vm_root_for_flush_def) apply (wp do_machine_op_wp|clarsimp simp:set_current_asid_def get_hw_asid_def)+ apply (wpc) apply wp apply (rule hoare_conjI,rule hoare_drop_imp) apply (wp do_machine_op_wp|clarsimp simp:load_hw_asid_def)+ apply (wpc|wp)+ apply (rule_tac Q="\rv s. transform s = cs" in hoare_strengthen_post) apply (wp|clarsimp)+ done lemma dcorres_flush_table: "dcorres dc \ \ (return x) (flush_table aa a b word)" apply (rule corres_dummy_return_r) apply (rule dcorres_symb_exec_r[OF corres_free_return[where P=\ and P'=\]]) apply wp apply (simp add:flush_table_def) apply wp apply (rule dcorres_to_wp[OF dcorres_set_vm_root]) apply wp apply clarsimp apply (wp do_machine_op_wp|clarsimp)+ apply (clarsimp simp:load_hw_asid_def) apply wp apply (clarsimp simp:set_vm_root_for_flush_def) apply (wp do_machine_op_wp|clarsimp simp:set_current_asid_def get_hw_asid_def)+ apply wpc apply wp apply (rule hoare_conjI,rule hoare_drop_imp) apply (wp do_machine_op_wp|clarsimp simp:load_hw_asid_def)+ apply (wpc|wp)+ apply (rule_tac Q="\rv s. transform s = cs" in hoare_strengthen_post) apply (wp|clarsimp)+ done lemma flush_table_exec: "\dcorres dc R (Q rv) h (g rv); \P\ flush_table aa a b word \Q\\\dcorres dc R P h ((flush_table aa a b word) >>= g)" apply (rule corres_dummy_return_pl) apply (rule corres_guard_imp) apply (rule corres_split[OF _ dcorres_flush_table]) apply (simp|wp)+ done lemma transform_cap_not_new_invented: "transform_cap z \ cdl_cap.PageTableCap word Fake asid" by (auto simp:transform_cap_def split:arch_cap.splits cap.splits) lemma page_table_not_idle: "\valid_idle s;page_table_at a s\ \ not_idle_thread a s" apply (clarsimp simp:obj_at_def valid_idle_def st_tcb_at_def) apply (clarsimp simp:a_type_def not_idle_thread_def split:arch_kernel_obj.splits Structures_A.kernel_object.split_asm if_splits arch_kernel_object.splits) done lemma page_directory_not_idle: "\valid_idle s;page_directory_at a s\ \ not_idle_thread a s" apply (clarsimp simp:obj_at_def valid_idle_def st_tcb_at_def) apply (clarsimp simp:a_type_def not_idle_thread_def split:arch_kernel_obj.splits Structures_A.kernel_object.split_asm if_splits arch_kernel_object.splits) done lemma page_table_at_rev: "\kheap s a = Some (ArchObj (arch_kernel_obj.PageTable fun))\ \ page_table_at a s" apply (clarsimp simp:obj_at_def valid_idle_def st_tcb_at_def) apply (clarsimp simp:a_type_def split:arch_kernel_obj.splits Structures_A.kernel_object.split_asm if_splits arch_kernel_object.splits) done lemma page_directory_at_rev: "\kheap s a = Some (ArchObj (arch_kernel_obj.PageDirectory fun))\ \ page_directory_at a s" apply (clarsimp simp:obj_at_def valid_idle_def st_tcb_at_def) apply (clarsimp simp:a_type_def split:arch_kernel_obj.splits Structures_A.kernel_object.split_asm if_splits arch_kernel_object.splits) done lemma mask_pd_bits_less': "uint ((ptr::word32) && mask pd_bits >> (2\nat)) < (4096\int)" apply (clarsimp simp:pd_bits_def pageBits_def) using shiftr_less_t2n'[where m = 12 and x ="(ptr && mask 14)" and n =2 ,simplified,THEN iffD1[OF word_less_alt]] apply (clarsimp simp:mask_twice ) done lemma mask_pd_bits_less: "nat (uint ((y::word32) && mask pd_bits >> 2)) < 4096" apply (clarsimp simp:pd_bits_def pageBits_def) apply (rule iffD2[OF nat_less_eq_zless[where z = 4096,simplified]]) apply (simp) using shiftr_less_t2n'[where m = 12 and x ="(y && mask 14)" and n =2 ,simplified,THEN iffD1[OF word_less_alt]] apply (clarsimp simp:mask_twice) done lemma mask_pt_bits_less': "uint (((ptr::word32) && mask pt_bits) >> 2)< 256" apply (clarsimp simp:pt_bits_def pageBits_def) using shiftr_less_t2n'[where m = 8 and x ="(ptr && mask 10)" and n =2 ,simplified,THEN iffD1[OF word_less_alt]] apply (clarsimp simp:mask_twice ) done lemma mask_pt_bits_less: "nat (uint ((y::word32) && mask pt_bits >> 2)) < 256" apply (clarsimp simp:pt_bits_def pageBits_def) apply (rule iffD2[OF nat_less_eq_zless[where z = 256,simplified]]) apply (simp) using shiftr_less_t2n'[where m = 8 and x ="(y && mask 10)" and n =2 ,simplified,THEN iffD1[OF word_less_alt]] apply (clarsimp simp:mask_twice) done definition pd_pt_relation :: "word32\word32\word32\'z::state_ext state\bool" where "pd_pt_relation pd pt offset s \ \fun u v ref. ( kheap s pd = Some (ArchObj (arch_kernel_obj.PageDirectory fun)) \ page_table_at pt s \ fun (ucast (offset && mask pd_bits >> 2)) = ARM_Structs_A.pde.PageTablePDE ref u v \ pt = Platform.ptrFromPAddr ref )" definition pd_section_relation :: "word32\word32\word32\'z::state_ext state\bool" where "pd_section_relation pd pt offset s \ \fun u v ref1 ref2. ( kheap s pd = Some (ArchObj (arch_kernel_obj.PageDirectory fun)) \ fun (ucast (offset && mask pd_bits >> 2)) = ARM_Structs_A.pde.SectionPDE ref1 u ref2 v \ pt = Platform.ptrFromPAddr ref1 )" definition pd_super_section_relation :: "word32\word32\word32\'z::state_ext state\bool" where "pd_super_section_relation pd pt offset s \ \fun u v ref1. ( kheap s pd = Some (ArchObj (arch_kernel_obj.PageDirectory fun)) \ fun (ucast (offset && mask pd_bits >> 2)) = ARM_Structs_A.pde.SuperSectionPDE ref1 u v \ pt = Platform.ptrFromPAddr ref1 )" definition pt_page_relation :: "word32\word32\word32\vmpage_size set\'z::state_ext state\bool" where "pt_page_relation pt page offset S s \ \fun. (kheap s pt = Some (ArchObj (arch_kernel_obj.PageTable fun))) \ (case fun (ucast (offset && mask pt_bits >> 2)) of ARM_Structs_A.pte.LargePagePTE ref fun1 fun2 \ page = Platform.ptrFromPAddr ref \ ARMLargePage \ S | ARM_Structs_A.pte.SmallPagePTE ref fun1 fun2 \ page = Platform.ptrFromPAddr ref \ ARMSmallPage \ S | _ \ False)" lemma slot_with_pt_frame_relation: "\valid_idle s;pt_page_relation a oid y S s\\ (a, nat (uint (y && mask pt_bits >> 2))) \ ((slots_with (\x. \rights sz asid. x = FrameCap oid rights sz Fake asid)) (transform s))" apply (clarsimp simp:pt_page_relation_def) apply (frule page_table_at_rev) apply (frule(1) page_table_not_idle) apply (clarsimp simp:slots_with_def transform_def transform_objects_def restrict_map_def) apply (clarsimp simp:not_idle_thread_def has_slots_def object_slots_def) apply (clarsimp simp:transform_page_table_contents_def transform_pte_def unat_map_def ucast_def) apply (simp add:word_of_int_nat[OF uint_ge_0,simplified] ) apply (clarsimp simp:mask_pt_bits_less split:ARM_Structs_A.pte.split_asm) done lemma below_kernel_base: "ucast (y && mask pd_bits >> 2) \ kernel_mapping_slots \ kernel_pde_mask f (of_nat (unat (y && mask pd_bits >> 2))) = f (of_nat (unat (y && mask pd_bits >> 2)))" apply (clarsimp simp:kernel_pde_mask_def kernel_mapping_slots_def ) apply (simp add:ucast_nat_def[symmetric] unat_def) done lemma slot_with_pd_pt_relation: "\valid_idle s; pd_pt_relation a b y s; ucast (y && mask pd_bits >> 2) \ kernel_mapping_slots\ \ (a, unat (y && mask pd_bits >> 2)) \ (slots_with (\x. \asid. x = cdl_cap.PageTableCap b Fake asid)) (transform s)" apply (clarsimp simp :pd_pt_relation_def) apply (frule page_directory_at_rev) apply (frule(1) page_directory_not_idle) apply (clarsimp simp:transform_def slots_with_def transform_objects_def obj_at_def) apply (clarsimp simp:restrict_map_def a_type_def page_table_not_idle not_idle_thread_def pt_bits_def split:Structures_A.kernel_object.split_asm if_splits arch_kernel_object.splits arch_kernel_obj.splits) apply (clarsimp simp:has_slots_def object_slots_def) apply (clarsimp simp:transform_page_directory_contents_def transform_pde_def unat_map_def below_kernel_base) apply (clarsimp simp:ucast_def) apply (simp add: word_of_int_nat[OF uint_ge_0,simplified] unat_def below_kernel_base) apply (simp add:mask_pd_bits_less) done lemma slot_with_pd_section_relation: "\valid_idle s; pd_super_section_relation a b y s \ pd_section_relation a b y s; ucast (y && mask pd_bits >> 2) \ kernel_mapping_slots\ \ (a, unat (y && mask pd_bits >> 2)) \ (slots_with (\x. \rights sz asid. x = cdl_cap.FrameCap b rights sz Fake asid)) (transform s)" apply (erule disjE) apply (clarsimp simp :pd_super_section_relation_def) apply (frule page_directory_at_rev) apply (frule(1) page_directory_not_idle) apply (clarsimp simp:transform_def slots_with_def transform_objects_def obj_at_def) apply (clarsimp simp:restrict_map_def a_type_def page_table_not_idle not_idle_thread_def pt_bits_def split:Structures_A.kernel_object.split_asm if_splits arch_kernel_object.splits arch_kernel_obj.splits) apply (clarsimp simp:has_slots_def object_slots_def) apply (clarsimp simp:transform_page_directory_contents_def transform_pde_def unat_map_def below_kernel_base) apply (clarsimp simp:ucast_def) apply (simp add: word_of_int_nat[OF uint_ge_0,simplified] unat_def mask_pd_bits_less) apply (clarsimp simp :pd_section_relation_def) apply (frule page_directory_at_rev) apply (frule(1) page_directory_not_idle) apply (clarsimp simp:transform_def slots_with_def transform_objects_def obj_at_def) apply (clarsimp simp:restrict_map_def a_type_def page_table_not_idle not_idle_thread_def pt_bits_def split:Structures_A.kernel_object.split_asm if_splits arch_kernel_object.splits arch_kernel_obj.splits) apply (clarsimp simp:has_slots_def object_slots_def) apply (clarsimp simp:transform_page_directory_contents_def transform_pde_def unat_map_def below_kernel_base) apply (clarsimp simp:ucast_def) apply (simp add: word_of_int_nat[OF uint_ge_0,simplified] unat_def) apply (simp add:mask_pd_bits_less) done lemma opt_cap_page_table:"\valid_idle s;pd_pt_relation a pt_id x s;ucast (x && mask pd_bits >> 2) \ kernel_mapping_slots\\ (opt_cap (a, unat (x && mask pd_bits >> 2) ) (transform s)) = Some (cdl_cap.PageTableCap pt_id Fake None)" apply (clarsimp simp:pd_pt_relation_def opt_cap_def transform_def unat_def slots_of_def opt_object_def) apply (frule page_directory_at_rev) apply (frule(1) page_directory_not_idle) apply (clarsimp simp:transform_objects_def not_idle_thread_def page_directory_not_idle restrict_map_def object_slots_def) apply (clarsimp simp:transform_page_directory_contents_def unat_def[symmetric] unat_map_def | rule conjI )+ apply (clarsimp simp:transform_page_directory_contents_def unat_map_def transform_pde_def) apply (clarsimp simp:below_kernel_base) apply (simp add:word_of_int_nat[OF uint_ge_0,simplified] unat_def ucast_def) apply (simp add:mask_pd_bits_less unat_def) done lemma opt_cap_page:"\valid_idle s;pt_page_relation a pg x S s \\ \f sz. (opt_cap (a, unat (x && mask pt_bits >> 2) ) (transform s)) = Some (cdl_cap.FrameCap pg f sz Fake None)" apply (clarsimp simp:pt_page_relation_def unat_def opt_cap_def transform_def slots_of_def opt_object_def) apply (frule page_table_at_rev) apply (frule(1) page_table_not_idle) apply (clarsimp simp:transform_objects_def not_idle_thread_def page_directory_not_idle restrict_map_def object_slots_def) apply (clarsimp simp:transform_page_table_contents_def unat_map_def split:ARM_Structs_A.pte.split_asm | rule conjI )+ apply (clarsimp simp:transform_page_table_contents_def unat_map_def transform_pte_def) apply (simp add:word_of_int_nat[OF uint_ge_0,simplified] ucast_def mask_pt_bits_less)+ apply (clarsimp simp:transform_page_table_contents_def unat_map_def transform_pte_def) done lemma opt_cap_section: "\valid_idle s;pd_section_relation a pg x s \ pd_super_section_relation a pg x s; ucast (x && mask pd_bits >> 2) \ kernel_mapping_slots\\ \f sz. (opt_cap (a, unat (x && mask pd_bits >> 2) ) (transform s)) = Some (cdl_cap.FrameCap pg f sz Fake None)" unfolding unat_def apply (erule disjE) apply (clarsimp simp: pd_section_relation_def opt_cap_def transform_def slots_of_def opt_object_def) apply (frule page_directory_at_rev) apply (frule(1) page_directory_not_idle) apply (clarsimp simp:transform_objects_def not_idle_thread_def page_directory_not_idle restrict_map_def object_slots_def) apply (clarsimp simp:transform_page_directory_contents_def unat_map_def split:ARM_Structs_A.pte.split_asm | rule conjI)+ apply (clarsimp simp:transform_page_directory_contents_def unat_map_def transform_pde_def unat_def[symmetric] below_kernel_base) apply (simp add:word_of_int_nat[OF uint_ge_0,simplified] ucast_def unat_def mask_pt_bits_less)+ apply (simp add:mask_pd_bits_less) apply (clarsimp simp:pd_super_section_relation_def opt_cap_def transform_def slots_of_def opt_object_def) apply (frule page_directory_at_rev) apply (frule(1) page_directory_not_idle) apply (clarsimp simp:transform_objects_def not_idle_thread_def page_directory_not_idle restrict_map_def object_slots_def) apply (clarsimp simp:transform_page_directory_contents_def unat_map_def split:ARM_Structs_A.pte.split_asm | rule conjI)+ apply (clarsimp simp:transform_page_directory_contents_def unat_map_def transform_pde_def unat_def[symmetric] below_kernel_base) apply (simp add:word_of_int_nat[OF uint_ge_0,simplified] ucast_def unat_def mask_pt_bits_less)+ apply (simp add:mask_pd_bits_less) done lemma opt_object_page_table:"\valid_idle s;kheap s a = Some (ArchObj (arch_kernel_obj.PageTable fun))\ \opt_object a (transform s) = Some (cdl_object.PageTable \cdl_page_table_caps = transform_page_table_contents fun\)" apply (frule page_table_at_rev) apply (frule(1) page_table_not_idle) apply (clarsimp simp:transform_objects_def opt_object_def transform_def not_idle_thread_def restrict_map_def) done lemma opt_object_page_directory:"\valid_idle s;kheap s a = Some (ArchObj (arch_kernel_obj.PageDirectory fun))\ \opt_object a (transform s) = Some (cdl_object.PageDirectory \cdl_page_directory_caps = transform_page_directory_contents fun\)" apply (frule page_directory_at_rev) apply (frule(1) page_directory_not_idle) apply (clarsimp simp:transform_objects_def opt_object_def transform_def not_idle_thread_def restrict_map_def) done lemma remove_cdt_pt_slot_exec: "\dcorres dc \ Q (g ()) f; \s. Q s\ ( (\s. mdb_cte_at (swp (cte_wp_at (op \ cap.NullCap)) s) (cdt s)) and valid_idle and pt_page_relation a pg_id ptr UNIV) s\ \ dcorres dc P Q (remove_parent (a ,aptr) >>= g) f" apply (rule corres_dummy_return_pr) apply (rule corres_guard_imp) apply (rule corres_split[OF _ dummy_remove_cdt_pt_slot]) apply (rule_tac F="rv = ()" in corres_gen_asm) unfolding K_bind_def apply clarsimp apply (assumption) apply (simp|wp)+ apply (drule_tac x = s in meta_spec) apply (clarsimp simp:pt_page_relation_def dest!:page_table_at_rev) done lemma remove_cdt_pd_slot_exec: "\dcorres dc \ Q (g ()) f; \s. Q s\ ((\s. mdb_cte_at (swp (cte_wp_at (op \ cap.NullCap)) s) (cdt s)) and valid_idle and page_directory_at a) s\ \ dcorres dc P Q (remove_parent (a ,aptr) >>= g) f" apply (rule corres_dummy_return_pr) apply (rule corres_guard_imp) apply (rule corres_split[OF _ dummy_remove_cdt_pd_slot]) unfolding K_bind_def apply (simp|wp)+ done lemma remove_cdt_asid_pool_slot_exec: "\dcorres dc \ Q (g ()) f; \s. Q s\ ((\s. mdb_cte_at (swp (cte_wp_at (op \ cap.NullCap)) s) (cdt s)) and valid_idle and asid_pool_at a) s\ \ dcorres dc P Q (remove_parent (a ,aptr) >>= g) f" apply (rule corres_dummy_return_pr) apply (rule corres_guard_imp) apply (rule corres_split[OF _ dummy_remove_cdt_asid_pool_slot]) unfolding K_bind_def apply (simp|wp)+ done lemma dcorres_set_pte_cap: "\ (x::word32) = (ptr && mask pt_bits >> 2);pte_cap = transform_pte a_pte\\ dcorres dc \ (valid_idle and ko_at (ArchObj (arch_kernel_obj.PageTable fun)) a ) (KHeap_D.set_cap (a, unat (ptr && mask pt_bits >> 2)) pte_cap) (KHeap_A.set_object a (ArchObj (arch_kernel_obj.PageTable (fun(ucast (ptr && mask pt_bits >> 2) := a_pte)))))" apply (simp add:KHeap_D.set_cap_def KHeap_A.set_object_def gets_the_def gets_def bind_assoc unat_def) apply (rule dcorres_absorb_get_r) apply (rule dcorres_absorb_get_l) apply (clarsimp simp:obj_at_def opt_object_page_table assert_opt_def has_slots_def object_slots_def) apply (clarsimp simp:KHeap_D.set_object_def simpler_modify_def put_def bind_def corres_underlying_def update_slots_def return_def object_slots_def) apply (rule sym) apply (clarsimp simp:transform_def transform_current_thread_def) apply (rule ext) apply (clarsimp | rule conjI)+ apply (frule page_table_at_rev) apply (frule(1) page_table_not_idle) apply (clarsimp simp:transform_objects_def not_idle_thread_def) apply (rule ext) apply (clarsimp simp:transform_page_table_contents_def transform_pte_def unat_map_def ucast_def) apply (clarsimp simp:word_of_nat mask_pt_bits_less ucast_def) apply (subst (asm) word_of_int_inj) apply (clarsimp simp:mask_pt_bits_less')+ apply (clarsimp simp:uint_nat) apply clarify apply (clarsimp simp: transform_objects_def restrict_map_def map_add_def) done lemma dcorres_delete_cap_simple_set_pt: "dcorres dc \ ((\s. mdb_cte_at (swp (cte_wp_at (op \ cap.NullCap)) s) (cdt s)) and pt_page_relation (ptr && ~~ mask pt_bits) pg_id ptr UNIV and valid_idle and ko_at (ArchObj (arch_kernel_obj.PageTable fun)) (ptr && ~~ mask pt_bits)) (delete_cap_simple (ptr && ~~ mask pt_bits, unat (ptr && mask pt_bits >> 2))) (set_pt (ptr && ~~ mask pt_bits) (fun(ucast (ptr && mask pt_bits >> 2) := ARM_Structs_A.pte.InvalidPTE)))" apply (simp add:delete_cap_simple_def set_pt_def gets_the_def gets_def bind_assoc get_object_def) apply (rule dcorres_absorb_get_l) apply (rule dcorres_absorb_get_r) apply (clarsimp simp:assert_def corres_free_fail split:Structures_A.kernel_object.split_asm arch_kernel_obj.splits) apply (frule opt_cap_page) apply (simp add:)+ apply (clarsimp simp:gets_def assert_opt_def PageTableUnmap_D.is_final_cap_def PageTableUnmap_D.is_final_cap'_def) apply (rule dcorres_absorb_get_l) apply (clarsimp simp: always_empty_slot_def gets_the_def gets_def bind_assoc) apply (rule remove_cdt_pt_slot_exec[where pg_id = pg_id]) apply (rule corres_guard_imp) apply (rule dcorres_set_pte_cap) apply (simp add:transform_pte_def)+ apply clarsimp apply simp done lemma dcorres_unmap_page_table_empty: " dcorres dc \ \ (PageTableUnmap_D.unmap_page_table word) (return a)" apply (simp add:PageTableUnmap_D.unmap_page_table_def) apply (rule corres_symb_exec_l) apply (rule_tac P =\ in select_pick_corres[where x="[]"]) apply (clarsimp simp:mapM_x_def revoke_cap_simple_def sequence_x_def) apply (simp add:validE_def exs_valid_def gets_def in_monad bind_def get_def return_def) apply wp apply clarsimp+ done lemma transform_page_table_contents_upd: "transform_page_table_contents fun(unat (y && mask pt_bits >> 2) \ transform_pte pte) = transform_page_table_contents (fun(ucast ((y::word32) && mask pt_bits >> 2) := pte))" apply (rule ext) apply (clarsimp simp:transform_page_table_contents_def unat_map_def ) apply (clarsimp simp:ucast_nat_def[symmetric]) apply (subgoal_tac "unat (y && mask pt_bits >> 2) < 256") apply (rule conjI|clarsimp)+ apply (drule word_unat.Abs_eqD) apply (simp add: unats_def)+ apply (rule unat_less_helper) apply (subst shiftr_div_2n_w) apply (clarsimp simp:word_size)+ apply (rule word_div_mult,simp) apply (clarsimp simp:pt_bits_def pageBits_def) apply (rule and_mask_less_size[where n = 10,simplified],simp add:word_size) done lemma transform_page_directory_contents_upd: "ucast ((ptr::word32) && mask pd_bits >> 2) \ kernel_mapping_slots \ transform_page_directory_contents f(unat (ptr && mask pd_bits >> 2) \ transform_pde a_pde) = transform_page_directory_contents (f(ucast (ptr && mask pd_bits >> 2) := a_pde))" apply (rule ext) apply (simp (no_asm) add:transform_page_directory_contents_def unat_map_def) apply (simp add:below_kernel_base) apply (clarsimp simp: unat_def mask_pd_bits_less|rule conjI)+ apply (clarsimp simp:kernel_pde_mask_def kernel_mapping_slots_def) apply (clarsimp simp:ucast_nat_def[symmetric]) apply (drule sym) apply (clarsimp simp:unat_def) apply (drule word_unat.Abs_eqD) apply (simp add:unats_def unat_def[symmetric])+ apply (rule unat_less_helper) apply (subst shiftr_div_2n_w,(simp add:word_size)+) apply (rule word_div_mult,simp) apply (clarsimp simp:pt_bits_def pd_bits_def pageBits_def) apply (rule and_mask_less_size[where n = 14,simplified],simp add:word_size) apply simp apply (clarsimp simp:ucast_def word_of_int_nat[OF uint_ge_0,simplified]) done lemma dcorres_set_pde_cap: "\ (x::word32) = (ptr && mask pd_bits >> 2);pde_cap = transform_pde a_pde; ucast (ptr && mask pd_bits >> 2) \ kernel_mapping_slots\\ dcorres dc \ (valid_idle and ko_at (ArchObj (arch_kernel_obj.PageDirectory fun)) a ) (KHeap_D.set_cap (a, unat x) pde_cap) (KHeap_A.set_object a (ArchObj (arch_kernel_obj.PageDirectory (fun(ucast x := a_pde)))))" apply (simp add:KHeap_D.set_cap_def KHeap_A.set_object_def gets_the_def gets_def bind_assoc) apply (rule dcorres_absorb_get_r) apply (rule dcorres_absorb_get_l) apply (clarsimp simp:obj_at_def opt_object_page_directory assert_opt_def has_slots_def object_slots_def) apply (clarsimp simp:KHeap_D.set_object_def simpler_modify_def put_def bind_def corres_underlying_def update_slots_def object_slots_def return_def) apply (clarsimp simp:transform_def transform_current_thread_def) apply (rule ext) apply (clarsimp | rule conjI)+ apply (frule page_directory_at_rev) apply (frule(1) page_directory_not_idle) apply (clarsimp simp:transform_objects_def not_idle_thread_def) apply (rule sym) apply (erule transform_page_directory_contents_upd) apply (clarsimp simp: transform_objects_def restrict_map_def map_add_def) done lemma dcorres_delete_cap_simple_set_pde: " ucast (ptr && mask pd_bits >> 2) \ kernel_mapping_slots \dcorres dc \ ((\s. mdb_cte_at (swp (cte_wp_at (op \ cap.NullCap)) s) (cdt s)) and (pd_pt_relation (ptr && ~~ mask pd_bits) oid ptr or pd_section_relation (ptr && ~~ mask pd_bits) oid ptr or pd_super_section_relation (ptr && ~~ mask pd_bits) oid ptr) and valid_idle and ko_at (ArchObj (arch_kernel_obj.PageDirectory fun)) (ptr && ~~ mask pd_bits)) (delete_cap_simple (ptr && ~~ mask pd_bits, unat (ptr && mask pd_bits >> 2))) (set_pd (ptr && ~~ mask pd_bits) (fun(ucast (ptr && mask pd_bits >> 2) := ARM_Structs_A.pde.InvalidPDE)))" apply (simp add:delete_cap_simple_def set_pd_def gets_the_def gets_def bind_assoc get_object_def) apply (rule dcorres_absorb_get_l) apply (rule dcorres_absorb_get_r) apply (clarsimp simp:assert_def corres_free_fail split:Structures_A.kernel_object.split_asm arch_kernel_obj.splits) apply (erule disjE) apply (frule opt_cap_page_table,simp+) apply (clarsimp simp:gets_def assert_opt_def PageTableUnmap_D.is_final_cap_def PageTableUnmap_D.is_final_cap'_def) apply (rule dcorres_absorb_get_l) apply (clarsimp simp:always_empty_slot_def gets_the_def gets_def bind_assoc) apply (rule remove_cdt_pd_slot_exec) apply (rule corres_guard_imp) apply (rule dcorres_set_pde_cap) apply (simp add:transform_pte_def)+ apply (clarsimp simp:pd_pt_relation_def transform_pde_def)+ apply (rule page_directory_at_rev) apply simp apply (frule opt_cap_section,simp+) apply (clarsimp simp:gets_def assert_opt_def PageTableUnmap_D.is_final_cap_def PageTableUnmap_D.is_final_cap'_def) apply (rule dcorres_absorb_get_l) apply (clarsimp simp:always_empty_slot_def gets_the_def gets_def bind_assoc) apply (rule remove_cdt_pd_slot_exec) apply (rule corres_guard_imp) apply (rule dcorres_set_pde_cap) apply simp+ apply (clarsimp simp:pd_pt_relation_def transform_pde_def)+ apply (rule page_directory_at_rev) apply simp done lemma large_frame_range_helper: "t \ set [0 , 4 .e. 0x3C] \ t < 0x40" apply (clarsimp simp: upto_enum_step_def) apply (subgoal_tac "x < 0x10") apply (subst mult_commute) apply (subst shiftl_t2n[where n =2,simplified,symmetric]) apply (rule shiftl_less_t2n[where m = 6 and n =2,simplified]) apply simp+ apply (rule le_less_trans) apply simp+ done lemma dcorres_unmap_page_single: "dcorres dc \ ((\s. mdb_cte_at (swp (cte_wp_at (op \ cap.NullCap)) s) (cdt s)) and valid_idle and pspace_aligned and pt_page_relation (ptr && ~~ mask pt_bits) pg_id ptr UNIV) (PageTableUnmap_D.unmap_page pg_id) (store_pte ptr ARM_Structs_A.pte.InvalidPTE)" apply (simp add:store_pte_def PageTableUnmap_D.unmap_page_def) apply (simp add:gets_def get_pt_def get_object_def bind_assoc) apply (rule dcorres_absorb_get_l) apply (rule dcorres_absorb_get_r) apply (clarsimp simp:assert_def corres_free_fail split:Structures_A.kernel_object.split_asm arch_kernel_obj.splits) apply (frule_tac slot_with_pt_frame_relation) apply simp apply (clarsimp simp:pt_page_relation_def assert_def) apply (clarsimp split: ARM_Structs_A.pte.split_asm) apply (rule corres_guard_imp) apply (rule_tac x = "[(ptr && ~~ mask pt_bits, nat(uint (ptr && mask pt_bits >> 2))) ]" in select_pick_corres [where P=\ ]) apply (clarsimp simp:mapM_x_def sequence_x_def unat_def[symmetric]) apply (rule_tac pg_id = "Platform.ptrFromPAddr word" in dcorres_delete_cap_simple_set_pt) apply (clarsimp simp:pt_page_relation_def obj_at_def obj_at_def)+ apply (rule corres_guard_imp) apply (rule_tac x = "[(ptr && ~~ mask pt_bits, nat(uint (ptr && mask pt_bits >> 2))) ]" in select_pick_corres [where P=\ ]) apply (clarsimp simp:mapM_x_def sequence_x_def unat_def[symmetric]) apply (rule_tac pg_id = "Platform.ptrFromPAddr word" in dcorres_delete_cap_simple_set_pt) apply (clarsimp simp:pt_page_relation_def obj_at_def obj_at_def)+ done lemma dcorres_unmap_section_single: " ucast (ptr && mask pd_bits >> 2) \ kernel_mapping_slots \ dcorres dc \ ((\s. mdb_cte_at (swp (cte_wp_at (op \ cap.NullCap)) s) (cdt s)) and valid_idle and pspace_aligned and (pd_section_relation (ptr && ~~ mask pd_bits) pg_id ptr or pd_super_section_relation (ptr && ~~ mask pd_bits) pg_id ptr)) (PageTableUnmap_D.unmap_page pg_id) (store_pde ptr ARM_Structs_A.pde.InvalidPDE)" apply (simp add:store_pde_def PageTableUnmap_D.unmap_page_def) apply (simp add:gets_def get_pd_def get_object_def bind_assoc) apply (rule dcorres_absorb_get_l) apply (rule dcorres_absorb_get_r) apply (clarsimp simp:assert_def corres_free_fail split:Structures_A.kernel_object.split_asm arch_kernel_obj.splits) apply (frule_tac slot_with_pd_section_relation) apply fastforce apply simp+ apply (erule disjE) apply (clarsimp simp:pd_section_relation_def assert_def) apply (rule corres_guard_imp) apply (rule_tac x = "[(ptr && ~~ mask pd_bits, nat(uint (ptr && mask pd_bits >> 2))) ]" in select_pick_corres [where P=\ ]) apply (clarsimp simp:mapM_x_def sequence_x_def unat_def[symmetric]) apply (rule_tac oid = "Platform.ptrFromPAddr ref1" in dcorres_delete_cap_simple_set_pde) apply (clarsimp simp:pd_section_relation_def obj_at_def obj_at_def unat_def)+ apply (clarsimp simp:pd_super_section_relation_def assert_def) apply (rule corres_guard_imp) apply (rule_tac x = "[(ptr && ~~ mask pd_bits, nat(uint (ptr && mask pd_bits >> 2))) ]" in select_pick_corres [where P=\ ]) apply (clarsimp simp:mapM_x_def sequence_x_def unat_def[symmetric]) apply (rule_tac oid = "Platform.ptrFromPAddr ref1" in dcorres_delete_cap_simple_set_pde) apply (clarsimp simp:pd_super_section_relation_def obj_at_def obj_at_def unat_def)+ done lemma zip_map_eqv: "(y, x) \ set (zip (map g xs) (map f xs)) = (\t. (y = g t \ x = f t \ t \ set xs))" apply (clarsimp simp:zip_map1 zip_map2) apply (rule iffI) apply fastforce apply (clarsimp simp:set_zip_same) using imageI[where f ="(\(a, b). (a, f b)) \ (\(x, y). (g x, y))",simplified] apply clarify apply (drule_tac x = t in meta_spec) apply (drule_tac x = t in meta_spec) apply (drule_tac x = "Id \ (set xs) \ (set xs) " in meta_spec) apply clarsimp done lemma page_directory_address_eq: "\is_aligned ptr 6; t \ set [0 , 4 .e. 0x3C]\ \ ptr && ~~ mask pd_bits = ptr + t && ~~ mask pd_bits" apply (drule large_frame_range_helper) using mask_lower_twice[where m = 14 and n = 6 and x= ptr,symmetric] apply (clarsimp simp:pd_bits_def pageBits_def pageBits_def) using mask_lower_twice[where m = 14 and n = 6 and x= "ptr+t",symmetric] apply (clarsimp simp:pd_bits_def pageBits_def pageBits_def) apply (subgoal_tac "(ptr && ~~ mask 6) = (ptr + t && ~~ mask 6)") apply simp apply (frule is_aligned_neg_mask_eq) apply simp apply (drule_tac q = t in mask_out_add_aligned) apply (subst(asm) less_mask_eq [THEN mask_eq_x_eq_0[THEN iffD1]], erule order_less_le_trans) apply clarsimp+ done lemma page_table_address_eq: "\is_aligned ptr 6; t \ set [0 , 4 .e. 0x3C]\ \ ptr && ~~ mask pt_bits = ptr + t && ~~ mask pt_bits" apply (drule large_frame_range_helper) using mask_lower_twice[where m = 10 and n = 6 and x= ptr,symmetric] apply (clarsimp simp:pt_bits_def pageBits_def pageBits_def) using mask_lower_twice[where m = 10 and n = 6 and x= "ptr+t",symmetric] apply (clarsimp simp:pt_bits_def pageBits_def pageBits_def) apply (subgoal_tac "(ptr && ~~ mask 6) = (ptr + t && ~~ mask 6)") apply simp apply (frule is_aligned_neg_mask_eq) apply simp apply (drule_tac q = t in mask_out_add_aligned) apply (subst(asm) less_mask_eq [THEN mask_eq_x_eq_0[THEN iffD1]], erule order_less_le_trans) apply clarsimp+ done lemma shiftl_inj_if: "\(shiftl a n) = (shiftl b n); shiftr (shiftl a n) n = a; shiftr (shiftl b n) n = b\ \ a = b" apply (drule arg_cong[where f = "\x. shiftr x n"]) apply (rule box_equals) defer apply (assumption)+ done lemma ucast_inj_mask: "((ucast (x::'a::len word)) :: ('b::len word)) = ((ucast (y::'a::len word)) :: ('b::len word)) \ (x && mask (len_of TYPE('b))) = (y && mask (len_of TYPE('b)))" apply (simp add:ucast_def) apply (simp add:word_ubin.inverse_norm) apply (simp add:word_ubin.eq_norm) apply (simp add:and_mask_bintr) done lemma split_word_noteq_on_mask: "(x \ y) = (x && mask k \ y && mask k \ x && ~~ mask k \ y && ~~ mask k)" apply (rule iffI) using split_word_eq_on_mask[symmetric] apply auto done lemma test_bits_mask: "\x && mask l = y && mask l;na < size x; size x = size y\ \ na x !! na = y !! na" apply (drule word_eqD) apply (auto simp:word_size) done lemma test_bits_neg_mask: "\x && ~~ mask l = y && ~~ mask l;na < size x; size x = size y\ \ l\ na \ x !! na = y !! na" apply (drule word_eqD) apply (auto simp:word_size neg_mask_bang) done lemma mask_compare_imply: "\ (x && mask k >> l) && mask n = (y && mask k >> l) && mask n;size x= size y; k\ size x; l+n \ k; x\y\ \ (x && mask l \y && mask l) \ (x && ~~ mask (l+n)) \ (y && ~~ mask (l+n))" apply (rule ccontr) apply (subgoal_tac "x = y") apply simp apply (rule word_eqI) apply clarsimp apply (case_tac "na na") apply (drule_tac na = na in test_bits_neg_mask) apply clarsimp+ apply (drule_tac na = "na-l" in test_bits_mask) apply (clarsimp simp: linorder_not_le) apply (subst (asm) add_commute[where a = l])+ apply (drule nat_diff_less) apply (clarsimp simp:word_size)+ apply (clarsimp simp:nth_shiftr) apply (auto simp:word_size) done lemma aligned_in_step_up_to: "\x\ set (map (\x. x + ptr) [0 , (2^t) .e. up]);t< WordSetup.word_bits; is_aligned ptr t\ \ is_aligned x t" apply (clarsimp simp:upto_enum_step_def image_def) apply (rule aligned_add_aligned[where n = t]) apply (rule is_aligned_mult_triv2) apply (simp add:WordSetup.word_bits_def)+ done lemma remain_pt_pd_relation: "\is_aligned ptr 2; \a\ys. is_aligned a 2; ptr\ ys\ \ \\s. \y\ys. pt_page_relation (y && ~~ mask pt_bits) pg_id y S s\ store_pte ptr sp \\r s. \y\ys. pt_page_relation (y && ~~ mask pt_bits) pg_id y S s\" apply (rule hoare_vcg_const_Ball_lift) apply (subgoal_tac "ptr\ y") apply (simp add:store_pte_def) apply wp apply (rule_tac Q = "ko_at (ArchObj (arch_kernel_obj.PageTable x)) (ptr && ~~ mask pt_bits) and pt_page_relation (y && ~~ mask pt_bits) pg_id y S" in hoare_vcg_precond_imp) apply (clarsimp simp:set_pt_def) apply wp apply (rule_tac Q = "ko_at (ArchObj (arch_kernel_obj.PageTable x)) (ptr && ~~ mask pt_bits) and pt_page_relation (y && ~~ mask pt_bits) pg_id y S" in hoare_vcg_precond_imp) apply (clarsimp simp:valid_def set_object_def in_monad) apply (drule_tac x= y in bspec,simp) apply (clarsimp simp:pt_page_relation_def dest!: ucast_inj_mask| rule conjI)+ apply (drule mask_compare_imply) apply ((simp add:word_size pt_bits_def pageBits_def is_aligned_mask)+) apply (clarsimp simp:pt_page_relation_def obj_at_def) apply (assumption) apply wp apply (simp add:get_object_def) apply wp apply (clarsimp simp:obj_at_def)+ apply (assumption) apply wp apply (clarsimp simp:obj_at_def pt_page_relation_def)+ done lemma remain_pd_section_relation: "\is_aligned ptr 2; is_aligned y 2; ptr \ y\ \ \\s. pd_section_relation ( y && ~~ mask pd_bits) sid y s\ store_pde ptr sp \\r s. pd_section_relation (y && ~~ mask pd_bits) sid y s\" apply (simp add:store_pde_def) apply wp apply (rule_tac Q = "ko_at (ArchObj (arch_kernel_obj.PageDirectory x)) (ptr && ~~ mask pd_bits) and pd_section_relation (y && ~~ mask pd_bits) sid y " in hoare_vcg_precond_imp) apply (clarsimp simp:set_pd_def) apply wp apply (rule_tac Q = "ko_at (ArchObj (arch_kernel_obj.PageDirectory x)) (ptr && ~~ mask pd_bits) and pd_section_relation (y && ~~ mask pd_bits) sid y " in hoare_vcg_precond_imp) apply (clarsimp simp:valid_def set_object_def in_monad) apply (clarsimp simp:pd_section_relation_def dest!:ucast_inj_mask | rule conjI)+ apply (drule mask_compare_imply) apply (simp add:word_size pd_bits_def pt_bits_def pageBits_def is_aligned_mask)+ apply (clarsimp simp:pt_page_relation_def obj_at_def) apply (assumption) apply wp apply (simp add:get_object_def) apply wp apply (clarsimp simp:obj_at_def)+ apply (assumption) apply wp apply (clarsimp simp:obj_at_def pt_page_relation_def)+ done lemma remain_pd_super_section_relation: "\is_aligned ptr 2; is_aligned y 2; ptr \ y\ \ \\s. pd_super_section_relation ( y && ~~ mask pd_bits) sid y s\ store_pde ptr sp \\r s. pd_super_section_relation (y && ~~ mask pd_bits) sid y s\" apply (simp add:store_pde_def) apply wp apply (rule_tac Q = "ko_at (ArchObj (arch_kernel_obj.PageDirectory x)) (ptr && ~~ mask pd_bits) and pd_super_section_relation (y && ~~ mask pd_bits) sid y " in hoare_vcg_precond_imp) apply (clarsimp simp:set_pd_def) apply wp apply (rule_tac Q = "ko_at (ArchObj (arch_kernel_obj.PageDirectory x)) (ptr && ~~ mask pd_bits) and pd_super_section_relation (y && ~~ mask pd_bits) sid y " in hoare_vcg_precond_imp) apply (clarsimp simp:valid_def set_object_def in_monad) apply (clarsimp simp:pd_super_section_relation_def dest!:ucast_inj_mask | rule conjI)+ apply (drule mask_compare_imply) apply (simp add:word_size pd_bits_def pt_bits_def pageBits_def is_aligned_mask)+ apply (clarsimp simp:pt_page_relation_def obj_at_def) apply (assumption) apply wp apply (simp add:get_object_def) apply wp apply (clarsimp simp:obj_at_def)+ apply (assumption) apply wp apply (clarsimp simp:obj_at_def pt_page_relation_def)+ done lemma remain_pd_either_section_relation: "\\y \ set ys. is_aligned y 2;ptr\ set ys;is_aligned ptr 2\ \ \\s. \y\ set ys. (pd_super_section_relation (y && ~~ mask pd_bits) pg_id y s \ pd_section_relation (y && ~~ mask pd_bits) pg_id y s) \ store_pde ptr ARM_Structs_A.pde.InvalidPDE \\r s. \y\set ys. (pd_super_section_relation (y && ~~ mask pd_bits) pg_id y s \ pd_section_relation (y && ~~ mask pd_bits) pg_id y s)\" apply (rule hoare_vcg_const_Ball_lift) apply (wp hoare_vcg_disj_lift) apply (rule hoare_strengthen_post[OF remain_pd_super_section_relation]) apply fastforce+ apply (rule hoare_strengthen_post[OF remain_pd_section_relation]) apply fastforce+ done lemma is_aligned_less_kernel_base_helper: "\is_aligned (ptr :: word32) 6; ucast (ptr && mask pd_bits >> 2) \ kernel_mapping_slots; x < 0x40 \ \ ucast (x + ptr && mask pd_bits >> 2) \ kernel_mapping_slots" apply (simp add: kernel_mapping_slots_def) apply (simp add: word_le_nat_alt shiftr_20_unat_ucast unat_ucast_pd_bits_shift) apply (fold word_le_nat_alt, unfold linorder_not_le) apply (drule minus_one_helper3[where x=x]) apply (subst add_commute, subst is_aligned_add_or, assumption) apply (erule order_le_less_trans, simp) apply (simp add: word_ao_dist shiftr_over_or_dist) apply (subst less_mask_eq, erule order_le_less_trans) apply (simp add: pd_bits_def pageBits_def) apply (subst is_aligned_add_or[symmetric]) apply (rule_tac n=4 in is_aligned_shiftr) apply (simp add: is_aligned_andI1) apply (rule shiftr_less_t2n) apply (erule order_le_less_trans, simp) apply (rule aligned_add_offset_less) apply (rule_tac n=4 in is_aligned_shiftr) apply (simp add: is_aligned_andI1) apply (simp add: kernel_base_def is_aligned_def) apply assumption apply (rule shiftr_less_t2n) apply (erule order_le_less_trans) apply simp done lemma neg_aligned_less_kernel_base_helper: "\ is_aligned (ptr :: word32) 6; ucast (ptr && mask pd_bits >> 2) \ kernel_mapping_slots; y - ptr < 0x40 \ \ ucast (y && mask pd_bits >> 2) \ kernel_mapping_slots" by (drule(2) is_aligned_less_kernel_base_helper, simp) lemma mapM_Cons_split: "xs \ [] \ (mapM f xs) = (do y \ f (hd xs); ys \ mapM f (tl xs); return (y # ys) od)" by (clarsimp simp:neq_Nil_conv mapM_Cons) lemma dcorres_store_invalid_pde_super_section: "dcorres dc \ (pd_super_section_relation (ptr && ~~ mask pd_bits) pg_id ptr and invs and K (ucast (ptr && mask pd_bits >> 2) \ kernel_mapping_slots)) (delete_cap_simple (ptr && ~~ mask pd_bits, unat (ptr && mask pd_bits >> 2))) (store_pde ptr ARM_Structs_A.pde.InvalidPDE)" apply (simp add:K_def) apply (rule corres_gen_asm2) apply (rule corres_guard_imp) apply (simp add:store_pde_def) apply (rule corres_symb_exec_r) apply (rule dcorres_delete_cap_simple_set_pde[where oid = pg_id]) apply simp apply (wp|simp)+ apply (clarsimp simp: invs_def valid_mdb_def valid_state_def valid_pspace_def) done lemma dcorres_store_invalid_pte: "dcorres dc \ (pt_page_relation (ptr && ~~ mask pt_bits) pg_id ptr UNIV and invs ) (delete_cap_simple (ptr && ~~ mask pt_bits, unat (ptr && mask pt_bits >> 2))) (store_pte ptr ARM_Structs_A.pte.InvalidPTE)" apply (rule corres_guard_imp) apply (simp add:store_pte_def) apply (rule corres_symb_exec_r) apply (rule dcorres_delete_cap_simple_set_pt[where pg_id = pg_id]) apply (wp|simp)+ apply (clarsimp simp: invs_def valid_mdb_def valid_state_def valid_pspace_def) done lemma dcorres_store_pde_non_sense: "dcorres dc \ (valid_idle and (\s. \f. ko_at (ArchObj (arch_kernel_obj.PageDirectory f)) (slot && ~~ mask pd_bits) s \ (f (ucast (slot && mask pd_bits >> 2)) = pde))) (return a) (store_pde slot pde)" apply (simp add:store_pde_def) apply (simp add:get_pd_def bind_assoc get_object_def set_pd_def gets_def) apply (rule dcorres_absorb_get_r) apply (clarsimp simp add:assert_def corres_free_fail split:Structures_A.kernel_object.splits arch_kernel_obj.splits) apply (rule dcorres_absorb_get_r) apply (clarsimp simp:corres_free_fail split:Structures_A.kernel_object.splits arch_kernel_obj.splits) apply (simp add:set_object_def put_def) apply (rule dcorres_absorb_get_r) apply (simp add:corres_underlying_def return_def transform_def transform_current_thread_def) apply (frule page_directory_at_rev) apply (drule(1) page_directory_not_idle[rotated]) apply (rule ext)+ apply (simp add:transform_objects_def not_idle_thread_def obj_at_def) done lemma dcorres_store_pte_non_sense: "dcorres dc \ (valid_idle and (\s. \f. ko_at (ArchObj (arch_kernel_obj.PageTable f)) (slot && ~~ mask pt_bits) s \ (f (ucast (slot && mask pt_bits >> 2)) = pte))) (return a) (store_pte slot pte)" apply (simp add:store_pte_def) apply (simp add:get_pt_def bind_assoc get_object_def set_pt_def gets_def) apply (rule dcorres_absorb_get_r) apply (clarsimp simp add:assert_def corres_free_fail split:Structures_A.kernel_object.splits arch_kernel_obj.splits) apply (rule dcorres_absorb_get_r) apply (clarsimp simp:corres_free_fail split:Structures_A.kernel_object.splits arch_kernel_obj.splits) apply (simp add:set_object_def put_def) apply (rule dcorres_absorb_get_r) apply (simp add:corres_underlying_def return_def transform_def transform_current_thread_def) apply (frule page_table_at_rev) apply (drule(1) page_table_not_idle[rotated]) apply (rule ext)+ apply (simp add:transform_objects_def not_idle_thread_def obj_at_def) done lemma store_pde_non_sense_wp: "\\s. (\f. ko_at (ArchObj (arch_kernel_obj.PageDirectory f)) (slot && ~~ mask pd_bits) s \ (\slot\set xs. f (ucast (slot && mask pd_bits >> 2)) = ARM_Structs_A.pde.InvalidPDE)) \ store_pde x ARM_Structs_A.pde.InvalidPDE \\r s. (\f. ko_at (ArchObj (arch_kernel_obj.PageDirectory f)) (slot && ~~ mask pd_bits) s \ (\slot\set xs. f (ucast (slot && mask pd_bits >> 2)) = ARM_Structs_A.pde.InvalidPDE))\" apply (simp add:store_pde_def get_object_def get_pde_def set_pd_def set_object_def) apply wp apply (clarsimp simp:obj_at_def split:Structures_A.kernel_object.splits arch_kernel_object.splits) done lemma dcorres_store_invalid_pde_tail_super_section: "dcorres dc \ (valid_idle and (\s. \f. ko_at (ArchObj (arch_kernel_obj.PageDirectory f)) (slot && ~~ mask pd_bits) s \ (\slot\ set slots. f (ucast (slot && mask pd_bits >> 2)) = ARM_Structs_A.pde.InvalidPDE)) and K (\sl\ set slots. sl && ~~ mask pd_bits = slot && ~~ mask pd_bits)) (return a) (mapM (swp store_pde ARM_Structs_A.pde.InvalidPDE) slots)" proof (induct slots arbitrary:a) case Nil show ?case by (simp add:mapM_Nil) next case (Cons x xs) show ?case apply (rule corres_guard_imp) apply (simp add:mapM_Cons dc_def[symmetric]) apply (rule corres_dummy_return_l) apply (rule corres_split[OF _ dcorres_store_pde_non_sense]) apply (rule corres_dummy_return_l) apply (rule corres_split[OF _ Cons.hyps[unfolded swp_def]]) apply (rule corres_free_return[where P=\ and P'=\]) apply wp apply simp apply (wp store_pde_non_sense_wp) apply simp apply (clarsimp simp:obj_at_def) done qed lemma store_pte_non_sense_wp: "\\s. (\f. ko_at (ArchObj (arch_kernel_obj.PageTable f)) (slot && ~~ mask pt_bits) s \ (\slot\set xs. f (ucast (slot && mask pt_bits >> 2)) = ARM_Structs_A.pte.InvalidPTE)) \ store_pte x ARM_Structs_A.pte.InvalidPTE \\r s. (\f. ko_at (ArchObj (arch_kernel_obj.PageTable f)) (slot && ~~ mask pt_bits) s \ (\slot\set xs. f (ucast (slot && mask pt_bits >> 2)) = ARM_Structs_A.pte.InvalidPTE))\" apply (simp add:store_pte_def get_object_def get_pte_def set_pt_def set_object_def) apply wp apply (clarsimp simp:obj_at_def split:Structures_A.kernel_object.splits arch_kernel_object.splits) done lemma dcorres_store_invalid_pte_tail_large_page: "dcorres dc \ (valid_idle and (\s. \f. ko_at (ArchObj (arch_kernel_obj.PageTable f)) (slot && ~~ mask pt_bits) s \ (\slot\ set slots. f (ucast (slot && mask pt_bits >> 2)) = ARM_Structs_A.pte.InvalidPTE)) and K (\sl\ set slots. sl && ~~ mask pt_bits = slot && ~~ mask pt_bits)) (return a) (mapM (swp store_pte ARM_Structs_A.pte.InvalidPTE) slots)" proof (induct slots arbitrary:a) case Nil show ?case by (simp add:mapM_Nil) next case (Cons x xs) show ?case apply (rule corres_guard_imp) apply (simp add:mapM_Cons dc_def[symmetric]) apply (rule corres_dummy_return_l) apply (rule corres_split[OF _ dcorres_store_pte_non_sense]) apply (rule corres_dummy_return_l) apply (rule corres_split[OF _ Cons.hyps[unfolded swp_def]]) apply (rule corres_free_return[where P=\ and P'=\]) apply wp apply simp apply (wp store_pte_non_sense_wp) apply simp apply (clarsimp simp:obj_at_def) done qed lemma dcorres_unmap_sections: "\is_aligned ptr 6;ucast (ptr && mask pd_bits >> 2) \ kernel_mapping_slots\ \ dcorres dc \ (invs and valid_pdpt_objs and (pd_super_section_relation (ptr && ~~ mask pd_bits) pg_id ptr)) (PageTableUnmap_D.unmap_page pg_id) (mapM (swp store_pde ARM_Structs_A.pde.InvalidPDE) (map (\x. x + ptr) [0 , 4 .e. 0x3C]))" apply (subst mapM_Cons_split) apply (simp add:upto_enum_step_def upto_enum_def) apply (simp add:store_pte_def PageTableUnmap_D.unmap_page_def) apply (simp add:gets_def get_pt_def get_object_def bind_assoc) apply (rule dcorres_absorb_get_l) apply (simp_all add:exs_valid_def get_def) apply (clarsimp simp:pd_super_section_relation_def) apply (rule corres_guard_imp) apply (rule_tac x = "[?n]" in select_pick_corres[where P = "\"]) apply (simp add:mapM_x_singleton) apply (rule corres_dummy_return_l) apply (rule corres_guard_imp) apply (rule corres_split[OF _ dcorres_store_invalid_pde_super_section]) apply(rule corres_dummy_return_l) apply (rule_tac r'=dc in corres_split[OF corres_free_return[where P=\ and P'=\]]) apply (rule dcorres_store_invalid_pde_tail_super_section[where slot = ptr]) apply wp apply (wp store_pde_non_sense_wp) apply simp apply simp+ apply (simp add: hd_map_simp upto_enum_step_def upto_enum_def) apply clarsimp apply (rule slot_with_pd_section_relation) apply (simp add:invs_valid_idle) apply (clarsimp simp:pd_super_section_relation_def) apply simp apply (simp add:obj_at_def hd_map_simp upto_enum_step_def upto_enum_def pd_super_section_relation_def drop_map) apply (rule conjI,simp) apply (rule conjI,fastforce) apply (subst conj_ac) apply (rule context_conjI) apply (clarsimp simp:tl_map field_simps) apply (subst mask_lower_twice[symmetric,where n = 6]) apply (simp add:pd_bits_def pageBits_def) apply (subst is_aligned_add_helper) apply simp apply (simp add:upto_0_to_n) apply (rule word_less_power_trans_ofnat[where k = 2 and m = 6,simplified]) apply simp apply simp apply simp apply (rule ballI) apply (drule(1) bspec) apply (clarsimp simp:tl_map field_simps upto_0_to_n) apply (drule(1) valid_pdpt_objs_pdD) apply clarsimp apply (rename_tac pd rights attr ref s slot) apply (drule_tac x = "(ucast (ptr + of_nat slot * 4 && mask pd_bits >> 2))" and y = "ucast (ptr && mask pd_bits >> 2)" in valid_entriesD[rotated]) apply (thin_tac "ptr + ?x && ~~ mask pd_bits = ?y") apply (rule ccontr) apply simp apply (drule arg_cong[where f = "ucast::(12 word\word32)"]) apply (drule arg_cong[where f = "\x. shiftl x 2"]) apply (subst (asm) ucast_ucast_len) apply (rule shiftr_less_t2n) apply (rule less_le_trans[OF and_mask_less']) apply (simp add:pd_bits_def pageBits_def) apply (simp add:pd_bits_def pageBits_def) apply (subst (asm) ucast_ucast_len) apply (rule shiftr_less_t2n) apply (rule less_le_trans[OF and_mask_less']) apply (simp add:pd_bits_def pageBits_def) apply (simp add:pd_bits_def pageBits_def) apply (simp add:shiftr_shiftl1) apply (subst (asm) is_aligned_neg_mask_eq[where n = 2]) apply (erule aligned_after_mask[OF aligned_add_aligned]) apply (simp add:shiftl_t2n[symmetric,where n =2, simplified field_simps,simplified] is_aligned_shiftl_self) apply simp apply (subst (asm) is_aligned_neg_mask_eq[where n = 2]) apply (erule aligned_after_mask[OF is_aligned_weaken]) apply simp apply (subst (asm) and_mask_plus) apply simp apply (simp add:pd_bits_def pageBits_def)+ apply (simp add:shiftl_t2n[symmetric,where n =2,simplified field_simps,simplified]) apply (rule shiftl_less_t2n[where m = 6,simplified]) apply (simp add:word_of_nat_less) apply simp apply simp apply (subgoal_tac "0 < (of_nat (slot * 4)::word32)") apply simp apply (rule le_less_trans[OF _ of_nat_mono_maybe[where Y = 0]]) apply fastforce apply simp apply fastforce apply (clarsimp split:if_splits) apply (rule ccontr) apply (erule_tac x = "ucast (ptr + of_nat slot * 4 && mask pd_bits >> 2)" in in_empty_interE) apply (rule non_invalid_in_pde_range) apply simp apply (simp add: ucast_neg_mask) apply (rule arg_cong[where f = ucast]) apply (rule shiftr_eq_neg_mask_eq) apply (simp add:shiftr_shiftr shiftr_over_and_dist) apply (subst aligned_shift') apply (simp add:shiftl_t2n[symmetric,where n =2,simplified field_simps,simplified]) apply (rule shiftl_less_t2n[where m = 6,simplified]) apply (simp add:word_of_nat_less) apply simp+ done lemma pt_page_relation_weaken: "\ pt_page_relation a b c S s; S \ T \ \ pt_page_relation a b c T s" apply (clarsimp simp: pt_page_relation_def) apply (auto split: ARM_Structs_A.pte.split) done lemma dcorres_unmap_pages: "is_aligned ptr 6 \ dcorres dc \ (invs and valid_pdpt_objs and pt_page_relation (ptr && ~~ mask pt_bits) pg_id ptr {ARMLargePage}) (PageTableUnmap_D.unmap_page pg_id) (mapM (swp store_pte ARM_Structs_A.pte.InvalidPTE) (map (\x. x + ptr) [0 , 4 .e. 0x3C]))" apply (subst mapM_Cons_split) apply (simp add:upto_enum_step_def upto_enum_def) apply (simp add: PageTableUnmap_D.unmap_page_def) apply (simp add:gets_def get_pt_def get_object_def bind_assoc) apply (rule dcorres_absorb_get_l) apply (clarsimp simp:pt_page_relation_def) apply (simp split:ARM_Structs_A.pte.split_asm) apply (rule corres_guard_imp) apply (rule_tac x = "[?n]" in select_pick_corres[where P = "\"]) apply (simp add:mapM_x_singleton) apply (rule corres_dummy_return_l) apply (rule corres_guard_imp) apply (rule corres_split[OF _ dcorres_store_invalid_pte]) apply(rule corres_dummy_return_l) apply (rule_tac r'=dc in corres_split[OF corres_free_return[where P=\ and P'=\]]) apply (rule dcorres_store_invalid_pte_tail_large_page[where slot = ptr]) apply wp apply (wp store_pte_non_sense_wp) apply simp apply simp+ apply (simp add: hd_map_simp upto_enum_step_def upto_enum_def) apply (clarsimp simp:unat_def) apply (rule slot_with_pt_frame_relation) apply (simp add:invs_valid_idle) apply (fastforce simp:pt_page_relation_def) apply simp apply (simp add:obj_at_def hd_map_simp upto_enum_step_def upto_enum_def pt_page_relation_def) apply (rule conjI,simp) apply (rule conjI,fastforce) apply (subst conj_ac) apply (rule context_conjI) apply (clarsimp simp:tl_map drop_map) apply (simp add:field_simps) apply (subst mask_lower_twice[symmetric,where n = 6]) apply (simp add:pt_bits_def pageBits_def) apply (subst is_aligned_add_helper) apply simp apply (simp add:upto_0_to_n) apply (rule word_less_power_trans_ofnat[where k = 2 and m = 6,simplified]) apply simp apply simp apply simp apply clarsimp apply (drule(1) bspec) apply (clarsimp simp:tl_map drop_map upto_0_to_n) apply (simp add: field_simps) apply (drule(1) valid_pdpt_objs_ptD,clarify) apply (drule_tac x = "(ucast (ptr + of_nat x * 4 && mask pt_bits >> 2))" and y = "ucast (ptr && mask pt_bits >> 2)" in valid_entriesD[rotated]) apply (thin_tac "ptr + ?x && ~~ mask pt_bits = ?y") apply (rule ccontr) apply simp apply (drule arg_cong[where f = "ucast::(word8\word32)"]) apply (drule arg_cong[where f = "\x. shiftl x 2"]) apply (subst (asm) ucast_ucast_len) apply (rule shiftr_less_t2n) apply (rule less_le_trans[OF and_mask_less']) apply (simp add:pt_bits_def pageBits_def) apply (simp add:pt_bits_def pageBits_def) apply (subst (asm) ucast_ucast_len) apply (rule shiftr_less_t2n) apply (rule less_le_trans[OF and_mask_less']) apply (simp add:pt_bits_def pageBits_def) apply (simp add:pt_bits_def pageBits_def) apply (simp add:shiftr_shiftl1) apply (subst (asm) is_aligned_neg_mask_eq[where n = 2]) apply (erule aligned_after_mask[OF aligned_add_aligned]) apply (simp add:shiftl_t2n[symmetric,where n =2, simplified field_simps,simplified] is_aligned_shiftl_self) apply simp apply (subst (asm) is_aligned_neg_mask_eq[where n = 2]) apply (erule aligned_after_mask[OF is_aligned_weaken]) apply simp apply (subst (asm) and_mask_plus) apply simp apply (simp add:pt_bits_def pageBits_def)+ apply (simp add:shiftl_t2n[symmetric,where n =2,simplified field_simps,simplified]) apply (rule shiftl_less_t2n[where m = 6,simplified]) apply (simp add:word_of_nat_less) apply simp apply simp apply (subgoal_tac "0 < (of_nat (x * 4)::word32)") apply simp apply (rule le_less_trans[OF _ of_nat_mono_maybe[where Y = 0]]) apply fastforce apply simp apply fastforce apply (clarsimp split:if_splits) apply (rule ccontr) apply (erule_tac x = "ucast (ptr + of_nat x * 4 && mask pt_bits >> 2)" in in_empty_interE) apply (rule non_invalid_in_pte_range) apply simp apply (simp add: ucast_neg_mask) apply (rule arg_cong[where f = ucast]) apply (rule shiftr_eq_neg_mask_eq) apply (simp add:shiftr_shiftr shiftr_over_and_dist) apply (subst aligned_shift') apply (simp add:shiftl_t2n[symmetric,where n =2,simplified field_simps,simplified]) apply (rule shiftl_less_t2n[where m = 6,simplified]) apply (simp add:word_of_nat_less) apply simp+ done lemma dcorres_unmap_page_table_store_pde: "ucast (ptr && mask pd_bits >> 2) \ kernel_mapping_slots \ dcorres dc \ ((\s. mdb_cte_at (swp (cte_wp_at (op \ cap.NullCap)) s) (cdt s)) and valid_idle and pd_pt_relation (ptr && ~~ mask pd_bits) pt_id ptr ) (PageTableUnmap_D.unmap_page_table pt_id) (store_pde ptr ARM_Structs_A.pde.InvalidPDE)" apply (clarsimp simp:PageTableUnmap_D.unmap_page_table_def store_pde_def bind_assoc) apply (simp add:gets_def) apply (rule dcorres_absorb_get_l) apply (simp add:get_pd_def) apply (clarsimp simp:get_object_def gets_def bind_assoc) apply (rule dcorres_absorb_get_r) apply (frule_tac slot_with_pd_pt_relation) apply simp+ apply (clarsimp simp:pd_pt_relation_def assert_def) apply (rule corres_guard_imp) apply (rule_tac x = "[(ptr && ~~ mask pd_bits, nat(uint (ptr && mask pd_bits >> 2))) ]" in select_pick_corres[where P=\ ]) apply (clarsimp simp:mapM_x_def sequence_x_def unat_def[symmetric]) apply (rule_tac oid = "Platform.ptrFromPAddr ref" in dcorres_delete_cap_simple_set_pde) apply clarsimp apply(clarsimp simp:pd_pt_relation_def unat_def obj_at_def)+ done lemma (in pspace_update_eq) pd_pt_relation_update[iff]: "pd_pt_relation a b c (f s) = pd_pt_relation a b c s" by (simp add: pd_pt_relation_def pspace) crunch cdt[wp] :flush_page "\s. P (cdt s)" (wp: crunch_wps simp:crunch_simps) crunch valid_idle[wp]: flush_page "valid_idle" (wp: crunch_wps simp:crunch_simps) lemma mdb_cte_at_flush_page[wp]: "\\s. mdb_cte_at (swp (cte_wp_at (op \ cap.NullCap)) s) (cdt s)\ flush_page a b c d \\_ s. mdb_cte_at (swp (cte_wp_at (op \ cap.NullCap)) s) (cdt s)\" apply (simp add:mdb_cte_at_def) apply (simp only: imp_conv_disj) apply (wp hoare_vcg_all_lift hoare_vcg_disj_lift) done crunch pd_pt_relation[wp]: flush_table "pd_pt_relation a b c" (wp: crunch_wps simp: crunch_simps) crunch valid_idle[wp]: flush_table "valid_idle" (wp: crunch_wps simp:crunch_simps) crunch valid_idle[wp]: page_table_mapped "valid_idle" (wp: crunch_wps simp:crunch_simps) crunch valid_idle[wp]: invalidate_asid_entry "valid_idle" (wp: crunch_wps simp:crunch_simps) crunch valid_idle[wp]: flush_space "valid_idle" (wp: crunch_wps simp:crunch_simps) lemma page_table_mapped_stable[wp]: "\op = s\ page_table_mapped a b w \\r. op = s\" apply (simp add:page_table_mapped_def) apply (wp|wpc)+ apply (simp add:get_pde_def) apply wp apply (simp add:find_pd_for_asid_def) apply (wp|wpc)+ apply clarsimp done lemma eqv_imply_stable: assumes "\cs. \op = cs\ f \\r. op = cs\" shows "\P\ f \\r. P\" using assms apply (fastforce simp:valid_def) done lemma check_mapping_pptr_pt_relation: "\\s. vmpage_size \ S\ check_mapping_pptr w vmpage_size (Inl b) \\r s. r \ pt_page_relation (b && ~~ mask pt_bits) w b S s\" apply (simp add:check_mapping_pptr_def get_pte_def) apply (rule hoare_pre, wp get_pte_wp) apply (clarsimp simp: obj_at_def) apply (clarsimp simp: a_type_def pt_page_relation_def split: Structures_A.kernel_object.split_asm split_if_asm arch_kernel_obj.split_asm) apply (simp split: ARM_Structs_A.pte.split_asm) done lemma check_mapping_pptr_section_relation: "\\\ check_mapping_pptr w ARMSection (Inr (lookup_pd_slot rv' b)) \\rv s. rv \ pd_section_relation (lookup_pd_slot rv' b && ~~ mask pd_bits) w (lookup_pd_slot rv' b) s\" apply (rule hoare_vcg_precond_imp) apply (simp add:check_mapping_pptr_def) apply (wp get_pde_wp) apply (clarsimp simp: obj_at_def) apply (clarsimp simp: a_type_def pd_section_relation_def pd_super_section_relation_def split: Structures_A.kernel_object.split_asm split_if_asm arch_kernel_obj.split_asm ARM_Structs_A.pde.split_asm) done lemma check_mapping_pptr_super_section_relation: "\\\ check_mapping_pptr w ARMSuperSection (Inr (lookup_pd_slot rv' b)) \\rv s. rv \ pd_super_section_relation (lookup_pd_slot rv' b && ~~ mask pd_bits) w (lookup_pd_slot rv' b) s\" apply (rule hoare_vcg_precond_imp) apply (simp add:check_mapping_pptr_def) apply (wp get_pde_wp) apply (clarsimp simp: obj_at_def) apply (clarsimp simp: a_type_def pd_section_relation_def pd_super_section_relation_def split: Structures_A.kernel_object.split_asm split_if_asm arch_kernel_obj.split_asm ARM_Structs_A.pde.split_asm) done lemma lookup_pt_slot_aligned: "\invs and \\ pd and K (is_aligned pd pd_bits \ is_aligned vptr 16 \ vptr < kernel_base)\ lookup_pt_slot pd vptr \\rb s. is_aligned rb 6\, -" apply (rule hoare_gen_asmE)+ apply (rule hoare_pre, rule hoare_post_imp_R, rule lookup_pt_slot_cap_to) apply auto done lemma get_pde_pd_relation: "\P\ get_pde x \\r s. \f. ko_at (ArchObj (arch_kernel_obj.PageDirectory f)) (x && ~~ mask pd_bits) s \ r = f (ucast (x && mask pd_bits >> 2))\" apply (simp add:get_pde_def) apply wp apply (clarsimp simp:obj_at_def) done lemma pd_pt_relation_page_table_mapped_wp: "\page_table_at w\ page_table_mapped a b w \\r s. (case r of Some pd \ pd_pt_relation (lookup_pd_slot pd b && ~~ mask pd_bits) w (lookup_pd_slot pd b) s | _ \ True)\" apply (simp add:page_table_mapped_def) apply wp apply wpc apply (clarsimp simp:validE_def valid_def return_def returnOk_def) apply wp apply simp apply (simp add:get_pde_def) apply wp apply (simp add:validE_def) apply (rule hoare_strengthen_post[where Q="\rv. page_table_at w"]) apply wp apply (clarsimp,rule conjI) apply fastforce apply (clarsimp simp:pd_pt_relation_def obj_at_def) done lemma hoare_post_Some_conj: "\ \P\f\\r s. case r of Some a \ Q a s | _ \ S \; \P\f\\r s. case r of Some a \ R a s | _ \ S \ \ \\P\f\\r s. case r of Some a \ Q a s \ R a s | _ \ S\" apply (clarsimp simp:valid_def) apply (drule_tac x = s in spec)+ apply clarsimp apply (drule_tac x= "(a,b)" in bspec,simp)+ apply (clarsimp split:option.splits) done lemma cleanByVA_PoU_underlying_memory[wp]: " \\m'. underlying_memory m' = m\ cleanByVA_PoU w q \\_ m'. underlying_memory m' = m\" apply(clarsimp simp: cleanByVA_PoU_def, wp) done lemma dcorres_unmap_page_table: "\a \ mask asid_bits ; b < kernel_base ; vmsz_aligned b ARMSection\ \ dcorres dc \ (invs and valid_cap (cap.ArchObjectCap (arch_cap.PageTableCap w (Some (a, b))))) (PageTableUnmap_D.unmap_page_table w) (ArchVSpace_A.unmap_page_table a b w)" apply (simp add: unmap_page_table_def) apply (rule dcorres_expand_pfx) apply (rule_tac Q'="\r. op = s' and (\s. (case r of Some pd \ is_aligned pd pd_bits \ pd_pt_relation (lookup_pd_slot pd b && ~~ mask pd_bits) w (lookup_pd_slot pd b) s | _ \ True))" in corres_symb_exec_r) apply (clarsimp split:option.splits | rule conjI)+ apply (rule corres_guard_imp[OF dcorres_unmap_page_table_empty]) apply clarsimp+ apply (rule dcorres_expand_pfx) apply (rule corres_guard_imp) apply (rule corres_dummy_return_l) apply (rule corres_split[where r'=dc]) apply clarify apply (rule corres_dummy_return_l) apply (rule corres_split[where r'=dc]) apply (rule dcorres_flush_table) apply (clarsimp) apply (rule dcorres_machine_op_noop) apply wp apply (simp add:dc_def[symmetric]) apply (rule dcorres_unmap_page_table_store_pde) apply (simp add:less_kernel_base_mapping_slots) apply (wp|simp)+ apply (clarsimp simp:valid_cap_def invs_def valid_state_def valid_pspace_def swp_def valid_mdb_def) apply (wp pd_pt_relation_page_table_mapped_wp | clarsimp)+ apply (simp add:asid_bits_def valid_cap_def invs_def valid_state_def) apply (wp pd_pt_relation_page_table_mapped_wp | clarsimp)+ apply (rule hoare_post_Some_conj) apply (wp page_table_mapped_wp) apply (clarsimp simp:invs_def valid_state_def valid_pspace_def) apply (wp pd_pt_relation_page_table_mapped_wp) apply (wp | clarsimp simp:valid_cap_def)+ done lemma imp_strength: "(A \ (B\C)) \ (B \ (A\C))" by clarsimp lemma cleanCacheRange_PoU_underlying_memory[wp]: "\\ms. underlying_memory ms = m\ cleanCacheRange_PoU a b c \\rv ms. underlying_memory ms = m\" apply (clarsimp simp: cleanCacheRange_PoU_def, wp) done lemma dcorres_unmap_page: notes swp_apply[simp del] shows "dcorres dc \ (invs and valid_pdpt_objs and valid_cap (cap.ArchObjectCap (arch_cap.PageCap word fun vmpage_size (Some (a, b))))) (PageTableUnmap_D.unmap_page word) (ArchVSpace_A.unmap_page vmpage_size a b word)" apply (rule dcorres_expand_pfx) apply (clarsimp simp:valid_cap_def) apply (simp add:ArchVSpace_A.unmap_page_def) apply (case_tac vmpage_size) apply simp_all apply (rule corres_guard_imp) apply (clarsimp simp: bindE_assoc) apply (rule dcorres_symb_exec_r_catch[OF dcorres_unmap_page_empty]) apply (rule dcorres_symb_exec_r_catch[OF dcorres_unmap_page_empty]) apply (rule dcorres_symb_exec_r_catch[OF dcorres_unmap_page_empty]) apply (clarsimp simp: catch_def bindE_def liftE_def bind_assoc lift_def throwError_def split: sum.splits) apply (rule corres_guard_imp) apply (rule corres_dummy_return_l) apply (rule corres_split[OF _ dcorres_unmap_page_single]) apply (rule dcorres_symb_exec_r) apply (rule dcorres_flush_page) apply (wp do_machine_op_wp | clarsimp)+ apply (assumption) apply wp apply (simp add: imp_conjR) apply ((wp check_mapping_pptr_pt_relation | wp_once hoare_drop_imps)+)[1] apply (simp del: swp_apply | wp lookup_pt_slot_inv)+ apply (simp del: swp_apply | wp lookup_pt_slot_inv | safe)+ (*LargePage*) apply (rule corres_guard_imp) apply (clarsimp simp: bindE_assoc) apply (rule dcorres_symb_exec_r_catch[OF dcorres_unmap_page_empty]) apply (rule dcorres_symb_exec_r_catch'[OF dcorres_unmap_page_empty]) apply (rule dcorres_symb_exec_r_catch[OF dcorres_unmap_page_empty]) apply (rule_tac F="is_aligned rv'a 6 " in corres_gen_asm2) apply (clarsimp simp: catch_def bindE_def liftE_def bind_assoc lift_def throwError_def split: sum.splits) apply (clarsimp simp:liftE_def catch_def is_aligned_mask[symmetric]) apply (rule corres_guard_imp) apply (rule corres_dummy_return_l) apply (rule corres_split[OF _ dcorres_unmap_pages]) apply (rule dcorres_symb_exec_r) apply (rule dcorres_flush_page) apply (wp do_machine_op_wp | clarsimp)+ apply (assumption) apply wp apply (simp add: imp_conjR) apply ((wp check_mapping_pptr_pt_relation | wp_once hoare_drop_imps)+)[1] apply (clarsimp |wp)+ apply (wp flush_page_invs lookup_pt_slot_inv lookup_pt_slot_aligned) apply (wp | simp)+ apply (clarsimp)+ apply (clarsimp simp:invs_def valid_state_def valid_mdb_def cap_aligned_def vmsz_aligned_def valid_pspace_def) (* Section *) apply (rule corres_guard_imp) apply (clarsimp simp: bindE_assoc) apply (rule dcorres_symb_exec_r_catch[OF dcorres_unmap_page_empty]) apply (rule dcorres_symb_exec_r_catch[OF dcorres_unmap_page_empty]) apply (rule_tac F = "is_aligned rv' pd_bits" in corres_gen_asm2) apply (rule corres_guard_imp) apply (clarsimp simp: catch_def bindE_def liftE_def bind_assoc lift_def throwError_def split: sum.splits) apply (rule corres_dummy_return_l) apply (rule corres_split) apply (rule dcorres_symb_exec_r) apply (rule dcorres_flush_page) apply (wp do_machine_op_wp | clarsimp )+ apply (rule dcorres_unmap_section_single) apply (simp add:less_kernel_base_mapping_slots) apply (simp add:cap_aligned_def) apply wp apply simp apply (assumption) apply (wp|clarsimp)+ apply (simp add: imp_conjR imp_disj1[symmetric] del: imp_disj1) apply ((wp check_mapping_pptr_section_relation hoare_vcg_disj_lift | wp_once hoare_drop_imps)+)[1] apply (wp|clarsimp)+ apply fastforce (*Super Section*) apply (rule corres_guard_imp) apply (rule dcorres_symb_exec_r_catch) apply (rule dcorres_unmap_page_empty) apply (clarsimp simp: bindE_assoc) apply (rule dcorres_symb_exec_r_catch'[OF dcorres_unmap_page_empty]) apply (rule_tac F="is_aligned rv' 6 \ is_aligned rv' pd_bits" in corres_gen_asm2) apply (clarsimp simp: catch_def bindE_def liftE_def bind_assoc lift_def throwError_def split: sum.splits) apply (clarsimp simp:liftE_def catch_def assert_def corres_free_fail) apply (rule corres_guard_imp) apply (rule corres_dummy_return_l) apply (rule corres_split[OF _ dcorres_unmap_sections[where pg_id = word]]) apply (rule dcorres_symb_exec_r) apply (rule dcorres_flush_page) apply (wp do_machine_op_wp | clarsimp)+ apply (simp add:lookup_pd_slot_def) apply (rule aligned_add_aligned) apply simp apply (simp add:vmsz_aligned_def) apply (drule is_aligned_shiftr[where w = b and m = 20 and n = 4,simplified]) apply (rule is_aligned_shiftl[where m = 2 and n = 6 and w = "b>>20"]) apply ((clarsimp simp:WordSetup.word_bits_def)+)[3] apply (simp add:less_kernel_base_mapping_slots) apply (clarsimp simp:cap_aligned_def) apply (wp|clarsimp)+ apply (assumption) apply wp apply (simp add: imp_conjR) apply ((wp check_mapping_pptr_super_section_relation | wp_once hoare_drop_imps)+)[1] apply (wp flush_page_invs|clarsimp)+ apply (rule validE_validE_R) apply (rule hoare_post_impErr[where E = "\r. \"]) apply (rule validE_R_validE[OF find_pd_for_asid_aligned_pd]) apply (rule conjI,erule is_aligned_weaken,simp+) apply (simp add:pd_bits_def pageBits_def) apply wp apply (clarsimp simp:cap_aligned_def invs_def valid_state_def valid_pspace_def) done lemma dcorres_delete_asid_none: "dcorres dc \ \ (CSpace_D.delete_asid x word) (return ())" apply (clarsimp simp:CSpace_D.delete_asid_def) apply (rule corres_alternate2) apply clarsimp done lemma asid_table_transform: "cdl_asid_table (transform s) slot = unat_map (Some \ transform_asid_table_entry \ arm_asid_table (arch_state s)) slot" apply (simp add:transform_def transform_asid_table_def transform_asid_table_entry_def) done lemma dcorres_delete_asid: "dcorres dc \ (valid_idle) (CSpace_D.delete_asid (transform_asid asid) word) (ArchVSpace_A.delete_asid asid word)" apply (clarsimp simp:CSpace_D.delete_asid_def ArchVSpace_A.delete_asid_def) apply (clarsimp simp:gets_def) apply (rule dcorres_absorb_get_r) apply (clarsimp simp:when_def split:option.splits) apply (rule conjI) apply clarsimp apply (rule corres_alternate2) apply clarsimp apply clarsimp apply (rule dcorres_symb_exec_r_strong) apply clarsimp apply (rule conjI) apply clarsimp apply (rule corres_alternate1) apply (rule dcorres_absorb_get_l) apply (drule_tac s="transform s'" in sym) apply (clarsimp simp:when_def asid_table_transform transform_asid_def transform_asid_table_entry_def split:option.splits if_splits) apply (rule dcorres_symb_exec_r_strong) apply (rule dcorres_symb_exec_r_strong) apply (rule corres_guard_imp) apply (rule corres_dummy_return_l) apply (rule corres_split[OF corres_trivial,where r'=dc]) apply (rule dcorres_symb_exec_r[OF dcorres_set_vm_root]) apply wp apply (rule dcorres_set_asid_pool) apply simp apply (clarsimp simp:transform_asid_def) apply (clarsimp simp:transform_asid_pool_entry_def) apply (wp | clarsimp)+ apply simp apply (wp | clarsimp)+ apply (subgoal_tac "valid_idle s \ ko_at (ArchObj (arch_kernel_obj.ASIDPool rv)) a s") apply simp+ apply (wp | clarsimp)+ apply (rule corres_alternate2) apply simp apply (wp | clarsimp)+ done lemma thread_in_thread_cap_not_idle: "\valid_global_refs s;cte_wp_at (op = (cap.ThreadCap ptr)) slot s\ \ not_idle_thread ptr s" apply (rule ccontr) apply (clarsimp simp:valid_cap_def valid_global_refs_def valid_refs_def) apply (case_tac slot) apply (drule_tac x = a in spec) apply (drule_tac x = b in spec) apply (clarsimp simp:cte_wp_at_def not_idle_thread_def) apply (simp add:cap_range_def global_refs_def) done lemma set_cap_set_thread_state_inactive: "dcorres dc \ (not_idle_thread thread and valid_etcbs) (KHeap_D.set_cap (thread, tcb_pending_op_slot) cdl_cap.NullCap) (set_thread_state thread Structures_A.thread_state.Inactive)" apply (clarsimp simp:set_thread_state_def) apply (rule dcorres_absorb_gets_the) apply (rule corres_guard_imp) apply (rule dcorres_rhs_noop_below_True[OF set_thread_state_ext_dcorres]) apply (rule set_pending_cap_corres) apply simp apply (clarsimp dest!:get_tcb_SomeD simp:obj_at_def infer_tcb_pending_op_def) done lemma dcorres_finalise_cap: "cdlcap = transform_cap cap \ dcorres (\r r'. fst r = transform_cap (fst r')) \ (invs and valid_cap cap and valid_pdpt_objs and cte_wp_at (op=cap) slot and valid_etcbs) (CSpace_D.finalise_cap cdlcap final) (CSpace_A.finalise_cap cap final)" apply (case_tac cap) apply (simp_all add:transform_cap_simps when_def) apply clarsimp apply (rule corres_rel_imp) apply (rule corres_guard_imp[OF dcorres_ep_cancel_all]) apply (clarsimp simp:invs_def valid_state_def)+ apply (rule corres_rel_imp) apply (rule corres_guard_imp[OF dcorres_aep_cancel_all]) apply ((clarsimp simp:invs_def valid_state_def)+)[3] apply (simp add:IpcCancel_A.suspend_def bind_assoc) apply clarsimp apply (rule corres_guard_imp) apply (rule corres_split[OF _ finalise_ipc_cancel]) apply (rule corres_split) unfolding K_bind_def apply (rule dcorres_rhs_noop_above_True[OF tcb_sched_action_dcorres[where P=\ and P'=\]]) apply (rule iffD2[OF corres_return[where P=\ and P'=\]]) apply (clarsimp simp:transform_cap_def) apply (rule set_cap_set_thread_state_inactive) apply wp apply (simp add:not_idle_thread_def) apply wp apply (simp+) apply clarsimp apply (drule(1) thread_in_thread_cap_not_idle[OF invs_valid_global_refs]) apply (simp add:not_idle_thread_def) apply clarsimp apply (rule corres_guard_imp) apply (rule corres_split[OF _ dcorres_deleting_irq_handler]) apply (rule iffD2[OF corres_return[where P=\ and P'=\]]) apply (clarsimp simp:transform_cap_def) apply (wp|clarsimp)+ apply (clarsimp simp:assert_def corres_free_fail) apply (case_tac arch_cap) apply (simp_all add: transform_cap_simps arch_finalise_cap_def split:arch_cap.split_asm) apply clarsimp -- arch_cap.ASIDPoolCap apply (rule corres_guard_imp) apply (rule corres_split[OF _ dcorres_delete_asid_pool]) apply (rule iffD2[OF corres_return[where P=\ and P'=\]]) apply (clarsimp simp:transform_cap_def) apply (wp|clarsimp)+ apply (clarsimp split:option.splits | rule conjI)+ -- arch_cap.PageCap apply (rule corres_dummy_return_pr) apply (rule corres_guard_imp) apply (rule corres_split[OF _ dcorres_unmap_page_empty]) unfolding K_bind_def apply (rule iffD2[OF corres_return[where P=\ and P'=\]]) apply (clarsimp simp:transform_cap_def) apply (wp|clarsimp split:)+ apply (rule corres_guard_imp) apply (rule_tac fun1 = "set" in corres_split[OF _ dcorres_unmap_page]) apply (rule iffD2[OF corres_return[where P=\ and P'=\]]) apply (clarsimp simp:transform_cap_def) apply (wp | clarsimp )+ apply (clarsimp split:option.splits | rule conjI)+ apply (rule corres_dummy_return_pr) apply (rule corres_guard_imp) apply (rule corres_split[OF _ dcorres_unmap_page_table_empty]) unfolding K_bind_def apply (rule iffD2[OF corres_return[where P=\ and P'=\]]) apply (clarsimp simp:transform_cap_def) apply (wp|clarsimp)+ --arch_cap.PageTableCap apply (rule dcorres_expand_pfx) apply (rule corres_guard_imp) apply (rule corres_split[OF _ dcorres_unmap_page_table]) apply (rule iffD2[OF corres_return[where P=\ and P'=\]]) apply (clarsimp simp:transform_cap_def) apply ((wp|clarsimp )+)[4] apply (rule iffD1[OF le_mask_iff_lt_2n,THEN iffD2],simp add:word_size asid_bits_def) apply (clarsimp simp:valid_cap_def cap_aligned_def )+ apply (simp add:vmsz_aligned_def) apply (wp|clarsimp)+ apply (rule conjI | clarsimp split:option.splits)+ apply (rule corres_guard_imp) apply (rule corres_split[OF _ dcorres_delete_asid]) apply (rule iffD2[OF corres_return[where P=\ and P'=\]]) apply (clarsimp simp:transform_cap_def) apply (wp|clarsimp split:option.splits)+ done lemma dcorres_splits: "\ T a \ dcorres r P (Q a) f (g a); \ T a \ dcorres r P (Q' a) f (g a)\\ dcorres r P ( (\s. (T a) \ (Q a s)) and (\s. (\ (T a)) \ (Q' a s)) ) f (g a)" apply (case_tac "T a") apply clarsimp+ done lemma get_cap_weak_wp: "\cte_wp_at Q slot\ CSpaceAcc_A.get_cap slot \\rv s. Q rv\" by (clarsimp simp:valid_def cte_wp_at_def) definition remainder_cap :: "bool \ cap \ cap" where "remainder_cap final c\ case c of cap.CNodeCap r bits g \ if final then cap.Zombie r (Some bits) (2 ^ bits) else cap.NullCap | cap.ThreadCap r \ if final then cap.Zombie r None 5 else cap.NullCap | cap.Zombie r b n \ cap.Zombie r b n | cap.ArchObjectCap a \ cap.NullCap | _ \ cap.NullCap" lemma finalise_cap_remainder: "\\\CSpace_A.finalise_cap cap final \\r s. fst (r) = (remainder_cap final cap) \" apply (case_tac cap) apply (simp_all add:CSpace_A.finalise_cap.simps remainder_cap_def) apply (wp|clarsimp)+ apply (fastforce simp:valid_def) apply (simp|clarify)+ apply (wp|clarsimp)+ apply (fastforce simp:valid_def) apply (simp|clarify)+ apply (wp|clarsimp|rule conjI)+ apply (simp add:arch_finalise_cap_def) apply (cases final) apply (case_tac arch_cap) apply (simp_all) apply (wp|clarsimp)+ apply (simp_all split:option.splits) apply (wp | clarsimp | rule conjI)+ apply (case_tac arch_cap) apply simp_all apply (wp|clarsimp split:option.splits | rule conjI)+ done lemma obj_ref_not_idle: "\valid_objs s;valid_global_refs s;cte_at slot s\ \ cte_wp_at (\cap. \x\obj_refs cap. not_idle_thread x s) slot s" apply (simp add:valid_global_refs_def valid_refs_def) apply (case_tac slot) apply clarsimp apply (drule_tac x = a in spec) apply (drule_tac x = b in spec) apply (clarsimp simp:cte_wp_at_def not_idle_thread_def cap_range_def global_refs_def) done lemma singleton_set_eq: "\x = {a}; b\ x\\ b = a" by clarsimp lemma zombies_final_ccontr: "\caps_of_state s p = Some cap; r \ obj_refs cap; is_zombie cap; zombies_final s; caps_of_state s p' = Some cap'\ \ r\ obj_refs cap' \ is_zombie cap' \ p = p'" apply (rule ccontr) apply (case_tac p) apply (clarsimp simp:zombies_final_def) apply (drule_tac x = a in spec,drule_tac x = b in spec) apply (frule caps_of_state_cteD) apply (simp add:cte_wp_at_def) apply (clarsimp simp:IpcCancel_A.is_final_cap'_def) apply (frule_tac a = "(aa,ba)" and b = p' in singleton_set_eq) apply (clarsimp) apply (drule_tac a = "(aa,ba)" and b = p' in singleton_set_eq) apply (clarsimp dest!:caps_of_state_cteD simp:cte_wp_at_def) apply (drule IntI) apply simp+ apply (drule_tac a = "(aa,ba)" and b = "(a,b)" in singleton_set_eq) apply clarsimp apply clarsimp done lemma zombie_cap_has_all: "\valid_objs s;if_unsafe_then_cap s; zombies_final s;valid_global_refs s; caps_of_state s slot = Some (cap.Zombie w option n); (w,x) \ cte_refs (cap.Zombie w option n) f \ \ caps_of_state s (w,x) = None \ caps_of_state s (w,x) = Some cap.NullCap" apply (clarsimp simp:if_unsafe_then_cap_def valid_cap_def split:option.splits) apply (drule_tac x = w in spec,drule_tac x = x in spec) apply (rule ccontr) apply clarsimp apply (clarsimp simp:ex_cte_cap_wp_to_def appropriate_cte_cap_def) apply (drule iffD1[OF cte_wp_at_caps_of_state]) apply clarsimp apply (frule_tac p = slot and p'="(a,b)" in zombies_final_ccontr) apply simp+ apply (simp add:is_zombie_def) apply simp+ apply (case_tac cap) apply simp_all apply (case_tac y) apply simp_all apply (frule_tac p = "(a,b)" in caps_of_state_valid_cap) apply simp apply (frule_tac p = slot in caps_of_state_valid_cap) apply simp apply (clarsimp simp:valid_cap_def tcb_at_def dest!:get_tcb_SomeD) apply (drule_tac p = "(interrupt_irq_node s word,[])" in caps_of_state_cteD) apply (clarsimp simp:cte_wp_at_cases) apply (clarsimp simp:obj_at_def is_tcb_def tcb_cap_cases_def tcb_cnode_index_def to_bl_1 split:if_splits) apply (drule valid_globals_irq_node[OF _ caps_of_state_cteD]) apply simp apply (fastforce simp:cap_range_def) done lemma monadic_trancl_steps: "monadic_rewrite False False \ (monadic_trancl f x) (do y \ monadic_trancl f x; monadic_trancl f y od)" apply (simp add: monadic_rewrite_def monadic_trancl_def bind_def split_def monadic_option_dest_def) apply (safe, simp_all) done lemma monadic_trancl_f: "monadic_rewrite False False \ (monadic_trancl f x) (f x)" apply (simp add: monadic_rewrite_def monadic_trancl_def bind_def split_def monadic_option_dest_def) apply (safe, simp_all) apply (simp add: r_into_rtrancl monadic_option_relation_form_def)+ done lemma monadic_trancl_step: "monadic_rewrite False False \ (monadic_trancl f x) (do y \ f x; monadic_trancl f y od)" apply (rule monadic_rewrite_imp) apply (rule monadic_rewrite_trans) apply (rule monadic_trancl_steps) apply (rule monadic_rewrite_bind_head) apply (rule monadic_trancl_f) apply simp done lemma monadic_trancl_return: "monadic_rewrite False False \ (monadic_trancl f x) (return x)" by (simp add: monadic_rewrite_def monadic_trancl_def monadic_option_dest_def return_def) lemma monadic_rewrite_if_lhs: "\ P \ monadic_rewrite F E Q b a; \ P \ monadic_rewrite F E R c a\ \ monadic_rewrite F E (\s. (P \ Q s) \ (\ P \ R s)) (if P then b else c) a" by (cases P, simp_all) lemma monadic_rewrite_option_case: "\ \y. x = Some y \ monadic_rewrite E F (P x) f (g y); x = None \ monadic_rewrite E F Q f h \ \ monadic_rewrite E F (\s. (\y. x = Some y \ P x s) \ (x = None \ Q s)) f (case x of Some y \ g y | None \ h)" by (cases x, simp_all) lemma rtrancl_idem: assumes S: "S `` T = T" shows "S\<^sup>* `` T = T" proof - note P = eqset_imp_iff[OF S, THEN iffD1, OF ImageI] have Q: "\x y. (x, y) \ S\<^sup>* \ x \ T \ y \ T" by (erule rtrancl.induct, auto dest: P) thus ?thesis by auto qed lemma monadic_trancl_lift_Inl: "monadic_trancl (lift f) (Inl err) = throwError err" apply (rule ext) apply (simp add: throwError_def return_def monadic_trancl_def) apply (subst rtrancl_idem) apply (auto simp: monadic_option_relation_form_def lift_def throwError_def return_def monadic_option_dest_def) done lemma monadic_trancl_preemptible_steps: "monadic_rewrite False False \ (monadic_trancl_preemptible f x) (doE y \ monadic_trancl_preemptible f x; monadic_trancl_preemptible f y odE)" apply (simp add: monadic_trancl_preemptible_def) apply (rule monadic_rewrite_imp) apply (rule monadic_rewrite_trans) apply (rule monadic_trancl_steps) apply (simp add: bindE_def) apply (rule_tac Q="\\" in monadic_rewrite_bind_tail) apply (case_tac x) apply (simp add: lift_def monadic_trancl_lift_Inl) apply (rule monadic_rewrite_refl) apply (simp add: lift_def) apply (rule monadic_rewrite_refl) apply (wp | simp)+ done lemma monadic_trancl_preemptible_f: "monadic_rewrite False False (\_. True) (monadic_trancl_preemptible f x) (f x)" apply (simp add: monadic_trancl_preemptible_def) apply (rule monadic_rewrite_imp) apply (rule monadic_rewrite_trans) apply (rule monadic_trancl_f) apply (simp add: lift_def) apply (rule monadic_rewrite_refl) apply simp done lemmas monadic_rewrite_bindE_head = monadic_rewrite_bindE[OF _ monadic_rewrite_refl hoare_vcg_propE_R] lemma monadic_trancl_preemptible_step: "monadic_rewrite False False \ (monadic_trancl_preemptible f x) (doE y \ f x; monadic_trancl_preemptible f y odE)" apply (rule monadic_rewrite_imp) apply (rule monadic_rewrite_trans) apply (rule monadic_trancl_preemptible_steps) apply (rule monadic_rewrite_bindE_head) apply (rule monadic_trancl_preemptible_f) apply simp done lemma monadic_trancl_preemptible_return: "monadic_rewrite False False (\_. True) (monadic_trancl_preemptible f x) (returnOk x)" apply (simp add: monadic_trancl_preemptible_def) apply (rule monadic_rewrite_imp) apply (rule monadic_rewrite_trans) apply (rule monadic_trancl_return) apply (simp add: returnOk_def) apply (rule monadic_rewrite_refl) apply simp done lemma monadic_rewrite_corres2: "\ monadic_rewrite False E Q a a'; corres_underlying R F r P P' a' c \ \ corres_underlying R F r (P and Q) P' a c" apply (simp add: corres_underlying_def monadic_rewrite_def) apply (erule ballEI, clarsimp) apply (drule(1) bspec, clarsimp) apply (drule spec, drule(1) mp) apply fastforce done lemma dcorres_get_cap_symb_exec: "\ \cap. dcorres r (P cap) (P' cap) f (g cap) \ \ dcorres r (\s. \cap. opt_cap (transform_cslot_ptr slot) s = Some (transform_cap cap) \ P cap s) (\s. fst slot \ idle_thread s \ (\cap. caps_of_state s slot = Some cap \ P' cap s) \ valid_etcbs s) f (do cap \ get_cap slot; g cap od)" apply (rule corres_symb_exec_r[OF _ get_cap_sp]) apply (rule stronger_corres_guard_imp, assumption) apply (clarsimp simp: cte_wp_at_caps_of_state caps_of_state_transform_opt_cap) apply (clarsimp simp: cte_wp_at_caps_of_state) apply (wp | simp)+ done lemma set_cdt_modify: "set_cdt c = modify (\s. s \ cdt := c \)" by (simp add: set_cdt_def modify_def) lemma no_cdt_loop_mloop: "no_mloop m \ m x \ Some x" apply (rule notI) apply (simp add: no_mloop_def cdt_parent_rel_def del: split_paired_All) apply (drule_tac x=x in spec) apply (erule notE, rule r_into_trancl) apply (simp add: is_cdt_parent_def) done lemma set_cdt_list_modify: "set_cdt_list c = modify (\s. s \ cdt_list := c \)" by (simp add: set_cdt_list_def modify_def) lemma swap_cap_corres: "dcorres dc \ (valid_idle and valid_mdb and cte_at slot_a and cte_at slot_b and valid_etcbs and K (slot_a \ slot_b) and not_idle_thread (fst slot_a) and not_idle_thread (fst slot_b)) (swap_cap (transform_cap cap_a) (transform_cslot_ptr slot_a) (transform_cap cap_b) (transform_cslot_ptr slot_b)) (cap_swap cap_a slot_a cap_b slot_b)" proof - note inj_on_insert[iff del] show ?thesis apply (simp add: swap_cap_def cap_swap_def) apply (rule corres_guard_imp) apply (rule corres_split_nor [OF _ set_cap_corres[OF refl refl]]) apply (rule corres_split_nor [OF _ set_cap_corres[OF refl refl]]) apply (simp add: swap_parents_def set_original_def set_cdt_modify gets_fold_into_modify bind_assoc cap_swap_ext_def update_cdt_list_def set_cdt_list_modify) apply (simp add: gets_fold_into_modify modify_modify Fun.swap_def o_def) apply (rule_tac P'="K (slot_a \ slot_b) and cte_at slot_a and cte_at slot_b and (\s. mdb_cte_at (swp cte_at s) (cdt s)) and no_mloop o cdt" and P=\ in corres_modify) apply (clarsimp simp:transform_def transform_current_thread_def transform_asid_table_def transform_objects_def transform_cdt_def split del: split_if) apply (rule sym) apply (subgoal_tac "inj_on transform_cslot_ptr ({slot_a, slot_b} \ dom (cdt s') \ ran (cdt s')) \ cdt s' slot_a \ Some slot_a \ cdt s' slot_b \ Some slot_b") apply (elim conjE) apply (subst map_lift_over_upd, erule subset_inj_on) apply (safe elim!: ranE, simp_all split: split_if_asm, simp_all add: ranI)[1] apply (subst map_lift_over_upd, erule subset_inj_on) apply (safe elim!: ranE, simp_all split: split_if_asm, simp_all add: ranI)[1] apply (subst map_lift_over_if_eq_twice) apply (erule subset_inj_on, fastforce) apply (rule ext) apply (cases slot_a, cases slot_b) apply (simp split del: split_if) apply (intro if_cong[OF refl], simp_all add: map_lift_over_eq_Some inj_on_iff[where f=transform_cslot_ptr] ranI domI)[1] apply (subst subset_inj_on, assumption, fastforce)+ prefer 2 apply (subst subset_inj_on, assumption, fastforce)+ apply (auto simp: map_lift_over_eq_Some inj_on_iff[where f=transform_cslot_ptr] ranI domI intro: map_lift_over_f_eq[THEN iffD2, OF _ refl] elim: subset_inj_on)[2] apply (clarsimp simp: no_cdt_loop_mloop) apply (rule_tac s=s' in transform_cdt_slot_inj_on_cte_at[where P=\]) apply (auto simp: swp_def dest: mdb_cte_atD elim!: ranE)[1] apply (wp set_cap_caps_of_state2 set_cap_idle | simp add: swp_def cte_wp_at_caps_of_state)+ apply clarsimp apply (clarsimp simp: cte_wp_at_caps_of_state valid_mdb_def) apply (safe intro!: mdb_cte_atI) apply (auto simp: swp_def cte_wp_at_caps_of_state not_idle_thread_def dest: mdb_cte_atD elim!: ranE) done qed lemma swap_for_delete_corres: "dcorres dc \ (valid_mdb and valid_idle and not_idle_thread (fst p) and not_idle_thread (fst p') and valid_etcbs and (\_. p \ p')) (swap_for_delete (transform_cslot_ptr p) (transform_cslot_ptr p')) (cap_swap_for_delete p p')" apply (rule corres_gen_asm2) apply (simp add: swap_for_delete_def cap_swap_for_delete_def when_def) apply (rule corres_guard_imp) apply (rule corres_split[OF _ get_cap_corres[OF refl]])+ apply simp apply (rule swap_cap_corres) apply (wp get_cap_wp) apply simp apply (clarsimp simp: cte_wp_at_caps_of_state) done definition "arch_page_vmpage_size cap \ case cap of cap.ArchObjectCap (arch_cap.PageCap _ _ sz _) \ sz | _ \ undefined" lemma set_cap_noop_dcorres3: "dcorres dc \ (cte_wp_at (\cap'. transform_cap cap = transform_cap cap' \ arch_page_vmpage_size cap = arch_page_vmpage_size cap') ptr) (return ()) (set_cap cap ptr)" apply (rule corres_noop, simp_all) apply (simp add: set_cap_def split_def set_object_def) apply (wp get_object_wp | wpc)+ apply (clarsimp simp: obj_at_def) apply (erule cte_wp_atE) apply (clarsimp simp: transform_def transform_current_thread_def transform_objects_def) apply (rule ext) apply (simp add: fun_upd_def[symmetric] del: dom_fun_upd) apply (simp add: restrict_map_def transform_cnode_contents_def fun_eq_iff option_map_join_def map_add_def split: option.split) apply (clarsimp simp: transform_def transform_current_thread_def transform_objects_def fun_eq_iff arch_page_vmpage_size_def) apply (simp add: restrict_map_def transform_cnode_contents_def map_add_def transform_tcb_def fun_eq_iff infer_tcb_pending_op_def split: option.split cong: Structures_A.thread_state.case_cong) apply (subgoal_tac "snd ptr = tcb_cnode_index 4 \ (\ms ns. get_ipc_buffer_words ms (tcb\tcb_ipcframe := cap\) ns = get_ipc_buffer_words ms tcb ns)") apply (simp cong: transform_full_intent_cong) apply (simp add: transform_full_intent_def Let_def get_tcb_message_info_def get_tcb_mrs_def) apply fastforce apply clarsimp apply (simp add: transform_cap_def split: cap.split_asm arch_cap.split_asm split_if_asm, simp_all add: get_ipc_buffer_words_def) done lemma finalise_zombie: "is_zombie cap \ finalise_cap cap final = do assert final; return (cap, None) od" by (clarsimp simp add: is_cap_simps) lemma corres_assert_rhs: "(F \ corres_underlying sr False r P P' f (g ())) \ corres_underlying sr False r P (\s. F \ P' s) f (assert F >>= g)" by (cases F, simp_all add: corres_fail) lemma monadic_rewrite_select_x: "monadic_rewrite F False (\s. x \ S) (select S) (return x)" by (simp add: monadic_rewrite_def return_def select_def) lemmas monadic_rewrite_select_pick_x = monadic_rewrite_bind_head [OF monadic_rewrite_select_x[where x=x], simplified, THEN monadic_rewrite_trans, standard] lemma finalise_cap_zombie': "(case cap of ZombieCap _ \ True | _ \ False) \ CSpace_D.finalise_cap cap fin = do assert fin; return (cap, None) od" by (simp split: cdl_cap.split_asm) lemma corres_use_cutMon: "\ \s. corres_underlying sr fl r P P' f (cutMon (op = s) g) \ \ corres_underlying sr fl r P P' f g" apply atomize apply (simp add: corres_underlying_def cutMon_def fail_def split: split_if_asm) apply (clarsimp simp: split_def) done lemma corres_drop_cutMon: "corres_underlying sr False r P P' f g \ corres_underlying sr False r P P' f (cutMon Q g)" apply (simp add: corres_underlying_def cutMon_def fail_def split: split_if) apply (clarsimp simp: split_def) done lemma corres_drop_cutMon_bind: "corres_underlying sr False r P P' f (g >>= h) \ corres_underlying sr False r P P' f (cutMon Q g >>= h)" apply (simp add: corres_underlying_def cutMon_def fail_def bind_def split: split_if) apply (clarsimp simp: split_def) done lemma corres_drop_cutMon_bindE: "corres_underlying sr False r P P' f (g >>=E h) \ corres_underlying sr False r P P' f (cutMon Q g >>=E h)" apply (simp add: bindE_def) apply (erule corres_drop_cutMon_bind) done lemma corres_cutMon: "\ \s. Q s \ corres_underlying sr False r P P' f (cutMon (op = s) g) \ \ corres_underlying sr False r P P' f (cutMon Q g)" apply atomize apply (simp add: corres_underlying_def cutMon_def fail_def split: split_if_asm) apply (clarsimp simp: split_def) done lemma underlying_memory_irq_state_independent[intro!, simp]: "underlying_memory (s\irq_state := f (irq_state s)\) = underlying_memory s" by simp lemma get_ipc_buffer_words_irq_state_independent[intro!, simp]: "get_ipc_buffer_words (s\irq_state := f (irq_state s)\) = get_ipc_buffer_words s" apply (rule ext, rule ext) apply (simp add: get_ipc_buffer_words_def) apply (case_tac "tcb_ipcframe x", simp_all) apply (clarsimp split: ARM_Structs_A.arch_cap.splits) apply (rule arg_cong[where f=the]) apply (rule evalMonad_mapM_cong) apply (simp add: evalMonad_def) apply safe apply ((clarsimp simp: loadWord_def bind_def gets_def get_def return_def in_monad)+)[3] apply (rule loadWord_inv) apply (rule df_loadWord) done lemma get_tcb_mrs_irq_state_independent[intro!, simp]: "get_tcb_mrs (s\irq_state := f (irq_state s)\) = get_tcb_mrs s" by (auto simp: get_tcb_mrs_def) lemma transform_full_intent_irq_state_independent[intro!, simp]: "transform_full_intent (s\irq_state := f (irq_state s)\) = transform_full_intent s" by (rule ext, rule ext, simp add: transform_full_intent_def) lemma transform_tcb_irq_state_independent[intro!, simp]: "transform_tcb (s\irq_state := f (irq_state s)\) = transform_tcb s" by (rule ext, rule ext, rule ext, simp add: transform_tcb_def) lemma transform_object_irq_state_independent[intro!, simp]: "transform_object (s \ irq_state := f (irq_state s) \) = transform_object s" by (rule ext, rule ext, rule ext, simp add: transform_object_def split: Structures_A.kernel_object.splits) lemma transform_objects_irq_state_independent[intro!, simp]: "transform_objects (s \ machine_state := machine_state s \ irq_state := f (irq_state (machine_state s)) \ \) = transform_objects s" by (simp add: transform_objects_def) lemma transform_irq_state_independent[intro!, simp]: "transform (s \ machine_state := machine_state s \ irq_state := f (irq_state (machine_state s)) \ \) = transform s" by (simp add: transform_def transform_current_thread_def) lemma transform_work_units_independent[intro!, simp]: "transform (s \ work_units_completed := f (work_units_completed s) \) = transform s" apply (simp add: transform_def transform_current_thread_def transform_objects_def transform_cdt_def transform_asid_table_def) done lemma transform_work_units_then_irq_state_independent[intro!, simp]: "transform (s \ work_units_completed := g (work_units_completed s) \ \ machine_state := machine_state s \ irq_state := f (irq_state (machine_state s)) \\) = transform s" apply (simp add: transform_def transform_current_thread_def transform_objects_def transform_cdt_def transform_asid_table_def) done lemma throw_or_return_preemption_corres: "dcorres (dc \ dc) P P' (Monads_D.throw \ returnOk ()) preemption_point" apply (simp add: preemption_point_def) apply (auto simp: preemption_point_def o_def gets_def liftE_def whenE_def getActiveIRQ_def corres_underlying_def select_def bind_def get_def bindE_def select_f_def modify_def alternative_def throwError_def returnOk_def return_def lift_def put_def do_machine_op_def update_work_units_def wrap_ext_bool_det_ext_ext_def work_units_limit_def work_units_limit_reached_def OR_choiceE_def reset_work_units_def mk_ef_def split: option.splits kernel_object.splits) done lemma cutMon_fail: "cutMon P fail = fail" by (simp add: cutMon_def) declare rec_del.simps[simp del] lemma select_pick_corres_asm: "\ x \ S; corres_underlying sr nf r P Q (f x) g \ \ corres_underlying sr nf r P Q (select S >>= f) g" by (drule select_pick_corres[where x=x and S=S], simp) lemma invs_weak_valid_mdb: "invs s \ weak_valid_mdb s" by (simp add: weak_valid_mdb_def invs_def valid_mdb_def valid_state_def) lemma invs_valid_idle_strg: "invs s \ valid_idle s" by auto lemma cutMon_validE_R_drop: "\P\ f \Q\,- \ \P\ cutMon R f \Q\,-" by (simp add: validE_R_def validE_def cutMon_valid_drop) crunch idle_thread [wp]: cap_swap_for_delete "\s. P (idle_thread s)" (wp: dxo_wp_weak) crunch idle_thread [wp]: finalise_cap "\s. P (idle_thread s)" (wp: crunch_wps simp: crunch_simps) lemma preemption_point_idle_thread[wp]: "\ \s. P (idle_thread s) \ preemption_point \ \_ s. P (idle_thread (s :: det_state)) \" apply (clarsimp simp: preemption_point_def) apply (auto simp: valid_def o_def gets_def liftE_def whenE_def getActiveIRQ_def corres_underlying_def select_def bind_def get_def bindE_def select_f_def modify_def alternative_def throwError_def returnOk_def return_def lift_def put_def do_machine_op_def update_work_units_def wrap_ext_bool_det_ext_ext_def work_units_limit_def work_units_limit_reached_def OR_choiceE_def reset_work_units_def mk_ef_def split: option.splits kernel_object.splits) done lemma rec_del_idle_thread[wp]: "\\s. P (idle_thread s)\ rec_del args \\rv s. P (idle_thread (s :: det_state))\" by (wp rec_del_preservation | simp)+ lemma gets_constant: "gets (\_. x) = return x" by (simp add: return_def simpler_gets_def) lemma monadic_rewrite_gets_the_gets: "monadic_rewrite F E (\s. f s \ None) (gets_the f) (gets (the o f))" apply (simp add: monadic_rewrite_def gets_the_def assert_opt_def exec_gets split: option.split) apply (auto simp: simpler_gets_def return_def) done lemmas corres_gets_the_bind = monadic_rewrite_corres2[OF monadic_rewrite_bind_head [OF monadic_rewrite_gets_the_gets]] lemma finalise_slot_inner1_add_if_Null: "monadic_rewrite F False \ (finalise_slot_inner1 victim) (do cap \ KHeap_D.get_cap victim; if cap = cdl_cap.NullCap then return (cdl_cap.NullCap, True) else do final \ PageTableUnmap_D.is_final_cap cap; (cap', irqopt) \ CSpace_D.finalise_cap cap final; removeable \ gets $ CSpace_D.cap_removeable cap' victim; when (\ removeable) (KHeap_D.set_cap victim cap') \ KHeap_D.set_cap victim cap'; return (cap', removeable) od od)" apply (simp add: finalise_slot_inner1_def) apply (rule monadic_rewrite_imp) apply (rule monadic_rewrite_bind_tail) apply (rule monadic_rewrite_if_rhs) apply (simp add: PageTableUnmap_D.is_final_cap_def) apply (rule monadic_rewrite_trans) apply (rule monadic_rewrite_bind_tail[where j="\_. j", standard, OF _ gets_wp])+ apply (rename_tac remove, rule_tac P=remove in monadic_rewrite_gen_asm) apply simp apply (rule monadic_rewrite_refl) apply (simp add: gets_bind_ign when_def) apply (rule monadic_rewrite_trans) apply (rule monadic_rewrite_bind_head) apply (rule monadic_rewrite_pick_alternative_1) apply simp apply (rule monadic_rewrite_refl) apply (rule monadic_rewrite_refl) apply wp apply (clarsimp simp: CSpace_D.cap_removeable_def) done lemma corres_if_rhs_only: "\ G \ corres_underlying sr nf rvr P Q a b; \ G \ corres_underlying sr nf rvr P' Q' a c\ \ corres_underlying sr nf rvr (P and P') (\s. (G \ Q s) \ (\ G \ Q' s)) a (if G then b else c)" by (rule corres_guard_imp, rule corres_if_rhs, simp+) lemma OR_choiceE_det: "\det c; \P. \P\ c \\rv. P\\ \ (OR_choiceE c (f :: ('a + 'b) det_ext_monad) g) = (doE rv \ liftE c; if rv then f else g odE)" apply (rule ext) apply (clarsimp simp: OR_choiceE_def select_f_def bind_def det_def valid_def wrap_ext_bool_det_ext_ext_def get_def bindE_def ethread_get_def split_def gets_the_def assert_opt_def return_def gets_def fail_def mk_ef_def liftE_def no_fail_def split: option.splits prod.splits) apply atomize apply (erule_tac x="op = x" in allE) apply (erule_tac x=x in allE)+ apply clarsimp done lemma transform_work_units_completed_update[simp]: "transform (s\ work_units_completed := a \) = transform s" by (auto simp: transform_def transform_cdt_def transform_current_thread_def transform_asid_table_def transform_objects_def) lemma finalise_preemption_corres: "dcorres (dc \ (\rv rv'. fst S \ fst rv)) \ \ (monadic_trancl_preemptible finalise_slot_inner2 S) (preemption_point)" apply (simp add: finalise_slot_inner2_def preemption_point_def split_def) apply (subst OR_choiceE_det) apply (simp add: work_units_limit_reached_def) apply ((simp add: work_units_limit_reached_def | wp)+)[1] apply (rule corres_guard_imp) apply (rule dcorres_symb_exec_rE) apply (rule dcorres_symb_exec_rE) apply simp apply (rule conjI, clarsimp) apply (rule dcorres_symb_exec_rE) apply (rule dcorres_symb_exec_rE) apply (simp split: option.splits) apply (rule conjI, clarsimp) apply (rule monadic_rewrite_corres2) apply (rule monadic_trancl_preemptible_return) apply (rule dcorres_returnOk, simp) apply clarsimp apply (rule corres_guard_imp) apply (rule monadic_rewrite_corres2) apply (rule monadic_trancl_preemptible_f) apply (rule corres_alternate2[OF dcorres_throw], simp_all)[4] apply ((wp | simp)+)[1] apply (rule hoare_TrueI) apply ((simp add: reset_work_units_def | wp)+)[1] apply clarsimp apply (rule corres_guard_imp) apply (rule monadic_rewrite_corres2) apply (rule monadic_trancl_preemptible_return) apply (rule dcorres_returnOk, simp_all)[3] apply (rule hoare_TrueI) apply ((simp add: work_units_limit_reached_def | wp)+)[1] apply (rule hoare_TrueI) apply (simp add: update_work_units_def | wp)+ done lemma zombie_is_cap_toE_pre2: "\ s \ cap.Zombie ptr zbits n; m < n \ \ (ptr, nat_to_cref (zombie_cte_bits zbits) m) \ cte_refs (cap.Zombie ptr zbits n) irqn" apply (clarsimp simp add: valid_cap_def cap_aligned_def) apply (clarsimp split: option.split_asm) apply (simp add: unat_of_bl_nat_to_cref) apply (simp add: nat_to_cref_def word_bits_conv) apply (simp add: unat_of_bl_nat_to_cref) apply (simp add: nat_to_cref_def word_bits_conv) done lemma corres_note_assumption: "\ F; corres_underlying sr fl r P P' f g \ \ corres_underlying sr fl r (\s. F \ P s) P' f g" by simp lemma corres_req2: "\\s s'. \(s, s') \ sr; P s; P' s'\ \ F; F \ corres_underlying sr nf r Q Q' f g\ \ corres_underlying sr nf r (P and Q) (P' and Q') f g" apply (rule_tac F=F in corres_req, simp_all) apply (erule corres_guard_imp, simp_all) done lemma opt_cap_cnode: "\ kheap s y = Some (CNode sz cn); y \ idle_thread s; well_formed_cnode_n sz cn \ \ (opt_cap (y, node) (transform s) = Some cap) = (\v cap'. transform_cslot_ptr (y, v) = (y, node) \ cn v = Some cap' \ cap = transform_cap cap')" apply clarsimp apply (simp add: opt_cap_def slots_of_def opt_object_def transform_def transform_objects_def restrict_map_def transform_cnode_contents_def option_map_join_def transform_cslot_ptr_def object_slots_def split: option.split) apply safe apply (frule(1) wf_cs_nD[rotated], clarsimp simp: nat_to_bl_id2) apply (frule(1) wf_cs_nD[rotated], clarsimp) apply (frule(1) nat_to_bl_to_bin) apply simp apply (fastforce simp add: nat_to_bl_id2) apply (frule(1) wf_cs_nD[rotated], clarsimp simp: nat_to_bl_id2) done lemma preemption_point_valid_etcbs[wp]: "\ valid_etcbs \ preemption_point \ \_. valid_etcbs \" apply (clarsimp simp: preemption_point_def) apply (auto simp: valid_def o_def gets_def liftE_def whenE_def getActiveIRQ_def corres_underlying_def select_def bind_def get_def bindE_def select_f_def modify_def alternative_def throwError_def returnOk_def return_def lift_def put_def do_machine_op_def update_work_units_def wrap_ext_bool_det_ext_ext_def work_units_limit_def work_units_limit_reached_def OR_choiceE_def reset_work_units_def mk_ef_def split: option.splits kernel_object.splits) done crunch valid_etcbs[wp]: cap_swap_ext, cap_swap_for_delete "valid_etcbs" lemma rec_del_valid_etcbs[wp]: "\ valid_etcbs \ rec_del args \\_. valid_etcbs \" by (wp rec_del_preservation | simp)+ lemma dcorres_rec_del: "\ (case args of CTEDeleteCall slot exp \ \ exp | _ \ True); (transform_cslot_ptr (slot_rdcall args), \ exposed_rdcall args) \ fst S; (case args of ReduceZombieCall (cap.Zombie p zbits (Suc n)) _ _ \ (transform_cslot_ptr (p, replicate (zombie_cte_bits zbits) False), True) \ fst S \ (transform_cslot_ptr (p, nat_to_cref (zombie_cte_bits zbits) n), True) \ fst S | _ \ True) \ \ dcorres (dc \ (\rv rv'. (case args of FinaliseSlotCall _ _ \ fst rv' \ (\v. (transform_cslot_ptr (slot_rdcall args), v) \ snd rv \ (\ exposed_rdcall args \ v)) | _ \ True) \ fst S \ fst rv)) \ (invs and valid_rec_del_call args and cte_at (slot_rdcall args) and valid_etcbs and valid_pdpt_objs and emptyable (slot_rdcall args) and not_idle_thread (fst (slot_rdcall args)) and (\s. \ exposed_rdcall args \ ex_cte_cap_wp_to (\cp. cap_irqs cp = {}) (slot_rdcall args) s) and (\s. case args of ReduceZombieCall cap sl ex \ \t\obj_refs cap. halted_if_tcb t s | _ \ True)) (doE S' \ monadic_trancl_preemptible finalise_slot_inner2 S; whenE ((case args of ReduceZombieCall _ _ _ \ False | _ \ True) \ exposed_rdcall args \ \ (transform_cslot_ptr (slot_rdcall args)) \ fst ` snd S') Monads_D.throw; returnOk S' odE) (cutMon (op = s) (rec_del args))" proof (induct arbitrary: S rule: rec_del.induct, simp_all(no_asm) only: rec_del_fails fail_bindE corres_free_fail cutMon_fail) case (1 slot exposed s S) note ps = "1.prems"[simplified] hence nexp[simp]: "\ exposed" by simp show ?case using ps apply (simp add: dc_def[symmetric]) apply (subst rec_del_simps_ext[unfolded split_def]) apply simp apply (rule corres_guard_imp) apply (rule monadic_rewrite_corres2) apply (rule monadic_trancl_preemptible_steps) apply (simp add: cutMon_walk_bindE) apply (rule corres_splitEE) prefer 2 apply (rule "1.hyps"[simplified, folded dc_def], assumption+) apply (rule corres_drop_cutMon) apply (simp add: liftME_def[symmetric]) apply (rule_tac R="fst rv" in corres_cases) apply (simp add: when_def) apply (rule monadic_rewrite_corres2) apply (rule monadic_trancl_preemptible_f) apply (simp add: finalise_slot_inner2_def[unfolded split_def]) apply (rule corres_alternate1, rule corres_alternate2) apply simp apply (rule select_pick_corres_asm) apply clarsimp apply assumption apply (simp add: liftM_def[symmetric] o_def dc_def[symmetric]) apply (rule empty_slot_corres) apply (simp add: when_def) apply (rule monadic_rewrite_corres2) apply (rule monadic_trancl_preemptible_return) apply (rule corres_trivial, simp add: returnOk_liftE) apply wp apply (wp_trace cutMon_validE_R_drop rec_del_invs | simp add: not_idle_thread_def | strengthen invs_weak_valid_mdb invs_valid_idle_strg | rule hoare_vcg_E_elim[rotated])+ done next case (2 slot exposed s S) note split_if[split del] have removeables: "\s cap fin. \ cte_wp_at (op = cap) slot s; s \ remainder_cap fin cap; invs s; valid_etcbs s; CSpace_A.cap_removeable (remainder_cap fin cap) slot \ \ CSpace_D.cap_removeable (transform_cap (remainder_cap fin cap)) (transform_cslot_ptr slot) (transform s)" apply (case_tac "remainder_cap fin cap = cap.NullCap") apply (simp add: CSpace_D.cap_removeable_def) apply (clarsimp simp: remainder_cap_def valid_cap_simps cte_wp_at_caps_of_state split: cap.split_asm split_if_asm) apply (frule valid_global_refsD2, clarsimp) apply (clarsimp simp: CSpace_D.cap_removeable_def) apply (subgoal_tac "\x cap. (word, b) = transform_cslot_ptr (word, x) \ caps_of_state s (word, x) = Some cap \ cap \ cap.NullCap") apply clarsimp apply (case_tac "(word, x) \ cte_refs (the (caps_of_state s slot)) (interrupt_irq_node s)") apply (clarsimp simp: unat_eq_0) apply (drule of_bl_eq_0) apply (simp add: cap_aligned_def word_bits_conv split: option.split_asm) apply clarsimp apply (frule zombie_cap_has_all[rotated -2], simp, clarsimp+) apply (clarsimp simp: tcb_at_def cap_range_def global_refs_def opt_cap_tcb split: option.split_asm split_if_asm | drule(1) valid_etcbs_get_tcb_get_etcb)+ apply (rule_tac x="tcb_cnode_index b" in exI) apply (clarsimp simp: transform_cslot_ptr_def dest!: get_tcb_SomeD) apply (rule conjI, rule sym, rule bl_to_bin_tcb_cnode_index) apply (auto simp: tcb_slot_defs)[1] apply (rule iffD1[OF cte_wp_at_caps_of_state cte_wp_at_tcbI], (simp | rule conjI)+) apply (frule final_zombie_not_live[rotated 1, OF caps_of_state_cteD], clarsimp) apply (rule ccontr, erule zombies_finalE) apply (simp add: is_cap_simps) apply clarsimp apply (erule caps_of_state_cteD) apply (clarsimp simp: obj_at_def dest!: get_tcb_SomeD) apply (auto simp: infer_tcb_pending_op_def)[1] apply (clarsimp simp: obj_at_def is_cap_table_def) apply (clarsimp simp: opt_cap_cnode split: Structures_A.kernel_object.split_asm) apply (subst (asm) opt_cap_cnode, assumption, simp, simp) apply clarsimp apply (rule exI, rule conjI, erule sym) apply (rule iffD1[OF cte_wp_at_caps_of_state cte_wp_at_cteI], (simp | rule conjI)+) done show ?case using "2.prems" apply (simp add: dc_def[symmetric]) apply (subst rec_del_simps_ext[unfolded split_def]) apply (simp add: bindE_assoc, simp add: liftE_bindE) apply (rule stronger_corres_guard_imp) apply (simp add: cutMon_walk_bind) apply (rule corres_drop_cutMon_bind) apply (rule monadic_rewrite_corres2) apply (rule monadic_rewrite_bindE_head) apply (rule monadic_trancl_preemptible_step) apply (simp add: finalise_slot_inner2_def [THEN fun_cong, unfolded split_def]) apply (simp add: alternative_bindE_distrib) apply (rule corres_alternate1)+ apply (simp add: liftE_bindE bind_bindE_assoc bind_assoc) apply (rule select_pick_corres_asm, assumption) apply (rule monadic_rewrite_corres2) apply (rule monadic_rewrite_bind_head) apply (rule finalise_slot_inner1_add_if_Null[unfolded split_def]) apply (simp add: bind_assoc if_to_top_of_bind) apply (rule corres_split[OF _ get_cap_corres[OF refl]]) apply (rename_tac cap) apply (rule corres_cutMon) apply (simp add: if_to_top_of_bindE cutMon_walk_if del: transform_cap_Null) apply (rule Corres_UL.corres_if2[unfolded if_apply_def2]) apply simp apply (rule corres_drop_cutMon) apply (rule corres_underlying_gets_pre_lhs)+ apply (rule monadic_rewrite_corres2) apply (rule monadic_rewrite_bindE_head) apply (rule monadic_trancl_preemptible_return) apply simp apply (rule corres_trivial, simp add: returnOk_liftE) apply (rule_tac F="cap \ cap.NullCap" in corres_gen_asm2) apply (rule corres_cutMon) apply (simp add: cutMon_walk_bind del: fst_conv) apply (rule corres_drop_cutMon_bind) apply (rule corres_split [OF _ is_final_cap_corres[OF refl]]) apply (rule corres_cutMon) apply (simp add: cutMon_walk_bind del: fst_conv) apply (rule corres_drop_cutMon_bind) apply (rule corres_split[OF _ dcorres_finalise_cap[where slot=slot]]) apply (rename_tac fin fin') apply (rule corres_cutMon) apply (simp(no_asm) add: cutMon_walk_if) apply (rule corres_underlying_gets_pre_lhs) apply (rename_tac remove) apply (rule_tac P="\s. remove = CSpace_D.cap_removeable (fst fin) (transform_cslot_ptr slot) s" and P'="cte_wp_at (op = cap) slot and invs and valid_etcbs and valid_cap (fst fin')" and F="CSpace_A.cap_removeable (fst fin') slot \ remove" in corres_req2) apply (drule use_valid[OF _ finalise_cap_remainder, OF _ TrueI]) apply (clarsimp simp: removeables) apply (rule corres_if_rhs_only) apply (rule_tac F=remove in corres_note_assumption, simp) apply (simp add: when_def) apply (rule monadic_rewrite_corres2) apply (rule monadic_rewrite_bind) apply (rule monadic_rewrite_pick_alternative_1) apply (rule monadic_rewrite_bind_tail) apply (rule monadic_rewrite_bindE_head) apply (rule monadic_trancl_preemptible_return) apply wp apply simp apply (rule corres_underlying_gets_pre_lhs) apply (rule corres_drop_cutMon) apply (rule corres_trivial, simp add: returnOk_liftE) apply (rule corres_if_rhs_only) apply simp apply (rule corres_drop_cutMon) apply (rule monadic_rewrite_corres2) apply (rule monadic_rewrite_bind) apply (rule monadic_rewrite_pick_alternative_2) apply (rule monadic_rewrite_bind_tail) apply (rule monadic_trancl_preemptible_return) apply wp apply (rule corres_split[OF _ set_cap_corres]) apply (rule corres_underlying_gets_pre_lhs) apply (rule corres_trivial, simp add: returnOk_liftE) apply (wp | simp)+ apply (rule monadic_rewrite_corres2) apply (rule monadic_rewrite_bind_head) apply (rule monadic_rewrite_pick_alternative_2) apply (simp add: cutMon_walk_bind) apply (rule corres_drop_cutMon_bind) apply (rule corres_split[OF _ set_cap_corres]) apply (rule_tac P="dcorres ?r ?P ?P' ?f" in subst) apply (rule_tac f="\_. ()" in gets_bind_ign) apply (rule_tac r'="\rv rv'. transform_cslot_ptr ` (case fst fin' of cap.Zombie p zb (Suc n) \ {(p, replicate (zombie_cte_bits zb) False), (p, nat_to_cref (zombie_cte_bits zb) n)} | _ \ {}) \ rv" and P=\ and P'="valid_cap (fst fin') and invs and valid_etcbs and (\s. idle_thread s \ obj_refs (fst fin'))" in corres_split) apply (rule monadic_rewrite_corres2) apply (rule monadic_rewrite_bindE_head) apply (rule monadic_rewrite_trans) apply (rule monadic_trancl_preemptible_steps) apply (rule monadic_rewrite_bindE[OF monadic_rewrite_refl]) apply (rule monadic_trancl_preemptible_steps) apply wp apply (rule corres_cutMon) apply (simp add: cutMon_walk_bindE bindE_assoc) apply (rule corres_splitEE) prefer 2 apply (rule "2.hyps"[simplified, folded dc_def], (assumption | simp | rule conjI refl)+) apply (clarsimp simp del: transform_cap_simps split: cap.split nat.split) apply (rule corres_cutMon) apply (simp add: cutMon_walk_bindE dc_def[symmetric]) apply (rule corres_drop_cutMon_bindE) apply (rule corres_splitEE[OF _ finalise_preemption_corres]) apply (rule corres_cutMon) apply (rule corres_rel_imp, rule "2.hyps"[simplified, folded dc_def], (assumption | simp | rule conjI refl)+) apply clarsimp apply blast apply (rename_tac excr excr', case_tac excr, simp_all)[1] apply clarsimp apply blast apply (wp cutMon_validE_R_drop rec_del_invs rec_del_cte_at rec_del_ReduceZombie_emptyable reduce_zombie_cap_to preemption_point_valid_etcbs preemption_point_inv | simp add: not_idle_thread_def del: gets_to_return)+ apply (clarsimp simp: get_zombie_range_def dom_def split: cap.split nat.split) apply (frule cte_at_nat_to_cref_zbits[OF _ lessI]) apply (frule cte_at_replicate_zbits) apply (clarsimp simp: cte_wp_at_caps_of_state caps_of_state_transform_opt_cap) apply (clarsimp simp: transform_cslot_ptr_def) apply (wp | simp)+ apply (simp add: conj_ac) apply (wp replace_cap_invs final_cap_same_objrefs set_cap_cte_wp_at hoare_vcg_const_Ball_lift set_cap_cte_cap_wp_to static_imp_wp | erule finalise_cap_not_reply_master[simplified in_monad, simplified] | simp only: not_idle_thread_def pred_conj_def simp_thms)+ apply (rule hoare_strengthen_post) apply (rule_tac Q="\fin s. invs s \ replaceable s slot (fst fin) cap \ valid_pdpt_objs s \ valid_etcbs s \ cte_wp_at (op = cap) slot s \ s \ fst fin \ emptyable slot s \ fst slot \ idle_thread s \ (\t\obj_refs (fst fin). halted_if_tcb t s)" in hoare_vcg_conj_lift) apply (wp finalise_cap_invs[where slot=slot] finalise_cap_replaceable finalise_cap_makes_halted[where slot=slot] hoare_vcg_disj_lift hoare_vcg_ex_lift)[1] apply (rule finalise_cap_cases[where slot=slot]) apply clarsimp apply (frule if_unsafe_then_capD, clarsimp+) apply (clarsimp simp: cte_wp_at_caps_of_state) apply (frule valid_global_refsD2, clarsimp+) apply (erule disjE[where P="c = cap.NullCap \ P", standard]) apply clarsimp apply (clarsimp simp: conj_ac invs_valid_idle global_refs_def cap_range_def dest!: is_cap_simps' [THEN iffD1]) apply (frule trans [OF _ appropriate_Zombie, OF sym]) apply (case_tac cap, simp_all add: fst_cte_ptrs_def is_cap_simps is_final_cap'_def)[1] apply assumption apply (wp get_cap_wp | simp add: is_final_cap_def)+ apply (auto simp: not_idle_thread_def cte_wp_at_caps_of_state elim: caps_of_state_valid_cap) done next case (3 ptr bits n slot s S) show ?case using "3.prems" apply (subst rec_del.simps) apply (clarsimp simp: assertE_assert liftE_bindE assert_def corres_free_fail cutMon_fail) apply (case_tac "ptr = idle_thread s \ fst slot = idle_thread s") apply (clarsimp simp: cutMon_def corres_underlying_def fail_def) apply (clarsimp simp: cte_wp_at_caps_of_state dest!: zombie_cap_two_nonidles) apply (rule corres_drop_cutMon) apply (simp add: liftME_def[symmetric] liftE_bindE[symmetric]) apply (rule stronger_corres_guard_imp) apply (rule monadic_rewrite_corres2) apply (rule monadic_trancl_preemptible_f) apply (simp add: finalise_slot_inner2_def[unfolded split_def]) apply (rule corres_alternate1, rule corres_alternate1, rule corres_alternate2) apply simp apply (rule_tac x="(?p, ?p')" in select_pick_corres) apply (simp add: liftM_def[symmetric] o_def dc_def[symmetric]) apply (rule swap_for_delete_corres) apply (clarsimp simp: cte_wp_at_caps_of_state) apply (frule(1) caps_of_state_valid, drule cte_at_replicate_zbits) apply (clarsimp simp: cte_wp_at_caps_of_state transform_cslot_ptr_inj) apply (clarsimp simp: cte_wp_at_caps_of_state) apply (auto simp: not_idle_thread_def dest: zombie_cap_two_nonidles) done next case (4 ptr bits n slot s S) show ?case using "4.prems" apply (subst rec_del.simps) apply simp apply (rule stronger_corres_guard_imp) apply (simp add: cutMon_walk_bindE) apply (rule monadic_rewrite_corres2) apply (rule monadic_trancl_preemptible_steps) apply (rule corres_splitEE[OF _ "4.hyps"[simplified, folded dc_def]]) apply (rule corres_drop_cutMon) apply (simp add: liftE_bindE) apply (rule corres_symb_exec_r) apply (simp add: liftME_def[symmetric] split del: split_if) apply (rule monadic_rewrite_corres2) apply (rule monadic_trancl_preemptible_return) apply (rule corres_if_rhs_only) apply (simp add: returnOk_liftE) apply (rule corres_add_noop_lhs, simp only: liftM_def[symmetric] corres_liftM_simp) apply (simp add: o_def dc_def[symmetric]) apply (rule set_cap_noop_dcorres3) apply (simp add: assertE_assert liftE_def) apply (rule corres_assert_rhs) apply (rule corres_trivial, simp add: returnOk_def) apply (rule hoare_strengthen_post, rule get_cap_cte_wp_at) apply (clarsimp simp: cte_wp_at_caps_of_state arch_page_vmpage_size_def) apply (wp | simp)+ apply (simp add: in_monad) apply simp apply (wp cutMon_validE_R_drop) apply clarsimp apply (clarsimp simp: cte_wp_at_caps_of_state halted_emptyable) apply (frule valid_global_refsD2, clarsimp+) apply (frule(1) caps_of_state_valid, drule_tac m=n in cte_at_nat_to_cref_zbits) apply simp apply (auto simp: cte_wp_at_caps_of_state not_idle_thread_def global_refs_def cap_range_def elim: zombie_is_cap_toE[OF caps_of_state_cteD]) done qed lemma dcorres_finalise_slot: "dcorres (dc \ dc) \ (invs and cte_at slot and valid_etcbs and valid_pdpt_objs and emptyable slot and not_idle_thread (fst slot)) (CSpace_D.finalise_slot (transform_cslot_ptr slot)) (rec_del (FinaliseSlotCall slot True))" apply (rule corres_use_cutMon) apply (cut_tac b="\_. returnOk ()" and d="\_. returnOk ()" and r=dc and args3="FinaliseSlotCall slot True" and S3="({(transform_cslot_ptr slot, False)}, {})" and s3=s in corres_splitEE[rotated, OF dcorres_rec_del wp_post_tautE wp_post_tautE]) apply (simp_all add: bindE_assoc CSpace_D.finalise_slot_def split_def) apply (simp_all add: liftME_def[symmetric]) apply (simp add: returnOk_def) done end