(* * Copyright 2014, General Dynamics C4 Systems * * This software may be distributed and modified according to the terms of * the GNU General Public License version 2. Note that NO WARRANTY is provided. * See "LICENSE_GPLv2.txt" for details. * * @TAG(GD_GPL) *) theory KHeap_AI imports "./$L4V_ARCH/ArchKHeap_AI" begin context begin interpretation Arch . requalify_consts valid_ao_at obj_is_device valid_vso_at non_vspace_obj vspace_obj_pred requalify_facts pspace_in_kernel_window_atyp_lift valid_vspace_objs_lift_weak vs_lookup_vspace_obj_at_lift vs_lookup_pages_vspace_obj_at_lift valid_arch_caps_lift_weak valid_global_objs_lift_weak valid_asid_map_lift valid_ioports_lift valid_kernel_mappings_lift equal_kernel_mappings_lift valid_global_vspace_mappings_lift valid_machine_state_lift valid_vso_at_lift valid_vso_at_lift_aobj_at valid_arch_state_lift_aobj_at in_user_frame_lift in_user_frame_obj_pred_lift set_object_v_ker_map non_vspace_objs vspace_obj_predE vspace_pred_imp in_user_frame_obj_upd in_device_frame_obj_upd device_mem_obj_upd_dom user_mem_obj_upd_dom pspace_respects_region_cong cap_is_device_obj_is_device storeWord_device_state_inv state_hyp_refs_of_ep_update state_hyp_refs_of_ntfn_update state_hyp_refs_of_tcb_state_update state_hyp_refs_of_tcb_bound_ntfn_update arch_valid_obj_same_type default_arch_object_not_live default_tcb_not_live getActiveIRQ_neq_non_kernel dmo_getActiveIRQ_non_kernel valid_arch_tcb_same_type valid_arch_tcb_typ_at valid_tcb_arch_ref_lift end lemmas cap_is_device_obj_is_device[simp] = cap_is_device_obj_is_device lemmas storeWord_device_state_hoare[wp] = storeWord_device_state_inv declare non_vspace_objs[intro] context notes get_object_wp [wp] begin method get_simple_ko_method = (wpsimp simp: get_simple_ko_def partial_inv_def the_equality split: kernel_object.splits) lemma get_simple_ko_wp: "\\s. \ntfn. ko_at (f ntfn) ntfnptr s \ P ntfn s\ get_simple_ko f ntfnptr \P\" by get_simple_ko_method lemma get_object_inv [wp]: "\P\ get_object t \\rv. P\" by wpsimp lemma get_tcb_rev: "kheap s p = Some (TCB t)\ get_tcb p s = Some t" by (clarsimp simp:get_tcb_def) lemma get_tcb_obj_atE[elim!]: "\ get_tcb t s = Some tcb; get_tcb t s = Some tcb \ P (TCB tcb) \ \ obj_at P t s" by (clarsimp dest!: get_tcb_SomeD simp: obj_at_def) lemma a_type_TCB[simp]: "a_type (TCB x) = ATCB" by (simp add: a_type_def) lemma pspace_aligned_obj_update: assumes obj: "obj_at P t s" assumes pa: "pspace_aligned s" assumes R: "\k. P k \ a_type k = a_type k'" shows "pspace_aligned (s\kheap := kheap s(t \ k')\)" using pa obj apply (simp add: pspace_aligned_def cong: conj_cong) apply (clarsimp simp: obj_at_def obj_bits_T dest!: R) apply (fastforce dest: bspec [OF _ domI]) done lemma cte_at_same_type: "\cte_at t s; a_type k = a_type ko; kheap s p = Some ko\ \ cte_at t (s\kheap := kheap s(p \ k)\)" apply (clarsimp simp: cte_at_cases del: disjCI) apply (elim exE disjE) apply (clarsimp simp: a_type_def well_formed_cnode_n_def length_set_helper split: Structures_A.kernel_object.split_asm if_split_asm) apply clarsimp done lemma untyped_same_type: "\valid_untyped (cap.UntypedCap dev r n f) s; a_type k = a_type ko; kheap s p = Some ko\ \ valid_untyped (cap.UntypedCap dev r n f) (s\kheap := kheap s(p \ k)\)" unfolding valid_untyped_def by (clarsimp simp: obj_range_def obj_bits_T) lemma valid_cap_same_type: "\ s \ cap; a_type k = a_type ko; kheap s p = Some ko \ \ s\kheap := kheap s(p \ k)\ \ cap" apply (simp add: valid_cap_def split: cap.split) apply (auto elim!: typ_at_same_type untyped_same_type simp: ntfn_at_typ ep_at_typ tcb_at_typ cap_table_at_typ split: option.split sum.split) by (intro hoare_to_pure_kheap_upd[OF valid_arch_cap_typ, simplified obj_at_def], assumption, auto) lemma valid_obj_same_type: "\ valid_obj p' obj s; valid_obj p k s; kheap s p = Some ko; a_type k = a_type ko \ \ valid_obj p' obj (s\kheap := kheap s(p \ k)\)" apply (cases obj; simp) apply (clarsimp simp add: valid_obj_def valid_cs_def) apply (drule (1) bspec) apply (erule (2) valid_cap_same_type) apply (clarsimp simp: valid_obj_def valid_tcb_def valid_bound_ntfn_def valid_arch_tcb_same_type) apply (fastforce elim: valid_cap_same_type typ_at_same_type simp: valid_tcb_state_def ep_at_typ ntfn_at_typ tcb_at_typ split: Structures_A.thread_state.splits option.splits) apply (clarsimp simp add: valid_obj_def valid_ep_def) apply (fastforce elim: typ_at_same_type simp: tcb_at_typ split: Structures_A.endpoint.splits) apply (clarsimp simp add: valid_obj_def valid_ntfn_def valid_bound_tcb_def) apply (auto elim: typ_at_same_type simp: tcb_at_typ split: Structures_A.ntfn.splits option.splits) apply (clarsimp simp add: valid_obj_def) apply (auto intro: arch_valid_obj_same_type) done lemma valid_vspace_obj_same_type: "\valid_vspace_obj ao s; kheap s p = Some ko; a_type ko' = a_type ko\ \ valid_vspace_obj ao (s\kheap := kheap s(p \ ko')\)" apply (rule hoare_to_pure_kheap_upd[OF valid_vspace_obj_typ]) by (auto simp: obj_at_def) lemma set_object_valid_objs: "\valid_objs and valid_obj p k and obj_at (\ko. a_type k = a_type ko) p\ set_object p k \\r. valid_objs\" apply (clarsimp simp: valid_def set_object_def in_monad obj_at_def) apply (clarsimp simp: valid_objs_def dom_def) apply (case_tac "ptr = p") apply clarsimp apply (rule valid_obj_same_type, assumption+) apply clarsimp apply (subgoal_tac "valid_obj ptr y s") prefer 2 apply fastforce apply (erule(3) valid_obj_same_type) done lemma set_object_aligned: "\pspace_aligned and obj_at (\ko. a_type k = a_type ko) p\ set_object p k \\r. pspace_aligned\" apply (clarsimp simp: valid_def in_monad set_object_def) apply (erule (1) pspace_aligned_obj_update) apply simp done lemma assert_get_tcb: "\ P \ gets_the (get_tcb t) \ \r. P and tcb_at t \" by (clarsimp simp: valid_def in_monad gets_the_def tcb_at_def) lemma dxo_wp_weak[wp]: assumes xopv: "\s f. P (trans_state f s) = P s" shows "\P\ do_extended_op x \\_. P\" unfolding do_extended_op_def apply (simp add: split_def) apply wp apply (clarsimp simp: mk_ef_def) apply (simp add: xopv[simplified trans_state_update']) done crunch ct[wp]: set_thread_state "\s. P (cur_thread s)" lemma sts_ep_at_inv[wp]: "\ ep_at ep \ set_thread_state t s \ \rv. ep_at ep \" apply (simp add: set_thread_state_def) apply (wp | simp add: set_object_def)+ apply (clarsimp simp: obj_at_def is_ep is_tcb get_tcb_def) done lemma sts_ntfn_at_inv[wp]: "\ ntfn_at ep \ set_thread_state t s \ \rv. ntfn_at ep \" apply (simp add: set_thread_state_def) apply (wp | simp add: set_object_def)+ apply (clarsimp simp: obj_at_def is_ntfn is_tcb get_tcb_def) done lemma sbn_ep_at_inv[wp]: "\ ep_at ep \ set_bound_notification t ntfn \ \rv. ep_at ep \" apply (simp add: set_bound_notification_def) apply (wp | simp add: set_object_def)+ apply (clarsimp simp: obj_at_def is_ep is_tcb get_tcb_def) done lemma sbn_ntfn_at_inv[wp]: "\ ntfn_at ep \ set_bound_notification t ntfn \ \rv. ntfn_at ep \" apply (simp add: set_bound_notification_def) apply (wp | simp add: set_object_def)+ apply (clarsimp simp: obj_at_def is_ntfn is_tcb get_tcb_def) done lemma prefix_to_eq: "\ take n xs \ ys; length xs = length ys; drop n xs = drop n ys \ \ xs = ys" apply (induct n arbitrary: xs ys) apply simp apply (case_tac xs) apply simp apply (case_tac ys) apply simp apply simp done lemma set_cdt_inv: assumes P: "\s. P s \ P (cdt_update (\_. m) s)" shows "\P\ set_cdt m \\_. P\" apply (simp add: set_cdt_def) apply wp apply (erule P) done lemmas cte_wp_at_cdt = cdt_update.cte_wp_at_update lemmas obj_at_cdt = cdt_update.obj_at_update lemmas valid_cap_cdt = cdt_update.valid_cap_update lemma set_object_at_obj3: "\K (P obj)\ set_object p obj \\rv. obj_at P p\" by (clarsimp simp: set_object_def obj_at_def valid_def in_monad) lemma set_object_valid_cap: "\valid_cap c and obj_at (\k. a_type ko = a_type k) p\ set_object p ko \\rv. valid_cap c\" apply (simp add: set_object_def) apply wp apply (clarsimp simp only: obj_at_def) apply (rule valid_cap_same_type) apply auto done lemma set_object_cte_at: "\cte_at c and obj_at (\k. a_type ko = a_type k) p\ set_object p ko \\rv. cte_at c\" apply (clarsimp simp: set_object_def in_monad valid_def obj_at_def) apply (erule(2) cte_at_same_type) done lemma obj_at_ko_atD: "obj_at P x s \ \k. ko_at k x s \ P k" by (clarsimp simp: obj_at_def) lemma set_object_ko: "\ko_at obj ptr and K (x \ ptr)\ set_object x ko \\rv. ko_at obj ptr\" by (clarsimp simp add: valid_def set_object_def in_monad obj_at_def) lemma tcb_aligned: "\ invs s; tcb_at t s \ \ is_aligned t tcb_bits" apply (clarsimp simp: invs_def valid_state_def valid_pspace_def pspace_aligned_def) apply (clarsimp simp: tcb_at_def, drule get_tcb_SomeD) apply (erule my_BallE [where y=t]) apply clarsimp apply simp done lemma set_object_ko_at: "\\\ set_object p ko \\_. ko_at ko p\" apply (simp add: set_object_def) apply wp apply (simp add: obj_at_def) done lemma get_simple_ko_sp: "\P\ get_simple_ko f p \\ep. ko_at (f ep) p and P\" by get_simple_ko_method lemma get_simple_ko_inv[wp]: "\P\ get_simple_ko f ep \\rv. P\" by get_simple_ko_method lemma get_simple_ko_actual_ko[wp]: "\ obj_at (\ko. bound (partial_inv f ko)) ep \ get_simple_ko f ep \ \rv. obj_at (\k. k = f rv) ep \" by (fastforce simp: get_simple_ko_def get_object_def bind_def partial_inv_def valid_def gets_def get_def return_def in_fail assert_def obj_at_def split_def the_equality split: kernel_object.splits option.splits) lemma get_object_valid [wp]: "\valid_objs\ get_object oref \ valid_obj oref \" apply (simp add: get_object_def) apply wp apply (clarsimp simp add: valid_pspace_def valid_objs_def dom_def) apply fastforce done lemma get_object_valid_obj_simple [wp]: notes valid_simple_obj_def[simp del] shows "\valid_objs\ get_object oref \ valid_simple_obj \" apply (simp add: get_object_def) apply wp apply (clarsimp simp: valid_pspace_def valid_objs_def dom_def intro!: valid_obj_imp_valid_simple) apply fastforce done lemma get_object_valid_simple [wp]: "\valid_simple_objs\ get_object oref \ valid_simple_obj \" apply (simp add: get_object_def) apply wp apply (clarsimp simp add: valid_pspace_def valid_simple_objs_def dom_def) apply fastforce done lemma get_simple_ko_valid [wp]: "\valid_objs\ get_simple_ko f oref \ \r s. valid_simple_obj (f r) s\" apply (simp add: get_simple_ko_def) apply (wpsimp) apply (drule valid_objs_imp_valid_simple_objs) apply (clarsimp simp: valid_simple_objs_def partial_inv_def obj_at_def the_equality split: if_splits) apply (drule_tac x=oref in bspec) apply (clarsimp simp: the_equality split: kernel_object.splits)+ done lemma get_simple_ko_valid_obj[wp]: "\ valid_objs and obj_at (\ko. bound (partial_inv f ko)) ep \ get_simple_ko f ep \ \r. valid_obj ep (f r) \" apply (simp add: get_simple_ko_def) apply (rule hoare_seq_ext) prefer 2 apply (rule hoare_pre_imp [OF _ get_object_valid]) apply (simp add: invs_def valid_state_def valid_pspace_def) apply (wpsimp simp: partial_inv_def the_equality valid_obj_def split: option.splits) done lemma get_simple_ko_valid_simple_obj[wp]: notes valid_simple_obj_def[simp del] shows "\ valid_objs and obj_at (\ko. bound (partial_inv f ko)) ep \ get_simple_ko f ep \ \r. valid_simple_obj (f r) \" apply (simp add: get_simple_ko_def) apply (rule hoare_seq_ext) prefer 2 apply (rule hoare_pre_imp [OF _ get_object_valid]) apply (simp add: invs_def valid_state_def valid_pspace_def) apply (wpsimp simp: partial_inv_def the_equality valid_obj_imp_valid_simple split: option.splits) done lemma get_ntfn_valid_ntfn[wp]: "\ valid_objs and ntfn_at ntfn \ get_notification ntfn \ valid_ntfn \" by (wpsimp simp: ntfn_at_def2 valid_ntfn_def2 simp_del: valid_simple_obj_def) lemma get_ep_valid_ep[wp]: "\ invs and ep_at ep \ get_endpoint ep \ valid_ep \" by (wpsimp simp: ep_at_def2 valid_ep_def2 simp_del: valid_simple_obj_def) lemma set_simple_ko_valid_objs[wp]: "\ valid_objs and valid_simple_obj (f v) and K (is_simple_type (f v))\ set_simple_ko f ptr v \\rv s. valid_objs s\" unfolding set_simple_ko_def by (wpsimp wp: set_object_valid_objs simp: valid_obj_def obj_at_def a_type_def partial_inv_def valid_ntfn_def2 valid_ep_def2 split: kernel_object.splits simp_del: valid_simple_obj_def) method set_simple_ko_method uses wp_thm simp_thm = (unfold set_simple_ko_def; wpsimp wp: wp_thm simp: simp_thm valid_obj_def obj_at_def a_type_def partial_inv_def the_equality split: kernel_object.splits) lemma set_simple_ko_aligned[wp]: "\pspace_aligned\ set_simple_ko f ptr v \\rv. pspace_aligned\" by (set_simple_ko_method wp_thm: set_object_aligned) lemma set_simple_ko_typ_at [wp]: "\\s. P (typ_at T p s)\ set_simple_ko f p' ep \\rv s. P (typ_at T p s)\" by (set_simple_ko_method wp_thm: set_object_typ_at) lemma set_simple_ko_cte_wp_at [wp]: "\cte_wp_at P p\ set_simple_ko f p' ep \\rv. cte_wp_at P p\" by (set_simple_ko_method simp_thm: set_object_def cte_wp_at_cases; fastforce) lemma get_simple_ko_ko_at: "\\\ get_simple_ko f ep \\rv. ko_at (f rv) ep\" by get_simple_ko_method lemma obj_set_prop_at: "\\s. P obj \ set_object p obj \\rv. obj_at P p\" apply (simp add: set_object_def) apply wp apply (simp add: obj_at_def) done lemma simple_obj_set_prop_at: "\\s. P (f v) \ set_simple_ko f p v \\rv. obj_at P p\" by (set_simple_ko_method wp_thm: obj_set_prop_at) lemma set_simple_ko_refs_of[wp]: "\\s. P ((state_refs_of s) (ep := refs_of (f val)))\ set_simple_ko f ep val \\rv s. P (state_refs_of s)\" apply (set_simple_ko_method simp_thm: set_object_def) by (fastforce simp: state_refs_of_def elim!: rsubst[where P=P]) lemma set_ep_refs_of[wp]: "\\s. P ((state_refs_of s) (ep := ep_q_refs_of val))\ set_endpoint ep val \\rv s. P (state_refs_of s)\" by (wp; fastforce simp: state_refs_of_def elim!: rsubst[where P=P]) lemma set_simple_ko_hyp_refs_of[wp]: "\\s. P ((state_hyp_refs_of s))\ set_simple_ko f ep val \\rv s. P (state_hyp_refs_of s)\" apply (set_simple_ko_method simp_thm: set_object_def) apply (rule conjI; clarsimp elim!: rsubst[where P=P]; simp only:) apply (subst state_hyp_refs_of_ep_update[of ep, symmetric]) apply (clarsimp simp: obj_at_def) apply (simp add: fun_upd_def) apply (subst state_hyp_refs_of_ntfn_update[of ep, symmetric]) apply (clarsimp simp: obj_at_def) apply (simp add: fun_upd_def) done lemma set_ntfn_refs_of[wp]: "\\s. P ((state_refs_of s) (ntfnptr := ntfn_q_refs_of (ntfn_obj ntfn) \ ntfn_bound_refs (ntfn_bound_tcb ntfn)))\ set_notification ntfnptr ntfn \\rv s. P (state_refs_of s)\" by (wp; fastforce simp: state_refs_of_def elim!: rsubst[where P=P]) lemma pspace_distinct_same_type: "\ kheap s t = Some ko; a_type ko = a_type ko'; pspace_distinct s\ \ pspace_distinct (s\kheap := kheap s(t \ ko')\)" apply (clarsimp simp add: pspace_distinct_def obj_bits_T) apply fastforce done lemma set_object_distinct: "\obj_at (\ko. a_type ko = a_type ko') p and pspace_distinct\ set_object p ko' \\rv. pspace_distinct\" apply (simp add: set_object_def) apply wp apply (clarsimp simp: obj_at_def simp del: fun_upd_apply) apply (erule(2) pspace_distinct_same_type) done lemma set_simple_ko_distinct[wp]: "\pspace_distinct\ set_simple_ko f ep v \\_. pspace_distinct\" by (set_simple_ko_method wp_thm: set_object_distinct) lemma set_simple_ko_cur_tcb[wp]: "\cur_tcb\ set_simple_ko f ep v \\rv. cur_tcb\" by (set_simple_ko_method simp_thm: set_object_def cur_tcb_def is_tcb is_ep; fastforce) lemma assert_pre: "\P\ do s <- get; assert (P s); f od \Q\ \ \P\ f \Q\" by (simp add: valid_def assert_def get_def bind_def return_def) lemma set_object_pspace_in_kernel_window: "\pspace_in_kernel_window and obj_at (\ko. a_type k = a_type ko) p\ set_object p k \\r. pspace_in_kernel_window\" unfolding set_object_def apply (rule assert_pre) apply (rule hoare_pre) apply (rule pspace_in_kernel_window_atyp_lift) apply (wp; clarsimp simp add: obj_at_def)+ by simp lemma set_object_pspace_respects_device_region: "\pspace_respects_device_region and obj_at (\ko. a_type k = a_type ko) p\ set_object p k \\r. pspace_respects_device_region\" apply (simp add: set_object_def, wp) apply (clarsimp simp: pspace_respects_device_region_def device_mem_obj_upd_dom user_mem_obj_upd_dom obj_at_def in_user_frame_obj_upd in_device_frame_obj_upd split: if_split_asm) done lemma set_simple_ko_kernel_window[wp]: "\pspace_in_kernel_window\ set_simple_ko f ptr val \\rv. pspace_in_kernel_window\" by (set_simple_ko_method wp_thm : set_object_pspace_in_kernel_window) lemma set_simple_ko_respect_device_region[wp]: "\pspace_respects_device_region\ set_simple_ko f ptr val \\rv. pspace_respects_device_region\" by (set_simple_ko_method wp_thm : set_object_pspace_respects_device_region) lemma swp_apply [simp]: "swp f x y = f y x" by (simp add: swp_def) lemma hoare_cte_wp_caps_of_state_lift: assumes c: "\P. \\s. P (caps_of_state s)\ f \\r s. P (caps_of_state s)\" shows "\\s. cte_wp_at P p s\ f \\r s. cte_wp_at P p s\" apply (simp add: cte_wp_at_caps_of_state) apply (rule c) done lemma valid_mdb_lift: assumes c: "\P. \\s. P (caps_of_state s)\ f \\r s. P (caps_of_state s)\" assumes m: "\P. \\s. P (cdt s)\ f \\r s. P (cdt s)\" assumes r: "\P. \\s. P (is_original_cap s)\ f \\r s. P (is_original_cap s)\" shows "\valid_mdb\ f \\r. valid_mdb\" apply (clarsimp simp add: valid_def valid_mdb_def mdb_cte_at_def) apply (frule_tac P1="op = (cdt s)" in use_valid [OF _ m], rule refl) apply (rule conjI) apply clarsimp apply (erule allE)+ apply (erule (1) impE) apply clarsimp apply (rule conjI) apply (erule use_valid [OF _ c [THEN hoare_cte_wp_caps_of_state_lift]]) apply simp apply (erule use_valid [OF _ c [THEN hoare_cte_wp_caps_of_state_lift]]) apply simp apply (rule use_valid [OF _ c], assumption+) apply (rule use_valid [OF _ r], assumption) apply simp done crunch no_cdt[wp]: set_simple_ko "\s. P (cdt s)" (wp: crunch_wps) lemma set_simple_ko_caps_of_state [wp]: "\\s. P (caps_of_state s)\ set_simple_ko f p ep \\r s. P (caps_of_state s)\" apply (set_simple_ko_method simp_thm: get_object_def bind_assoc set_object_def) apply (rule conjI; clarsimp split: if_splits; subst cte_wp_caps_of_lift; assumption?) apply (auto simp: cte_wp_at_cases) done lemma set_simple_ko_revokable [wp]: "\\s. P (is_original_cap s)\ set_simple_ko f p ep \\r s. P (is_original_cap s)\" by (set_simple_ko_method simp_thm: set_object_def) lemma set_ep_mdb [wp]: "\valid_mdb\ set_simple_ko f p ep \\r. valid_mdb\" by (wp valid_mdb_lift) lemma cte_wp_at_after_update: "\ obj_at (same_caps val) p' s \ \ cte_wp_at P p (kheap_update (\a b. if b = p' then Some val else kheap s b) s) = cte_wp_at P p s" by (fastforce simp: obj_at_def cte_wp_at_cases split: if_split_asm dest: bspec [OF _ ranI]) lemma ex_cap_to_after_update: "\ ex_nonz_cap_to p s; obj_at (same_caps val) p' s \ \ ex_nonz_cap_to p (kheap_update (\a b. if b = p' then Some val else kheap s b) s)" by (clarsimp simp: ex_nonz_cap_to_def cte_wp_at_after_update) lemma ex_cte_cap_to_after_update: "\ ex_cte_cap_wp_to P p s; obj_at (same_caps val) p' s \ \ ex_cte_cap_wp_to P p (kheap_update (\a b. if b = p' then Some val else kheap s b) s)" by (clarsimp simp: ex_cte_cap_wp_to_def cte_wp_at_after_update) lemma set_object_iflive[wp]: "\\s. if_live_then_nonz_cap s \ (live val \ ex_nonz_cap_to p s) \ obj_at (same_caps val) p s\ set_object p val \\rv. if_live_then_nonz_cap\" apply (simp add: set_object_def) apply wp apply (fastforce simp: if_live_then_nonz_cap_def obj_at_def elim!: ex_cap_to_after_update) done lemma set_object_ifunsafe[wp]: "\if_unsafe_then_cap and obj_at (same_caps val) p\ set_object p val \\rv. if_unsafe_then_cap\" apply (simp add: set_object_def) apply wp apply (clarsimp simp: if_unsafe_then_cap_def simp: cte_wp_at_after_update dest!: caps_of_state_cteD) apply (clarsimp simp: cte_wp_at_caps_of_state) apply (fastforce elim!: ex_cte_cap_to_after_update) done lemma set_object_zombies[wp]: "\zombies_final and obj_at (same_caps val) p\ set_object p val \\rv. zombies_final\" apply (simp add: set_object_def) apply wp apply (clarsimp simp: zombies_final_def is_final_cap'_def2 cte_wp_at_after_update) done lemma set_simple_ko_iflive[wp]: "\\s. if_live_then_nonz_cap s \ (live (f ep) \ ex_nonz_cap_to p s)\ set_simple_ko f p ep \\rv. if_live_then_nonz_cap\" apply (set_simple_ko_method wp_thm: set_object_iflive) apply (rule conjI; clarsimp elim!: obj_at_weakenE split: Structures_A.kernel_object.splits simp: is_ep_def is_ntfn_def) done lemma set_simple_ko_ifunsafe[wp]: "\if_unsafe_then_cap\ set_simple_ko f p val \\rv. if_unsafe_then_cap\" apply (set_simple_ko_method wp_thm: ) by (clarsimp elim!: obj_at_weakenE simp: is_ep_def is_ntfn_def) lemma set_simple_ko_zombies[wp]: "\zombies_final\ set_simple_ko f p val \\rv. zombies_final\" apply (set_simple_ko_method wp_thm: ) by (clarsimp elim!: obj_at_weakenE simp: is_ep_def is_ntfn_def) lemma set_object_cap_refs_in_kernel_window: "\cap_refs_in_kernel_window and obj_at (same_caps ko) p\ set_object p ko \\r. cap_refs_in_kernel_window\" apply (simp add: set_object_def, wp) apply (clarsimp simp: cap_refs_in_kernel_window_def) apply (clarsimp simp: valid_refs_def cte_wp_at_after_update) done lemma set_object_cap_refs_respects_device_region: "\cap_refs_respects_device_region and obj_at (same_caps ko) p\ set_object p ko \\r. cap_refs_respects_device_region\" apply (simp add: set_object_def, wp) apply (clarsimp simp: cap_refs_respects_device_region_def) apply (drule_tac x = a in spec) apply (drule_tac x = b in spec) apply (clarsimp simp: valid_refs_def cte_wp_at_after_update cap_range_respects_device_region_def) apply (erule notE) apply (erule cte_wp_at_weakenE) apply auto done crunch no_revokable[wp]: set_simple_ko "\s. P (is_original_cap s)" (wp: crunch_wps) lemma get_object_ret: "\obj_at P addr\ get_object addr \\r s. P r\" unfolding get_object_def by (wp, clarsimp elim!: obj_atE)+ lemma mask_in_range: "is_aligned ptr bits \ (ptr' && (~~ mask bits) = ptr) = (ptr' \ {ptr .. ptr + 2 ^ bits - 1})" apply (erule is_aligned_get_word_bits) defer apply (simp add: power_overflow mask_def) apply (rule iffI) apply (drule sym) apply (simp add: word_and_le2) apply (subst field_simps[symmetric], subst mask_2pm1[symmetric]) apply (subst word_plus_and_or_coroll) apply (rule word_eqI, clarsimp simp: word_ops_nth_size) apply (subgoal_tac "ptr' && ~~ mask bits || mask bits = ptr' || mask bits") apply (simp add: le_word_or2) apply (rule word_eqI, clarsimp simp: word_ops_nth_size word_size) apply fastforce apply (subgoal_tac "\x. ptr' = ptr || x \ x && mask bits = x") apply (rule word_eqI) apply (clarsimp simp: word_ops_nth_size word_size is_aligned_mask) apply (drule_tac x=n in word_eqD)+ apply (simp add: word_ops_nth_size word_size is_aligned_mask) apply safe[1] apply (subgoal_tac "\x. ptr' = ptr + x") apply clarsimp apply (drule(1) word_le_minus_mono_left[where x=ptr]) apply simp apply (subst conj_commute) apply (rule exI, rule context_conjI[OF _ word_plus_and_or_coroll]) apply (subst mask_eq_iff_w2p) apply (simp add: word_bits_conv word_size) apply (rule minus_one_helper5) apply simp apply simp apply (simp add: is_aligned_mask) apply (rule word_eqI) apply (drule_tac x=n in word_eqD)+ apply (clarsimp simp: word_ops_nth_size word_size) apply (rule exI[where x="ptr' - ptr"]) apply simp done lemma captable_case_helper: "\ \sz cs. ob \ CNode sz cs \ \ (case ob of CNode sz cs \ P sz cs | _ \ Q) = Q" by (case_tac ob, simp_all add: not_ex[symmetric]) lemma null_filter_caps_of_stateD: "null_filter (caps_of_state s) p = Some c \ cte_wp_at (\c'. c' = c \ c' \ cap.NullCap) p s" apply (simp add: null_filter_def split: if_split_asm) apply (drule caps_of_state_cteD) apply (simp add: cte_wp_at_def) done lemma caps_of_state_after_update: "obj_at (same_caps val) p s \ (caps_of_state (kheap_update (\a b. if b = p then Some val else kheap s b) s)) = caps_of_state s" by (simp add: caps_of_state_cte_wp_at cte_wp_at_after_update cong: if_cong) lemma elim_CNode_case: "\ (case x of CNode sz ct \ False | _ \ True) \ \ (case x of CNode sz ct \ f sz ct | _ \ k) = k" by (simp split: Structures_A.kernel_object.split_asm) lemma no_fail_obj_at [wp]: "no_fail (obj_at \ ptr) (get_object ptr)" apply (simp add: get_object_def) apply (rule no_fail_pre, wp) apply (fastforce simp: obj_at_def) done lemma do_machine_op_obj_at[wp]: "\\s. P (obj_at Q p s)\ do_machine_op f \\_ s. P (obj_at Q p s)\" by (clarsimp simp: do_machine_op_def split_def | wp)+ lemma dmo_cur_tcb[wp]: "\cur_tcb\ do_machine_op f \\_. cur_tcb\" apply (simp add: do_machine_op_def split_def) apply wp apply (clarsimp simp: cur_tcb_def) done lemma valid_irq_states_machine_state_updateI: "(\irq. interrupt_states s irq = IRQInactive \ irq_masks m irq) \ valid_irq_states (s\machine_state := m\)" apply(simp add: valid_irq_states_def valid_irq_masks_def) done lemma valid_irq_statesE: "\valid_irq_states s; (\ irq. interrupt_states s irq = IRQInactive \ irq_masks (machine_state s) irq) \ R\ \ R" by(auto simp: valid_irq_states_def valid_irq_masks_def) lemma cap_refs_respects_region_cong: "\caps_of_state a = caps_of_state b; device_state (machine_state a) = device_state (machine_state b)\ \ cap_refs_respects_device_region a = cap_refs_respects_device_region b" by (simp add: cap_refs_respects_device_region_def cte_wp_at_caps_of_state dom_def cap_range_respects_device_region_def) lemmas device_region_congs[cong] = pspace_respects_region_cong cap_refs_respects_region_cong lemma dmo_invs1: assumes valid_mf: "\P. \\ms. P (device_state ms)\ f \\r ms. P (device_state ms)\" shows "\(\s. \m. \(r,m')\fst (f m). m = machine_state s \ (\p. in_user_frame p s \ underlying_memory m' p = underlying_memory m p) \ ((\irq. (interrupt_states s irq = IRQInactive \ irq_masks m' irq) \ (irq_masks m' irq = irq_masks m irq)))) and invs\ do_machine_op f \\_. invs\" apply (simp add: do_machine_op_def split_def) apply wp apply (clarsimp simp: invs_def cur_tcb_def valid_state_def valid_machine_state_def intro!: valid_irq_states_machine_state_updateI elim: valid_irq_statesE) apply (frule_tac P1 = "op = (device_state (machine_state s))" in use_valid[OF _ valid_mf]) apply simp apply clarsimp apply (intro conjI) apply (fastforce simp: invs_def cur_tcb_def valid_state_def valid_machine_state_def intro: valid_irq_states_machine_state_updateI elim: valid_irq_statesE) apply fastforce done lemma dmo_invs: assumes valid_mf: "\P. \\ms. P (device_state ms)\ f \\r ms. P (device_state ms)\" shows "\(\s. \m. \(r,m')\fst (f m). (\p. in_user_frame p s \ underlying_memory m' p = underlying_memory m p) \ ((\irq. m = machine_state s \ (interrupt_states s irq = IRQInactive \ irq_masks m' irq) \ (irq_masks m' irq = irq_masks m irq)))) and invs\ do_machine_op f \\_. invs\" apply (wp dmo_invs1 valid_mf) apply clarsimp apply (drule spec, drule(1) bspec) apply simp done lemma as_user_typ_at[wp]: "\\s. P (typ_at T p s)\ as_user t m \\rv s. P (typ_at T p s)\" unfolding as_user_def apply (simp add: as_user_def split_def set_object_def) apply wp apply (clarsimp simp: obj_at_def) apply (drule get_tcb_SomeD) apply clarsimp done lemma as_user_no_del_ntfn[wp]: "\ntfn_at p\ as_user t m \\rv. ntfn_at p\" by (simp add: ntfn_at_typ, rule as_user_typ_at) lemma as_user_no_del_ep[wp]: "\ep_at p\ as_user t m \\rv. ep_at p\" by (simp add: ep_at_typ, rule as_user_typ_at) lemma set_simple_ko_tcb[wp]: "\ tcb_at t \ set_simple_ko f ep v \ \rv. tcb_at t \" by (simp add: tcb_at_typ) wp lemma set_simple_ko_pred_tcb_at [wp]: "\ pred_tcb_at proj f t \ set_simple_ko g ep v \ \rv. pred_tcb_at proj f t \" by(set_simple_ko_method wp_thm: set_object_at_obj2 simp_thm: pred_tcb_at_def) lemma set_endpoint_ep_at[wp]: "\ep_at ptr'\ set_endpoint ptr val \\rv. ep_at ptr'\" by (simp add: ep_at_typ, wp) lemma set_notification_ntfn_at[wp]: "\ntfn_at ptr'\ set_notification ptr val \\rv. ntfn_at ptr'\" by (simp add: ntfn_at_typ, wp) lemma cte_wp_at_neg2: "(\ cte_wp_at P p s) = (cte_at p s \ cte_wp_at (\cap. \ P cap) p s)" by (fastforce simp: cte_wp_at_def) lemma cte_wp_at_neg: "cte_wp_at (\cap. \ P cap) p s = (cte_at p s \ \ cte_wp_at P p s)" by (fastforce simp: cte_wp_at_def) lemma valid_cte_at_neg_typ: assumes x: "\P T p. \\s. P (typ_at T p s)\ f \\rv s. P (typ_at T p s)\" shows "\\s. \ cte_at p s\ f \\rv s. \ cte_at p s\" apply (simp add: cte_at_typ) apply (rule hoare_vcg_conj_lift [OF x]) apply (simp only: imp_conv_disj) apply (rule hoare_vcg_disj_lift [OF x]) apply (rule hoare_vcg_prop) done lemma ex_nonz_cap_to_pres: assumes y: "\P p. \cte_wp_at P p\ f \\rv. cte_wp_at P p\" shows "\ex_nonz_cap_to p\ f \\rv. ex_nonz_cap_to p\" apply (simp only: ex_nonz_cap_to_def not_ex) apply (intro hoare_vcg_disj_lift hoare_vcg_ex_lift y hoare_vcg_all_lift valid_cte_at_neg_typ) done lemma set_simple_ko_ex_cap[wp]: "\ex_nonz_cap_to p\ set_simple_ko f p' v \\rv. ex_nonz_cap_to p\" by (wp ex_nonz_cap_to_pres) crunch it[wp]: set_simple_ko "\s. P (idle_thread s)" (wp: crunch_wps simp: crunch_simps) lemma set_simple_ko_idle[wp]: "\obj_at (\ko. partial_inv f ko \ None) ptr and valid_idle\ set_simple_ko f ptr ep \\_. valid_idle\" by (set_simple_ko_method simp_thm: set_object_def obj_at_def valid_idle_def pred_tcb_at_def) (* FIXME-NTFN *) lemma ep_redux_simps: "valid_ep (case xs of [] \ Structures_A.IdleEP | y # ys \ Structures_A.SendEP (y # ys)) = (\s. distinct xs \ (\t\set xs. tcb_at t s))" "valid_ep (case xs of [] \ Structures_A.IdleEP | y # ys \ Structures_A.RecvEP (y # ys)) = (\s. distinct xs \ (\t\set xs. tcb_at t s))" "valid_ntfn (ntfn\ntfn_obj := (case xs of [] \ Structures_A.IdleNtfn | y # ys \ Structures_A.WaitingNtfn (y # ys))\) = (\s. distinct xs \ (\t\set xs. tcb_at t s) \ (case ntfn_bound_tcb ntfn of Some t \ tcb_at t s \ (case xs of y # ys \ xs = [t] | _ \ True) | _ \ True))" "ep_q_refs_of (case xs of [] \ Structures_A.IdleEP | y # ys \ Structures_A.SendEP (y # ys)) = (set xs \ {EPSend})" "ep_q_refs_of (case xs of [] \ Structures_A.IdleEP | y # ys \ Structures_A.RecvEP (y # ys)) = (set xs \ {EPRecv})" "ntfn_q_refs_of (case xs of [] \ Structures_A.IdleNtfn | y # ys \ Structures_A.WaitingNtfn (y # ys)) = (set xs \ {NTFNSignal})" by (fastforce split: list.splits option.splits simp: valid_ep_def valid_ntfn_def valid_bound_tcb_def intro!: ext)+ crunch arch[wp]: set_simple_ko "\s. P (arch_state s)" (wp: crunch_wps simp: crunch_simps) crunch irq_node_inv[wp]: set_simple_ko "\s. P (interrupt_irq_node s)" (wp: crunch_wps) lemma set_simple_ko_global_refs [wp]: "\valid_global_refs\ set_simple_ko f ntfn p \\_. valid_global_refs\" by (rule valid_global_refs_cte_lift; wpsimp) lemma set_simple_ko_reply[wp]: "\valid_reply_caps\ set_simple_ko f p ep \\_. valid_reply_caps\" by (wp valid_reply_caps_st_cte_lift) lemma set_simple_ko_reply_masters[wp]: "\valid_reply_masters\ set_simple_ko f p ep \\_. valid_reply_masters\" by (wp valid_reply_masters_cte_lift) lemma obj_at_ko_atE: "\ obj_at P ptr s; ko_at k ptr s; P k \ Q \ \ Q" by (clarsimp simp: obj_at_def) crunch interrupt_states[wp]: set_simple_ko "\s. P (interrupt_states s)" (wp: crunch_wps) lemma set_object_non_arch: "arch_obj_pred P' \ \(\s. P (obj_at P' p' s)) and K(non_arch_obj ko) and obj_at non_arch_obj p \ set_object p ko \\r s. P (obj_at P' p' s)\" unfolding set_object_def apply wp apply clarsimp apply (erule_tac P=P in rsubst) apply (clarsimp simp: obj_at_def) by (rule arch_obj_predE) lemma set_object_non_pagetable: "vspace_obj_pred P' \ \(\s. P (obj_at P' p' s)) and K(non_vspace_obj ko) and obj_at non_vspace_obj p \ set_object p ko \\r s. P (obj_at P' p' s)\" unfolding set_object_def apply wp apply clarsimp apply (erule_tac P=P in rsubst) apply (clarsimp simp: obj_at_def) by (rule vspace_obj_predE) lemma set_object_memory[wp]: "\\s. P (underlying_memory (machine_state s))\ set_object p ko \\_ s. P (underlying_memory (machine_state s))\" unfolding set_object_def apply wp by simp end locale non_aobj_op = fixes f assumes aobj_at: "\P P' p. arch_obj_pred P' \ \\s. P (obj_at P' p s)\ f \\r s. P (obj_at P' p s)\" and arch_state[wp]: "\P. \\s. P (arch_state s)\ f \\r s. P (arch_state s)\" context non_aobj_op begin lemma valid_arch_state[wp]:"\valid_arch_state\ f \\_. valid_arch_state\" by (rule valid_arch_state_lift_aobj_at; wp aobj_at; simp) end locale non_vspace_op = fixes f assumes vsobj_at: "\P P' p. vspace_obj_pred P' \ \\s. P (obj_at P' p s)\ f \\r s. P (obj_at P' p s)\" and arch_state'[wp]: "\P. \\s. P (arch_state s)\ f \\r s. P (arch_state s)\" sublocale non_aobj_op < non_vspace_op apply (unfold_locales) apply (auto simp: vspace_pred_imp arch_state aobj_at) done context non_vspace_op begin lemma valid_vspace_obj[wp]:"\valid_vspace_objs\ f \\_. valid_vspace_objs\" by (rule valid_vspace_objs_lift_weak; wp vsobj_at; simp) lemma vs_lookup[wp]: "\\s. P (vs_lookup s)\ f \\_ s. P (vs_lookup s)\" by (rule vs_lookup_vspace_obj_at_lift; wp vsobj_at; simp) lemma vs_lookup_pages[wp]: "\\s. P (vs_lookup_pages s)\ f \\_ s. P (vs_lookup_pages s)\" by (rule vs_lookup_pages_vspace_obj_at_lift; wp vsobj_at; simp) lemma valid_global_objs[wp]: "\valid_global_objs\ f \\_. valid_global_objs\" by (rule valid_global_objs_lift_weak, (wp vsobj_at)+) lemma valid_global_vspace_mappings[wp]: "\valid_global_vspace_mappings\ f \\_. valid_global_vspace_mappings\" by (rule valid_global_vspace_mappings_lift, (wp vsobj_at)+) lemma valid_asid_map[wp]: "\valid_asid_map\ f \\_. valid_asid_map\" by (rule valid_asid_map_lift, (wp vsobj_at)+) lemma valid_kernel_mappings[wp]: "\valid_kernel_mappings\ f \\_. valid_kernel_mappings\" by (rule valid_kernel_mappings_lift, (wp vsobj_at)+) lemma equal_kernel_mappings[wp]: "\equal_kernel_mappings\ f \\_. equal_kernel_mappings\" by (rule equal_kernel_mappings_lift, wp vsobj_at) lemma valid_vso_at[wp]:"\valid_vso_at p\ f \\_. valid_vso_at p\" by (rule valid_vso_at_lift_aobj_at; wp vsobj_at; simp) lemma in_user_frame[wp]:"\in_user_frame p\ f \\_. in_user_frame p\" by (rule in_user_frame_obj_pred_lift; wp vsobj_at; simp) end locale non_mem_op = fixes f assumes memory[wp]: "\P. \\s. P (underlying_memory (machine_state s))\ f \\_ s. P (underlying_memory (machine_state s))\" (* non_vspace_op version *) locale non_vspace_non_mem_op = non_vspace_op f + non_mem_op f for f begin lemma valid_machine_state[wp]: "\valid_machine_state\ f \\rv. valid_machine_state\" unfolding valid_machine_state_def by (wp hoare_vcg_disj_lift hoare_vcg_all_lift vsobj_at memory) end locale non_aobj_non_mem_op = non_aobj_op f + non_mem_op f for f sublocale non_aobj_non_mem_op < non_vspace_non_mem_op .. (* non_vspace_op version *) locale non_cap_op = fixes f assumes caps[wp]: "\P. \\s. P (caps_of_state s)\ f \\_ s. P (caps_of_state s)\" locale non_vspace_non_cap_op = non_vspace_op f + non_cap_op f for f begin lemma valid_arch_caps[wp]: "\valid_arch_caps\ f \\_. valid_arch_caps\" by (rule valid_arch_caps_lift_weak[OF arch_state' vsobj_at caps]) end locale non_aobj_non_cap_op = non_aobj_op f + non_cap_op f for f sublocale non_aobj_non_cap_op < non_vspace_non_cap_op .. (* non_vspace_op version *) locale non_vspace_non_cap_non_mem_op = non_vspace_non_mem_op f + non_vspace_non_cap_op f for f locale non_aobj_non_cap_non_mem_op = non_aobj_non_mem_op f + non_aobj_non_cap_op f for f sublocale non_aobj_non_cap_non_mem_op < non_vspace_non_cap_non_mem_op .. lemma shows sts_caps_of_state[wp]: "\\s. P (caps_of_state s)\ set_thread_state t st \\_ s. P (caps_of_state s)\" and set_bound_caps_of_state[wp]: "\\s. P (caps_of_state s)\ set_bound_notification t e \\_ s. P (caps_of_state s)\" and as_user_caps_of_state[wp]: "\\s. P (caps_of_state s)\ as_user p f \\_ s. P (caps_of_state s)\" unfolding set_thread_state_def set_bound_notification_def as_user_def set_object_def set_mrs_def apply (all \(wp | wpc | simp)+ ; clarsimp, erule rsubst[where P=P], rule cte_wp_caps_of_lift\) by (auto simp: cte_wp_at_cases2 tcb_cnode_map_def dest!: get_tcb_SomeD) lemma store_word_offs_caps_of_state[wp]: "\\s. P (caps_of_state s)\ store_word_offs a b c \\_ s. P (caps_of_state s)\" unfolding store_word_offs_def do_machine_op_def[abs_def] by wpsimp lemma set_mrs_caps_of_state[wp]: "\\s. P (caps_of_state s)\ set_mrs thread buf msgs \\_ s. P (caps_of_state s)\" unfolding set_mrs_def set_object_def[abs_def] apply (wp mapM_x_inv_wp | wpc | simp add: zipWithM_x_mapM_x split del: if_split | clarsimp)+ apply (safe; erule rsubst[where P=P], rule cte_wp_caps_of_lift) by (auto simp: cte_wp_at_cases2 tcb_cnode_map_def dest!: get_tcb_SomeD) interpretation set_simple_ko: non_aobj_non_cap_non_mem_op "set_simple_ko c p ep" + sts: non_aobj_non_cap_non_mem_op "set_thread_state p st" + sbn: non_aobj_non_cap_non_mem_op "set_bound_notification p b" + as_user: non_aobj_non_cap_non_mem_op "as_user p g" + thread_set: non_aobj_non_mem_op "thread_set f p" + set_cap: non_aobj_non_mem_op "set_cap cap p'" apply (all \unfold_locales; (wp ; fail)?\) unfolding set_simple_ko_def set_thread_state_def set_bound_notification_def thread_set_def set_cap_def[simplified split_def] as_user_def set_mrs_def apply - apply (all \(wp set_object_non_arch get_object_wp | wpc | simp split del: if_split)+\) apply (auto simp: obj_at_def[abs_def] partial_inv_def the_equality split: Structures_A.kernel_object.splits)[1] by (fastforce simp: obj_at_def[abs_def] a_type_def split: Structures_A.kernel_object.splits)+ lemmas set_cap_arch[wp] = set_cap.arch_state interpretation store_word_offs: non_aobj_non_cap_op "store_word_offs a b c" apply unfold_locales unfolding store_word_offs_def do_machine_op_def[abs_def] by wpsimp+ lemma store_word_offs_obj_at_P[wp]: "\\s. P (obj_at P' p s)\ store_word_offs a b c \\r s. P (obj_at P' p s)\" unfolding store_word_offs_def by (wp | fastforce)+ interpretation set_mrs: non_aobj_non_cap_op "set_mrs thread buf msgs" apply unfold_locales apply (all \(wp ; fail)?\) unfolding set_mrs_def set_object_def apply (all \(wp mapM_x_inv_wp | wpc | simp add: zipWithM_x_mapM_x split del: if_split | clarsimp)+\) apply (rule drop_imp) apply (clarsimp simp: obj_at_def get_tcb_def split: kernel_object.splits option.splits) subgoal for _ P' by (subst arch_obj_predE[where P="P'"]) auto done lemma valid_irq_handlers_lift: assumes x: "\P. \\s. P (caps_of_state s)\ f \\rv s. P (caps_of_state s)\" assumes y: "\P. \\s. P (interrupt_states s)\ f \\rv s. P (interrupt_states s)\" shows "\valid_irq_handlers\ f \\rv. valid_irq_handlers\" apply (simp add: valid_irq_handlers_def irq_issued_def) apply (rule hoare_use_eq [where f=caps_of_state, OF x y]) done lemmas set_simple_ko_valid_irq_handlers[wp] = valid_irq_handlers_lift [OF set_simple_ko_caps_of_state set_simple_ko_interrupt_states] crunch irq_node[wp]: set_simple_ko "\s. P (interrupt_irq_node s)" lemmas hoare_use_eq_irq_node = hoare_use_eq[where f=interrupt_irq_node] lemma cap_table_at_lift_valid: "\ \T. \typ_at T p\ f \\rv. typ_at T p\ \ \ \cap_table_at n p\ f \\rv. cap_table_at n p\" by (simp add: cap_table_at_typ) lemmas cap_table_at_lift_irq = hoare_use_eq_irq_node [OF _ cap_table_at_lift_valid] crunch interrupt_states[wp]: set_notification "\s. P (interrupt_states s)" (wp: crunch_wps) lemma set_simple_ko_only_idle [wp]: "\only_idle\ set_simple_ko f p ntfn \\_. only_idle\" by (wp only_idle_lift) lemma set_simple_ko_cap_refs_kernel_window[wp]: "\cap_refs_in_kernel_window\ set_simple_ko f p ep \\rv. cap_refs_in_kernel_window\" by (set_simple_ko_method wp_thm: set_object_cap_refs_in_kernel_window get_object_wp simp_thm: is_ep_def is_ntfn_def) lemma set_simple_ko_cap_refs_respects_device_region[wp]: "\cap_refs_respects_device_region\ set_simple_ko f p ep \\rv. cap_refs_respects_device_region\" by (set_simple_ko_method wp_thm: set_object_cap_refs_respects_device_region get_object_wp simp_thm: is_ep_def is_ntfn_def) crunch v_ker_map[wp]: set_simple_ko "valid_kernel_mappings" (ignore: set_object wp: set_object_v_ker_map crunch_wps simp: set_simple_ko_def) (* There are two wp rules for preserving valid_ioc over set_object. First, the more involved rule for CNodes and TCBs *) lemma set_object_valid_ioc_caps: "\\s. valid_ioc s \ typ_at (a_type obj) ptr s \ (\b. is_original_cap s (ptr,b) \ null_filter (cap_of obj) b \ None)\ set_object ptr obj \\_ s. valid_ioc s\" apply (clarsimp simp: set_object_def valid_def get_def put_def bind_def return_def) apply (clarsimp simp add: valid_ioc_def) apply (drule spec, drule spec, erule impE, assumption) apply (case_tac "a=ptr", simp_all add: cte_wp_at_cases) apply (drule spec, erule impE, assumption) apply (erule disjE) apply (rule disjI1) apply (clarsimp simp add: obj_at_def a_type_simps) apply (fastforce simp: a_type_def cap_of_def null_filter_def split: Structures_A.kernel_object.splits if_split_asm) apply (rule disjI2) apply (clarsimp simp add: obj_at_def a_type_simps) apply (fastforce simp: a_type_def cap_of_def tcb_cnode_map_def null_filter_def split: Structures_A.kernel_object.splits if_split_asm) done (* Second, the simpler rule suitable for all objects except CNodes and TCBs. *) lemma set_object_valid_ioc_no_caps: "\\s. valid_ioc s \ typ_at (a_type obj) ptr s \ \ is_tcb obj \ (\n. \ is_cap_table n obj) \ set_object ptr obj \\_ s. valid_ioc s\" apply (clarsimp simp: set_object_def valid_def get_def put_def bind_def return_def) apply (clarsimp simp add: valid_ioc_def cte_wp_at_cases is_tcb) apply (drule spec, drule spec, erule impE, assumption) apply (elim disjE) prefer 2 apply (fastforce simp: obj_at_def a_type_def split: Structures_A.kernel_object.splits if_split_asm) apply (fastforce simp: obj_at_def a_type_def is_cap_table_def well_formed_cnode_n_def split: Structures_A.kernel_object.splits if_split_asm) done lemma set_simple_ko_valid_ioc[wp]: "\valid_ioc\ set_simple_ko f ptr val \\_. valid_ioc\" by (set_simple_ko_method wp_thm: set_object_valid_ioc_no_caps get_object_wp simp_thm: is_tcb_def is_cap_table_def) lemma set_object_machine_state[wp]: "\\s. P (machine_state s)\ set_object p ko \\_ s. P (machine_state s)\" by (simp add: set_object_def, wp, simp) lemma valid_irq_states_triv: assumes irqs: "\P. \\s. P (interrupt_states s)\ f \\_ s. P (interrupt_states s)\" assumes ms: "\P. \\s. P (machine_state s)\ f \\_ s. P (machine_state s)\" shows "\ valid_irq_states \ f \\_. valid_irq_states \" apply(clarsimp simp: valid_def valid_irq_states_def valid_irq_masks_def) apply(case_tac "interrupt_states s irq = IRQInactive") apply(erule use_valid[OF _ ms]) apply blast apply(drule_tac P1="\x. x irq \ IRQInactive" in use_valid[OF _ irqs]) apply assumption by blast crunch valid_irq_states[wp]: set_simple_ko "valid_irq_states" (wp: crunch_wps simp: crunch_simps rule: valid_irq_states_triv) crunch valid_irq_states[wp]: set_cap "valid_irq_states" (wp: crunch_wps simp: crunch_simps) crunch valid_irq_states[wp]: thread_set "valid_irq_states" (wp: crunch_wps simp: crunch_simps) crunch valid_irq_states[wp]: set_thread_state, set_bound_notification "valid_irq_states" (wp: crunch_wps simp: crunch_simps) lemma set_ntfn_minor_invs: "\invs and ntfn_at ptr and obj_at (\ko. refs_of ko = ntfn_q_refs_of (ntfn_obj val) \ ntfn_bound_refs (ntfn_bound_tcb val)) ptr and valid_ntfn val and (\s. \typ. (idle_thread s, typ) \ ntfn_q_refs_of (ntfn_obj val)) and (\s. live (Notification val) \ ex_nonz_cap_to ptr s)\ set_notification ptr val \\rv. invs\" apply (simp add: invs_def valid_state_def valid_pspace_def) apply (wp set_simple_ko_valid_objs valid_irq_node_typ valid_irq_handlers_lift valid_ioports_lift) apply (clarsimp simp: ntfn_at_def2 elim!: rsubst[where P=sym_refs] intro!: ext dest!: obj_at_state_refs_ofD) done crunch asid_map[wp]: set_bound_notification "valid_asid_map" lemma dmo_aligned[wp]: "\pspace_aligned\ do_machine_op f \\_. pspace_aligned\" apply (simp add: do_machine_op_def split_def) apply (wp select_wp) apply (clarsimp simp: pspace_aligned_def) done lemma do_machine_op_result[wp]: "\P\ mop \\rv s. Q rv\ \ \\s. P (machine_state s)\ do_machine_op mop \\rv s. Q rv\" apply (simp add: do_machine_op_def split_def) apply wp apply clarsimp apply (erule(2) use_valid) done lemma dmo_zombies[wp]: "\zombies_final\ do_machine_op oper \\rv. zombies_final\" apply (simp add: do_machine_op_def split_def) apply wp apply (clarsimp elim!: zombies_final_pspaceI) done lemma dmo_iflive[wp]: "\if_live_then_nonz_cap\ do_machine_op oper \\_. if_live_then_nonz_cap\" apply (simp add: do_machine_op_def split_def) apply wp apply (clarsimp elim!: iflive_pspaceI) done lemma dmo_ifunsafe[wp]: "\if_unsafe_then_cap\ do_machine_op oper \\_. if_unsafe_then_cap\" apply (simp add: do_machine_op_def split_def) apply wp apply (clarsimp elim!: ifunsafe_pspaceI) done lemma dmo_refs_of[wp]: "\\s. P (state_refs_of s)\ do_machine_op oper \\rv s. P (state_refs_of s)\" apply (simp add: do_machine_op_def split_def) apply wp apply (clarsimp elim!: state_refs_of_pspaceI) done lemma dmo_hyp_refs_of[wp]: "\\s. P (state_hyp_refs_of s)\ do_machine_op oper \\rv s. P (state_hyp_refs_of s)\" apply (simp add: do_machine_op_def split_def) apply wp apply (clarsimp elim!: state_hyp_refs_of_pspaceI) done crunch it[wp]: do_machine_op "\s. P (idle_thread s)" crunch irq_node[wp]: do_machine_op "\s. P (interrupt_irq_node s)" crunch cte_wp_at[wp]: do_machine_op "\s. P (cte_wp_at P' c s)" (wp: crunch_wps) crunch valid_idle[wp]: do_machine_op "valid_idle" (wp: crunch_wps simp: crunch_simps) crunch reply[wp]: do_machine_op "valid_reply_caps" crunch reply_masters[wp]: do_machine_op "valid_reply_masters" crunch valid_irq_handlers[wp]: do_machine_op "valid_irq_handlers" crunch valid_global_objs[wp]: do_machine_op "valid_global_objs" crunch valid_global_vspace_mappings[wp]: do_machine_op "valid_global_vspace_mappings" crunch valid_arch_caps[wp]: do_machine_op "valid_arch_caps" lemma dmo_cap_to[wp]: "\ex_nonz_cap_to p\ do_machine_op mop \\rv. ex_nonz_cap_to p\" by (simp add: ex_nonz_cap_to_def, wp hoare_vcg_ex_lift) lemma dmo_st_tcb [wp]: "\pred_tcb_at proj P t\ do_machine_op f \\_. pred_tcb_at proj P t\" apply (simp add: do_machine_op_def split_def) apply (wp select_wp) apply (clarsimp simp: pred_tcb_at_def obj_at_def) done crunch ct[wp]: do_machine_op "\s. P (cur_thread s)" (wp: select_wp) lemma do_machine_op_arch [wp]: "\\s. P (arch_state s)\ do_machine_op f \\_ s. P (arch_state s)\" apply (simp add: do_machine_op_def split_def) apply wp apply simp done lemma do_machine_op_valid_arch [wp]: "\valid_arch_state\ do_machine_op f \\_. valid_arch_state\" by (rule valid_arch_state_lift) wp+ lemma do_machine_op_vs_lookup [wp]: "\\s. P (vs_lookup s)\ do_machine_op f \\_ s. P (vs_lookup s)\" apply (rule vs_lookup_vspace_obj_at_lift) apply (simp add: do_machine_op_def split_def) apply (wp | simp)+ done lemma dmo_inv: assumes R: "\P. \P\ f \\_. P\" shows "\P\ do_machine_op f \\_. P\" apply (simp add: do_machine_op_def split_def) apply (wp select_f_wp) apply (clarsimp simp del: ) apply (drule in_inv_by_hoareD [OF R]) apply simp done lemma dom_objs [wp]: "\valid_objs\ do_machine_op f \\_. valid_objs\" apply (simp add: do_machine_op_def split_def) apply (wp select_wp) apply (fastforce intro: valid_objs_pspaceI) done lemma tcb_cap_wp_at: "\tcb_at t s; valid_objs s; ref \ dom tcb_cap_cases; \cap st getF setF restr. tcb_cap_cases ref = Some (getF, setF, restr) \ restr t st cap \ Q cap\ \ cte_wp_at Q (t, ref) s" apply (clarsimp simp: cte_wp_at_cases tcb_at_def dest!: get_tcb_SomeD) apply (rename_tac getF setF restr) apply (erule(1) valid_objsE) apply (clarsimp simp add: valid_obj_def valid_tcb_def) apply (erule_tac x="(getF, setF, restr)" in ballE) apply (fastforce simp add: ranI)+ done lemma tcb_cap_valid_caps_of_stateD: "\ caps_of_state s p = Some cap; valid_objs s \ \ tcb_cap_valid cap p s" apply (rule cte_wp_tcb_cap_valid) apply (simp add: cte_wp_at_caps_of_state) apply assumption done lemma add_mask_eq: "\is_aligned (w::'a::len word) n; x \ 2 ^ n - 1; n < len_of TYPE('a)\ \ (w + x) && mask n = x" by (drule is_aligned_add_helper) auto lemma thread_get_wp': "\\s. \tcb. ko_at (TCB tcb) ptr s \ P (f tcb) s\ thread_get f ptr \P\" apply (simp add: thread_get_def) apply wp apply clarsimp apply (clarsimp simp: obj_at_def dest!: get_tcb_SomeD) done crunch valid_ioc[wp]: do_machine_op valid_ioc crunch inv[wp]: get_irq_slot "P" end