(* * Copyright 2014, NICTA * * This software may be distributed and modified according to the terms of * the GNU General Public License version 2. Note that NO WARRANTY is provided. * See "LICENSE_GPLv2.txt" for details. * * @TAG(NICTA_GPL) *) theory Ipc_IF imports Finalise_IF begin context begin interpretation Arch . (*FIXME: arch_split*) section "reads_respects" subsection "Notifications" lemma equiv_valid_2_get_assert: "equiv_valid_2 I A A R P P' f f' \ equiv_valid_2 I A A R P P' (get >>= (\ s. assert (g s) >>= (\ y. f))) (get >>= (\ s. assert (g' s) >>= (\ y. f')))" apply(rule equiv_valid_2_guard_imp) apply(rule_tac R'="\\" in equiv_valid_2_bind) apply(rule_tac R'="\\" in equiv_valid_2_bind) apply assumption apply(simp add: assert_ev2) apply(wp equiv_valid_rv_trivial | simp)+ done lemma dummy_machine_state_update: "st = st\machine_state := machine_state st\" apply simp done lemma dmo_storeWord_modifies_at_most: "modifies_at_most aag (pasObjectAbs aag ` ptr_range p 2) \ (do_machine_op (storeWord p w))" apply(rule modifies_at_mostI) apply(simp add: do_machine_op_def storeWord_def) apply(wp modify_wp | simp add: split_def)+ apply clarsimp apply(erule use_valid) apply(wp modify_wp) apply(clarsimp simp: equiv_but_for_labels_def) apply(subst (asm) is_aligned_mask[symmetric]) apply(subst dummy_machine_state_update) apply(rule states_equiv_for_machine_state_update) apply assumption apply (erule states_equiv_forE_mem) apply (intro conjI equiv_forI) apply(fastforce simp: image_def dest: distinct_lemma[where f="pasObjectAbs aag"] intro: ptr_range_memI ptr_range_add_memI)+ done lemma get_object_reads_respects: "reads_respects aag l (K (aag_can_read aag oref \ aag_can_affect aag l oref)) (get_object oref)" unfolding get_object_def apply(subst gets_apply) apply(wp gets_apply_ev | wpc | simp)+ apply(blast intro: reads_affects_equiv_kheap_eq) done lemma get_cap_reads_respects: "reads_respects aag l (K (aag_can_read aag (fst slot) \ aag_can_affect aag l (fst slot))) (get_cap slot)" apply(simp add: get_cap_def split_def) apply(wp get_object_reads_respects | wpc | simp)+ done lemma lookup_ipc_buffer_reads_respects: "reads_respects aag l (K (aag_can_read aag thread \ aag_can_affect aag l thread)) (lookup_ipc_buffer is_receiver thread)" unfolding lookup_ipc_buffer_def apply(wp thread_get_reads_respects get_cap_reads_respects | wpc | simp)+ done lemmas lookup_ipc_buffer_reads_respects_g = reads_respects_g_from_inv[OF lookup_ipc_buffer_reads_respects lookup_ipc_buffer_inv] lemma as_user_equiv_but_for_labels: "\equiv_but_for_labels aag L st and K (pasObjectAbs aag thread \ L)\ as_user thread f \\_. equiv_but_for_labels aag L st\" unfolding as_user_def apply (wp set_object_equiv_but_for_labels | simp add: split_def)+ apply(blast dest: get_tcb_not_asid_pool_at) done crunch equiv_but_for_labels: set_message_info "equiv_but_for_labels aag L st" lemma storeWord_equiv_but_for_labels: "\\ms. equiv_but_for_labels aag L st (s\machine_state := ms\) \ for_each_byte_of_word (\ x. pasObjectAbs aag x \ L) p\ storeWord p v \\a b. equiv_but_for_labels aag L st (s\machine_state := b\)\" unfolding storeWord_def apply (wp modify_wp) apply (clarsimp simp: equiv_but_for_labels_def) apply (rule states_equiv_forI) apply(fastforce intro!: equiv_forI elim!: states_equiv_forE dest: equiv_forD[where f=kheap]) apply (simp add: states_equiv_for_def) apply (rule conjI) apply(rule equiv_forI) apply clarsimp apply(drule_tac f=underlying_memory in equiv_forD,fastforce) apply(fastforce intro: is_aligned_no_wrap' word_plus_mono_right simp: is_aligned_mask for_each_byte_of_word_def) apply(rule equiv_forI) apply clarsimp apply(drule_tac f=device_state in equiv_forD,fastforce) apply clarsimp apply(fastforce elim: states_equiv_forE intro: equiv_forI dest: equiv_forD[where f=cdt]) apply(fastforce elim: states_equiv_forE intro: equiv_forI dest: equiv_forD[where f=ekheap]) apply(fastforce elim: states_equiv_forE intro: equiv_forI dest: equiv_forD[where f=cdt_list]) apply(fastforce elim: states_equiv_forE intro: equiv_forI dest: equiv_forD[where f=is_original_cap]) apply(fastforce elim: states_equiv_forE intro: equiv_forI dest: equiv_forD[where f=interrupt_states]) apply(fastforce elim: states_equiv_forE intro: equiv_forI dest: equiv_forD[where f=interrupt_irq_node]) apply(fastforce simp: equiv_asids_def equiv_asid_def elim: states_equiv_forE) apply(fastforce elim: states_equiv_forE intro: equiv_forI dest: equiv_forD[where f=ready_queues]) done lemma store_word_offs_equiv_but_for_labels: "\ equiv_but_for_labels aag L st and K (for_each_byte_of_word (\x. pasObjectAbs aag x \ L) (ptr + of_nat offs * of_nat word_size)) \ store_word_offs ptr offs v \ \_. equiv_but_for_labels aag L st \" unfolding store_word_offs_def apply(wp modify_wp | simp add: do_machine_op_def split_def)+ apply clarsimp apply(erule use_valid[OF _ storeWord_equiv_but_for_labels]) apply simp done definition ipc_buffer_has_read_auth :: "'a PAS \ 'a \ word32 option \ bool" where "ipc_buffer_has_read_auth aag l \ case_option True (\buf'. is_aligned buf' msg_align_bits \ (\x \ ptr_range buf' msg_align_bits. (l,Read,pasObjectAbs aag x) \ (pasPolicy aag)))" lemma set_mrs_equiv_but_for_labels: "\ equiv_but_for_labels aag L st and K (pasObjectAbs aag thread \ L \ (case buf of (Some buf') \ is_aligned buf' msg_align_bits \ (\x \ ptr_range buf' msg_align_bits. pasObjectAbs aag x \ L) | _ \ True)) \ set_mrs thread buf msgs \ \_. equiv_but_for_labels aag L st \" unfolding set_mrs_def apply (wp | wpc)+ apply(subst zipWithM_x_mapM_x) apply(rule_tac Q="\_. equiv_but_for_labels aag L st and K (pasObjectAbs aag thread \ L \ (case buf of (Some buf') \ is_aligned buf' msg_align_bits \ (\x \ ptr_range buf' msg_align_bits. pasObjectAbs aag x \ L) | _ \ True))" in hoare_strengthen_post) apply(wp mapM_x_wp' store_word_offs_equiv_but_for_labels | simp add: split_def)+ apply(case_tac xa, clarsimp split: if_split_asm elim!: in_set_zipE) apply(clarsimp simp: for_each_byte_of_word_def) apply(erule bspec) apply(clarsimp simp: ptr_range_def) apply(rule conjI) apply(erule order_trans[rotated]) apply(erule is_aligned_no_wrap') apply(rule mul_word_size_lt_msg_align_bits_ofnat) apply(fastforce simp: msg_max_length_def msg_align_bits) apply(erule order_trans) apply(subst p_assoc_help) apply(simp add: add.assoc) apply(rule word_plus_mono_right) apply(rule word_less_sub_1) apply(rule_tac y="of_nat msg_max_length * of_nat word_size + 3" in le_less_trans) apply(rule word_plus_mono_left) apply(rule word_mult_le_mono1) apply(erule disjE) apply(rule word_of_nat_le) apply(simp add: msg_max_length_def) apply clarsimp apply(rule word_of_nat_le) apply(simp add: msg_max_length_def) apply(simp add: word_size_def) apply(simp add: msg_max_length_def word_size_def) apply(simp add: msg_max_length_def word_size_def) apply(rule mul_add_word_size_lt_msg_align_bits_ofnat) apply(simp add: msg_max_length_def msg_align_bits) apply simp apply(erule is_aligned_no_overflow') apply simp apply(wp set_object_equiv_but_for_labels hoare_vcg_all_lift static_imp_wp | simp)+ apply (fastforce dest: get_tcb_not_asid_pool_at)+ done definition all_to_which_has_auth where "all_to_which_has_auth aag auth source \ {t. (source,auth,t) \ pasPolicy aag}" definition all_with_auth_to where "all_with_auth_to aag auth target \ {x. (x, auth, target) \ pasPolicy aag}" lemma valid_ntfn_WaitingNtfn_tl: "\ntfn_obj ntfn = (WaitingNtfn list); valid_ntfn ntfn s; tl list \ []; ntfn' = ntfn\ntfn_obj := (WaitingNtfn (tl list))\ \ \ valid_ntfn ntfn' s" apply(case_tac list, simp_all) apply(rename_tac a lista) apply(case_tac lista, simp_all) apply(clarsimp simp: valid_ntfn_def split: option.splits) done lemma update_waiting_ntfn_reads_respects: assumes domains_distinct[wp]: "pas_domains_distinct aag" notes tl_drop_1[simp del] shows "reads_respects aag l (valid_objs and sym_refs \ state_refs_of and pas_refined aag and pas_cur_domain aag and ko_at (Notification ntfn) ntfnptr and (\s. is_subject aag (cur_thread s)) and K (ntfn_obj ntfn = WaitingNtfn queue)) (update_waiting_ntfn ntfnptr queue bound_tcb badge)" unfolding update_waiting_ntfn_def fun_app_def apply (wp assert_sp possible_switch_to_reads_respects gets_cur_thread_ev | simp add: split_def)+ apply (wp as_user_set_register_reads_respects' set_thread_state_reads_respects set_simple_ko_reads_respects set_thread_state_pas_refined set_simple_ko_valid_objs hoare_vcg_disj_lift set_simple_ko_pas_refined | simp add: split_def reads_lrefl)+ done lemma set_thread_state_ext_runnable_equiv_but_for_labels: "\equiv_but_for_labels aag L st and K (pasObjectAbs aag thread \ L) and st_tcb_at runnable thread\ set_thread_state_ext thread \\_. equiv_but_for_labels aag L st\" apply (simp add: set_thread_state_ext_def) apply wp apply (rule hoare_pre_cont) apply (wp gts_wp)+ apply (force simp: st_tcb_at_def obj_at_def) done lemma set_thread_state_runnable_equiv_but_for_labels: "runnable tst \ \equiv_but_for_labels aag L st and K (pasObjectAbs aag thread \ L)\ set_thread_state thread tst \\_. equiv_but_for_labels aag L st\" unfolding set_thread_state_def apply (wp set_object_equiv_but_for_labels set_thread_state_ext_runnable_equiv_but_for_labels | simp add: split_def)+ apply (simp add: set_object_def, wp+) apply (fastforce dest: get_tcb_not_asid_pool_at simp: st_tcb_at_def obj_at_def) done lemma tcb_sched_action_equiv_but_for_labels: "\equiv_but_for_labels aag L st and K (pasObjectAbs aag thread \ L) and pas_refined aag\ tcb_sched_action action thread \\_. equiv_but_for_labels aag L st\" apply (simp add: tcb_sched_action_def, wp) apply (clarsimp simp: etcb_at_def equiv_but_for_labels_def split: option.splits) apply (rule states_equiv_forI) apply(fastforce intro!: equiv_forI elim!: states_equiv_forE dest: equiv_forD[where f=kheap]) apply (simp add: states_equiv_for_def) apply(fastforce elim: states_equiv_forE intro: equiv_forI dest: equiv_forD[where f=cdt]) apply(fastforce elim: states_equiv_forE intro: equiv_forI dest: equiv_forD[where f=ekheap]) apply(fastforce elim: states_equiv_forE intro: equiv_forI dest: equiv_forD[where f=cdt_list]) apply(fastforce elim: states_equiv_forE intro: equiv_forI dest: equiv_forD[where f=is_original_cap]) apply(fastforce elim: states_equiv_forE intro: equiv_forI dest: equiv_forD[where f=interrupt_states]) apply(fastforce elim: states_equiv_forE intro: equiv_forI dest: equiv_forD[where f=interrupt_irq_node]) apply(fastforce simp: equiv_asids_def equiv_asid_def elim: states_equiv_forE) apply (clarsimp simp: pas_refined_def tcb_domain_map_wellformed_aux_def split: option.splits) apply (rule equiv_forI) apply (erule_tac x="(thread, tcb_domain (the (ekheap s thread)))" in ballE) apply(fastforce elim: states_equiv_forE intro: equiv_forI dest: equiv_forD[where f=ready_queues]) apply (force intro: domtcbs) done lemma possible_switch_to_equiv_but_for_labels: "\equiv_but_for_labels aag L st and (\s. etcb_at (\etcb. tcb_domain etcb \ cur_domain s) target s) and K (pasObjectAbs aag target \ L) and pas_refined aag\ possible_switch_to target \\_. equiv_but_for_labels aag L st\" apply (simp add: possible_switch_to_def) apply (wp tcb_sched_action_equiv_but_for_labels) (* possible_switch_to does not modify scheduler action if target is in different domain *) apply (rule hoare_pre_cont) apply (wp tcb_sched_action_equiv_but_for_labels) apply (rule hoare_pre_cont) apply (wp tcb_sched_action_equiv_but_for_labels)+ apply (clarsimp simp: etcb_at_def split: option.splits) done crunch etcb_at_cdom[wp]: set_thread_state_ext, set_thread_state, set_simple_ko "\s. etcb_at (P (cur_domain s)) t s" (wp: crunch_wps) lemma update_waiting_ntfn_equiv_but_for_labels: notes tl_drop_1[simp del] shows "\ equiv_but_for_labels aag L st and pas_refined aag and valid_objs and ko_at (Notification ntfn) ntfnptr and sym_refs \ state_refs_of and (\s. \t\ set list. etcb_at (\etcb. tcb_domain etcb \ cur_domain s) t s) and K (ntfn_obj ntfn = WaitingNtfn list \ pasObjectAbs aag ntfnptr \ L \ all_with_auth_to aag Receive (pasObjectAbs aag ntfnptr) \ L \ \ ((all_to_which_has_auth aag Write) ` (all_with_auth_to aag Receive (pasObjectAbs aag ntfnptr))) \ L)\ update_waiting_ntfn ntfnptr list boundtcb badge \ \_. equiv_but_for_labels aag L st \" unfolding update_waiting_ntfn_def apply (wp static_imp_wp as_user_equiv_but_for_labels set_thread_state_runnable_equiv_but_for_labels set_thread_state_pas_refined set_notification_equiv_but_for_labels set_simple_ko_pred_tcb_at set_simple_ko_pas_refined hoare_vcg_disj_lift possible_switch_to_equiv_but_for_labels | wpc | simp add: split_def)+ apply (clarsimp simp: conj_ac) apply(frule_tac P="receive_blocked_on ntfnptr" and t="hd list" in ntfn_queued_st_tcb_at') apply(fastforce) apply assumption apply assumption apply simp apply (subgoal_tac "pasObjectAbs aag (hd list) \ all_with_auth_to aag Receive (pasObjectAbs aag ntfnptr)") apply(fastforce) apply(clarsimp simp: all_with_auth_to_def) apply (erule pas_refined_mem[rotated]) apply (rule sta_ts) apply(clarsimp simp: thread_states_def split: option.split simp: tcb_states_of_state_def st_tcb_def2) apply(case_tac "tcb_state tcb", simp_all) done lemma update_waiting_ntfn_modifies_at_most: "modifies_at_most aag ({pasObjectAbs aag ntfnptr} \ all_with_auth_to aag Receive (pasObjectAbs aag ntfnptr) \ \ ((all_to_which_has_auth aag Write) ` (all_with_auth_to aag Receive (pasObjectAbs aag ntfnptr)))) (pas_refined aag and valid_objs and ko_at (Notification ntfn) ntfnptr and (\s. \t\ set list. etcb_at (\etcb. tcb_domain etcb \ cur_domain s) t s) and sym_refs \ state_refs_of and K (ntfn_obj ntfn = WaitingNtfn list)) (update_waiting_ntfn ntfnptr list boundtcb badge)" apply(rule modifies_at_mostI) apply(wp update_waiting_ntfn_equiv_but_for_labels | fastforce)+ done lemma invisible_ntfn_invisible_receivers_and_ipcbuffers: "\labels_are_invisible aag l {pasObjectAbs aag ntfnptr}; (pasSubject aag, Notify, pasObjectAbs aag ntfnptr) \ pasPolicy aag\ \ labels_are_invisible aag l ({pasObjectAbs aag ntfnptr} \ all_with_auth_to aag Receive (pasObjectAbs aag ntfnptr) \ \(all_to_which_has_auth aag Write ` all_with_auth_to aag Receive (pasObjectAbs aag ntfnptr)))" apply(auto simp: labels_are_invisible_def aag_can_affect_label_def dest: reads_read_page_read_thread reads_read_queued_thread_read_ep simp: all_to_which_has_auth_def all_with_auth_to_def) done lemma invisible_ntfn_invisible_receivers_and_receivers: "\labels_are_invisible aag l {pasObjectAbs aag ntfnptr}; (pasSubject aag, auth, pasObjectAbs aag ntfnptr) \ pasPolicy aag; auth \ {Notify,Receive,SyncSend}\ \ labels_are_invisible aag l ({pasObjectAbs aag ntfnptr} \ all_with_auth_to aag Receive (pasObjectAbs aag ntfnptr) \ (\(all_to_which_has_auth aag Receive ` all_with_auth_to aag Receive (pasObjectAbs aag ntfnptr))) \ (\(all_to_which_has_auth aag Write ` all_with_auth_to aag Receive (pasObjectAbs aag ntfnptr))))" by (auto simp: labels_are_invisible_def aag_can_affect_label_def dest: read_sync_ep_read_senders_strong read_sync_ep_read_receivers_strong reads_read_queued_thread_read_ep reads_read_page_read_thread reads_ep simp: all_to_which_has_auth_def all_with_auth_to_def) lemma read_queued_thread_reads_ntfn: "\ko_at (Notification ntfn) ntfnptr s; t \ set queue; aag_can_read aag t; valid_objs s; sym_refs (state_refs_of s); pas_refined aag s; ntfn_obj ntfn = WaitingNtfn queue; (pasSubject aag, Notify, pasObjectAbs aag ntfnptr) \ pasPolicy aag\ \ aag_can_read aag ntfnptr" apply(frule_tac P="receive_blocked_on ntfnptr" and t=t in ntfn_queued_st_tcb_at') apply(fastforce) apply assumption apply assumption apply simp apply (rule_tac t="pasObjectAbs aag t" and auth="Receive" and auth'="Notify" in reads_read_queued_thread_read_ep) apply assumption apply simp apply (erule pas_refined_mem[rotated]) apply (rule sta_ts) apply(clarsimp simp: thread_states_def split: option.split simp: tcb_states_of_state_def st_tcb_def2) apply (case_tac "tcb_state tcb", simp_all)[1] apply simp apply simp done lemma not_etcb_at_not_cdom_can_read: assumes domains_distinct[wp]: "pas_domains_distinct aag" shows "\\ etcb_at (\etcb. tcb_domain etcb \ cur_domain s) t s; tcb_at t s; valid_etcbs s; pas_refined aag s; pas_cur_domain aag s\ \ aag_can_read aag t" apply (clarsimp simp: valid_etcbs_def tcb_at_st_tcb_at etcb_at_def is_etcb_at_def pas_refined_def tcb_domain_map_wellformed_aux_def) apply (erule_tac x="(t, cur_domain s)" in ballE) apply (force dest: domains_distinct[THEN pas_domains_distinct_inj]) apply (force intro: domtcbs) done lemma tcb_at_ntfn_queue: "\valid_objs s; t \ set queue; ko_at (Notification ntfn) ntfnptr s; ntfn_obj ntfn = WaitingNtfn queue\ \ tcb_at t s" apply (erule valid_objsE, force simp: obj_at_def) apply (simp add: valid_obj_def valid_ntfn_def) done lemma invisible_ep_invisible_receiver: "\labels_are_invisible aag l {pasObjectAbs aag epptr}; (pasObjectAbs aag tcb, Receive, pasObjectAbs aag epptr) \ pasPolicy aag; (pasObjectAbs aag tcb, Reset, pasObjectAbs aag epptr) \ pasPolicy aag\ \ labels_are_invisible aag l ({pasObjectAbs aag epptr} \ {pasObjectAbs aag tcb})" apply (auto simp: labels_are_invisible_def aag_can_affect_label_def all_with_auth_to_def dest: reads_ep reads_read_queued_thread_read_ep) done lemma no_fail_gts:"no_fail (tcb_at tcb) (get_thread_state tcb)" apply (clarsimp simp: get_thread_state_def thread_get_def) apply (rule no_fail_pre) apply wp by (clarsimp simp: get_tcb_def tcb_at_def) lemma monadic_rewrite_impossible: "monadic_rewrite F E (\_. False) f g" by (clarsimp simp: monadic_rewrite_def) lemma monadic_rewrite_add_get: "monadic_rewrite F E P (do x <- get; f od) (do x <- get; g od) \ monadic_rewrite F E P f g" by (clarsimp simp: bind_def get_def) lemma sts_noop: "monadic_rewrite True True (tcb_at tcb and (\s. tcb \ cur_thread s)) (set_thread_state_ext tcb) (return ())" apply (rule monadic_rewrite_imp) apply (rule monadic_rewrite_add_get) apply (rule monadic_rewrite_bind_tail) apply (clarsimp simp: set_thread_state_ext_def) apply (rule_tac x="tcb_state (the (get_tcb tcb x))" in monadic_rewrite_symb_exec) apply (wp gts_wp | simp)+ apply (rule monadic_rewrite_symb_exec) apply wp+ apply (rule monadic_rewrite_symb_exec) apply wp+ apply (simp only: when_def) apply (rule monadic_rewrite_trans) apply (rule monadic_rewrite_if) apply (rule monadic_rewrite_impossible[where g="return ()"]) apply (rule monadic_rewrite_refl) apply simp apply (rule monadic_rewrite_refl) apply wp by (auto simp: pred_tcb_at_def obj_at_def is_tcb_def get_tcb_def) lemma sts_to_modify': "monadic_rewrite True True (tcb_at tcb and (\s :: det_ext state. tcb \ cur_thread s)) (set_thread_state tcb st) (modify (\s. s\kheap := kheap s(tcb \ TCB (the (get_tcb tcb s)\tcb_state := st\))\))" apply (clarsimp simp: set_thread_state_def set_object_def) apply (rule monadic_rewrite_add_get) apply (rule monadic_rewrite_bind_tail) apply (rule monadic_rewrite_imp) apply (rule monadic_rewrite_trans) apply (simp only: bind_assoc[symmetric]) apply (rule monadic_rewrite_bind_tail) apply (rule sts_noop) apply wp apply simp apply (rule_tac x="the (get_tcb tcb x)" in monadic_rewrite_symb_exec,(wp | simp)+) apply (rule_tac x="x" in monadic_rewrite_symb_exec,(wp | simp)+) apply (rule_tac P="(=) x" in monadic_rewrite_refl3) apply (clarsimp simp add: put_def modify_def get_def bind_def) apply assumption apply wp by (clarsimp simp: get_tcb_def tcb_at_def) lemma monadic_rewrite_weaken_failure: "monadic_rewrite True True P f f' \ no_fail P' f \ no_fail Q' f' \ monadic_rewrite F E (P and P' and Q') f f'" by (clarsimp simp: monadic_rewrite_def no_fail_def) lemma sts_no_fail: "no_fail (\s :: det_ext state. tcb_at tcb s) (set_thread_state tcb st)" apply (simp add: set_thread_state_def set_object_def) apply (simp add: set_thread_state_ext_def get_thread_state_def thread_get_def set_scheduler_action_def) apply (rule no_fail_pre) apply wp by (clarsimp simp: get_tcb_def tcb_at_def) lemmas sts_to_modify = monadic_rewrite_weaken_failure[OF sts_to_modify' sts_no_fail no_fail_modify,simplified] definition "blocked_cancel_ipc_nosts tcb \ do state <- get_thread_state tcb; epptr \ get_blocking_object state; ep \ get_endpoint epptr; queue \ get_ep_queue ep; queue' \ return $ remove1 tcb queue; ep' \ return (case queue' of [] \ IdleEP | a # list \ update_ep_queue ep queue'); set_endpoint epptr ep'; set_thread_state tcb Running od" lemma cancel_ipc_to_blocked_nosts: "monadic_rewrite False False (\s. st_tcb_at receive_blocked tcb (s :: det_ext state) \ cur_thread s \ tcb) (blocked_cancel_ipc_nosts tcb) (cancel_ipc tcb >>= (\_. set_thread_state tcb Running))" apply (simp add: cancel_ipc_def bind_assoc blocked_cancel_ipc_nosts_def) apply (rule monadic_rewrite_bind_tail) apply (rule monadic_rewrite_transverse) apply (rename_tac state) apply (rule_tac P="\_. \xa. state = BlockedOnReceive xa" in monadic_rewrite_bind_head) apply (rule monadic_rewrite_gen_asm[where Q=\,simplified]) apply clarsimp apply (rule monadic_rewrite_refl) apply (simp add: blocked_cancel_ipc_def blocked_cancel_ipc_nosts_def bind_assoc) apply (rule monadic_rewrite_bind_tail) apply (rule monadic_rewrite_bind_tail) apply (rule monadic_rewrite_bind_tail) apply (rule monadic_rewrite_bind_tail) apply (rule monadic_rewrite_trans) apply (rule sts_to_modify) apply (rule monadic_rewrite_transverse) apply (rule monadic_rewrite_bind) apply (rule sts_to_modify) apply (rule sts_to_modify) apply (rule hoare_modifyE_var[where P="tcb_at tcb and (\s. tcb \ cur_thread s)"]) apply (clarsimp simp: tcb_at_def get_tcb_def) apply (simp add: modify_modify) apply (rule monadic_rewrite_refl2) apply (fastforce simp add: simpler_modify_def o_def get_tcb_def) apply (wp gts_wp)+ apply (simp add: set_thread_state_def bind_assoc gets_the_def) apply (clarsimp simp add: pred_tcb_at_def receive_blocked_def obj_at_def is_tcb_def split: thread_state.splits) by (case_tac "tcb_state tcba";fastforce) lemma gts_reads_respects: "reads_respects aag l (K (aag_can_read aag thread \ aag_can_affect aag l thread)) (get_thread_state thread)" unfolding get_thread_state_def by (wp thread_get_reads_respects) lemma ev2_invisible_simple: assumes domains_distinct: "pas_domains_distinct aag" shows "labels_are_invisible aag l L \ modifies_at_most aag L Q f \ reads_respects aag l Q (f :: det_ext state \ (unit \ det_ext state) set \ bool)" apply (simp add: equiv_valid_def2) apply (rule equiv_valid_2_guard_imp) apply (rule ev2_invisible[OF domains_distinct]) by fastforce+ lemma blocked_cancel_ipc_nosts_equiv_but_for_labels: "\pas_refined aag and st_tcb_at (\st. st = BlockedOnReceive x) t and bound_tcb_at ((=) (Some ntfnptr)) t and equiv_but_for_labels aag L st and K(pasObjectAbs aag x \ L) and K(pasObjectAbs aag t \ L) \ blocked_cancel_ipc_nosts t \\_. equiv_but_for_labels aag L st\" unfolding blocked_cancel_ipc_nosts_def get_blocking_object_def apply (wp set_endpoint_equiv_but_for_labels get_object_wp gts_wp set_thread_state_runnable_equiv_but_for_labels | wpc | simp)+ by (clarsimp simp: pred_tcb_at_def obj_at_def) lemma blocked_cancel_ipc_nosts_reads_respects: assumes domains_distinct[wp]: "pas_domains_distinct aag" shows "reads_respects aag l (pas_refined aag and st_tcb_at (\st. \xa. st = (BlockedOnReceive x)) t and bound_tcb_at ((=) (Some ntfnptr)) t and (\s. is_subject aag (cur_thread s)) and K ( (pasObjectAbs aag t, Receive, pasObjectAbs aag ntfnptr) \ pasPolicy aag \ (pasSubject aag, Notify, pasObjectAbs aag ntfnptr) \ pasPolicy aag \ (pasObjectAbs aag t, Receive, pasObjectAbs aag x) \ pasPolicy aag)) (blocked_cancel_ipc_nosts t)" unfolding blocked_cancel_ipc_nosts_def apply (simp only:bind_assoc[symmetric]) apply (rule bind_ev[where P''=\,simplified]) apply (wp set_thread_state_runnable_reads_respects,simp) subgoal proof (cases "aag_can_read_label aag (pasObjectAbs aag x) \ aag_can_affect aag l x") case True thus ?thesis \ \boring case, can read or affect ep\ unfolding blocked_cancel_ipc_nosts_def get_blocking_object_def apply clarsimp apply (rule pre_ev) apply ((wp set_thread_state_reads_respects get_ep_queue_reads_respects get_simple_ko_reads_respects get_blocking_object_reads_respects gts_reads_respects set_simple_ko_reads_respects gts_wp | wpc | simp add: get_blocking_object_def get_thread_state_rev)+)[2] apply (clarsimp simp: pred_tcb_at_def obj_at_def) by (fastforce dest:read_sync_ep_read_receivers_strong ) next case False thus ?thesis apply - \ \can't read or affect ep\ apply (rule gen_asm_ev) apply (drule label_is_invisible[THEN iffD2]) apply clarsimp apply (rule ev2_invisible_simple[OF domains_distinct],assumption) apply (simp add: get_blocking_object_def) apply (rule modifies_at_mostI) apply (rule hoare_pre) apply (wp set_thread_state_runnable_equiv_but_for_labels set_endpoint_equiv_but_for_labels get_object_wp gts_wp set_thread_state_runnable_equiv_but_for_labels | wpc | simp)+ by (fastforce simp: pred_tcb_at_def obj_at_def) qed by wp crunch silc_inv[wp]: "blocked_cancel_ipc_nosts" "silc_inv aag st" lemmas blocked_cancel_ipc_nosts_reads_respects_f = reads_respects_f[where Q=\,simplified, OF blocked_cancel_ipc_nosts_reads_respects blocked_cancel_ipc_nosts_silc_inv, simplified] lemma monadic_rewrite_is_valid: "monadic_rewrite False False P' f f' \ \P\ do x <- f; g x od \Q\ \ \P and P'\ do x <- f'; g x od \Q\" by (fastforce simp: monadic_rewrite_def valid_def bind_def) lemma monadic_rewrite_reads_respects: "monadic_rewrite False False P f f' \ reads_respects l aag P' (do x <- f; g x od) \ reads_respects l aag (P and P') (do x <- f'; g x od)" apply (clarsimp simp: monadic_rewrite_def equiv_valid_def spec_equiv_valid_def equiv_valid_2_def bind_def) apply (frule_tac x=st in spec) apply (drule_tac x=t in spec) by fastforce lemmas cancel_ipc_reads_respects_rewrite = monadic_rewrite_reads_respects[OF cancel_ipc_to_blocked_nosts, simplified bind_assoc] lemmas cancel_ipc_valid_rewrite = monadic_rewrite_is_valid[OF cancel_ipc_to_blocked_nosts, simplified bind_assoc] crunch etcb_at[wp]: blocked_cancel_ipc_nosts "etcb_at P t" crunch cur_domain[wp]: blocked_cancel_ipc_nosts "\s. P (cur_domain s)" crunch pas_refined[wp]: blocked_cancel_ipc_nosts "pas_refined aag" crunch cur_thread[wp]: blocked_cancel_ipc_nosts "\s. P (cur_thread s)" lemma BlockedOnReceive_inj: "x = (case (BlockedOnReceive x) of BlockedOnReceive x \ x)" by (cases "BlockedOnReceive x";simp) lemma send_signal_reads_respects: assumes domains_distinct[wp]: "pas_domains_distinct aag" notes set_thread_state_owned_reads_respects[wp del] cancel_ipc_pas_refined[wp del] shows "reads_respects aag l (pas_refined aag and pas_cur_domain aag and (\s. is_subject aag (cur_thread s)) and valid_etcbs and ct_active and (\s. sym_refs (state_refs_of s)) and valid_objs and K ((pasSubject aag, Notify, pasObjectAbs aag ntfnptr) \ pasPolicy aag)) (send_signal ntfnptr badge)" unfolding send_signal_def fun_app_def subgoal proof (cases "aag_can_read aag ntfnptr \ aag_can_affect aag l ntfnptr") case True note visible = this show ?thesis apply (rule pre_ev) apply (simp split del: if_split | rule_tac ntfnptr=ntfnptr in blocked_cancel_ipc_nosts_reads_respects | rule cancel_ipc_reads_respects_rewrite | wp_once set_simple_ko_reads_respects possible_switch_to_reads_respects as_user_set_register_reads_respects' set_thread_state_pas_refined set_thread_state_pas_refined set_simple_ko_reads_respects gts_reads_respects cancel_ipc_receive_blocked_pas_refined gts_wp hoare_vcg_imp_lift update_waiting_ntfn_reads_respects get_simple_ko_wp get_simple_ko_reads_respects | wpc | simp )+ apply (insert visible) apply clarsimp apply (rule conjI[rotated]) apply fastforce apply (rule disjI2) apply (intro impI allI) apply (simp add: obj_at_def) apply (rule conjI) apply (frule (3) ntfn_bound_tcb_at[where P="(=) (Some ntfnptr)",OF _ _ _ _ refl]) apply (frule (1) bound_tcb_at_implies_receive) apply (elim disjE) apply (rule disjI1) apply (fastforce dest:read_sync_ep_read_receivers_strong) apply (rule disjI2) apply (fastforce dest:read_sync_ep_read_receivers_strong) apply (clarsimp) apply (frule (1) ntfn_bound_tcb_at[where P="(=) (Some ntfnptr)",OF _ _ _ _ refl]) apply (fastforce simp: obj_at_def) apply assumption apply (rule conjI) apply (fastforce simp: pred_tcb_at_def receive_blocked_def obj_at_def) apply (rule conjI[rotated]) apply (frule (1) bound_tcb_at_implies_receive) apply (frule (1) bound_tcb_at_implies_reset) apply (clarsimp simp: pred_tcb_at_def get_tcb_def obj_at_def) apply (rule context_conjI) apply (fastforce simp: receive_blocked_def intro!: BlockedOnReceive_inj split:thread_state.splits) apply (frule_tac t=x and tcb=tcb and ep = "case (tcb_state tcb) of BlockedOnReceive a \ a" in get_tcb_recv_blocked_implies_receive) apply (fastforce simp: pred_tcb_at_def get_tcb_def obj_at_def) apply (fastforce simp: receive_blocked_def split:thread_state.splits) apply (fastforce simp: receive_blocked_def intro!: BlockedOnReceive_inj split:thread_state.splits) by (fastforce simp: pred_tcb_at_def get_tcb_def obj_at_def receive_blocked_def ct_in_state_def split:thread_state.splits) next case False note invisible = this show ?thesis apply (insert label_is_invisible[THEN iffD2, OF invisible]) apply (rule gen_asm_ev) apply (drule (1) invisible_ntfn_invisible_receivers_and_receivers) apply simp apply (rule ev2_invisible_simple[OF domains_distinct],assumption) apply (rule modifies_at_mostI) apply ( simp split del: if_split | rule cancel_ipc_valid_rewrite | wp_once set_notification_equiv_but_for_labels possible_switch_to_equiv_but_for_labels as_user_equiv_but_for_labels set_thread_state_runnable_equiv_but_for_labels set_thread_state_pas_refined blocked_cancel_ipc_nosts_equiv_but_for_labels gts_wp update_waiting_ntfn_equiv_but_for_labels get_simple_ko_wp | wpc | wps )+ apply (elim conjE) apply (match premises in "ntfn_bound_tcb _ = _" \ \fail\ \ _ \ \rule allI impI conjI\)+ prefer 2 apply (intro conjI allI impI; fastforce?) subgoal waiting_ntfn apply clarsimp apply (rule ccontr) apply (frule (3) not_etcb_at_not_cdom_can_read[OF domains_distinct, rotated 2]) apply (rule tcb_at_ntfn_queue;assumption) apply(frule (7) read_queued_thread_reads_ntfn) using invisible by (fastforce simp add: all_with_auth_to_def all_to_which_has_auth_def) apply (frule (1) ntfn_bound_tcb_at[where P="(=) (Some ntfnptr)",OF _ _ _ _ refl]) apply (fastforce simp: obj_at_def) apply assumption apply (intro allI conjI impI) apply (fastforce simp: pred_tcb_at_def receive_blocked_def obj_at_def split:thread_state.splits intro!: BlockedOnReceive_inj) apply assumption apply distinct_subgoals apply (fold_subgoals (prefix)) apply (frule st_tcb_at_tcb_at) subgoal bound_ntfn premises prems for st s ntfn x sta prefer 2 apply (rule disjI2) apply (rule disjI1) subgoal bound_tcb_can_receive using prems apply (clarsimp simp: all_with_auth_to_def obj_at_def) by (rule bound_tcb_at_implies_receive;assumption) apply (rule disjI2) apply (rule disjI2) apply (rule disjI1) subgoal bound_ep_can_receive apply (rule bexI[OF _ bound_tcb_can_receive]) apply (simp add: all_with_auth_to_def all_to_which_has_auth_def) using prems apply (case_tac sta;(clarsimp simp: pred_tcb_at_def obj_at_def receive_blocked_def split:thread_state.splits)) apply (rule get_tcb_recv_blocked_implies_receive, assumption) apply (fastforce simp: get_tcb_def) by (fastforce split:thread_state.splits) apply (rule ccontr) apply (insert prems) apply (frule (4) not_etcb_at_not_cdom_can_read[OF domains_distinct]) using bound_tcb_can_receive apply (fastforce simp: labels_are_invisible_def all_with_auth_to_def all_to_which_has_auth_def) apply (fastforce simp: pred_tcb_at_def receive_blocked_def obj_at_def) apply (rule ccontr) apply clarsimp using invisible bound_tcb_can_receive reads_ep by (fastforce simp add: all_with_auth_to_def all_to_which_has_auth_def) done qed done lemma receive_signal_reads_respects: assumes domains_distinct[wp]: "pas_domains_distinct aag" shows "reads_respects aag l (valid_objs and pas_refined aag and (\s. is_subject aag (cur_thread s)) and K ((\ntfnptr\Access.obj_refs cap. (pasSubject aag, Receive, pasObjectAbs aag ntfnptr) \ pasPolicy aag \ is_subject aag thread))) (receive_signal thread cap is_blocking)" unfolding receive_signal_def fun_app_def do_nbrecv_failed_transfer_def apply(wp set_simple_ko_reads_respects set_thread_state_reads_respects as_user_set_register_reads_respects' get_simple_ko_reads_respects hoare_vcg_all_lift | wpc | wp_once hoare_drop_imps)+ apply(force dest: reads_ep) done subsection "Sync IPC" (* FIXME move *) lemma conj_imp: "\Q \ R; P \ Q; P' \ Q\ \ (P \ R) \ (P' \ R)" by(fastforce) (* basically clagged directly from lookup_ipc_buffer_has_auth *) lemma lookup_ipc_buffer_has_read_auth: "\pas_refined aag and valid_objs\ lookup_ipc_buffer is_receiver thread \\rv s. ipc_buffer_has_read_auth aag (pasObjectAbs aag thread) rv\" apply (rule hoare_pre) apply (simp add: lookup_ipc_buffer_def) apply (wp get_cap_wp thread_get_wp' | wpc)+ apply (clarsimp simp: cte_wp_at_caps_of_state ipc_buffer_has_read_auth_def get_tcb_ko_at [symmetric]) apply (frule caps_of_state_tcb_cap_cases [where idx = "tcb_cnode_index 4"]) apply (simp add: dom_tcb_cap_cases) apply (frule (1) caps_of_state_valid_cap) apply (clarsimp simp: vm_read_only_def vm_read_write_def) apply (rule_tac Q="AllowRead \ xc" in conj_imp) apply (clarsimp simp: valid_cap_simps cap_aligned_def) apply (rule conjI) apply (erule aligned_add_aligned) apply (rule is_aligned_andI1) apply (drule (1) valid_tcb_objs) apply (clarsimp simp: valid_obj_def valid_tcb_def valid_ipc_buffer_cap_def split: if_splits) apply (rule order_trans [OF _ pbfs_atleast_pageBits]) apply (simp add: msg_align_bits pageBits_def) apply (drule (1) cap_auth_caps_of_state) apply (clarsimp simp: aag_cap_auth_def cap_auth_conferred_def vspace_cap_rights_to_auth_def vm_read_only_def) apply (drule bspec) apply (erule (3) ipcframe_subset_page) apply (clarsimp split: if_split_asm simp: vspace_cap_rights_to_auth_def is_page_cap_def) apply(simp_all) done definition aag_can_read_or_affect_ipc_buffer :: "'a PAS \ 'a \ word32 option \ bool" where "aag_can_read_or_affect_ipc_buffer aag l \ case_option True (\buf'. is_aligned buf' msg_align_bits \ (\x \ ptr_range buf' msg_align_bits. aag_can_read aag x \ aag_can_affect aag l x))" lemma lookup_ipc_buffer_aag_can_read_or_affect: "\pas_refined aag and valid_objs and K (aag_can_read aag thread \ aag_can_affect aag l thread)\ lookup_ipc_buffer is_receiver thread \\rv s. aag_can_read_or_affect_ipc_buffer aag l rv\" apply(rule hoare_gen_asm) apply(rule hoare_strengthen_post[OF lookup_ipc_buffer_has_read_auth]) apply(auto simp: ipc_buffer_has_read_auth_def aag_can_read_or_affect_ipc_buffer_def intro: reads_read_thread_read_pages simp: aag_can_affect_label_def split: option.splits) done lemma cptrs_in_ipc_buffer: "\x \ set [buffer_cptr_index..< buffer_cptr_index + unat (mi_extra_caps mi)]; is_aligned a msg_align_bits; buffer_cptr_index + unat (mi_extra_caps mi) < 2 ^ (msg_align_bits - 2)\ \ ptr_range (a + of_nat x * of_nat word_size) 2 \ ptr_range (a :: word32) msg_align_bits" apply(rule ptr_range_subset) apply assumption apply(simp add: msg_align_bits) apply(simp add: msg_align_bits word_bits_def) apply(simp add: word_size_def) apply(subst upto_enum_step_shift_red[where us=2, simplified]) apply (simp add: msg_align_bits word_bits_def)+ done lemma for_each_byte_of_word_def2: "for_each_byte_of_word P ptr \ (\ x\ptr_range ptr 2. P x)" apply(simp add: for_each_byte_of_word_def ptr_range_def add.commute) done lemma aag_has_auth_to_read_cptrs: "\x \ set [buffer_cptr_index..< buffer_cptr_index + unat (mi_extra_caps mi)]; ipc_buffer_has_read_auth aag (pasSubject aag) (Some a); buffer_cptr_index + unat (mi_extra_caps mi) < 2 ^ (msg_align_bits - 2)\ \ for_each_byte_of_word (\ y. aag_can_read aag y) (a + of_nat x * of_nat word_size)" apply(simp add: for_each_byte_of_word_def2 ipc_buffer_has_read_auth_def) apply(rule ballI) apply(rule reads_read) apply(clarify) apply(erule bspec) apply(rule subsetD[OF cptrs_in_ipc_buffer]) apply fastforce apply assumption apply assumption apply assumption done lemma get_extra_cptrs_rev: "reads_equiv_valid_inv A aag (K (ipc_buffer_has_read_auth aag (pasSubject aag) buffer \ (buffer_cptr_index + unat (mi_extra_caps mi) < 2 ^ (msg_align_bits - 2)))) (get_extra_cptrs buffer mi)" unfolding get_extra_cptrs_def apply (rule gen_asm_ev) apply clarsimp apply(case_tac buffer, simp_all add: return_ev_pre) apply (wp mapM_ev equiv_valid_guard_imp[OF load_word_offs_rev] | erule (2) aag_has_auth_to_read_cptrs)+ done lemma lookup_extra_caps_rev: shows "reads_equiv_valid_inv A aag (pas_refined aag and (K (is_subject aag thread)) and (\ s. ipc_buffer_has_read_auth aag (pasSubject aag) buffer \ buffer_cptr_index + unat (mi_extra_caps mi) < 2 ^ (msg_align_bits - 2))) (lookup_extra_caps thread buffer mi)" apply(rule gen_asm_ev) unfolding lookup_extra_caps_def fun_app_def apply (wp mapME_ev cap_fault_on_failure_rev lookup_cap_and_slot_rev get_extra_cptrs_rev) apply simp done lemmas lookup_extra_caps_reads_respects_g = reads_respects_g_from_inv[OF lookup_extra_caps_rev lookup_extra_caps_inv] lemma msg_in_ipc_buffer: "\x = msg_max_length \ x < msg_max_length; unat (mi_length mi) < 2 ^ (msg_align_bits - 2); is_aligned a msg_align_bits\ \ ptr_range (a + of_nat x * of_nat word_size) 2 \ ptr_range (a::word32) msg_align_bits" apply(rule ptr_range_subset) apply assumption apply(simp add: msg_align_bits) apply(simp add: msg_align_bits word_bits_def) apply(simp add: word_size_def) apply(subst upto_enum_step_shift_red[where us=2, simplified]) apply (simp add: msg_align_bits word_bits_def)+ apply(simp add: image_def) apply(rule_tac x=x in bexI) apply(rule refl) apply(auto simp: msg_max_length_def) done lemma aag_has_auth_to_read_msg: "\x = msg_max_length \ x < msg_max_length; ipc_buffer_has_read_auth aag (pasSubject aag) (Some a); unat (mi_length mi) < 2 ^ (msg_align_bits - 2)\ \ for_each_byte_of_word (aag_can_read aag) (a + of_nat x * of_nat word_size)" apply(simp add: for_each_byte_of_word_def2 ipc_buffer_has_read_auth_def) apply(rule ballI) apply(rule reads_read) apply(clarify) apply(erule bspec) apply(rule subsetD[OF msg_in_ipc_buffer[where x=x]]) apply assumption apply assumption apply assumption apply assumption done (* only called within do_reply_transfer for which access assumes sender and receiver in same domain *) lemma get_mrs_rev: shows "reads_equiv_valid_inv A aag ((K (is_subject aag thread \ ipc_buffer_has_read_auth aag (pasSubject aag) buf \ unat (mi_length mi) < 2 ^ (msg_align_bits - 2)))) (get_mrs thread buf mi)" apply (rule gen_asm_ev) unfolding get_mrs_def apply (wp mapM_ev'' load_word_offs_rev thread_get_rev | wpc | rule aag_has_auth_to_read_msg[where mi=mi] | clarsimp split: if_split_asm)+ done lemmas get_mrs_reads_respects_g = reads_respects_g_from_inv[OF get_mrs_rev get_mrs_inv] lemma setup_caller_cap_reads_respects: "reads_respects aag l (K (is_subject aag sender \ is_subject aag receiver)) (setup_caller_cap sender receiver)" unfolding setup_caller_cap_def apply(wp cap_insert_reads_respects set_thread_state_owned_reads_respects | simp)+ done lemma const_on_failure_ev: "equiv_valid_inv I A P m \ equiv_valid_inv I A P (const_on_failure c m)" unfolding const_on_failure_def catch_def apply(wp | wpc | simp)+ done lemma set_extra_badge_reads_respects: "reads_respects aag l \ (set_extra_badge buffer badge n)" unfolding set_extra_badge_def by (rule store_word_offs_reads_respects) lemma reads_equiv_cdt_has_children: "\pas_refined aag s; pas_refined aag s'; is_subject aag (fst slot); equiv_for (aag_can_read aag \ fst) cdt s s'\ \ (\ c. (cdt s) c = Some slot) = (\ c. (cdt s') c = Some slot)" apply(rule iffI) apply(erule exE) apply(frule (2) aag_owned_cdt_link) apply(fastforce elim: equiv_forE dest: aag_can_read_self) apply(erule exE) apply(drule (2) aag_owned_cdt_link[rotated]) apply(erule equiv_forE) apply(drule_tac x=c in meta_spec) apply(fastforce dest: aag_can_read_self) done lemma ensure_no_children_rev: "reads_equiv_valid_inv A aag (pas_refined aag and K (is_subject aag (fst slot))) (ensure_no_children slot)" unfolding ensure_no_children_def fun_app_def equiv_valid_def2 apply(rule equiv_valid_rv_guard_imp) apply(rule_tac Q="\ rv s. pas_refined aag s \ is_subject aag (fst slot) \ rv = cdt s" in equiv_valid_rv_liftE_bindE[OF equiv_valid_rv_guard_imp[OF gets_cdt_revrv']]) apply(rule TrueI) apply(clarsimp simp: equiv_valid_2_def) apply(drule reads_equiv_cdt_has_children) apply assumption apply assumption apply(fastforce elim: reads_equivE) apply(fastforce simp: in_whenE in_throwError) apply(wp ,simp) done lemma arch_derive_cap_reads_respects: "reads_respects aag l \ (arch_derive_cap cap)" unfolding arch_derive_cap_def apply(rule equiv_valid_guard_imp) apply(wp | wpc)+ apply(simp) done lemma derive_cap_rev': "reads_equiv_valid_inv A aag (\ s. (\x xa xb d. cap = cap.UntypedCap d x xa xb) \ pas_refined aag s \ is_subject aag (fst slot)) (derive_cap slot cap)" unfolding derive_cap_def arch_derive_cap_def apply(rule equiv_valid_guard_imp) apply(wp ensure_no_children_rev | wpc | simp)+ done lemma derive_cap_rev: "reads_equiv_valid_inv A aag (\ s. pas_refined aag s \ is_subject aag (fst slot)) (derive_cap slot cap)" by(blast intro: equiv_valid_guard_imp[OF derive_cap_rev']) lemma transfer_caps_loop_reads_respects: "reads_respects aag l (pas_refined aag and K ((\cap\set caps. is_subject aag (fst (snd cap)) \ pas_cap_cur_auth aag (fst cap)) \ (\slot\set slots. is_subject aag (fst slot)))) (transfer_caps_loop ep rcv_buffer n caps slots mi)" apply(induct caps arbitrary: slots n mi) apply simp apply(rule return_ev_pre) apply(case_tac a) apply(simp split del: if_split) apply(rule equiv_valid_guard_imp) apply(wp const_on_failure_ev | simp | intro conjI impI)+ apply fast apply(wp set_extra_badge_reads_respects | simp)+ apply fast apply(wp cap_insert_reads_respects cap_insert_pas_refined whenE_throwError_wp derive_cap_rev derive_cap_cap_cur_auth | simp split del: if_split | wp_once hoare_drop_imps)+ apply(clarsimp simp: remove_rights_cur_auth) apply(fastforce dest: subsetD[OF set_tl_subset]) done lemma empty_on_failure_ev: "equiv_valid_inv I A P m \ equiv_valid_inv I A P (empty_on_failure m)" unfolding empty_on_failure_def catch_def apply(wp | wpc | simp)+ done lemma unify_failure_ev: "equiv_valid_inv I A P m \ equiv_valid_inv I A P (unify_failure m)" unfolding unify_failure_def handleE'_def apply(wp | wpc | simp)+ done lemma lookup_slot_for_cnode_op_rev: "reads_equiv_valid_inv A aag (\s. ((depth \ 0 \ depth \ word_bits) \ (pas_refined aag s \ (is_cnode_cap croot \ is_subject aag (obj_ref_of croot))))) (lookup_slot_for_cnode_op is_source croot ptr depth)" unfolding lookup_slot_for_cnode_op_def apply (clarsimp split del: if_split) apply (wp resolve_address_bits_rev lookup_error_on_failure_rev whenE_throwError_wp | wpc | rule hoare_post_imp_R[OF hoare_True_E_R[where P="\"]] | simp add: split_def split del: if_split)+ done lemma lookup_slot_for_cnode_op_reads_respects: "reads_respects aag l (pas_refined aag and K (is_subject aag (obj_ref_of croot))) (lookup_slot_for_cnode_op is_source croot ptr depth)" apply(rule equiv_valid_guard_imp[OF lookup_slot_for_cnode_op_rev]) by simp lemma lookup_cap_rev: "reads_equiv_valid_inv A aag (pas_refined aag and K (is_subject aag thread)) (lookup_cap thread ref)" unfolding lookup_cap_def split_def fun_app_def apply(wp lookup_slot_for_thread_rev get_cap_rev | simp)+ apply(rule lookup_slot_for_thread_authorised) apply(simp) done lemma captransfer_indices_in_range: "x \ {0..2} \ ((2::word32) + (of_nat msg_max_length + of_nat msg_max_extra_caps)) * word_size + (x * word_size) \ 2 ^ msg_align_bits - 1" apply(rule order_trans) prefer 2 apply(rule word_less_sub_1) apply(rule_tac p=127 in mul_word_size_lt_msg_align_bits_ofnat) apply(simp add: msg_align_bits) apply(rule_tac y="0x7F * word_size" in order_trans) apply(clarsimp simp: msg_max_length_def msg_max_extra_caps_def word_size_def) apply(drule_tac k=4 in word_mult_le_mono1) apply simp apply simp apply(drule_tac x="0x1F4" in word_plus_mono_right) apply simp apply simp apply (simp add: word_size_def) done lemma word_plus_power_2_offset_le: "\is_aligned (p :: 'a :: len word) n; is_aligned q m; p < q; n \ m; n < len_of TYPE('a)\ \ p + (2^n) \ q" apply(drule is_aligned_weaken, assumption) apply(clarsimp simp: is_aligned_def) apply(elim dvdE) apply(rename_tac k ka) apply(rule_tac ua=0 and n="int k" and n'="int ka" in udvd_incr') apply assumption apply(clarsimp simp: uint_nat)+ done lemma is_aligned_mult_word_size: "is_aligned (p * word_size) 2" apply(rule_tac k=p in is_alignedI) apply(fastforce simp: word_size_def) done lemma captransfer_in_ipc_buffer: "\is_aligned (buffer :: word32) msg_align_bits; x \ {0..2}\ \ ptr_range (buffer + (2 + (of_nat msg_max_length + of_nat msg_max_extra_caps)) * word_size + x * word_size) 2 \ ptr_range buffer msg_align_bits" apply(rule ptr_range_subset) apply assumption apply(simp add: msg_align_bits) apply(simp add: msg_align_bits word_bits_def) apply(simp add: word_size_def) apply(subst upto_enum_step_shift_red[where us=2, simplified]) apply (simp add: msg_align_bits word_bits_def)+ apply(simp add: image_def msg_max_length_def msg_max_extra_caps_def) apply(rule_tac x="(125::nat) + unat x" in bexI) apply simp+ apply(fastforce intro: unat_less_helper minus_one_helper5) done lemma aag_has_auth_to_read_captransfer: "\ipc_buffer_has_read_auth aag (pasSubject aag) (Some buffer); x \ {0..2}\ \ for_each_byte_of_word (aag_can_read aag) (buffer + (2 + (of_nat msg_max_length + of_nat msg_max_extra_caps)) * word_size + x * word_size)" apply(simp add: for_each_byte_of_word_def2 ipc_buffer_has_read_auth_def) apply(rule ballI) apply(rule reads_read) apply(clarify) apply(erule bspec) apply(rule subsetD[OF captransfer_in_ipc_buffer]) apply fastforce+ done lemma load_cap_transfer_rev: "reads_equiv_valid_inv A aag (K (ipc_buffer_has_read_auth aag (pasSubject aag) (Some buffer))) (load_cap_transfer buffer)" unfolding load_cap_transfer_def fun_app_def captransfer_from_words_def apply(wp dmo_loadWord_rev | simp)+ apply safe apply(erule aag_has_auth_to_read_captransfer[where x=0, simplified]) apply(erule aag_has_auth_to_read_captransfer[where x=1, simplified]) apply(erule aag_has_auth_to_read_captransfer[where x=2, simplified]) done lemma get_endpoint_rev: "reads_equiv_valid_inv A aag (K (is_subject aag ptr)) (get_endpoint ptr)" unfolding get_simple_ko_def apply(wp get_object_rev | wpc | simp)+ done lemma send_endpoint_threads_blocked: "\valid_objs s; (sym_refs \ state_refs_of) s; ko_at (Endpoint (SendEP list)) ep s; x\set list\ \ st_tcb_at (send_blocked_on ep) x s" apply (rule ep_queued_st_tcb_at'') apply simp+ done lemma send_blocked_threads_have_SyncSend_auth: "\pas_refined aag s; valid_objs s; sym_refs (state_refs_of s); st_tcb_at (send_blocked_on ep) x s\ \ (pasObjectAbs aag x,SyncSend,pasObjectAbs aag ep) \ pasPolicy aag" apply(drule_tac auth="SyncSend" and x=x in pas_refined_mem[rotated]) apply(rule sta_ts) apply(clarsimp simp: thread_states_def split: option.split simp: tcb_states_of_state_def st_tcb_def2) apply(case_tac "tcb_state tcb", simp_all) done (*MOVE*) lemma ev_invisible: assumes domains_distinct: "pas_domains_distinct aag" shows "\labels_are_invisible aag l L; modifies_at_most aag L Q f; \s t. P s \ P t \ (\(rva, s') \ fst (f s). \(rvb, t') \ fst(f t). W rva rvb)\ \ equiv_valid_2 (reads_equiv aag) (affects_equiv aag l) (affects_equiv aag l) W (P and Q) (P and Q) f f" apply (rule ev2_invisible[OF domains_distinct]) apply simp+ done lemma get_thread_state_reads_respects: "reads_respects aag l (\ s. aag_can_read aag thread \ aag_can_affect aag l thread) (get_thread_state thread)" unfolding get_thread_state_def apply(rule equiv_valid_guard_imp) apply(wp thread_get_reads_respects | simp)+ done lemma send_endpoint_reads_affects_queued: "\(pasSubject aag, auth, pasObjectAbs aag epptr) \ pasPolicy aag; auth \ {Receive,Reset}; aag_can_read_label aag (pasObjectAbs aag epptr) \ aag_can_affect aag l epptr; pas_refined aag s; valid_objs s; sym_refs (state_refs_of s); ko_at (Endpoint (SendEP list)) epptr s; ep = SendEP list; x \ set list\ \ aag_can_read_label aag (pasObjectAbs aag x) \ aag_can_affect aag l x" apply(frule send_endpoint_threads_blocked, (simp | assumption)+) apply(drule send_blocked_threads_have_SyncSend_auth, (simp | assumption)+) apply(auto dest: read_sync_ep_read_senders) done (* lemma cancel_badged_sends_equiv_but_for_labels: "\ pas_refined aag and valid_objs and sym_refs \ state_refs_of and equiv_but_for_labels aag L st and K ({pasObjectAbs aag epptr} \ all_with_auth_to aag SyncSend (pasObjectAbs aag epptr) \ L) \ cancel_badged_sends epptr badge \ \_. equiv_but_for_labels aag L st \" unfolding cancel_badged_sends_def apply(wp set_endpoint_equiv_but_for_labels | wpc | simp)+ apply(rule_tac Q="\ r s. equiv_but_for_labels aag L st s \ {pasObjectAbs aag epptr} \ all_with_auth_to aag SyncSend (pasObjectAbs aag epptr) \ L \ (\x\set list. (pasObjectAbs aag x, SyncSend, pasObjectAbs aag epptr) \ pasPolicy aag)" in hoare_strengthen_post) apply(wp mapM_wp' set_thread_state_equiv_but_for_labels gts_wp | simp add: filterM_mapM)+ apply(fastforce simp: all_with_auth_to_def) apply simp apply(wp set_endpoint_equiv_but_for_labels get_simple_ko_wp | simp)+ apply clarsimp apply(frule send_endpoint_threads_blocked, (simp | assumption)+) apply(drule send_blocked_threads_have_SyncSend_auth, (simp | assumption)+) done *) (* lemma cancel_badged_sends_reads_respects: shows "reads_respects aag l (pas_refined aag and valid_objs and (sym_refs \ state_refs_of) and K ((pasSubject aag, Reset, pasObjectAbs aag epptr) \ pasPolicy aag)) (cancel_badged_sends epptr badge)" apply (rule gen_asm_ev)+ apply(case_tac "aag_can_read aag epptr \ aag_can_affect aag l epptr") apply(simp add: cancel_badged_sends_def fun_app_def) apply wp apply (rule_tac Q="\s. (case rv of SendEP list \ \x\set list. aag_can_read aag x \ aag_can_affect aag l x | _ \ True)" in equiv_valid_guard_imp) apply (case_tac rv) apply ((wp mapM_ev'' get_thread_state_reads_respects set_thread_state_reads_respects set_simple_ko_reads_respects get_simple_ko_reads_respects hoare_vcg_ball_lift | wpc | simp add: filterM_mapM tcb_at_st_tcb_at[symmetric])+) apply (wp get_simple_ko_wp) apply (intro impI allI conjI) apply simp apply (case_tac ep,simp_all) apply (elim conjE, rule ballI) apply (rule send_endpoint_reads_affects_queued, (simp | assumption)+) apply(simp add: equiv_valid_def2) apply(rule equiv_valid_rv_guard_imp) apply(rule_tac Q="pas_refined aag and valid_objs and sym_refs \ state_refs_of" and L="{pasObjectAbs aag epptr} \ all_with_auth_to aag SyncSend (pasObjectAbs aag epptr)" in ev_invisible) apply(auto dest: reads_read_queued_thread_read_ep simp: labels_are_invisible_def aag_can_affect_label_def all_with_auth_to_def)[1] apply(rule modifies_at_mostI) apply(wp cancel_badged_sends_equiv_but_for_labels | simp)+ done *) lemma mapM_ev''': assumes reads_res: "\ x. x \ set lst \ equiv_valid_inv D A (Q and P x) (m x)" assumes inv: "\ x. x \ set lst \ invariant (m x) (\ s. Q s \ (\x\set lst. P x s))" shows "equiv_valid_inv D A (\ s. Q s \ (\x\set lst. P x s)) (mapM m lst)" apply(rule mapM_ev) apply(rule equiv_valid_guard_imp[OF reads_res], simp+) apply(wpsimp wp: inv) done lemma cancel_badged_sends_reads_respects: assumes domains_distinct[wp]: "pas_domains_distinct aag" notes gts_st_tcb_at[wp del] shows "reads_respects aag l (pas_refined aag and valid_objs and (sym_refs \ state_refs_of) and (\s. is_subject aag (cur_thread s)) and K (is_subject aag epptr)) (cancel_badged_sends epptr badge)" apply (rule gen_asm_ev)+ apply(simp add: cancel_badged_sends_def fun_app_def) apply wp apply ((wp mapM_ev'' mapM_wp get_thread_state_reads_respects set_thread_state_runnable_reads_respects set_simple_ko_reads_respects get_simple_ko_reads_respects hoare_vcg_ball_lift tcb_sched_action_reads_respects set_thread_state_pas_refined | wpc | simp add: filterM_mapM tcb_at_st_tcb_at[symmetric] | wp_once hoare_drop_imps | rule subset_refl | force)+)[1] apply (wp get_simple_ko_reads_respects) apply (wp get_simple_ko_wp) apply simp apply (intro conjI allI impI ballI, elim conjE) apply (rule send_endpoint_reads_affects_queued[where epptr = epptr]) apply (force simp: pas_refined_def policy_wellformed_def | assumption)+ done lemma get_cap_ret_is_subject': "\pas_refined aag and K (is_subject aag (fst ptr))\ get_cap ptr \\rv s. is_cnode_cap rv \ (\x\Access.obj_refs rv. is_subject aag x)\" apply(rule hoare_strengthen_post[OF get_cap_ret_is_subject]) apply(clarsimp simp: is_cap_simps) done lemma get_receive_slots_rev: "reads_equiv_valid_inv A aag (pas_refined aag and (K (is_subject aag thread \ ipc_buffer_has_read_auth aag (pasSubject aag) buf))) (get_receive_slots thread buf)" apply(case_tac buf) apply(fastforce intro: return_ev_pre) apply(simp add: lookup_cap_def split_def | wp empty_on_failure_ev unify_failure_ev lookup_slot_for_cnode_op_rev get_cap_rev lookup_slot_for_thread_rev lookup_slot_for_thread_authorised get_cap_ret_is_subject get_cap_ret_is_subject' load_cap_transfer_rev | wp_once hoare_drop_imps)+ done lemma transfer_caps_reads_respects: "reads_respects aag l (pas_refined aag and K (is_subject aag receiver \ ipc_buffer_has_read_auth aag (pasSubject aag) receive_buffer \ (\cap\set caps. is_subject aag (fst (snd cap)) \ pas_cap_cur_auth aag (fst cap)))) (transfer_caps mi caps endpoint receiver receive_buffer)" unfolding transfer_caps_def fun_app_def apply(wp transfer_caps_loop_reads_respects get_receive_slots_rev get_receive_slots_authorised hoare_vcg_all_lift static_imp_wp | wpc | simp)+ done lemma mrs_in_ipc_buffer: "\is_aligned (buf :: word32) msg_align_bits; x \ set [length msg_registers + 1.. \ ptr_range (buf + of_nat x * of_nat word_size) 2 \ ptr_range buf msg_align_bits" apply(rule ptr_range_subset) apply assumption apply(simp add: msg_align_bits) apply(simp add: msg_align_bits word_bits_def) apply(simp add: word_size_def) apply(subst upto_enum_step_shift_red[where us=2, simplified]) apply (simp add: msg_align_bits word_bits_def)+ apply(simp add: image_def) apply(rule_tac x=x in bexI) apply(rule refl) apply (fastforce split: if_split_asm) done lemma aag_has_auth_to_read_mrs: "\aag_can_read_or_affect_ipc_buffer aag l (Some buf); x \ set [length msg_registers + 1.. \ for_each_byte_of_word (\x. aag_can_read_label aag (pasObjectAbs aag x) \ aag_can_affect aag l x) (buf + of_nat x * of_nat word_size)" apply(simp add: for_each_byte_of_word_def2 aag_can_read_or_affect_ipc_buffer_def) apply(rule ballI) apply(erule conjE) apply(erule bspec) apply(rule subsetD[OF mrs_in_ipc_buffer[where x=x and n=n]]) apply assumption apply (clarsimp split: if_splits) apply assumption apply assumption done abbreviation aag_can_read_or_affect where "aag_can_read_or_affect aag l x \ aag_can_read aag x \ aag_can_affect aag l x" lemma dmo_loadWord_reads_respects: "reads_respects aag l (K (for_each_byte_of_word (\ x. aag_can_read_or_affect aag l x) p)) (do_machine_op (loadWord p))" apply(rule gen_asm_ev) apply(rule use_spec_ev) apply(rule spec_equiv_valid_hoist_guard) apply(rule do_machine_op_spec_reads_respects) apply(simp add: loadWord_def equiv_valid_def2 spec_equiv_valid_def) apply(rule_tac R'="\ rv rv'. for_each_byte_of_word (\ y. rv y = rv' y) p" and Q="\\" and Q'="\\" and P="\" and P'="\" in equiv_valid_2_bind_pre) apply(rule_tac R'="(=)" and Q="\ r s. p && mask 2 = 0" and Q'="\ r s. p && mask 2 = 0" and P="\" and P'="\" in equiv_valid_2_bind_pre) apply(rule return_ev2) apply(rule_tac f="word_rcat" in arg_cong) apply(fastforce intro: is_aligned_no_wrap' word_plus_mono_right simp: is_aligned_mask for_each_byte_of_word_def) (* slow *) apply(rule assert_ev2[OF refl]) apply(rule assert_wp)+ apply simp+ apply(clarsimp simp: equiv_valid_2_def in_monad for_each_byte_of_word_def) apply(fastforce elim: equiv_forD orthD1 simp: ptr_range_def add.commute) apply (wp wp_post_taut loadWord_inv | simp)+ done lemma load_word_offs_reads_respects: "reads_respects aag l (\ s. for_each_byte_of_word (\ x. aag_can_read_or_affect aag l x) (a + of_nat x * of_nat word_size)) (load_word_offs a x)" unfolding load_word_offs_def fun_app_def apply(rule equiv_valid_guard_imp[OF dmo_loadWord_reads_respects]) apply(clarsimp) done lemma as_user_reads_respects: "reads_respects aag l (K (det f \ aag_can_read_or_affect aag l thread)) (as_user thread f)" apply (simp add: as_user_def fun_app_def split_def) apply (rule gen_asm_ev) apply (wp set_object_reads_respects select_f_ev gets_the_ev) apply (auto intro: reads_affects_equiv_get_tcb_eq[where aag=aag]) done lemma copy_mrs_reads_respects: assumes domains_distinct[wp]: "pas_domains_distinct aag" shows "reads_respects aag l (K (aag_can_read_or_affect aag l sender \ aag_can_read_or_affect_ipc_buffer aag l sbuf \ unat n < 2 ^ (msg_align_bits - 2))) (copy_mrs sender sbuf receiver rbuf n)" unfolding copy_mrs_def fun_app_def apply(rule gen_asm_ev) apply(wp mapM_ev'' store_word_offs_reads_respects load_word_offs_reads_respects as_user_set_register_reads_respects' as_user_reads_respects | wpc | simp add: det_setRegister det_getRegister split del: if_split)+ apply clarsimp apply(rename_tac n') apply(subgoal_tac " ptr_range (x + of_nat n' * of_nat word_size) 2 \ ptr_range x msg_align_bits") apply(simp add: for_each_byte_of_word_def2) apply(simp add: aag_can_read_or_affect_ipc_buffer_def) apply(erule conjE) apply(rule ballI) apply(erule bspec) apply(erule (1) subsetD[rotated]) apply(rule ptr_range_subset) apply(simp add: aag_can_read_or_affect_ipc_buffer_def) apply(simp add: msg_align_bits) apply(simp add: msg_align_bits word_bits_def) apply(simp add: word_size_def) apply(subst upto_enum_step_shift_red[where us=2, simplified]) apply (simp add: msg_align_bits word_bits_def aag_can_read_or_affect_ipc_buffer_def )+ apply(fastforce simp: image_def) done lemma get_mi_length': "\\\ get_message_info sender \\rv s. buffer_cptr_index + unat (mi_extra_caps rv) < 2 ^ (msg_align_bits - 2)\" apply(rule hoare_post_imp[OF _ get_mi_valid']) apply(clarsimp simp: valid_message_info_def msg_align_bits msg_max_length_def word_le_nat_alt buffer_cptr_index_def msg_max_extra_caps_def) done lemma validE_E_wp_post_taut: "\ P \ f -, \\ r s. True \" by(auto simp: validE_E_def validE_def valid_def) lemma aag_has_read_auth_can_read_or_affect_ipc_buffer: "ipc_buffer_has_read_auth aag (pasSubject aag) buf \ aag_can_read_or_affect_ipc_buffer aag l buf" apply(clarsimp simp: ipc_buffer_has_read_auth_def aag_can_read_or_affect_ipc_buffer_def split: option.splits) apply(rule reads_read) apply blast done lemma ev_irrelevant_bind: assumes inv: "\ P. \ P \ f \\_. P \" assumes ev: "equiv_valid I A A P g" shows "equiv_valid I A A P (do y \ f; g od)" apply(simp add: equiv_valid_def2) apply(rule equiv_valid_rv_guard_imp) apply(rule equiv_valid_2_bind) apply(rule ev[simplified equiv_valid_def2]) apply(wp equiv_valid_rv_trivial[OF inv] inv | simp)+ done lemma get_message_info_reads_respects: "reads_respects aag l (K (aag_can_read_or_affect aag l ptr)) (get_message_info ptr)" apply (simp add: get_message_info_def) apply (wp as_user_reads_respects | clarsimp simp: getRegister_def)+ done lemma do_normal_transfer_reads_respects: assumes domains_distinct[wp]: "pas_domains_distinct aag" shows "reads_respects aag l (pas_refined aag and K (aag_can_read_or_affect aag l sender \ ipc_buffer_has_read_auth aag (pasObjectAbs aag sender) sbuf \ ipc_buffer_has_read_auth aag (pasObjectAbs aag receiver) rbuf \ (grant \ (is_subject aag sender \ is_subject aag receiver)))) (do_normal_transfer sender sbuf endpoint badge grant receiver rbuf)" apply(case_tac grant) apply(rule gen_asm_ev) apply(simp add: do_normal_transfer_def) apply(wp get_message_info_rev lookup_extra_caps_rev as_user_set_register_reads_respects' set_message_info_reads_respects transfer_caps_reads_respects copy_mrs_reads_respects lookup_extra_caps_rev lookup_extra_caps_authorised lookup_extra_caps_auth get_message_info_rev get_mi_length' get_mi_length validE_E_wp_post_taut | wpc | simp add: det_setRegister ball_conj_distrib)+ apply (fastforce intro: aag_has_read_auth_can_read_or_affect_ipc_buffer) apply(rule gen_asm_ev) apply(simp add: do_normal_transfer_def transfer_caps_def) apply(subst transfer_caps_loop.simps) apply(wp ev_irrelevant_bind[where f="get_receive_slots receiver rbuf"] as_user_set_register_reads_respects' set_message_info_reads_respects copy_mrs_reads_respects get_message_info_reads_respects get_mi_length |wpc |simp)+ apply(auto simp: ipc_buffer_has_read_auth_def aag_can_read_or_affect_ipc_buffer_def dest: reads_read_thread_read_pages split: option.splits) done lemma getRestartPC_det: "det getRestartPC" apply (clarsimp simp: getRestartPC_def getRegister_def) done lemma getRegister_det: "det (getRegister x)" by (clarsimp simp: getRegister_def) lemma make_fault_msg_reads_respects: "reads_respects aag l (K (aag_can_read_or_affect aag l sender)) (make_fault_msg rva sender)" apply(case_tac rva) apply (wp as_user_reads_respects | simp split del: if_split add: getRestartPC_det getRegister_det | rule det_mapM | rule subset_refl)+ apply (case_tac x4) apply (wp as_user_reads_respects | simp split del: if_split add: getRestartPC_det getRegister_det)+ done lemma set_mrs_returns_a_constant: "\ x. \ \ \ set_mrs thread buf msgs \ \ rv s. rv = x \" apply(case_tac buf) apply(rule exI) apply((simp add: set_mrs_def | wp | rule impI)+)[1] apply(rule exI) apply((simp add: set_mrs_def split del: if_split | wp | rule impI)+)[1] done lemma set_mrs_ret_eq: "\(s::'a::state_ext state) (t::'a::state_ext state). \(rva, s')\fst (set_mrs thread buf msgs s). \(rvb, t')\fst (set_mrs thread buf msgs t). rva = rvb" apply(clarsimp) apply(cut_tac thread=thread and buf=buf and msgs=msgs in set_mrs_returns_a_constant) apply(erule exE) apply(subgoal_tac "a = x \ aa = x") apply simp apply(rule conjI) apply(erule (1) use_valid | simp)+ done lemma set_mrs_reads_respects': assumes domains_distinct[wp]: "pas_domains_distinct aag" shows "reads_respects aag l (K (ipc_buffer_has_auth aag thread buf \ (case buf of (Some buf') \ is_aligned buf' msg_align_bits | _ \ True))) (set_mrs thread buf msgs)" apply(case_tac "aag_can_read_or_affect aag l thread") apply((wp equiv_valid_guard_imp[OF set_mrs_reads_respects] | simp)+)[1] apply(rule gen_asm_ev) apply(simp add: equiv_valid_def2) apply(rule equiv_valid_rv_guard_imp) apply(case_tac buf) apply(rule_tac Q="\" and P="\" and L="{pasObjectAbs aag thread}" in ev_invisible[OF domains_distinct]) apply(clarsimp simp: labels_are_invisible_def) apply(rule modifies_at_mostI) apply(simp add: set_mrs_def) apply((wp set_object_equiv_but_for_labels | simp | auto dest: get_tcb_not_asid_pool_at)+)[1] apply(simp) apply(rule set_mrs_ret_eq) apply(rename_tac buf') apply(rule_tac Q="\" and L="{pasObjectAbs aag thread} \ (pasObjectAbs aag) ` (ptr_range buf' msg_align_bits)" in ev_invisible[OF domains_distinct]) apply(auto simp: labels_are_invisible_def ipc_buffer_has_auth_def dest: reads_read_page_read_thread simp: aag_can_affect_label_def)[1] apply(rule modifies_at_mostI) apply(wp set_mrs_equiv_but_for_labels | simp)+ apply(rule set_mrs_ret_eq) by simp lemma do_fault_transfer_reads_respects: assumes domains_distinct[wp]: "pas_domains_distinct aag" shows "reads_respects aag l (K (aag_can_read_or_affect aag l sender \ ipc_buffer_has_auth aag receiver buf \ (case buf of None \ True | Some buf' \ is_aligned buf' msg_align_bits))) (do_fault_transfer badge sender receiver buf)" unfolding do_fault_transfer_def apply (wp as_user_set_register_reads_respects' as_user_reads_respects set_message_info_reads_respects set_mrs_reads_respects' make_fault_msg_reads_respects thread_get_reads_respects | wpc | simp add: split_def det_setRegister | wp_once hoare_drop_imps)+ done lemma tl_tl_in_set: "tl xs = (x # xs') \ set xs' \ set xs" apply(case_tac xs, auto) done (* GENERALIZE the following is possible *) lemma ptr_in_obj_range: "\valid_objs s; pspace_aligned s; kheap s ptr = Some obj\ \ ptr + (a && mask (obj_bits obj)) \ obj_range ptr obj" apply (simp add: obj_range_def) apply (rule context_conjI) apply (frule(1) pspace_alignedD) apply (erule is_aligned_no_wrap') apply (rule and_mask_less') apply (drule valid_obj_sizes) apply fastforce apply (simp add: word_bits_def) apply (simp add: p_assoc_help) apply (rule word_plus_mono_right) apply (rule word_less_sub_1) apply (drule valid_obj_sizes) apply fastforce apply (simp add: word_bits_def and_mask_less') apply (rule is_aligned_no_overflow') apply (erule(1) pspace_alignedD) done lemma do_ipc_transfer_reads_respects: assumes domains_distinct[wp]: "pas_domains_distinct aag" shows "reads_respects aag l (valid_objs and valid_global_refs and pspace_distinct and pspace_aligned and valid_arch_state and pas_refined aag and K ((grant \ (is_subject aag sender \ is_subject aag receiver)) \ aag_can_read_or_affect aag l sender \ aag_can_read_or_affect aag l receiver )) (do_ipc_transfer sender ep badge grant receiver)" unfolding do_ipc_transfer_def apply (wp do_normal_transfer_reads_respects lookup_ipc_buffer_reads_respects lookup_ipc_buffer_has_read_auth do_fault_transfer_reads_respects thread_get_reads_respects lookup_ipc_buffer_has_auth lookup_ipc_buffer_aligned | wpc | simp | wp_once hoare_drop_imps)+ done crunch pas_cur_domain[wp]: set_extra_badge, do_ipc_transfer "pas_cur_domain aag" (wp: crunch_wps transfer_caps_loop_pres ignore: const_on_failure simp: crunch_simps) lemma complete_signal_reads_respects: assumes domains_distinct[wp]: "pas_domains_distinct aag" shows "reads_respects aag l ( K(aag_can_read aag ntfnptr \ aag_can_affect aag l ntfnptr)) (complete_signal ntfnptr receiver)" unfolding complete_signal_def apply (wp set_simple_ko_reads_respects get_simple_ko_reads_respects as_user_set_register_reads_respects' | wpc | simp)+ done lemma receive_ipc_base_reads_respects: assumes domains_distinct[wp]: "pas_domains_distinct aag" notes do_nbrecv_failed_transfer_def[simp] shows "reads_respects aag l (valid_objs and valid_global_refs and pspace_distinct and pspace_aligned and pas_refined aag and pas_cur_domain aag and valid_arch_state and ko_at (Endpoint ep) epptr and (\s. is_subject aag (cur_thread s) \ sym_refs (state_refs_of s)) and K (is_subject aag thread \ (pasSubject aag, Receive, pasObjectAbs aag epptr) \ pasPolicy aag)) (receive_ipc_base aag thread ep epptr rights is_blocking)" apply (rule gen_asm_ev) apply (simp add: thread_get_def split: endpoint.split) apply (intro conjI impI) prefer 2 defer apply ((wp set_thread_state_reads_respects set_simple_ko_reads_respects as_user_set_register_reads_respects' | simp | intro allI impI | rule pre_ev, wpc)+)[2] apply (intro allI impI) apply (wp static_imp_wp set_simple_ko_reads_respects set_thread_state_reads_respects setup_caller_cap_reads_respects do_ipc_transfer_reads_respects possible_switch_to_reads_respects gets_cur_thread_ev set_thread_state_pas_refined | wpc | simp)+ apply (rename_tac list rvc rvd) apply (rule_tac Q="\rv s. pas_refined aag s \ pas_cur_domain aag s \ is_subject aag (cur_thread s) \ (sender_can_grant rvd \ is_subject aag (hd list))" in hoare_strengthen_post) apply(wp set_simple_ko_reads_respects hoare_vcg_imp_lift [OF set_simple_ko_get_tcb, unfolded disj_not1] hoare_vcg_all_lift set_thread_state_reads_respects get_simple_ko_reads_respects get_simple_ko_wp do_ipc_transfer_pas_refined | wpc | simp add: get_thread_state_def thread_get_def)+ apply (clarsimp simp: conj_comms) apply (rename_tac x s) apply (rule context_conjI[rotated]) apply clarsimp apply(rule conjI, rule impI) (* clagged from Ipc_AC *) apply (subgoal_tac "aag_has_auth_to aag Control (hd x)") apply (fastforce simp add: pas_refined_refl dest!: aag_Control_into_owns) apply (rule_tac ep = "pasObjectAbs aag epptr" in aag_wellformed_grant_Control_to_send [OF _ _ pas_refined_wellformed]) apply (rule_tac s = s in pas_refined_mem [OF sta_ts]) apply (clarsimp simp: tcb_at_def thread_states_def tcb_states_of_state_def dest!: pred_tcb_at_tcb_at) apply (frule (1) sym_refs_obj_atD) apply clarsimp apply (drule (1) bspec [OF _ hd_in_set]) apply (clarsimp simp: obj_at_def tcb_bound_refs_def dest!: get_tcb_SomeD split: option.splits) apply assumption+ apply(rule conjI) (* clagged from Ipc_AC *) apply (auto elim!: ep_queued_st_tcb_at simp: tcb_at_st_tcb_at valid_ep_def valid_obj_def neq_Nil_conv split: list.split)[1] apply (simp add: obj_at_def) apply (erule (1) valid_objsE) apply (fastforce simp: valid_obj_def valid_ep_def dest: distinct_drop[where i=1]) apply (simp add: obj_at_def) apply (erule (1) valid_objsE) apply (fastforce simp: valid_obj_def valid_ep_def dest: distinct_drop[where i=1]) apply(rule send_endpoint_reads_affects_queued, simp+) apply(fastforce dest: reads_ep) apply simp+ apply(clarsimp) apply(rule_tac aag=aag and l=l in reads_affects_equiv_get_tcb_eq) apply(rule send_endpoint_reads_affects_queued) apply assumption apply blast apply(fastforce dest: reads_ep) apply assumption apply assumption apply assumption apply assumption apply(rule refl) apply simp apply simp apply simp done lemma receive_ipc_reads_respects: assumes domains_distinct[wp]: "pas_domains_distinct aag" shows "reads_respects aag l (valid_objs and pspace_distinct and pspace_aligned and valid_global_refs and valid_arch_state and sym_refs \ state_refs_of and pas_refined aag and pas_cur_domain aag and valid_cap cap and (\s. is_subject aag (cur_thread s)) and K (is_subject aag receiver \ (\epptr\Access.obj_refs cap. (pasSubject aag, Receive, pasObjectAbs aag epptr) \ pasPolicy aag))) (receive_ipc receiver cap is_blocking)" apply (rule gen_asm_ev) apply (simp add: receive_ipc_def thread_get_def split: cap.split) apply (clarsimp simp: fail_ev_pre) apply (rename_tac word1 word2 rights) apply (wp receive_ipc_base_reads_respects[simplified AllowSend_def] complete_signal_reads_respects | simp)+ apply (wp static_imp_wp set_simple_ko_reads_respects set_thread_state_reads_respects setup_caller_cap_reads_respects do_ipc_transfer_reads_respects complete_signal_reads_respects thread_get_reads_respects get_thread_state_reads_respects possible_switch_to_reads_respects gets_cur_thread_ev set_thread_state_pas_refined do_ipc_transfer_pas_refined hoare_vcg_all_lift get_simple_ko_reads_respects get_bound_notification_reads_respects' gbn_wp get_simple_ko_reads_respects get_simple_ko_wp get_simple_ko_wp | wpc | simp)+ apply (clarsimp) apply(rule conjI) apply(auto dest: reads_ep)[1] apply clarsimp apply(rule context_conjI, rule allI, rule impI) apply (rule disjI1) apply (frule bound_tcb_at_implies_receive) apply simp apply (frule bound_tcb_at_implies_read[where t = receiver]) apply simp apply simp apply simp apply clarsimp done lemma receive_endpoint_threads_blocked: "\valid_objs s; (sym_refs \ state_refs_of) s; ko_at (Endpoint (RecvEP list)) ep s; x\set list\ \ st_tcb_at (receive_blocked_on ep) x s" apply (rule ep_queued_st_tcb_at'') apply simp+ done lemma receive_blocked_threads_have_Receive_auth: "\pas_refined aag s; valid_objs s; sym_refs (state_refs_of s); st_tcb_at (receive_blocked_on ep) x s\ \ (pasObjectAbs aag x,Receive,pasObjectAbs aag ep) \ pasPolicy aag" apply(drule_tac auth="Receive" and x=x in pas_refined_mem[rotated]) apply(rule sta_ts) apply(clarsimp simp: thread_states_def split: option.split simp: tcb_states_of_state_def st_tcb_def2) apply(case_tac "tcb_state tcb", simp_all) done lemma receive_endpoint_reads_affects_queued: "\(pasSubject aag, SyncSend, pasObjectAbs aag epptr) \ pasPolicy aag; aag_can_read_label aag (pasObjectAbs aag epptr) \ aag_can_affect aag l epptr; pas_refined aag s; valid_objs s; sym_refs (state_refs_of s); ko_at (Endpoint (RecvEP list)) epptr s; ep = RecvEP list; x \ set list\ \ aag_can_read_label aag (pasObjectAbs aag x) \ aag_can_affect aag l x" apply(frule receive_endpoint_threads_blocked, (simp | assumption)+) apply(drule receive_blocked_threads_have_Receive_auth, (simp | assumption)+) apply(auto dest: read_sync_ep_read_receivers) done lemma send_ipc_reads_respects: assumes domains_distinct[wp]: "pas_domains_distinct aag" shows "reads_respects aag l (pas_refined aag and pas_cur_domain aag and valid_objs and pspace_distinct and pspace_aligned and valid_arch_state and valid_global_refs and sym_refs \ state_refs_of and (\s. is_subject aag (cur_thread s)) and (\s. \ep. ko_at (Endpoint ep) epptr s \ (can_grant \ ((\(t, rt) \ ep_q_refs_of ep. rt = EPRecv \ is_subject aag t) \ aag_has_auth_to aag Grant epptr))) and K (is_subject aag thread \ (pasSubject aag, SyncSend, pasObjectAbs aag epptr) \ pasPolicy aag)) (send_ipc block call badge can_grant thread epptr)" apply(rule gen_asm_ev) apply(simp add: send_ipc_def) apply (wp set_simple_ko_reads_respects set_thread_state_reads_respects when_ev setup_caller_cap_reads_respects thread_get_reads_respects | wpc | simp split del: if_split)+ apply(rename_tac list word list' rvb) apply(rule_tac Q="\r s. is_subject aag (cur_thread s) \ (can_grant \ is_subject aag (hd list))" in hoare_strengthen_post) apply(wp set_thread_state_reads_respects do_ipc_transfer_reads_respects set_simple_ko_reads_respects hoare_vcg_imp_lift [OF set_simple_ko_get_tcb, unfolded disj_not1] hoare_vcg_all_lift get_simple_ko_reads_respects get_simple_ko_wp possible_switch_to_reads_respects gets_cur_thread_ev set_thread_state_pas_refined do_ipc_transfer_pas_refined | wpc | simp add: get_thread_state_def thread_get_def)+ apply (rule conjI) apply(fastforce dest: reads_ep) apply clarsimp apply(subgoal_tac "\ s t. reads_equiv aag s t \ affects_equiv aag l s t \ get_tcb xa s = get_tcb xa t") apply (clarsimp simp: conj_comms cong: conj_cong) apply(rule conjI) (* clagged from Ipc_AC *) apply (clarsimp simp: split_def obj_at_def) apply(rule conjI) apply (rule obj_at_valid_objsE, assumption+) apply (clarsimp cong: conj_cong imp_cong simp: tcb_at_st_tcb_at conj_comms) apply (auto dest: ep_queued_st_tcb_at [where P = \] simp: tcb_at_st_tcb_at valid_ep_def valid_obj_def obj_at_def split: list.split)[1] apply(rule receive_endpoint_reads_affects_queued) apply (assumption | simp)+ apply(fastforce dest: reads_ep) apply (assumption | simp)+ apply clarsimp apply(rule_tac aag=aag and l=l in reads_affects_equiv_get_tcb_eq) apply(rule receive_endpoint_reads_affects_queued) apply assumption apply(fastforce dest: reads_ep) apply assumption apply assumption apply assumption apply assumption apply(rule refl) apply simp apply simp apply simp done subsection "Faults" lemma send_fault_ipc_reads_respects: assumes domains_distinct[wp]: "pas_domains_distinct aag" shows "reads_respects aag l (sym_refs \ state_refs_of and pas_refined aag and pas_cur_domain aag and valid_objs and pspace_distinct and pspace_aligned and valid_global_refs and valid_arch_state and (\s. is_subject aag (cur_thread s)) and K (is_subject aag thread \ valid_fault fault)) (send_fault_ipc thread fault)" apply (rule gen_asm_ev) apply (simp add: send_fault_ipc_def Let_def lookup_cap_def split_def) apply (wp send_ipc_reads_respects thread_set_reads_respects thread_set_refs_trivial thread_set_obj_at_impossible thread_set_valid_objs'' hoare_vcg_conj_lift hoare_vcg_ex_lift hoare_vcg_all_lift thread_set_pas_refined cap_fault_on_failure_rev lookup_slot_for_thread_rev lookup_slot_for_thread_authorised hoare_vcg_all_lift_R thread_get_reads_respects get_cap_auth_wp[where aag=aag] get_cap_rev | wpc | simp add: split_def del: if_split add: tcb_cap_cases_def)+ (* clagged from Ipc_AC *) apply (rule_tac Q'="\rv s. pas_refined aag s \ pas_cur_domain aag s \ valid_objs s \ pspace_distinct s \ pspace_aligned s \ valid_global_refs s \ valid_arch_state s \ sym_refs (state_refs_of s) \ valid_fault fault \ is_subject aag (fst (fst rv)) \ is_subject aag (cur_thread s)" in hoare_post_imp_R[rotated]) apply (clarsimp simp: invs_valid_objs invs_sym_refs cte_wp_at_caps_of_state | intro conjI)+ apply (fastforce intro: valid_tcb_fault_update) apply (frule caps_of_state_valid_cap, assumption) apply (clarsimp simp: valid_cap_simps obj_at_def is_ep) apply rule apply clarsimp apply (subgoal_tac "\auth. aag_has_auth_to aag auth x") apply (erule (3) owns_ep_owns_receivers', simp add: obj_at_def, assumption) apply (auto dest!: pas_refined_mem[OF sta_caps] simp: cap_auth_conferred_def cap_rights_to_auth_def)[3] apply (wp get_cap_auth_wp[where aag=aag] lookup_slot_for_thread_authorised thread_get_reads_respects | simp add: add: lookup_cap_def split_def)+ done lemma handle_fault_reads_respects: assumes domains_distinct[wp]: "pas_domains_distinct aag" shows "reads_respects aag l (sym_refs \ state_refs_of and pas_refined aag and pas_cur_domain aag and valid_objs and pspace_distinct and pspace_aligned and valid_global_refs and valid_arch_state and (\s. is_subject aag (cur_thread s)) and K (is_subject aag thread \ valid_fault fault)) (handle_fault thread fault)" unfolding handle_fault_def catch_def fun_app_def handle_double_fault_def apply(wp_once hoare_drop_imps | wp set_thread_state_reads_respects send_fault_ipc_reads_respects | wpc | simp)+ apply(fastforce intro: reads_affects_equiv_get_tcb_eq reads_lrefl) done subsection "Replies" lemma handle_arch_fault_reply_reads_respects: "reads_respects aag l (K (is_subject aag thread)) (handle_arch_fault_reply afault thread x y)" by (simp add: handle_arch_fault_reply_def, wp) lemma handle_fault_reply_reads_respects: "reads_respects aag l (K (is_subject aag thread)) (handle_fault_reply fault thread x y)" apply(case_tac fault) apply (wp as_user_reads_respects thread_get_reads_respects thread_get_wp' handle_arch_fault_reply_reads_respects[simplified K_def] | simp add: reads_lrefl det_zipWithM_x det_setRegister)+ done lemma lookup_ipc_buffer_has_read_auth': "\pas_refined aag and valid_objs and K (is_subject aag thread)\ lookup_ipc_buffer is_receiver thread \\rv s. ipc_buffer_has_read_auth aag (pasSubject aag) rv\" apply(rule hoare_gen_asm) apply(rule hoare_strengthen_post[OF lookup_ipc_buffer_has_read_auth]) apply(drule sym, simp) done crunch valid_ko_at_arm[wp]: handle_fault_reply "valid_ko_at_arm" crunch pas_cur_domain[wp]: handle_fault_reply "pas_cur_domain aag" lemma do_reply_transfer_reads_respects_f: assumes domains_distinct[wp]: "pas_domains_distinct aag" shows "reads_respects_f aag l (silc_inv aag st and invs and pas_refined aag and pas_cur_domain aag and tcb_at receiver and tcb_at sender and emptyable slot and (\s. is_subject aag (cur_thread s)) and K (is_subject aag sender \ is_subject aag receiver \ is_subject aag (fst slot))) (do_reply_transfer sender receiver slot)" unfolding do_reply_transfer_def apply (wp gets_cur_thread_ev[THEN reads_respects_f[where aag=aag and st=st and Q=\]] set_thread_state_reads_respects cap_delete_one_reads_respects_f do_ipc_transfer_reads_respects do_ipc_transfer_pas_refined thread_set_reads_respects handle_fault_reply_reads_respects get_mrs_rev lookup_ipc_buffer_reads_respects lookup_ipc_buffer_has_read_auth' get_message_info_rev get_mi_length cap_delete_one_silc_inv do_ipc_transfer_silc_inv set_thread_state_pas_refined thread_set_fault_pas_refined' possible_switch_to_reads_respects[THEN reads_respects_f[where aag=aag and st=st and Q=\]] when_ev | wpc | simp split del: if_split | wp_once reads_respects_f[where aag=aag and st=st] | elim conjE | assumption | simp split del: if_split cong: if_cong | wp_once hoare_drop_imps)+ apply(rule_tac Q="\ rv s. pas_refined aag s \ pas_cur_domain aag s \ invs s \ is_subject aag (cur_thread s) \ is_subject aag sender \ silc_inv aag st s \ is_subject aag receiver" in hoare_strengthen_post) apply((wp_once hoare_drop_imps | wp cap_delete_one_invs hoare_vcg_all_lift cap_delete_one_silc_inv reads_respects_f[OF thread_get_reads_respects] reads_respects_f[OF get_thread_state_rev] | simp add: invs_valid_objs invs_psp_aligned invs_valid_global_refs invs_distinct invs_arch_state invs_valid_ko_at_arm | rule conjI | elim conjE | assumption)+)[8] apply(clarsimp simp: conj_comms) apply(rule conjI, fastforce intro: reads_lrefl)+ apply(rule allI) apply(rule conjI, fastforce intro: reads_lrefl)+ apply(fastforce intro: reads_lrefl) done lemma handle_reply_reads_respects_f: assumes domains_distinct[wp]: "pas_domains_distinct aag" shows "reads_respects_f aag l (silc_inv aag st and invs and pas_refined aag and pas_cur_domain aag and is_subject aag \ cur_thread) (handle_reply)" unfolding handle_reply_def apply (wp do_reply_transfer_reads_respects_f get_cap_wp reads_respects_f[OF get_cap_reads_respects, where Q="\" and st=st] hoare_vcg_all_lift | wpc | blast)+ apply(rule conjI) apply(fastforce intro: requiv_cur_thread_eq simp: reads_equiv_f_def) apply clarsimp apply(rule conjI) apply assumption apply(rule conjI) apply(drule cte_wp_valid_cap) apply(erule invs_valid_objs) apply(simp add: valid_cap_simps) apply(rule conjI, fastforce simp: tcb_at_invs) apply(rule conjI) apply(erule emptyable_cte_wp_atD) apply(erule invs_valid_objs) apply(simp add: is_master_reply_cap_def) apply(frule_tac p="(cur_thread s, tcb_cnode_index 3)" in cap_cur_auth_caps_of_state[rotated]) apply simp apply(simp add: cte_wp_at_caps_of_state) apply(simp add: aag_cap_auth_Reply) done lemma reply_from_kernel_reads_respects: assumes domains_distinct[wp]: "pas_domains_distinct aag" shows "reads_respects aag l (K (is_subject aag thread)) (reply_from_kernel thread x)" unfolding reply_from_kernel_def fun_app_def apply (wp set_message_info_reads_respects set_mrs_reads_respects as_user_reads_respects lookup_ipc_buffer_reads_respects | simp add: split_def reads_lrefl det_setRegister)+ done section "globals_equiv" subsection "Sync IPC" lemma setup_caller_cap_globals_equiv: "\globals_equiv s and valid_ko_at_arm and valid_global_objs\ setup_caller_cap sender receiver \\_. globals_equiv s\" unfolding setup_caller_cap_def apply(wp cap_insert_globals_equiv'' set_thread_state_globals_equiv) apply(simp_all) done lemma set_extra_badge_globals_equiv: "\globals_equiv s \ set_extra_badge buffer badge n \\_. globals_equiv s\" unfolding set_extra_badge_def apply(wp store_word_offs_globals_equiv) done lemma transfer_caps_loop_globals_equiv: "\globals_equiv st and valid_ko_at_arm and valid_global_objs\ transfer_caps_loop ep rcv_buffer n caps slots mi \\_. globals_equiv st\" proof (induct caps arbitrary: slots n mi) case Nil thus ?case by (simp, wp, simp) next case (Cons c caps') show ?case apply(cases c) apply(simp split del: if_split cong: if_cong) apply(rule hoare_pre) apply(wp) apply(erule conjE, erule subst, rule Cons.hyps) apply(clarsimp) apply(wp set_extra_badge_globals_equiv)+ apply(rule Cons.hyps) apply(simp) apply(wp cap_insert_globals_equiv'') apply(rule_tac Q="\_. globals_equiv st and valid_ko_at_arm and valid_global_objs" and E="\_. globals_equiv st and valid_ko_at_arm and valid_global_objs" in hoare_post_impErr) apply(simp add: whenE_def, rule conjI) apply(rule impI, wp)+ apply(simp)+ apply wp+ apply(fastforce) done qed lemma transfer_caps_globals_equiv: "\globals_equiv st and valid_ko_at_arm and valid_global_objs\ transfer_caps info caps endpoint receiver recv_buffer \\_. globals_equiv st\" unfolding transfer_caps_def apply(wp transfer_caps_loop_globals_equiv | wpc | simp)+ done lemma copy_mrs_globals_equiv: "\globals_equiv s and valid_ko_at_arm and (\s. receiver \ idle_thread s)\ copy_mrs sender sbuf receiver rbuf n \\_. globals_equiv s\" unfolding copy_mrs_def including no_pre apply(wp | wpc)+ apply(rule_tac Q="\_. globals_equiv s" in hoare_strengthen_post) apply(wp mapM_wp' | wpc)+ apply(wp store_word_offs_globals_equiv)+ apply fastforce apply simp apply(rule_tac Q="\_. globals_equiv s and valid_ko_at_arm and (\sa. receiver \ idle_thread sa)" in hoare_strengthen_post) apply(wp mapM_wp' as_user_globals_equiv) apply(simp) apply(fastforce) apply simp done (* FIXME: move *) lemma validE_to_valid: "\P\ f \\rv s. \v. rv = Inr v \ Q v s\ \ \P\ f \\v. Q v\, -" apply(rule validE_validE_R) apply(simp add: validE_def valid_def) done lemma do_normal_transfer_globals_equiv: "\globals_equiv st and valid_ko_at_arm and valid_global_objs and (\sa. receiver \ idle_thread sa)\ do_normal_transfer sender sbuf endpoint badge grant receiver rbuf \\_. globals_equiv st\" unfolding do_normal_transfer_def apply(wp as_user_globals_equiv set_message_info_globals_equiv transfer_caps_globals_equiv) apply(wp copy_mrs_globals_equiv) apply(subst K_def) apply(wp | rule impI)+ apply(clarsimp) done lemma do_fault_transfer_globals_equiv: "\globals_equiv s and valid_ko_at_arm and (\sa. receiver \ idle_thread sa)\ do_fault_transfer badge sender receiver buf \\_. globals_equiv s\" unfolding do_fault_transfer_def apply(wp) apply(simp add: split_def) apply(wp as_user_globals_equiv set_message_info_globals_equiv set_mrs_globals_equiv | wpc)+ apply(clarsimp) apply(rule hoare_drop_imps) apply(wp thread_get_inv, simp) done lemma lookup_ipc_buffer_ptr_range': "\valid_objs\ lookup_ipc_buffer True thread \\rv s. rv = Some buf' \ auth_ipc_buffers s thread = ptr_range buf' msg_align_bits\" unfolding lookup_ipc_buffer_def apply (rule hoare_pre) apply (wp get_cap_wp thread_get_wp' | wpc)+ apply (clarsimp simp: cte_wp_at_caps_of_state ipc_buffer_has_auth_def get_tcb_ko_at [symmetric]) apply (frule caps_of_state_tcb_cap_cases [where idx = "tcb_cnode_index 4"]) apply (simp add: dom_tcb_cap_cases) apply (clarsimp simp: auth_ipc_buffers_def get_tcb_ko_at [symmetric]) apply (drule(1) valid_tcb_objs) apply (drule get_tcb_SomeD)+ apply (simp add: vm_read_write_def valid_tcb_def valid_ipc_buffer_cap_def split: bool.splits) done lemma lookup_ipc_buffer_aligned': "\valid_objs\ lookup_ipc_buffer True thread \\rv s. rv = Some buf' \ is_aligned buf' msg_align_bits\" apply(insert lookup_ipc_buffer_aligned) apply(fastforce simp: valid_def) done lemma set_collection: "a = {x. x\a}" by simp lemma do_ipc_transfer_globals_equiv: "\globals_equiv st and valid_ko_at_arm and valid_objs and valid_arch_state and valid_global_refs and pspace_distinct and pspace_aligned and valid_global_objs and (\s. receiver \ idle_thread s)\ do_ipc_transfer sender ep badge grant receiver \\_. globals_equiv st\" unfolding do_ipc_transfer_def apply(wp do_normal_transfer_globals_equiv do_fault_transfer_globals_equiv | wpc)+ apply(rule_tac Q="\_. globals_equiv st and valid_ko_at_arm and valid_global_objs and (\sa. receiver \ idle_thread sa) and (\sa. (\rb. recv_buffer = Some rb \ auth_ipc_buffers sa receiver = ptr_range rb msg_align_bits) \ (\rb. recv_buffer = Some rb \ is_aligned rb msg_align_bits))" in hoare_strengthen_post) apply(wp) apply(clarsimp | rule conjI)+ apply(wp hoare_vcg_all_lift lookup_ipc_buffer_ptr_range' lookup_ipc_buffer_aligned' | fastforce)+ done crunch valid_ko_at_arm[wp]: do_ipc_transfer "valid_ko_at_arm" lemma send_ipc_globals_equiv: "\globals_equiv st and valid_objs and valid_arch_state and valid_global_refs and pspace_distinct and pspace_aligned and valid_global_objs and valid_idle and (\s. sym_refs (state_refs_of s))\ send_ipc block call badge can_grant thread epptr \\_. globals_equiv st\" unfolding send_ipc_def apply(wp set_simple_ko_globals_equiv set_thread_state_globals_equiv setup_caller_cap_globals_equiv | wpc)+ apply(rule_tac Q="\_. globals_equiv st and valid_ko_at_arm and valid_global_objs" in hoare_strengthen_post) apply(rule thread_get_inv) apply(fastforce) apply(wp set_thread_state_globals_equiv dxo_wp_weak | simp)+ apply wpc apply(wp do_ipc_transfer_globals_equiv)+ apply(clarsimp) apply(rule hoare_drop_imps) apply(wp set_simple_ko_globals_equiv)+ apply(rule_tac Q="\ep. ko_at (Endpoint ep) epptr and globals_equiv st and valid_objs and valid_arch_state and valid_global_refs and pspace_distinct and pspace_aligned and valid_global_objs and (\s. sym_refs (state_refs_of s)) and valid_idle" in hoare_strengthen_post) apply(wp get_simple_ko_sp) apply(clarsimp simp: valid_arch_state_ko_at_arm)+ apply (rule context_conjI) apply(rule valid_ep_recv_dequeue') apply(simp)+ apply (frule_tac x=xa in receive_endpoint_threads_blocked,simp+) by (clarsimp simp add: valid_idle_def pred_tcb_at_def obj_at_def)+ lemma valid_ep_send_enqueue: "\ko_at (Endpoint (SendEP (t # ts))) a s; valid_objs s\ \ valid_ep (case ts of [] \ IdleEP | b # bs \ SendEP (b # bs)) s" unfolding valid_objs_def valid_obj_def valid_ep_def obj_at_def apply (drule bspec) apply (auto split: list.splits) done crunch globals_equiv[wp]: complete_signal "globals_equiv st" lemma receive_ipc_globals_equiv: notes do_nbrecv_failed_transfer_def[simp] shows "\globals_equiv st and valid_objs and valid_arch_state and valid_global_refs and pspace_distinct and pspace_aligned and valid_global_objs and (\s. thread \ idle_thread s)\ receive_ipc thread cap is_blocking \\_. globals_equiv st\" unfolding receive_ipc_def thread_get_def including no_pre apply(wp) apply(simp add: split_def) apply(wp set_simple_ko_globals_equiv set_thread_state_globals_equiv setup_caller_cap_globals_equiv dxo_wp_weak as_user_globals_equiv | wpc | simp split del: if_split)+ apply (rule hoare_strengthen_post[where Q= "\_. globals_equiv st and valid_ko_at_arm and valid_global_objs"]) apply (wp do_ipc_transfer_globals_equiv as_user_globals_equiv) apply clarsimp apply (wp gts_wp get_simple_ko_sp | wpc)+ apply (wp hoare_vcg_all_lift hoare_drop_imps)[1] apply(wp set_simple_ko_globals_equiv | wpc)+ apply(wp set_thread_state_globals_equiv) apply (wp get_simple_ko_wp gbn_wp get_simple_ko_wp as_user_globals_equiv | wpc | simp)+ apply (rule hoare_pre) apply(wpc) apply(rule fail_wp | rule return_wp)+ by (auto intro: valid_arch_state_ko_at_arm valid_ep_send_enqueue simp: neq_Nil_conv cong: case_list_cons_cong) subsection "Notifications" lemma valid_ntfn_dequeue: "\ ko_at (Notification ntfn) ntfnptr s; ntfn_obj ntfn = (WaitingNtfn (t # ts)); valid_objs s; ts \ []\ \ valid_ntfn ntfn s" unfolding valid_objs_def valid_obj_def valid_ntfn_def obj_at_def apply (drule bspec) apply (auto split: list.splits) done (* FIXME: NTFN OBJECT CHANGED *) lemma update_waiting_ntfn_globals_equiv: "\globals_equiv s and valid_objs and valid_arch_state and valid_global_refs and ko_at (Notification ntfn) ntfnptr and pspace_distinct and sym_refs \ state_refs_of and (\s. idle_thread s \ set queue) and K (ntfn_obj ntfn = WaitingNtfn queue)\ update_waiting_ntfn ntfnptr queue bound_tcb badge \\_. globals_equiv s\" unfolding update_waiting_ntfn_def apply(wp) apply(simp add: split_def) apply(wp set_thread_state_globals_equiv as_user_globals_equiv set_notification_globals_equiv set_notification_valid_ko_at_arm dxo_wp_weak | simp)+ by (auto intro: valid_arch_state_ko_at_arm simp: neq_Nil_conv) lemma blocked_cancel_ipc_globals_equiv[wp]: "\globals_equiv st and valid_ko_at_arm\ blocked_cancel_ipc a b \\_. globals_equiv st\" unfolding blocked_cancel_ipc_def by (wp set_thread_state_globals_equiv set_simple_ko_globals_equiv | wpc | simp)+ lemma cancel_ipc_blocked_globals_equiv: "\globals_equiv st and valid_ko_at_arm and st_tcb_at receive_blocked a\ cancel_ipc a \\_. globals_equiv st\" unfolding cancel_ipc_def apply (rule hoare_seq_ext[OF _ gts_sp]) apply (rule hoare_pre) apply (wpc; (simp,rule blocked_cancel_ipc_globals_equiv)?) apply (rule hoare_pre_cont)+ apply clarsimp apply (case_tac state;(clarsimp simp: pred_tcb_at_def obj_at_def receive_blocked_def)) by (simp add: eq_commute) crunch globals_equiv[wp]: possible_switch_to "globals_equiv (st :: det_ext state)" (wp: tcb_sched_action_extended.globals_equiv reschedule_required_ext_extended.globals_equiv crunch_wps) lemma send_signal_globals_equiv: "\globals_equiv (s :: det_ext state) and valid_objs and valid_arch_state and valid_global_refs and sym_refs \ state_refs_of and pspace_distinct and valid_idle\ send_signal ntfnptr badge \\_. globals_equiv s\" unfolding send_signal_def apply (wp set_notification_globals_equiv possible_switch_to_globals_equiv set_thread_state_globals_equiv as_user_globals_equiv cancel_ipc_blocked_globals_equiv update_waiting_ntfn_globals_equiv get_simple_ko_wp gts_wp | wpc | simp)+ apply clarsimp apply (frule (1) sym_refs_ko_atD) apply (intro allI impI conjI) prefer 8 apply clarsimp apply (frule_tac t="idle_thread sa" and P="\ref. \ idle ref" in ntfn_queued_st_tcb_at') by (auto intro: valid_arch_state_ko_at_arm simp: pred_tcb_at_def obj_at_def valid_idle_def receive_blocked_def) (*FIXME: belongs in Arch_IF*) lemma receive_signal_globals_equiv: "\globals_equiv s and valid_objs and valid_arch_state and valid_global_refs and pspace_distinct and (\s. thread \ idle_thread s)\ receive_signal thread cap is_blocking \\_. globals_equiv s\" unfolding receive_signal_def fun_app_def do_nbrecv_failed_transfer_def apply (rule hoare_pre) apply(wp set_notification_globals_equiv set_thread_state_globals_equiv as_user_globals_equiv get_simple_ko_wp | wpc)+ apply(simp add: valid_arch_state_ko_at_arm) done lemma set_object_valid_global_refs: "\valid_global_refs and (\s. \b. (\sz fun. obj=CNode sz fun \ well_formed_cnode_n sz fun \ (\cap. fun b = Some cap \ global_refs s \ cap_range cap = {})) \ (\tcb. obj = (TCB tcb) \ (\get. (\set restr. tcb_cap_cases b \ Some (get, set, restr) \ global_refs s \ cap_range(get tcb) = {}))))\ set_object ptr obj \\_. valid_global_refs\" unfolding set_object_def valid_global_refs_def valid_refs_def apply(clarsimp simp: cte_wp_at_cases) apply(wp) apply(clarify) apply(rule conjI) apply(clarsimp) apply(clarsimp) apply(erule_tac x=b in allE) apply(erule_tac x=get in allE) apply(simp) done lemma send_fault_ipc_globals_equiv: "\globals_equiv st and valid_objs and valid_arch_state and valid_global_refs and pspace_distinct and pspace_aligned and valid_global_objs and valid_idle and (\s. sym_refs (state_refs_of s)) and K (valid_fault fault)\ send_fault_ipc tptr fault \\_. globals_equiv st\" unfolding send_fault_ipc_def apply(wp) apply(simp add: Let_def) apply(wp send_ipc_globals_equiv thread_set_globals_equiv thread_set_valid_objs'' thread_set_fault_valid_global_refs thread_set_valid_idle_trivial thread_set_refs_trivial | wpc | simp)+ apply(rule_tac Q'="\_. globals_equiv st and valid_objs and valid_arch_state and valid_global_refs and pspace_distinct and pspace_aligned and valid_global_objs and K (valid_fault fault) and valid_idle and (\s. sym_refs (state_refs_of s))" in hoare_post_imp_R) apply(wp | simp)+ apply(clarsimp simp: valid_arch_state_ko_at_arm) apply(rule valid_tcb_fault_update) apply(wp | simp)+ done lemma handle_double_fault_globals_equiv: "\globals_equiv s and valid_ko_at_arm\ handle_double_fault tptr ex1 ex2 \\_. globals_equiv s\" unfolding handle_double_fault_def by (wp set_thread_state_globals_equiv) lemma send_ipc_valid_global_objs: "\valid_global_objs \ send_ipc block call badge can_grant thread epptr \\_. valid_global_objs\" unfolding send_ipc_def apply(wp | wpc)+ apply(rule_tac Q="\_. valid_global_objs" in hoare_strengthen_post) apply(wp, simp, (wp dxo_wp_weak |simp)+) apply(wpc) apply(rule fail_wp | rule return_wp | wp)+ apply(simp) apply(rule hoare_drop_imps) apply(wp)+ apply(rule_tac Q="\_. valid_global_objs" in hoare_strengthen_post) apply(wp, simp+) done lemma send_fault_ipc_valid_global_objs: "\valid_global_objs \ send_fault_ipc tptr fault \\_. valid_global_objs\" unfolding send_fault_ipc_def apply(wp) apply(simp add: Let_def) apply(wp send_ipc_valid_global_objs | wpc)+ apply(rule_tac Q'="\_. valid_global_objs" in hoare_post_imp_R) apply(wp | simp)+ done crunch valid_ko_at_arm[wp]: send_ipc "valid_ko_at_arm" (wp: hoare_drop_imps hoare_vcg_if_lift2 dxo_wp_weak) lemma send_fault_ipc_valid_ko_at_arm[wp]: "invariant (send_fault_ipc a b) valid_ko_at_arm" unfolding send_fault_ipc_def apply wp apply(simp add: Let_def) apply (wp send_ipc_valid_ko_at_arm | wpc)+ apply(rule_tac Q'="\_. valid_ko_at_arm" in hoare_post_imp_R) apply (wp | simp)+ done lemma handle_fault_globals_equiv: "\globals_equiv st and valid_objs and valid_arch_state and valid_global_refs and pspace_distinct and pspace_aligned and valid_global_objs and valid_idle and (\s. sym_refs (state_refs_of s)) and K (valid_fault ex)\ handle_fault thread ex \\_. globals_equiv st\" unfolding handle_fault_def apply(wp handle_double_fault_globals_equiv) apply(rule_tac Q="\_. globals_equiv st and valid_ko_at_arm" and E="\_. globals_equiv st and valid_ko_at_arm" in hoare_post_impErr) apply(wp send_fault_ipc_globals_equiv | simp add: valid_arch_state_ko_at_arm)+ done lemma handle_fault_reply_globals_equiv: "\globals_equiv st and valid_ko_at_arm and (\s. thread \ idle_thread s)\ handle_fault_reply fault thread x y \\_. globals_equiv st\" apply(case_tac fault) apply(wp as_user_globals_equiv | simp add: handle_arch_fault_reply_def)+ done crunch valid_global_objs: handle_fault_reply "valid_global_objs" lemma do_reply_transfer_globals_equiv: "\globals_equiv st and valid_objs and valid_arch_state and valid_global_refs and pspace_distinct and pspace_aligned and valid_global_objs and valid_idle\ do_reply_transfer sender receiver slot \\_. globals_equiv st\" unfolding do_reply_transfer_def apply(wp set_thread_state_globals_equiv cap_delete_one_globals_equiv do_ipc_transfer_globals_equiv thread_set_globals_equiv handle_fault_reply_globals_equiv dxo_wp_weak | wpc | simp split del: if_split)+ apply(rule_tac Q="\_. globals_equiv st and valid_ko_at_arm and valid_objs and valid_arch_state and valid_global_refs and pspace_distinct and pspace_aligned and valid_global_objs and (\s. receiver \ idle_thread s) and valid_idle" in hoare_strengthen_post) apply (wp gts_wp | fastforce simp: valid_arch_state_ko_at_arm pred_tcb_at_def obj_at_def valid_idle_def)+ done lemma handle_reply_globals_equiv: "\globals_equiv st and valid_objs and valid_arch_state and valid_global_refs and pspace_distinct and pspace_aligned and valid_global_objs and valid_idle\ handle_reply \\_. globals_equiv st\" unfolding handle_reply_def apply(wp do_reply_transfer_globals_equiv | wpc)+ apply(rule_tac Q="\_. globals_equiv st and valid_objs and valid_arch_state and valid_global_refs and pspace_distinct and pspace_aligned and valid_global_objs and valid_idle" in hoare_strengthen_post) apply(wp | simp)+ done lemma reply_from_kernel_globals_equiv: "\globals_equiv s and valid_objs and valid_arch_state and valid_global_refs and pspace_distinct and pspace_aligned and (\s. thread \ idle_thread s)\ reply_from_kernel thread x \\_. globals_equiv s\" unfolding reply_from_kernel_def apply(wp set_message_info_globals_equiv set_mrs_globals_equiv as_user_globals_equiv | simp add: split_def)+ apply(insert length_msg_lt_msg_max) apply(simp add: valid_arch_state_ko_at_arm) done section "reads_respects_g" subsection "Notifications" lemma send_signal_reads_respects_g: assumes domains_distinct: "pas_domains_distinct aag" shows "reads_respects_g aag l (pas_refined aag and pas_cur_domain aag and valid_etcbs and valid_objs and valid_global_objs and valid_arch_state and valid_global_refs and pspace_distinct and valid_idle and sym_refs \ state_refs_of and ct_active and is_subject aag \ cur_thread and K ((pasSubject aag, Notify, pasObjectAbs aag ntfnptr) \ pasPolicy aag)) (send_signal ntfnptr badge)" apply(rule equiv_valid_guard_imp[OF reads_respects_g]) apply(rule send_signal_reads_respects[OF domains_distinct]) apply(rule doesnt_touch_globalsI) apply(wp send_signal_globals_equiv | simp)+ done lemma receive_signal_reads_respects_g: assumes domains_distinct: "pas_domains_distinct aag" shows "reads_respects_g aag l (valid_global_objs and valid_objs and valid_arch_state and valid_global_refs and pspace_distinct and pas_refined aag and (\s. thread \ idle_thread s) and is_subject aag \ cur_thread and K ((\ntfnptr\Access.obj_refs cap. (pasSubject aag, Receive, pasObjectAbs aag ntfnptr) \ pasPolicy aag \ is_subject aag thread))) (receive_signal thread cap is_blocking)" apply(rule equiv_valid_guard_imp[OF reads_respects_g]) apply(rule receive_signal_reads_respects[OF domains_distinct]) apply(rule doesnt_touch_globalsI) apply(wp receive_signal_globals_equiv | simp)+ done subsection "Sycn IPC" lemma send_ipc_reads_respects_g: assumes domains_distinct: "pas_domains_distinct aag" shows "reads_respects_g aag l (pas_refined aag and pas_cur_domain aag and valid_objs and valid_global_objs and valid_arch_state and valid_global_refs and pspace_distinct and pspace_aligned and valid_idle and sym_refs \ state_refs_of and is_subject aag \ cur_thread and (\ s. \ep. ko_at (Endpoint ep) epptr s \ (can_grant \ (\x\ep_q_refs_of ep. (\(t, rt). rt = EPRecv \ is_subject aag t) x) \ (pasSubject aag, Grant, pasObjectAbs aag epptr) \ pasPolicy aag)) and K (is_subject aag thread \ (pasSubject aag, SyncSend, pasObjectAbs aag epptr) \ pasPolicy aag)) (send_ipc block call badge can_grant thread epptr)" apply(rule equiv_valid_guard_imp[OF reads_respects_g]) apply(rule send_ipc_reads_respects[OF domains_distinct]) apply(rule doesnt_touch_globalsI) apply(wp send_ipc_globals_equiv | simp)+ done lemma receive_ipc_reads_respects_g: assumes domains_distinct: "pas_domains_distinct aag" shows "reads_respects_g aag l (valid_objs and valid_global_objs and valid_arch_state and valid_global_refs and pspace_distinct and pspace_aligned and (\s. receiver \ idle_thread s) and sym_refs \ state_refs_of and pas_refined aag and pas_cur_domain aag and valid_cap cap and is_subject aag \ cur_thread and K (is_subject aag receiver \ (\epptr\Access.obj_refs cap. (pasSubject aag, Receive, pasObjectAbs aag epptr) \ pasPolicy aag))) (receive_ipc receiver cap is_blocking)" apply(rule equiv_valid_guard_imp[OF reads_respects_g]) apply(rule receive_ipc_reads_respects[OF domains_distinct]) apply(rule doesnt_touch_globalsI) apply(wp receive_ipc_globals_equiv | simp)+ done subsection "Faults" lemma send_fault_ipc_reads_respects_g: assumes domains_distinct: "pas_domains_distinct aag" shows "reads_respects_g aag l (sym_refs \ state_refs_of and pas_refined aag and pas_cur_domain aag and valid_objs and valid_global_objs and valid_arch_state and valid_global_refs and pspace_distinct and pspace_aligned and valid_idle and is_subject aag \ cur_thread and K (is_subject aag thread \ valid_fault fault)) (send_fault_ipc thread fault)" apply(rule equiv_valid_guard_imp[OF reads_respects_g]) apply(rule send_fault_ipc_reads_respects[OF domains_distinct]) apply(rule doesnt_touch_globalsI) apply(wp send_fault_ipc_globals_equiv | simp)+ done lemma handle_fault_reads_respects_g: assumes domains_distinct: "pas_domains_distinct aag" shows "reads_respects_g aag l (sym_refs \ state_refs_of and pas_refined aag and pas_cur_domain aag and valid_objs and valid_global_objs and valid_arch_state and valid_global_refs and pspace_distinct and pspace_aligned and valid_idle and is_subject aag \ cur_thread and K (is_subject aag thread \ valid_fault fault)) (handle_fault thread fault)" apply(rule equiv_valid_guard_imp[OF reads_respects_g]) apply(rule handle_fault_reads_respects[OF domains_distinct]) apply(rule doesnt_touch_globalsI) apply(wp handle_fault_globals_equiv | simp)+ done subsection "Replies" lemma handle_fault_reply_reads_respects_g: "reads_respects_g aag l (valid_ko_at_arm and (\s. thread \ idle_thread s) and K (is_subject aag thread)) (handle_fault_reply fault thread x y)" apply(rule equiv_valid_guard_imp[OF reads_respects_g]) apply(rule handle_fault_reply_reads_respects) apply(rule doesnt_touch_globalsI) apply(wp handle_fault_reply_globals_equiv | simp)+ done lemma do_reply_transfer_reads_respects_f_g: assumes domains_distinct: "pas_domains_distinct aag" shows "reads_respects_f_g aag l (silc_inv aag st and invs and pas_refined aag and pas_cur_domain aag and tcb_at receiver and tcb_at sender and emptyable slot and is_subject aag \ cur_thread and K (is_subject aag sender \ is_subject aag receiver \ is_subject aag (fst slot))) (do_reply_transfer sender receiver slot)" apply(rule equiv_valid_guard_imp[OF reads_respects_f_g]) apply(rule do_reply_transfer_reads_respects_f[OF domains_distinct]) apply(rule doesnt_touch_globalsI) apply(wp do_reply_transfer_globals_equiv | simp)+ apply(simp add: invs_def valid_state_def valid_pspace_def | blast)+ done lemma handle_reply_reads_respects_g: assumes domains_distinct: "pas_domains_distinct aag" shows "reads_respects_f_g aag l (silc_inv aag st and invs and pas_refined aag and pas_cur_domain aag and is_subject aag \ cur_thread) (handle_reply)" apply(rule equiv_valid_guard_imp[OF reads_respects_f_g]) apply(rule handle_reply_reads_respects_f[OF domains_distinct]) apply(rule doesnt_touch_globalsI) apply(wp handle_reply_globals_equiv | simp)+ apply(simp add: invs_def valid_state_def valid_pspace_def | blast)+ done lemma reply_from_kernel_reads_respects_g: assumes domains_distinct: "pas_domains_distinct aag" shows "reads_respects_g aag l (valid_global_objs and valid_objs and valid_arch_state and valid_global_refs and pspace_distinct and pspace_aligned and (\s. thread \ idle_thread s) and K (is_subject aag thread)) (reply_from_kernel thread x)" apply(rule equiv_valid_guard_imp[OF reads_respects_g]) apply(rule reply_from_kernel_reads_respects[OF domains_distinct]) apply(rule doesnt_touch_globalsI) apply(wp reply_from_kernel_globals_equiv | simp)+ done end end