(* * 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 requalify_facts pspace_in_kernel_window_atyp_lift valid_arch_objs_lift_weak vs_lookup_arch_obj_at_lift vs_lookup_pages_arch_obj_at_lift valid_arch_caps_lift_weak valid_global_objs_lift_weak valid_asid_map_lift valid_kernel_mappings_lift equal_kernel_mappings_lift valid_global_vspace_mappings_lift valid_machine_state_lift valid_ao_at_lift_aobj_at valid_arch_state_lift_aobj_at valid_global_pts_lift in_user_frame_lift 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 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 lemma get_object_wp: "\\s. \ko. ko_at ko p s \ Q ko s\ get_object p \Q\" apply (clarsimp simp: get_object_def) apply wp apply (clarsimp simp: obj_at_def) done lemma get_ntfn_wp: "\\s. \ntfn. ko_at (Notification ntfn) ntfnptr s \ P ntfn s\ get_notification ntfnptr \P\" apply (simp add: get_notification_def) apply (wp get_object_wp | wpc)+ apply clarsimp done lemma get_object_inv [wp]: "\P\ get_object t \\rv. P\" by (wp get_object_wp) simp 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_SomeD: "get_tcb t s = Some v \ kheap s t = Some (TCB v)" apply (case_tac "kheap s t", simp_all add: get_tcb_def) apply (case_tac a, simp_all) done 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 typ_at_same_type: assumes "typ_at T p s" "a_type k = a_type ko" "kheap s p' = Some ko" shows "typ_at T p (s\kheap := kheap s(p' \ k)\)" using assms by (clarsimp simp: obj_at_def) 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 split_if_asm) apply (clarsimp simp: a_type_def split: Structures_A.kernel_object.split_asm split_if_asm) 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 hoare_to_pure_kheap_upd: assumes hoare[rule_format]: "\f. (\P p T. \\s. P (typ_at (AArch T) p s)\ f \\r s. P (typ_at (AArch T) p s)\) \ \P\ f \\_. P\" assumes typ_eq: "a_type k = a_type ko" assumes valid: "P (s :: ('z :: state_ext) state)" assumes at: "ko_at ko p s" shows "P (s\kheap := kheap s(p \ k)\)" apply (rule use_valid[where f=" do s' <- get; assert (s' = s); (modify (\s. s\kheap := kheap s(p \ k)\)); return undefined od", OF _ hoare valid]) apply (fastforce simp add: simpler_modify_def get_def bind_def assert_def return_def[abs_def] fail_def)[1] apply wp apply (insert typ_eq at) apply clarsimp apply (erule_tac P=P in rsubst) by (auto simp add: obj_at_def a_type_def split: kernel_object.splits if_splits) 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) apply (clarsimp simp add: valid_obj_def valid_cs_def) apply (drule (1) bspec) apply (erule (2) valid_cap_same_type) apply (clarsimp simp add: valid_obj_def valid_tcb_def valid_bound_ntfn_def) 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) done lemma valid_arch_obj_same_type: "\valid_arch_obj ao s; kheap s p = Some ko; a_type ko' = a_type ko\ \ valid_arch_obj ao (s\kheap := kheap s(p \ ko')\)" apply (rule hoare_to_pure_kheap_upd[OF valid_arch_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 get_endpoint_sp: "\P\ get_endpoint p \\ep. ko_at (Endpoint ep) p and P\" apply (simp add: get_endpoint_def) apply wp prefer 2 apply (rule get_object_sp) apply (case_tac kobj) apply (simp|wp)+ done 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 9" 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_ep_inv[wp]: "\P\ get_endpoint ep \\rv. P\" apply (simp add: get_endpoint_def) apply wp defer apply (rule get_object_inv) apply (case_tac kobj, simp_all) done lemma get_ntfn_inv[wp]: "\P\ get_notification ep \\rv. P\" apply (simp add: get_notification_def) apply wp defer apply (rule get_object_inv) apply (case_tac kobj, simp_all) done lemma get_ep_actual_ep[wp]: "\ invs and ep_at ep \ get_endpoint ep \ \rv. obj_at (\k. k = Endpoint rv) ep \" apply (clarsimp simp add: get_endpoint_def get_object_def bind_def valid_def gets_def get_def return_def fail_def assert_def obj_at_def is_ep_def) apply (case_tac y, simp_all add: return_def) done 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_ep_valid_ep[wp]: "\ invs and ep_at ep \ get_endpoint ep \ valid_ep \" apply (simp add: get_endpoint_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 (case_tac kobj, simp_all) apply (wp | simp add: valid_obj_def)+ done lemma get_ntfn_actual_ntfn[wp]: "\ ntfn_at ntfn \ get_notification ntfn \ \rv. obj_at (\k. k = Notification rv) ntfn \" apply (clarsimp simp add: get_notification_def get_object_def bind_def valid_def gets_def get_def return_def fail_def assert_def obj_at_def is_ntfn_def) apply (case_tac y, simp_all add: return_def) done lemma get_ntfn_valid_ntfn[wp]: "\ valid_objs and ntfn_at ntfn \ get_notification ntfn \ valid_ntfn \" apply (simp add: get_notification_def) apply (rule hoare_seq_ext) prefer 2 apply (rule hoare_pre_imp [OF _ get_object_valid]) apply (simp add: valid_objs_def valid_state_def valid_pspace_def) apply (case_tac kobj, simp_all) apply (wp | simp add: valid_obj_def)+ done lemma set_ep_valid_objs[wp]: "\valid_ep v and valid_objs\ set_endpoint ep v \\rv s. valid_objs s\" apply (simp add: set_endpoint_def) apply (wp set_object_valid_objs) apply (rule hoare_strengthen_post [OF get_object_sp]) apply (clarsimp simp add: valid_obj_def obj_at_def) apply (case_tac r, simp_all add: a_type_def) done lemma set_ep_aligned[wp]: "\pspace_aligned\ set_endpoint ep v \\rv. pspace_aligned\" apply (simp add: set_endpoint_def) apply (wp set_object_aligned) apply (rule hoare_strengthen_post [OF get_object_sp]) apply (clarsimp simp add: obj_at_def a_type_def) apply (case_tac r, simp_all) done lemma set_endpoint_typ_at [wp]: "\\s. P (typ_at T p s)\ set_endpoint p' ep \\rv s. P (typ_at T p s)\" apply (simp add: set_endpoint_def set_object_def) apply wp apply (rule hoare_strengthen_post [OF get_object_sp]) apply (case_tac r, simp_all) apply (clarsimp simp: obj_at_def a_type_def) done lemma set_endpoint_cte_wp_at[wp]: "\cte_wp_at P p\ set_endpoint ep v \\rv. cte_wp_at P p\" apply (simp add: set_endpoint_def set_object_def get_object_def) apply wp apply (fastforce simp: cte_wp_at_cases) done lemma set_ntfn_valid_objs: "\valid_objs and valid_ntfn ntfn\ set_notification p ntfn \\rv. valid_objs\" apply (simp add: set_notification_def) apply (wp set_object_valid_objs) apply (rule hoare_strengthen_post [OF get_object_sp]) apply (clarsimp simp: valid_obj_def obj_at_def is_ntfn) apply (case_tac r, simp_all add: a_type_def) done lemma set_ntfn_aligned[wp]: "\pspace_aligned\ set_notification p ntfn \\rv. pspace_aligned\" apply (simp add: set_notification_def) apply (wp set_object_aligned) apply (rule hoare_strengthen_post [OF get_object_sp]) apply (clarsimp simp add: obj_at_def is_ntfn) apply (case_tac r, simp_all add: a_type_def) done lemma set_notification_typ_at [wp]: "\\s. P (typ_at T p s)\ set_notification p' ntfn \\rv s. P (typ_at T p s)\" apply (simp add: set_notification_def set_object_def) apply wp apply (rule hoare_strengthen_post [OF get_object_sp]) apply (case_tac r, simp_all) apply (clarsimp simp: obj_at_def a_type_def) done lemma set_notification_cte_wp_at[wp]: "\cte_wp_at P p\ set_notification ep v \\rv. cte_wp_at P p\" apply (simp add: set_notification_def set_object_def get_object_def) apply wp apply (fastforce simp: cte_wp_at_cases) done lemma get_ntfn_ko: "\\\ get_notification ep \\rv. ko_at (Notification rv) ep\" apply (simp add: get_notification_def) apply wp prefer 2 apply (rule get_object_sp) apply (case_tac kobj) apply (wp|simp)+ done 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 get_ntfn_sp: "\P\ get_notification p \\ntfn. ko_at (Notification ntfn) p and P\" apply wp apply (rule hoare_weaken_pre) apply (rule hoare_vcg_conj_lift) apply (rule get_ntfn_ko) apply (rule get_ntfn_inv) apply simp done 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)\" apply (simp add: set_endpoint_def set_object_def) apply (rule hoare_seq_ext [OF _ get_object_sp]) apply wp apply (fastforce simp: state_refs_of_def elim!: rsubst[where P=P]) done 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_ep_distinct[wp]: "\pspace_distinct\ set_endpoint ep v \\_. pspace_distinct\" apply (simp add: set_endpoint_def) apply (wp set_object_distinct) apply (rule hoare_strengthen_post [OF get_object_sp]) apply (clarsimp elim!: obj_at_weakenE) apply (case_tac ko, simp_all add: a_type_def) done lemma set_ep_cur_tcb[wp]: "\cur_tcb\ set_endpoint ep v \\rv. cur_tcb\" apply (simp add: set_endpoint_def set_object_def) apply wp apply (rule hoare_strengthen_post [OF get_object_sp]) apply (auto simp: cur_tcb_def obj_at_def is_tcb is_ep) done 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_respect_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: split_if_asm) done lemma set_ntfn_kernel_window[wp]: "\pspace_in_kernel_window\ set_notification ptr val \\rv. pspace_in_kernel_window\" apply (simp add: set_notification_def) apply (wp set_object_pspace_in_kernel_window get_object_wp) apply (clarsimp simp: obj_at_def a_type_def split: Structures_A.kernel_object.split_asm) done lemma set_ntfn_respect_device_region[wp]: "\pspace_respects_device_region\ set_notification ptr val \\rv. pspace_respects_device_region\" apply (simp add: set_notification_def) apply (wp set_object_pspace_respect_device_region get_object_wp) apply (clarsimp simp: obj_at_def a_type_def split: Structures_A.kernel_object.split_asm) done lemma set_ep_kernel_window[wp]: "\pspace_in_kernel_window\ set_endpoint ptr val \\rv. pspace_in_kernel_window\" apply (simp add: set_endpoint_def) apply (wp set_object_pspace_in_kernel_window get_object_wp) apply (clarsimp simp: obj_at_def a_type_def split: Structures_A.kernel_object.split_asm) done lemma set_ep_respects_device_region[wp]: "\pspace_respects_device_region\ set_endpoint ptr val \\rv. pspace_respects_device_region\" apply (simp add: set_endpoint_def) apply (wp set_object_pspace_respect_device_region get_object_wp) apply (clarsimp simp: obj_at_def a_type_def split: Structures_A.kernel_object.split_asm) done 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 (erule use_valid [OF _ r]) apply simp done crunch no_cdt[wp]: set_endpoint "\s. P (cdt s)" (wp: crunch_wps) lemma set_ep_caps_of_state [wp]: "\\s. P (caps_of_state s)\ set_endpoint p ep \\r s. P (caps_of_state s)\" apply (simp add: set_endpoint_def get_object_def bind_assoc set_object_def) apply wp apply clarsimp apply (subst cte_wp_caps_of_lift) prefer 2 apply assumption apply (case_tac y, auto simp: cte_wp_at_cases) done lemma set_ep_revokable [wp]: "\\s. P (is_original_cap s)\ set_endpoint p ep \\r s. P (is_original_cap s)\" apply (simp add: set_endpoint_def get_object_def bind_assoc set_object_def) apply wp apply simp done lemma set_ep_mdb [wp]: "\valid_mdb\ set_endpoint 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: split_if_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_ep_iflive[wp]: "\\s. if_live_then_nonz_cap s \ (live (Endpoint ep) \ ex_nonz_cap_to p s)\ set_endpoint p ep \\rv. if_live_then_nonz_cap\" apply (simp add: set_endpoint_def) apply wp apply (rule hoare_strengthen_post [OF get_object_sp]) apply (clarsimp elim!: obj_at_weakenE split: Structures_A.kernel_object.splits simp: is_ep_def) done lemma set_ep_ifunsafe[wp]: "\if_unsafe_then_cap\ set_endpoint p val \\rv. if_unsafe_then_cap\" apply (simp add: set_endpoint_def) apply wp apply (rule hoare_strengthen_post [OF get_object_sp]) apply (clarsimp elim!: obj_at_weakenE simp: is_ep_def) done lemma set_ep_zombies[wp]: "\zombies_final\ set_endpoint p val \\rv. zombies_final\" apply (simp add: set_endpoint_def) apply wp apply (rule hoare_strengthen_post [OF get_object_sp]) apply (clarsimp elim!: obj_at_weakenE simp: is_ep_def) done lemma set_ntfn_distinct[wp]: "\pspace_distinct\ set_notification ntfn v \\rv. pspace_distinct\" apply (simp add: set_notification_def) apply (wp set_object_distinct) apply (rule hoare_strengthen_post [OF get_object_sp]) apply clarsimp apply (erule obj_at_weakenE) apply (case_tac ko, simp_all add: a_type_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)\" apply (simp add: set_notification_def set_object_def) apply (rule hoare_seq_ext [OF _ get_object_sp]) apply wp apply (clarsimp simp: state_refs_of_def elim!: rsubst [where P=P] intro!: ext) done lemma set_ntfn_cur_tcb[wp]: "\cur_tcb\ set_notification ntfn v \\rv. cur_tcb\" apply (simp add: set_notification_def set_object_def) apply wp apply (rule hoare_strengthen_post [OF get_object_sp]) apply (auto simp: cur_tcb_def obj_at_def is_tcb is_ntfn) done lemma set_ntfn_caps_of_state[wp]: "\\s. P (caps_of_state s)\ set_notification p ntfn \\r s. P (caps_of_state s)\" apply (simp add: set_notification_def get_object_def bind_assoc set_object_def) apply wp apply clarsimp apply (subst cte_wp_caps_of_lift) prefer 2 apply assumption apply (case_tac y, auto simp: cte_wp_at_cases) done 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_cdt[wp]: set_notification "\s. P (cdt s)" (wp: crunch_wps) crunch no_revokable[wp]: set_notification "\s. P (is_original_cap s)" (wp: crunch_wps) lemma set_ntfn_mdb [wp]: "\valid_mdb\ set_notification p ep \\r. valid_mdb\" by (wp valid_mdb_lift) lemma set_ntfn_iflive[wp]: "\\s. if_live_then_nonz_cap s \ (live (Notification ntfn) \ ex_nonz_cap_to p s)\ set_notification p ntfn \\rv. if_live_then_nonz_cap\" apply (simp add: set_notification_def) apply wp apply (rule hoare_strengthen_post [OF get_object_sp]) apply (clarsimp elim!: obj_at_weakenE simp: is_ntfn_def split: Structures_A.kernel_object.splits) done lemma set_ntfn_ifunsafe[wp]: "\if_unsafe_then_cap\ set_notification p val \\rv. if_unsafe_then_cap\" apply (simp add: set_notification_def) apply wp apply (rule hoare_strengthen_post [OF get_object_sp]) apply (clarsimp elim!: obj_at_weakenE simp: is_ntfn_def) done lemma set_ntfn_zombies[wp]: "\zombies_final\ set_notification p val \\rv. zombies_final\" apply (simp add: set_notification_def) apply wp apply (rule hoare_strengthen_post [OF get_object_sp]) apply (clarsimp elim!: obj_at_weakenE simp: is_ntfn_def) done 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: split_if_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)\" 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 simp: a_type_def) 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, wp) lemma as_user_no_del_ep[wp]: "\ep_at p\ as_user t m \\rv. ep_at p\" by (simp add: ep_at_typ, wp) lemma set_ep_tcb[wp]: "\ tcb_at t \ set_endpoint ep v \ \rv. tcb_at t \" by (simp add: tcb_at_typ) wp lemma set_ntfn_tcb[wp]: "\ tcb_at t \ set_notification e v \ \rv. tcb_at t \" by (simp add: tcb_at_typ) wp lemma set_ep_pred_tcb_at [wp]: "\ pred_tcb_at proj f t \ set_endpoint ep v \ \rv. pred_tcb_at proj f t \" apply (simp add: set_endpoint_def pred_tcb_at_def) apply wp defer apply (rule assert_sp) apply (rule get_object_sp) apply simp apply (case_tac obj, simp_all) apply (rule set_object_at_obj2 [unfolded pred_conj_def]) apply clarsimp done 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_endpoint_obj_at: "\\s. P (Endpoint ep)\ set_endpoint ptr ep \\rv. obj_at P ptr\" apply (simp add: set_endpoint_def) apply (wp obj_set_prop_at) apply (rule hoare_drop_imps, wp) done lemma set_notification_obj_at: "\\s. P (Notification ep)\ set_notification ptr ep \\rv. obj_at P ptr\" apply (simp add: set_notification_def) apply (wp obj_set_prop_at) apply (rule hoare_drop_imps, wp) done 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_ep_ex_cap[wp]: "\ex_nonz_cap_to p\ set_endpoint p' v \\rv. ex_nonz_cap_to p\" by (wp ex_nonz_cap_to_pres) lemma set_ntfn_st_tcb [wp]: "\pred_tcb_at proj P t\ set_notification ntfn x \\rv. pred_tcb_at proj P t\" apply (simp add: set_notification_def set_object_def get_object_def) apply wp apply (clarsimp simp: pred_tcb_at_def obj_at_def is_ntfn) done crunch it[wp]: set_notification "\s. P (idle_thread s)" (wp: crunch_wps simp: crunch_simps) lemma set_notification_cap_to[wp]: "\ex_nonz_cap_to p\ set_notification p' val \\rv. ex_nonz_cap_to p\" by (wp ex_nonz_cap_to_pres) lemma set_endpoint_idle[wp]: "\valid_idle and ep_at ptr\ set_endpoint ptr ep \\_. valid_idle\" apply (simp add: set_endpoint_def set_object_def get_object_def) apply (wp hoare_drop_imp) apply (clarsimp simp: valid_idle_def pred_tcb_at_def obj_at_def is_ep_def) done (* 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 it[wp]: set_notification "\s. P (idle_thread s)" (wp: crunch_wps simp: crunch_simps) crunch arch[wp]: set_notification "\s. P (arch_state s)" (wp: crunch_wps simp: crunch_simps) lemma set_notification_valid_arch [wp]: "\valid_arch_state\ set_notification ntfn p \\_. valid_arch_state\" by (rule valid_arch_state_lift) wp crunch irq_node_inv[wp]: set_notification "\s. P (interrupt_irq_node s)" (wp: crunch_wps) lemma set_notification_global_refs [wp]: "\valid_global_refs\ set_notification ntfn p \\_. valid_global_refs\" by (rule valid_global_refs_cte_lift) wp lemma set_notification_idle[wp]: "\ntfn_at p and valid_idle\ set_notification p ep \\_. valid_idle\" apply (simp add: set_notification_def set_object_def get_object_def) apply (wp hoare_drop_imp) apply (clarsimp simp: valid_idle_def pred_tcb_at_def obj_at_def is_ntfn_def) done lemma set_notification_reply[wp]: "\valid_reply_caps\ set_notification p ep \\_. valid_reply_caps\" by (wp valid_reply_caps_st_cte_lift) lemma set_notification_reply_masters[wp]: "\valid_reply_masters\ set_notification 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 arch[wp]: set_endpoint "\s. P (arch_state s)" (wp: crunch_wps simp: crunch_simps) lemma set_endpoint_valid_arch [wp]: "\valid_arch_state\ set_endpoint ep p \\_. valid_arch_state\" by (rule valid_arch_state_lift) wp crunch irq_node_inv[wp]: set_endpoint "\s. P (interrupt_irq_node s)" (wp: crunch_wps) crunch it[wp]: set_endpoint "\s. P (idle_thread s)" (wp: crunch_wps) lemma set_ep_global_refs [wp]: "\valid_global_refs\ set_endpoint ep p \\_. valid_global_refs\" by (rule valid_global_refs_cte_lift) wp lemma set_endpoint_reply[wp]: "\valid_reply_caps\ set_endpoint ep p \\rv. valid_reply_caps\" by (wp valid_reply_caps_st_cte_lift) lemma set_endpoint_reply_masters[wp]: "\valid_reply_masters\ set_endpoint p ep \\_. valid_reply_masters\" by (wp valid_reply_masters_cte_lift) crunch interrupt_states[wp]: set_endpoint "\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_arch_objs_non_arch: "\valid_arch_objs and K (non_arch_obj ko) and obj_at non_arch_obj p\ set_object p ko \\_. valid_arch_objs\" apply (rule assert_pre) apply (rule hoare_pre) apply (rule valid_arch_objs_lift_weak) apply (wp set_object_non_arch | clarsimp)+ done 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 locale non_arch_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)\" begin lemma valid_arch_obj[wp]:"\valid_arch_objs\ f \\_. valid_arch_objs\" by (rule valid_arch_objs_lift_weak; wp aobj_at; simp) lemma vs_lookup[wp]: "\\s. P (vs_lookup s)\ f \\_ s. P (vs_lookup s)\" by (rule vs_lookup_arch_obj_at_lift; wp aobj_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_arch_obj_at_lift; wp aobj_at; simp) lemma valid_global_objs[wp]: "\valid_global_objs\ f \\rv. valid_global_objs\" by (rule valid_global_objs_lift_weak, wp aobj_at) lemma valid_asid_map[wp]: "\valid_asid_map\ f \\_. valid_asid_map\" by (rule valid_asid_map_lift, wp aobj_at) lemma valid_kernel_mappings[wp]: "\valid_kernel_mappings\ f \\_. valid_kernel_mappings\" by (rule valid_kernel_mappings_lift, wp aobj_at) lemma equal_kernel_mappings[wp]: "\equal_kernel_mappings\ f \\_. equal_kernel_mappings\" by (rule equal_kernel_mappings_lift, wp aobj_at) lemma valid_global_vspace_mappings[wp]: "\valid_global_vspace_mappings\ f \\rv. valid_global_vspace_mappings\" by (rule valid_global_vspace_mappings_lift, wp aobj_at) lemma valid_ao_at[wp]:"\valid_ao_at p\ f \\_. valid_ao_at p\" by (rule valid_ao_at_lift_aobj_at; wp aobj_at; simp) lemma valid_arch_state[wp]:"\valid_arch_state\ f \\_. valid_arch_state\" by (rule valid_arch_state_lift; wp aobj_at; simp) lemma in_user_frame[wp]:"\in_user_frame p\ f \\_. in_user_frame p\" by (rule in_user_frame_lift; wp aobj_at; simp) end locale non_arch_non_mem_op = non_arch_op f for f + assumes memory[wp]: "\P. \\s. P (underlying_memory (machine_state s))\ f \\_ s. P (underlying_memory (machine_state s))\" begin lemma valid_machine_state[wp]: "\valid_machine_state\ f \\rv. valid_machine_state\" by (rule valid_machine_state_lift[OF memory aobj_at]) end locale non_arch_non_cap_op = non_arch_op f for f + assumes caps[wp]: "\P. \\s. P (caps_of_state s)\ f \\_ s. P (caps_of_state s)\" begin lemma valid_arch_caps[wp]: "\valid_arch_caps\ f \\_. valid_arch_caps\" by (rule valid_arch_caps_lift_weak[OF arch_state aobj_at caps]) end locale non_arch_non_cap_non_mem_op = non_arch_non_mem_op f + non_arch_non_cap_op f for f 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 (wp modify_wp | fastforce)+ 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: split_if | 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_endpoint: non_arch_non_cap_non_mem_op "set_endpoint p ep" + set_notification: non_arch_non_cap_non_mem_op "set_notification p ntfn" + sts: non_arch_non_cap_non_mem_op "set_thread_state p st" + sbn: non_arch_non_cap_non_mem_op "set_bound_notification p b" + as_user: non_arch_non_cap_non_mem_op "as_user p g" + thread_set: non_arch_non_mem_op "thread_set f p" + set_cap: non_arch_non_mem_op "set_cap cap p'" apply (all \unfold_locales; (wp ; fail)?\) unfolding set_endpoint_def set_notification_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: split_if)+\) by (fastforce simp: obj_at_def[abs_def] a_type_def split: Structures_A.kernel_object.splits)+ interpretation store_word_offs: non_arch_non_cap_op "store_word_offs a b c" apply unfold_locales unfolding store_word_offs_def do_machine_op_def[abs_def] by (wp modify_wp | fastforce)+ 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_arch_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: split_if | 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_endpoint_valid_irq_handlers[wp] = valid_irq_handlers_lift [OF set_ep_caps_of_state set_endpoint_interrupt_states] crunch irq_node[wp]: set_notification "\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) lemmas set_notification_irq_handlers[wp] = valid_irq_handlers_lift [OF set_ntfn_caps_of_state set_notification_interrupt_states] lemma set_notification_only_idle [wp]: "\only_idle\ set_notification p ntfn \\_. only_idle\" by (wp only_idle_lift) lemma set_endpoint_only_idle [wp]: "\only_idle\ set_endpoint p ntfn \\_. only_idle\" by (wp only_idle_lift) lemma set_ntfn_cap_refs_kernel_window[wp]: "\cap_refs_in_kernel_window\ set_notification p ep \\rv. cap_refs_in_kernel_window\" apply (simp add: set_notification_def) apply (wp set_object_cap_refs_in_kernel_window get_object_wp) apply (clarsimp simp: obj_at_def is_ntfn split: Structures_A.kernel_object.split_asm) done lemma set_ntfn_cap_refs_respects_device_region[wp]: "\cap_refs_respects_device_region\ set_notification p ep \\rv. cap_refs_respects_device_region\" apply (simp add: set_notification_def) apply (wp set_object_cap_refs_respects_device_region get_object_wp) apply (clarsimp simp: obj_at_def is_ntfn split: Structures_A.kernel_object.split_asm) done (* 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 split_if_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 split_if_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 split_if_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 split_if_asm) done lemma set_notification_valid_ioc[wp]: "\valid_ioc\ set_notification ptr val \\_. valid_ioc\" apply (simp add: set_notification_def) apply (wp set_object_valid_ioc_no_caps get_object_inv) by (clarsimp simp: valid_def get_object_def simpler_gets_def assert_def return_def fail_def bind_def a_type_simps obj_at_def is_tcb is_cap_table split: Structures_A.kernel_object.splits) 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_object "valid_irq_states" (wp: valid_irq_states_triv) crunch valid_irq_states[wp]: set_notification "valid_irq_states" (wp: crunch_wps simp: crunch_simps) crunch valid_irq_states[wp]: set_endpoint "valid_irq_states" (wp: crunch_wps simp: crunch_simps) 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 (rule hoare_pre, wp set_ntfn_valid_objs valid_irq_node_typ valid_irq_handlers_lift) apply (clarsimp 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 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_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_arch_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 do_machine_op_arch_objs [wp]: "\valid_arch_objs\ do_machine_op f \\_. valid_arch_objs\" apply (simp add: do_machine_op_def split_def) apply wp apply simp 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 end