lh-l4v/proof/refine/ARM/KHeap_R.thy

2156 lines
94 KiB
Plaintext

(*
* Copyright 2014, General Dynamics C4 Systems
*
* SPDX-License-Identifier: GPL-2.0-only
*)
theory KHeap_R
imports
"AInvs.ArchDetSchedSchedule_AI"
Machine_R
begin
lemma lookupAround2_known1:
"m x = Some y \<Longrightarrow> fst (lookupAround2 x m) = Some (x, y)"
by (fastforce simp: lookupAround2_char1)
context begin interpretation Arch . (*FIXME: arch_split*)
lemma obj_at_getObject:
assumes R:
"\<And>a b n ko s obj::'a::pspace_storable.
\<lbrakk> (a, b) \<in> fst (loadObject t t n ko s); projectKO_opt ko = Some obj \<rbrakk> \<Longrightarrow> a = obj"
shows "\<lbrace>obj_at' P t\<rbrace> getObject t \<lbrace>\<lambda>(rv::'a::pspace_storable) s. P rv\<rbrace>"
by (auto simp: getObject_def obj_at'_def in_monad valid_def
split_def projectKOs lookupAround2_known1
dest: R)
declare projectKO_inv [wp]
lemma loadObject_default_inv:
"\<lbrace>P\<rbrace> loadObject_default addr addr' next obj \<lbrace>\<lambda>rv. P\<rbrace>"
apply (simp add: loadObject_default_def magnitudeCheck_def
alignCheck_def unless_def alignError_def
| wp hoare_vcg_split_case_option
hoare_drop_imps hoare_vcg_all_lift)+
done
lemma getObject_inv:
assumes x: "\<And>p q n ko. \<lbrace>P\<rbrace> loadObject p q n ko \<lbrace>\<lambda>(rv :: 'a :: pspace_storable). P\<rbrace>"
shows "\<lbrace>P\<rbrace> getObject p \<lbrace>\<lambda>(rv :: 'a :: pspace_storable). P\<rbrace>"
by (simp add: getObject_def split_def | wp x)+
lemma getObject_inv_tcb [wp]: "\<lbrace>P\<rbrace> getObject l \<lbrace>\<lambda>(rv :: Structures_H.tcb). P\<rbrace>"
apply (rule getObject_inv)
apply simp
apply (rule loadObject_default_inv)
done
end
(* FIXME: this should go somewhere in spec *)
translations
(type) "'a kernel" <=(type) "kernel_state \<Rightarrow> ('a \<times> kernel_state) set \<times> bool"
context begin interpretation Arch . (*FIXME: arch_split*)
lemma no_fail_loadObject_default [wp]:
"no_fail (\<lambda>s. \<exists>obj. projectKO_opt ko = Some (obj::'a) \<and>
is_aligned p (objBits obj) \<and> q = p
\<and> case_option True (\<lambda>x. 2 ^ (objBits obj) \<le> x - p) n)
(loadObject_default p q n ko :: ('a::pre_storable) kernel)"
apply (simp add: loadObject_default_def split_def projectKO_def
alignCheck_def alignError_def magnitudeCheck_def
unless_def)
apply (rule no_fail_pre)
apply (wp case_option_wp)
apply (clarsimp simp: is_aligned_mask)
apply (clarsimp split: option.split_asm)
apply (clarsimp simp: is_aligned_mask[symmetric])
apply simp
done
lemma no_fail_getObject_tcb [wp]:
"no_fail (tcb_at' t) (getObject t :: tcb kernel)"
apply (simp add: getObject_def split_def)
apply (rule no_fail_pre)
apply wp
apply (clarsimp simp add: obj_at'_def projectKOs objBits_simps'
cong: conj_cong)
apply (rule ps_clear_lookupAround2, assumption+)
apply simp
apply (simp add: field_simps)
apply (erule is_aligned_no_wrap')
apply simp
apply (fastforce split: option.split_asm simp: objBits_simps' archObjSize_def)
done
lemma typ_at_to_obj_at':
"typ_at' (koType (TYPE ('a :: pspace_storable))) p s
= obj_at' (\<top> :: 'a \<Rightarrow> bool) p s"
by (simp add: typ_at'_def obj_at'_real_def project_koType[symmetric])
lemmas typ_at_to_obj_at_arches
= typ_at_to_obj_at'[where 'a=pte, simplified]
typ_at_to_obj_at' [where 'a=pde, simplified]
typ_at_to_obj_at'[where 'a=asidpool, simplified]
typ_at_to_obj_at'[where 'a=user_data, simplified]
typ_at_to_obj_at'[where 'a=user_data_device, simplified]
lemmas page_table_at_obj_at'
= page_table_at'_def[unfolded typ_at_to_obj_at_arches]
lemma corres_get_tcb [corres]:
"corres (tcb_relation \<circ> the) (tcb_at t) (tcb_at' t) (gets (get_tcb t)) (getObject t)"
apply (rule corres_no_failI)
apply wp
apply (clarsimp simp add: gets_def get_def return_def bind_def get_tcb_def)
apply (frule in_inv_by_hoareD [OF getObject_inv_tcb])
apply (clarsimp simp add: obj_at_def is_tcb obj_at'_def projectKO_def
projectKO_opt_tcb split_def
getObject_def loadObject_default_def in_monad)
apply (case_tac koa)
apply (simp_all add: fail_def return_def)
apply (case_tac bb)
apply (simp_all add: fail_def return_def)
apply (clarsimp simp add: state_relation_def pspace_relation_def)
apply (drule bspec)
apply clarsimp
apply blast
apply (clarsimp simp add: other_obj_relation_def
lookupAround2_known1)
done
lemma lookupAround2_same1[simp]:
"(fst (lookupAround2 x s) = Some (x, y)) = (s x = Some y)"
apply (rule iffI)
apply (simp add: lookupAround2_char1)
apply (simp add: lookupAround2_known1)
done
lemma getObject_tcb_at':
"\<lbrace> \<top> \<rbrace> getObject t \<lbrace>\<lambda>r::tcb. tcb_at' t\<rbrace>"
by (clarsimp simp: valid_def getObject_def in_monad
loadObject_default_def obj_at'_def projectKOs split_def
in_magnitude_check objBits_simps')
text \<open>updateObject_cte lemmas\<close>
lemma koType_objBitsKO:
"koTypeOf k = koTypeOf k' \<Longrightarrow> objBitsKO k = objBitsKO k'"
by (auto simp: objBitsKO_def archObjSize_def
split: Structures_H.kernel_object.splits
ARM_H.arch_kernel_object.splits)
lemma updateObject_objBitsKO:
"(ko', t') \<in> fst (updateObject (val :: 'a :: pspace_storable) ko p q n t)
\<Longrightarrow> objBitsKO ko' = objBitsKO ko"
apply (drule updateObject_type)
apply (erule koType_objBitsKO)
done
lemma updateObject_cte_is_tcb_or_cte:
fixes cte :: cte and ptr :: word32
shows "\<lbrakk> fst (lookupAround2 p (ksPSpace s)) = Some (q, ko);
snd (lookupAround2 p (ksPSpace s)) = n;
(ko', s') \<in> fst (updateObject cte ko p q n s) \<rbrakk> \<Longrightarrow>
(\<exists>tcb getF setF. ko = KOTCB tcb \<and> s' = s \<and> tcb_cte_cases (p - q) = Some (getF, setF)
\<and> ko' = KOTCB (setF (\<lambda>x. cte) tcb) \<and> is_aligned q tcbBlockSizeBits \<and> ps_clear q tcbBlockSizeBits s) \<or>
(\<exists>cte'. ko = KOCTE cte' \<and> ko' = KOCTE cte \<and> s' = s
\<and> p = q \<and> is_aligned p cte_level_bits \<and> ps_clear p cte_level_bits s)"
apply (clarsimp simp: updateObject_cte typeError_def alignError_def
tcbVTableSlot_def tcbCTableSlot_def to_bl_1 rev_take objBits_simps'
in_monad map_bits_to_bl cte_level_bits_def in_magnitude_check
lookupAround2_char1
split: kernel_object.splits)
apply (subst(asm) in_magnitude_check3, simp+)
apply (simp add: in_monad tcbCTableSlot_def tcbVTableSlot_def
tcbReplySlot_def tcbCallerSlot_def tcbIPCBufferSlot_def
split: if_split_asm)
apply (simp add: in_monad tcbCTableSlot_def tcbVTableSlot_def
tcbReplySlot_def tcbCallerSlot_def tcbIPCBufferSlot_def
split: if_split_asm)
done
declare plus_1_less[simp]
lemma updateObject_default_result:
"(x, s'') \<in> fst (updateObject_default e ko p q n s) \<Longrightarrow> x = injectKO e"
by (clarsimp simp add: updateObject_default_def in_monad)
lemma obj_at_setObject1:
assumes R: "\<And>(v::'a::pspace_storable) p q n ko s x s''.
(x, s'') \<in> fst (updateObject v ko p q n s) \<Longrightarrow> x = injectKO v"
assumes Q: "\<And>(v::'a::pspace_storable) (v'::'a). objBits v = objBits v'"
shows
"\<lbrace> obj_at' (\<lambda>x::'a::pspace_storable. True) t \<rbrace>
setObject p (v::'a::pspace_storable)
\<lbrace> \<lambda>rv. obj_at' (\<lambda>x::'a::pspace_storable. True) t \<rbrace>"
apply (simp add: setObject_def split_def)
apply (rule hoare_seq_ext [OF _ hoare_gets_sp])
apply (clarsimp simp: valid_def in_monad obj_at'_def
projectKOs lookupAround2_char1
project_inject
dest!: R)
apply (subgoal_tac "objBitsKO (injectKO v) = objBitsKO (injectKO obj)")
apply (intro conjI impI, simp_all)
apply fastforce+
apply (fold objBits_def)
apply (rule Q)
done
lemma obj_at_setObject2:
fixes v :: "'a::pspace_storable"
fixes P :: "'b::pspace_storable \<Rightarrow> bool"
assumes R: "\<And>ko s' (v :: 'a) oko x y n s. (ko, s') \<in> fst (updateObject v oko x y n s)
\<Longrightarrow> koTypeOf ko \<noteq> koType TYPE('b)"
shows
"\<lbrace> obj_at' P t \<rbrace>
setObject p (v::'a)
\<lbrace> \<lambda>rv. obj_at' P t \<rbrace>"
apply (simp add: setObject_def split_def)
apply (rule hoare_seq_ext [OF _ hoare_gets_sp])
apply (clarsimp simp: valid_def in_monad)
apply (frule updateObject_type)
apply (drule R)
apply (clarsimp simp: obj_at'_def projectKOs)
apply (rule conjI)
apply (clarsimp simp: lookupAround2_char1)
apply (drule iffD1 [OF project_koType, OF exI])
apply simp
apply (clarsimp simp: ps_clear_upd lookupAround2_char1)
done
lemma updateObject_ep_eta:
"updateObject (v :: endpoint) = updateObject_default v"
by ((rule ext)+, simp)
lemma updateObject_tcb_eta:
"updateObject (v :: tcb) = updateObject_default v"
by ((rule ext)+, simp)
lemma updateObject_ntfn_eta:
"updateObject (v :: Structures_H.notification) = updateObject_default v"
by ((rule ext)+, simp)
lemmas updateObject_eta =
updateObject_ep_eta updateObject_tcb_eta updateObject_ntfn_eta
lemma objBits_type:
"koTypeOf k = koTypeOf k' \<Longrightarrow> objBitsKO k = objBitsKO k'"
by (erule koType_objBitsKO)
lemma setObject_typ_at_inv:
"\<lbrace>typ_at' T p'\<rbrace> setObject p v \<lbrace>\<lambda>r. typ_at' T p'\<rbrace>"
apply (clarsimp simp: setObject_def split_def)
apply (clarsimp simp: valid_def typ_at'_def ko_wp_at'_def in_monad
lookupAround2_char1 ps_clear_upd)
apply (drule updateObject_type)
apply clarsimp
apply (drule objBits_type)
apply (simp add: ps_clear_upd)
done
lemma setObject_typ_at_not:
"\<lbrace>\<lambda>s. \<not> (typ_at' T p' s)\<rbrace> setObject p v \<lbrace>\<lambda>r s. \<not> (typ_at' T p' s)\<rbrace>"
apply (clarsimp simp: setObject_def valid_def in_monad split_def)
apply (erule notE)
apply (clarsimp simp: typ_at'_def ko_wp_at'_def lookupAround2_char1
split: if_split_asm)
apply (drule updateObject_type)
apply clarsimp
apply (drule objBits_type)
apply (clarsimp elim!: ps_clear_domE)
apply fastforce
apply (clarsimp elim!: ps_clear_domE)
apply fastforce
done
lemma setObject_typ_at'[wp]:
"\<lbrace>\<lambda>s. P (typ_at' T p' s)\<rbrace> setObject p v \<lbrace>\<lambda>r s. P (typ_at' T p' s)\<rbrace>"
by (blast intro: P_bool_lift setObject_typ_at_inv setObject_typ_at_not)
lemmas setObject_typ_ats [wp] = typ_at_lifts [OF setObject_typ_at']
lemma setObject_cte_wp_at2':
assumes x: "\<And>x n tcb s t. \<lbrakk> t \<in> fst (updateObject v (KOTCB tcb) ptr x n s); Q s;
lookupAround2 ptr (ksPSpace s) = (Some (x, KOTCB tcb), n) \<rbrakk>
\<Longrightarrow> \<exists>tcb'. t = (KOTCB tcb', s) \<and> (\<forall>(getF, setF) \<in> ran tcb_cte_cases. getF tcb' = getF tcb)"
assumes y: "\<And>x n cte s. fst (updateObject v (KOCTE cte) ptr x n s) = {}"
shows "\<lbrace>\<lambda>s. P' (cte_wp_at' P p s) \<and> Q s\<rbrace> setObject ptr v \<lbrace>\<lambda>rv s. P' (cte_wp_at' P p s)\<rbrace>"
apply (clarsimp simp add: setObject_def valid_def in_monad split_def)
apply (simp add: cte_wp_at_cases' split del: if_split)
apply (erule rsubst[where P=P'])
apply (rule iffI)
apply (erule disjEI)
apply (clarsimp simp: ps_clear_upd lookupAround2_char1 y)
apply (erule exEI [where 'a=word32])
apply (clarsimp simp: ps_clear_upd lookupAround2_char1)
apply (drule(1) x)
apply (clarsimp simp: lookupAround2_char1 prod_eqI)
apply (fastforce dest: bspec [OF _ ranI])
apply (erule disjEI)
apply (clarsimp simp: ps_clear_upd lookupAround2_char1
split: if_split_asm)
apply (frule updateObject_type)
apply (case_tac ba, simp_all add: y)[1]
apply (erule exEI)
apply (clarsimp simp: ps_clear_upd lookupAround2_char1
split: if_split_asm)
apply (frule updateObject_type)
apply (case_tac ba, simp_all)
apply (drule(1) x)
apply (clarsimp simp: prod_eqI lookupAround2_char1)
apply (fastforce dest: bspec [OF _ ranI])
done
lemma setObject_cte_wp_at':
assumes x: "\<And>x n tcb s t. \<lbrakk> t \<in> fst (updateObject v (KOTCB tcb) ptr x n s); Q s;
lookupAround2 ptr (ksPSpace s) = (Some (x, KOTCB tcb), n) \<rbrakk>
\<Longrightarrow> \<exists>tcb'. t = (KOTCB tcb', s) \<and> (\<forall>(getF, setF) \<in> ran tcb_cte_cases. getF tcb' = getF tcb)"
assumes y: "\<And>x n cte s. fst (updateObject v (KOCTE cte) ptr x n s) = {}"
shows "\<lbrace>cte_wp_at' P p and Q\<rbrace> setObject ptr v \<lbrace>\<lambda>rv. cte_wp_at' P p\<rbrace>"
unfolding pred_conj_def
by (rule setObject_cte_wp_at2'[OF x y], assumption+)
lemma setObject_ep_pre:
assumes "\<lbrace>P and ep_at' p\<rbrace> setObject p (e::endpoint) \<lbrace>Q\<rbrace>"
shows "\<lbrace>P\<rbrace> setObject p (e::endpoint) \<lbrace>Q\<rbrace>" using assms
apply (clarsimp simp: valid_def setObject_def in_monad
split_def updateObject_default_def
projectKOs in_magnitude_check objBits_simps')
apply (drule spec, drule mp, erule conjI)
apply (simp add: obj_at'_def projectKOs objBits_simps')
apply (simp add: split_paired_Ball)
apply (drule spec, erule mp)
apply (clarsimp simp: in_monad projectKOs in_magnitude_check)
done
lemma setObject_ntfn_pre:
assumes "\<lbrace>P and ntfn_at' p\<rbrace> setObject p (e::Structures_H.notification) \<lbrace>Q\<rbrace>"
shows "\<lbrace>P\<rbrace> setObject p (e::Structures_H.notification) \<lbrace>Q\<rbrace>" using assms
apply (clarsimp simp: valid_def setObject_def in_monad
split_def updateObject_default_def
projectKOs in_magnitude_check objBits_simps')
apply (drule spec, drule mp, erule conjI)
apply (simp add: obj_at'_def projectKOs objBits_simps')
apply (simp add: split_paired_Ball)
apply (drule spec, erule mp)
apply (clarsimp simp: in_monad projectKOs in_magnitude_check)
done
lemma setObject_tcb_pre:
assumes "\<lbrace>P and tcb_at' p\<rbrace> setObject p (t::tcb) \<lbrace>Q\<rbrace>"
shows "\<lbrace>P\<rbrace> setObject p (t::tcb) \<lbrace>Q\<rbrace>" using assms
apply (clarsimp simp: valid_def setObject_def in_monad
split_def updateObject_default_def
projectKOs in_magnitude_check objBits_simps')
apply (drule spec, drule mp, erule conjI)
apply (simp add: obj_at'_def projectKOs objBits_simps')
apply (simp add: split_paired_Ball)
apply (drule spec, erule mp)
apply (clarsimp simp: in_monad projectKOs in_magnitude_check)
done
lemma obj_at_setObject3:
fixes Q::"'a::pspace_storable \<Rightarrow> bool"
fixes P::"'a::pspace_storable \<Rightarrow> bool"
assumes R: "\<And>ko s x y n. (updateObject v ko p y n s)
= (updateObject_default v ko p y n s)"
assumes P: "\<And>(v::'a::pspace_storable). (1 :: word32) < 2 ^ (objBits v)"
shows "\<lbrace>(\<lambda>s. P v)\<rbrace> setObject p v \<lbrace>\<lambda>rv. obj_at' P p\<rbrace>"
apply (clarsimp simp add: valid_def in_monad obj_at'_def
setObject_def split_def projectKOs
project_inject objBits_def[symmetric]
R updateObject_default_def
in_magnitude_check P ps_clear_upd)
apply fastforce
done
lemma setObject_tcb_strongest:
"\<lbrace>\<lambda>s. if t = t' then P tcb else obj_at' P t' s\<rbrace>
setObject t (tcb :: tcb)
\<lbrace>\<lambda>rv. obj_at' P t'\<rbrace>"
apply (cases "t = t'")
apply simp
apply (rule hoare_weaken_pre)
apply (rule obj_at_setObject3)
apply simp
apply (simp add: objBits_simps')
apply simp
apply (simp add: setObject_def split_def)
apply (clarsimp simp: valid_def obj_at'_def split_def in_monad
updateObject_default_def projectKOs
ps_clear_upd)
done
lemma getObject_obj_at':
assumes x: "\<And>q n ko. loadObject p q n ko =
(loadObject_default p q n ko :: ('a :: pspace_storable) kernel)"
assumes P: "\<And>(v::'a::pspace_storable). (1 :: word32) < 2 ^ (objBits v)"
shows "\<lbrace> \<top> \<rbrace> getObject p \<lbrace>\<lambda>r::'a::pspace_storable. obj_at' ((=) r) p\<rbrace>"
by (clarsimp simp: valid_def getObject_def in_monad
loadObject_default_def obj_at'_def projectKOs
split_def in_magnitude_check lookupAround2_char1
x P project_inject objBits_def[symmetric])
lemma getObject_valid_obj:
assumes x: "\<And>p q n ko. loadObject p q n ko =
(loadObject_default p q n ko :: ('a :: pspace_storable) kernel)"
assumes P: "\<And>(v::'a::pspace_storable). (1 :: word32) < 2 ^ (objBits v)"
shows "\<lbrace> valid_objs' \<rbrace> getObject p \<lbrace>\<lambda>rv::'a::pspace_storable. valid_obj' (injectKO rv) \<rbrace>"
apply (rule hoare_chain)
apply (rule hoare_vcg_conj_lift)
apply (rule getObject_obj_at' [OF x P])
apply (rule getObject_inv)
apply (subst x)
apply (rule loadObject_default_inv)
apply (clarsimp, assumption)
apply clarsimp
apply (drule(1) obj_at_valid_objs')
apply (clarsimp simp: project_inject)
done
declare fail_inv[simp]
lemma typeError_inv [wp]:
"\<lbrace>P\<rbrace> typeError x y \<lbrace>\<lambda>rv. P\<rbrace>"
by (simp add: typeError_def|wp)+
lemma getObject_cte_inv [wp]: "\<lbrace>P\<rbrace> (getObject addr :: cte kernel) \<lbrace>\<lambda>rv. P\<rbrace>"
apply (simp add: getObject_def loadObject_cte split_def)
apply (clarsimp simp: valid_def in_monad)
apply (clarsimp simp: typeError_def in_monad magnitudeCheck_def
split: kernel_object.split_asm if_split_asm option.split_asm)
done
lemma getObject_ko_at:
assumes x: "\<And>q n ko. loadObject p q n ko =
(loadObject_default p q n ko :: ('a :: pspace_storable) kernel)"
assumes P: "\<And>(v::'a::pspace_storable). (1 :: word32) < 2 ^ (objBits v)"
shows "\<lbrace> \<top> \<rbrace> getObject p \<lbrace>\<lambda>r::'a::pspace_storable. ko_at' r p\<rbrace>"
by (subst eq_commute, rule getObject_obj_at' [OF x P])
lemma getObject_ko_at_tcb [wp]:
"\<lbrace>\<top>\<rbrace> getObject p \<lbrace>\<lambda>rv::tcb. ko_at' rv p\<rbrace>"
by (rule getObject_ko_at | simp add: objBits_simps')+
lemma OMG_getObject_tcb:
"\<lbrace>obj_at' P t\<rbrace> getObject t \<lbrace>\<lambda>(tcb :: tcb) s. P tcb\<rbrace>"
apply (rule obj_at_getObject)
apply (clarsimp simp: loadObject_default_def in_monad projectKOs)
done
lemma setObject_nosch:
assumes x: "\<And>p q n ko. \<lbrace>\<lambda>s. P (ksSchedulerAction s)\<rbrace> updateObject val p q n ko \<lbrace>\<lambda>rv s. P (ksSchedulerAction s)\<rbrace>"
shows "\<lbrace>\<lambda>s. P (ksSchedulerAction s)\<rbrace> setObject t val \<lbrace>\<lambda>rv s. P (ksSchedulerAction s)\<rbrace>"
apply (simp add: setObject_def split_def)
apply (wp x | simp)+
done
lemma getObject_ep_inv: "\<lbrace>P\<rbrace> (getObject addr :: endpoint kernel) \<lbrace>\<lambda>rv. P\<rbrace>"
apply (rule getObject_inv)
apply (simp add: loadObject_default_inv)
done
lemma getObject_ntfn_inv:
"\<lbrace>P\<rbrace> (getObject addr :: Structures_H.notification kernel) \<lbrace>\<lambda>rv. P\<rbrace>"
apply (rule getObject_inv)
apply (simp add: loadObject_default_inv)
done
lemma get_ep_inv'[wp]: "\<lbrace>P\<rbrace> getEndpoint ep \<lbrace>\<lambda>rv. P\<rbrace>"
by (simp add: getEndpoint_def getObject_ep_inv)
lemma get_ntfn_inv'[wp]: "\<lbrace>P\<rbrace> getNotification ntfn \<lbrace>\<lambda>rv. P\<rbrace>"
by (simp add: getNotification_def getObject_ntfn_inv)
lemma get_ep'_valid_ep[wp]:
"\<lbrace> invs' and ep_at' ep \<rbrace> getEndpoint ep \<lbrace> valid_ep' \<rbrace>"
apply (simp add: getEndpoint_def)
apply (rule hoare_chain)
apply (rule getObject_valid_obj)
apply simp
apply (simp add: objBits_simps')
apply clarsimp
apply (simp add: valid_obj'_def)
done
lemma get_ntfn'_valid_ntfn[wp]:
"\<lbrace> invs' and ntfn_at' ep \<rbrace> getNotification ep \<lbrace> valid_ntfn' \<rbrace>"
apply (simp add: getNotification_def)
apply (rule hoare_chain)
apply (rule getObject_valid_obj)
apply simp
apply (simp add: objBits_simps')
apply clarsimp
apply (simp add: valid_obj'_def)
done
lemma setObject_distinct[wp]:
shows "\<lbrace>pspace_distinct'\<rbrace> setObject p val \<lbrace>\<lambda>rv. pspace_distinct'\<rbrace>"
apply (clarsimp simp: setObject_def split_def valid_def in_monad
projectKOs pspace_distinct'_def ps_clear_upd
objBits_def[symmetric] lookupAround2_char1
split: if_split_asm
dest!: updateObject_objBitsKO)
apply (fastforce dest: bspec[OF _ domI])
apply (fastforce dest: bspec[OF _ domI])
done
lemma setObject_aligned[wp]:
shows "\<lbrace>pspace_aligned'\<rbrace> setObject p val \<lbrace>\<lambda>rv. pspace_aligned'\<rbrace>"
apply (clarsimp simp: setObject_def split_def valid_def in_monad
projectKOs pspace_aligned'_def ps_clear_upd
objBits_def[symmetric] lookupAround2_char1
split: if_split_asm
dest!: updateObject_objBitsKO)
apply (fastforce dest: bspec[OF _ domI])
apply (fastforce dest: bspec[OF _ domI])
done
lemma set_ep_aligned' [wp]:
"\<lbrace>pspace_aligned'\<rbrace> setEndpoint ep v \<lbrace>\<lambda>rv. pspace_aligned'\<rbrace>"
unfolding setEndpoint_def by wp
lemma set_ep_distinct' [wp]:
"\<lbrace>pspace_distinct'\<rbrace> setEndpoint ep v \<lbrace>\<lambda>rv. pspace_distinct'\<rbrace>"
unfolding setEndpoint_def by wp
lemma setEndpoint_cte_wp_at':
"\<lbrace>cte_wp_at' P p\<rbrace> setEndpoint ptr v \<lbrace>\<lambda>rv. cte_wp_at' P p\<rbrace>"
unfolding setEndpoint_def
apply (rule setObject_cte_wp_at'[where Q="\<top>", simplified])
apply (clarsimp simp add: updateObject_default_def in_monad
projectKOs
intro!: set_eqI)+
done
lemma setEndpoint_pred_tcb_at'[wp]:
"\<lbrace>pred_tcb_at' proj P t\<rbrace> setEndpoint ptr val \<lbrace>\<lambda>rv. pred_tcb_at' proj P t\<rbrace>"
apply (simp add: pred_tcb_at'_def setEndpoint_def)
apply (rule obj_at_setObject2)
apply (clarsimp simp: updateObject_default_def in_monad)
done
lemma get_ntfn_ko':
"\<lbrace>\<top>\<rbrace> getNotification ep \<lbrace>\<lambda>rv. ko_at' rv ep\<rbrace>"
apply (simp add: getNotification_def)
apply (rule getObject_ko_at)
apply simp
apply (simp add: objBits_simps')
done
lemma set_ntfn_aligned'[wp]:
"\<lbrace>pspace_aligned'\<rbrace> setNotification p ntfn \<lbrace>\<lambda>rv. pspace_aligned'\<rbrace>"
unfolding setNotification_def by wp
lemma set_ntfn_distinct'[wp]:
"\<lbrace>pspace_distinct'\<rbrace> setNotification p ntfn \<lbrace>\<lambda>rv. pspace_distinct'\<rbrace>"
unfolding setNotification_def by wp
lemma setNotification_cte_wp_at':
"\<lbrace>cte_wp_at' P p\<rbrace> setNotification ptr v \<lbrace>\<lambda>rv. cte_wp_at' P p\<rbrace>"
unfolding setNotification_def
apply (rule setObject_cte_wp_at'[where Q="\<top>", simplified])
apply (clarsimp simp add: updateObject_default_def in_monad
projectKOs
intro!: set_eqI)+
done
lemma setObject_ntfn_tcb':
"\<lbrace>tcb_at' t\<rbrace> setObject p (e::Structures_H.notification) \<lbrace>\<lambda>_. tcb_at' t\<rbrace>"
apply (rule obj_at_setObject2)
apply (clarsimp simp: updateObject_default_def in_monad)
done
lemma set_ntfn_tcb' [wp]:
"\<lbrace> tcb_at' t \<rbrace> setNotification ntfn v \<lbrace> \<lambda>rv. tcb_at' t \<rbrace>"
by (simp add: setNotification_def setObject_ntfn_tcb')
lemma pspace_dom_update:
"\<lbrakk> ps ptr = Some x; a_type x = a_type v \<rbrakk> \<Longrightarrow> pspace_dom (ps(ptr \<mapsto> v)) = pspace_dom ps"
apply (simp add: pspace_dom_def dom_fun_upd2 del: dom_fun_upd)
apply (rule SUP_cong [OF refl])
apply clarsimp
apply (simp add: obj_relation_cuts_def3)
done
lemmas ps_clear_def3 = ps_clear_def2 [OF order_less_imp_le [OF aligned_less_plus_1]]
declare diff_neg_mask[simp del]
lemma cte_wp_at_ctes_of:
"cte_wp_at' P p s = (\<exists>cte. ctes_of s p = Some cte \<and> P cte)"
apply (simp add: cte_wp_at_cases' map_to_ctes_def Let_def
cte_level_bits_def objBits_simps'
split del: if_split)
apply (safe del: disjCI)
apply (clarsimp simp: ps_clear_def3 field_simps)
apply (clarsimp simp: ps_clear_def3 field_simps
split del: if_split)
apply (frule is_aligned_sub_helper)
apply (clarsimp simp: tcb_cte_cases_def split: if_split_asm)
apply (case_tac "n = 0")
apply (clarsimp simp: field_simps)
apply (subgoal_tac "ksPSpace s p = None")
apply clarsimp
apply (clarsimp simp: field_simps)
apply (elim conjE)
apply (subst(asm) mask_in_range, assumption)
apply (drule arg_cong[where f="\<lambda>S. p \<in> S"])
apply (simp add: dom_def field_simps)
apply (erule mp)
apply (rule ccontr, simp add: linorder_not_le)
apply (drule word_le_minus_one_leq)
apply clarsimp
apply (simp add: field_simps)
apply (clarsimp split: if_split_asm del: disjCI)
apply (simp add: ps_clear_def3 field_simps)
apply (rule disjI2, rule exI[where x="p - (p && ~~ mask 9)"])
apply (clarsimp simp: ps_clear_def3[where na=9] is_aligned_mask
word_bw_assocs field_simps)
done
lemma tcb_cte_cases_small:
"\<lbrakk> tcb_cte_cases v = Some (getF, setF) \<rbrakk>
\<Longrightarrow> v < 2 ^ tcbBlockSizeBits"
by (simp add: tcb_cte_cases_def objBits_defs split: if_split_asm)
lemmas tcb_cte_cases_aligned_helpers =
is_aligned_add_helper [OF _ tcb_cte_cases_small]
is_aligned_sub_helper [OF _ tcb_cte_cases_small]
lemma ctes_of_from_cte_wp_at:
assumes x: "\<And>P P' p. \<lbrace>\<lambda>s. P (cte_wp_at' P' p s) \<and> Q s\<rbrace> f \<lbrace>\<lambda>r s. P (cte_wp_at' P' p s)\<rbrace>"
shows "\<lbrace>\<lambda>s. P (ctes_of s) \<and> Q s\<rbrace> f \<lbrace>\<lambda>rv s. P (ctes_of s)\<rbrace>"
apply (clarsimp simp: valid_def
elim!: rsubst[where P=P]
intro!: ext)
apply (case_tac "ctes_of s x", simp_all)
apply (drule_tac P1=Not and P'1="\<top>" and p1=x in use_valid [OF _ x],
simp_all add: cte_wp_at_ctes_of)
apply (drule_tac P1=id and P'1="(=) aa" and p1=x in use_valid [OF _ x],
simp_all add: cte_wp_at_ctes_of)
done
lemmas setObject_ctes_of = ctes_of_from_cte_wp_at [OF setObject_cte_wp_at2']
lemma map_to_ctes_upd_cte:
"\<lbrakk> s p = Some (KOCTE cte'); is_aligned p cte_level_bits;
{p + 1..p + mask cte_level_bits} \<inter> dom s = {} \<rbrakk> \<Longrightarrow>
map_to_ctes (s (p \<mapsto> (KOCTE cte))) = ((map_to_ctes s) (p \<mapsto> cte))"
apply (rule ext)
apply (simp add: map_to_ctes_def Let_def dom_fun_upd2
split del: if_split del: dom_fun_upd)
apply (case_tac "x = p")
apply (simp add: objBits_simps' cte_level_bits_def mask_def field_simps)
apply (case_tac "(x && ~~ mask (objBitsKO (KOTCB undefined))) = p")
apply clarsimp
apply (simp del: dom_fun_upd split del: if_split cong: if_cong
add: dom_fun_upd2 field_simps objBits_simps)
done
declare overflow_plus_one_self[simp]
lemma map_to_ctes_upd_tcb:
"\<lbrakk> s p = Some (KOTCB tcb'); is_aligned p tcbBlockSizeBits;
{p + 1..p + mask tcbBlockSizeBits} \<inter> dom s = {} \<rbrakk> \<Longrightarrow>
map_to_ctes (s (p \<mapsto> (KOTCB tcb))) =
(\<lambda>x. if \<exists>getF setF. tcb_cte_cases (x - p) = Some (getF, setF)
\<and> getF tcb \<noteq> getF tcb'
then (case tcb_cte_cases (x - p) of Some (getF, setF) \<Rightarrow> Some (getF tcb))
else map_to_ctes s x)"
supply
is_aligned_neg_mask_eq[simp del]
is_aligned_neg_mask_weaken[simp del]
apply (subgoal_tac "p && ~~ (mask tcbBlockSizeBits) = p")
apply (rule ext)
apply (simp add: map_to_ctes_def Let_def dom_fun_upd2
split del: if_split del: dom_fun_upd
cong: option.case_cong if_cong)
apply (case_tac "x = p")
apply (simp add: objBits_simps' field_simps map_to_ctes_def mask_def)
apply (case_tac "x && ~~ mask (objBitsKO (KOTCB undefined)) = p")
apply (case_tac "tcb_cte_cases (x - p)")
apply (simp split del: if_split cong: if_cong option.case_cong)
apply (subgoal_tac "s x = None")
apply (simp add: field_simps objBits_simps' split del: if_split
cong: if_cong option.case_cong)
apply (clarsimp simp: mask_def)
apply (subst(asm) mask_in_range[where bits="objBitsKO v" for v])
apply (simp add: objBitsKO_def)
apply (drule_tac a=x in equals0D)
apply (simp add: dom_def objBits_simps' mask_def field_simps)
apply (erule mp)
apply (rule ccontr, simp add: linorder_not_le)
apply (drule word_le_minus_one_leq, simp)
apply (case_tac "tcb_cte_cases (x - p)")
apply (simp split del: if_split cong: if_cong option.case_cong)
apply (rule FalseE)
apply (subst(asm) mask_in_range[where bits="objBitsKO v" for v])
apply (simp add: objBitsKO_def)
apply (subgoal_tac "x - p < 2 ^ tcbBlockSizeBits")
apply (frule word_le_minus_one_leq)
apply (frule(1) is_aligned_no_wrap')
apply (drule word_plus_mono_right[where x=p])
apply (simp only: field_simps)
apply (erule is_aligned_no_overflow)
apply (simp add: objBits_simps field_simps)
apply (clarsimp simp: tcb_cte_cases_def objBits_simps'
split: if_split_asm)
apply (subst mask_in_range, assumption)
apply (simp only: atLeastAtMost_iff order_refl simp_thms)
apply (erule is_aligned_no_overflow)
done
lemma map_to_ctes_upd_other:
"\<lbrakk> s p = Some ko; case ko of KOTCB tcb \<Rightarrow> False | KOCTE cte \<Rightarrow> False | _ \<Rightarrow> True;
case ko' of KOTCB tcb \<Rightarrow> False | KOCTE cte \<Rightarrow> False | _ \<Rightarrow> True \<rbrakk> \<Longrightarrow>
map_to_ctes (s (p \<mapsto> ko')) = (map_to_ctes s)"
apply (rule ext)
apply (simp add: map_to_ctes_def Let_def dom_fun_upd2
split del: if_split del: dom_fun_upd
cong: if_cong)
apply (rule if_cong)
apply clarsimp
apply fastforce
apply clarsimp
apply (rule if_cong)
apply clarsimp
apply fastforce
apply clarsimp
apply (rule refl)
done
lemma ctes_of_eq_cte_wp_at':
"cte_wp_at' ((=) cte) x s \<Longrightarrow> ctes_of s x = Some cte"
by (simp add: cte_wp_at_ctes_of)
lemma tcb_cte_cases_change:
"tcb_cte_cases x = Some (getF, setF) \<Longrightarrow>
(\<exists>getF. (\<exists>setF. tcb_cte_cases y = Some (getF, setF)) \<and> getF (setF f tcb) \<noteq> getF tcb)
= (x = y \<and> f (getF tcb) \<noteq> getF tcb)"
apply (rule iffI)
apply (clarsimp simp: tcb_cte_cases_def split: if_split_asm)
apply (clarsimp simp: tcb_cte_cases_def split: if_split_asm)
done
lemma cte_level_bits_nonzero [simp]: "0 < cte_level_bits"
by (simp add: cte_level_bits_def)
lemma ctes_of_setObject_cte:
"\<lbrace>\<lambda>s. P ((ctes_of s) (p \<mapsto> cte))\<rbrace> setObject p (cte :: cte) \<lbrace>\<lambda>rv s. P (ctes_of s)\<rbrace>"
apply (clarsimp simp: setObject_def split_def valid_def in_monad)
apply (drule(1) updateObject_cte_is_tcb_or_cte[OF _ refl, rotated])
apply (elim exE conjE disjE rsubst[where P=P])
apply (clarsimp simp: lookupAround2_char1)
apply (subst map_to_ctes_upd_tcb; assumption?)
apply (clarsimp simp: mask_def objBits_defs field_simps ps_clear_def3)
apply (clarsimp simp: tcb_cte_cases_change)
apply (rule ext, clarsimp)
apply (intro conjI impI)
apply (clarsimp simp: tcb_cte_cases_def split: if_split_asm)
apply (drule(1) cte_wp_at_tcbI'[where P="(=) cte"])
apply (simp add: ps_clear_def3 field_simps)
apply assumption+
apply (simp add: cte_wp_at_ctes_of)
apply (clarsimp simp: map_to_ctes_upd_cte ps_clear_def3 field_simps mask_def)
done
declare foldl_True[simp]
lemma real_cte_at':
"real_cte_at' p s \<Longrightarrow> cte_at' p s"
by (clarsimp simp add: cte_wp_at_cases' obj_at'_def projectKOs
objBits_simps' cte_level_bits_def
del: disjCI)
lemma no_fail_getEndpoint [wp]:
"no_fail (ep_at' ptr) (getEndpoint ptr)"
apply (simp add: getEndpoint_def getObject_def
split_def)
apply (rule no_fail_pre)
apply wp
apply (clarsimp simp add: obj_at'_def projectKOs objBits_simps'
lookupAround2_known1)
apply (erule(1) ps_clear_lookupAround2)
apply simp
apply (simp add: field_simps)
apply (erule is_aligned_no_wrap')
apply (simp add: word_bits_conv)
apply (clarsimp split: option.split_asm simp: objBits_simps' archObjSize_def)
done
lemma getEndpoint_corres [corres]:
"corres ep_relation (ep_at ptr) (ep_at' ptr)
(get_endpoint ptr) (getEndpoint ptr)"
apply (rule corres_no_failI)
apply wp
apply (simp add: get_simple_ko_def getEndpoint_def get_object_def
getObject_def bind_assoc ep_at_def2)
apply (clarsimp simp: in_monad split_def bind_def gets_def get_def return_def)
apply (clarsimp simp: assert_def fail_def obj_at_def return_def is_ep partial_inv_def)
apply (clarsimp simp: loadObject_default_def in_monad projectKOs
in_magnitude_check objBits_simps')
apply (clarsimp simp add: state_relation_def pspace_relation_def)
apply (drule bspec)
apply blast
apply (simp add: other_obj_relation_def)
done
declare magnitudeCheck_inv [wp]
declare alignCheck_inv [wp]
lemma setObject_ct_inv:
"\<lbrace>\<lambda>s. P (ksCurThread s)\<rbrace> setObject t (v::tcb) \<lbrace>\<lambda>rv s. P (ksCurThread s)\<rbrace>"
apply (simp add: setObject_def split_def)
apply (wp updateObject_default_inv | simp)+
done
lemma setObject_cd_inv:
"\<lbrace>\<lambda>s. P (ksCurDomain s)\<rbrace> setObject t (v::tcb) \<lbrace>\<lambda>rv s. P (ksCurDomain s)\<rbrace>"
apply (simp add: setObject_def split_def)
apply (wp updateObject_default_inv | simp)+
done
lemma setObject_it_inv:
"\<lbrace>\<lambda>s. P (ksIdleThread s)\<rbrace> setObject t (v::tcb) \<lbrace>\<lambda>rv s. P (ksIdleThread s)\<rbrace>"
apply (simp add: setObject_def split_def)
apply (wp updateObject_default_inv | simp)+
done
lemma setObject_ksDomSchedule_inv:
"\<lbrace>\<lambda>s. P (ksDomSchedule s)\<rbrace> setObject t (v::tcb) \<lbrace>\<lambda>rv s. P (ksDomSchedule s)\<rbrace>"
apply (simp add: setObject_def split_def)
apply (wp updateObject_default_inv | simp)+
done
lemma projectKO_def2:
"projectKO ko = assert_opt (projectKO_opt ko)"
by (simp add: projectKO_def assert_opt_def)
lemma no_fail_magnitudeCheck[wp]:
"no_fail (\<lambda>s. case y of None \<Rightarrow> True | Some z \<Rightarrow> 2 ^ n \<le> z - x)
(magnitudeCheck x y n)"
apply (clarsimp simp add: magnitudeCheck_def split: option.splits)
apply (rule no_fail_pre, wp)
apply simp
done
lemma no_fail_setObject_other [wp]:
fixes ob :: "'a :: pspace_storable"
assumes x: "updateObject ob = updateObject_default ob"
shows "no_fail (obj_at' (\<lambda>k::'a. objBits k = objBits ob) ptr)
(setObject ptr ob)"
apply (simp add: setObject_def x split_def updateObject_default_def
projectKO_def2 alignCheck_def alignError_def)
apply (rule no_fail_pre)
apply (wp )
apply (clarsimp simp: is_aligned_mask[symmetric] obj_at'_def
objBits_def[symmetric] projectKOs
project_inject lookupAround2_known1)
apply (erule(1) ps_clear_lookupAround2)
apply simp
apply (erule is_aligned_get_word_bits)
apply (subst add_diff_eq[symmetric])
apply (erule is_aligned_no_wrap')
apply simp
apply simp
apply fastforce
done
lemma obj_relation_cut_same_type:
"\<lbrakk> (y, P) \<in> obj_relation_cuts ko x; P ko z;
(y', P') \<in> obj_relation_cuts ko' x'; P' ko' z \<rbrakk>
\<Longrightarrow> (a_type ko = a_type ko') \<or> (\<exists>n n'. a_type ko = ACapTable n \<and> a_type ko' = ACapTable n')
\<or> (\<exists>sz sz'. a_type ko = AArch (AUserData sz) \<and> a_type ko' = AArch (AUserData sz'))
\<or> (\<exists>sz sz'. a_type ko = AArch (ADeviceData sz) \<and> a_type ko' = AArch (ADeviceData sz'))"
apply (rule ccontr)
apply (simp add: obj_relation_cuts_def2 a_type_def)
apply (auto simp: other_obj_relation_def cte_relation_def
pte_relation_def pde_relation_def
split: Structures_A.kernel_object.split_asm if_split_asm
Structures_H.kernel_object.split_asm
ARM_A.arch_kernel_obj.split_asm)
done
definition exst_same :: "Structures_H.tcb \<Rightarrow> Structures_H.tcb \<Rightarrow> bool"
where
"exst_same tcb tcb' \<equiv> tcbPriority tcb = tcbPriority tcb'
\<and> tcbTimeSlice tcb = tcbTimeSlice tcb'
\<and> tcbDomain tcb = tcbDomain tcb'"
fun exst_same' :: "Structures_H.kernel_object \<Rightarrow> Structures_H.kernel_object \<Rightarrow> bool"
where
"exst_same' (KOTCB tcb) (KOTCB tcb') = exst_same tcb tcb'" |
"exst_same' _ _ = True"
lemma setObject_other_corres:
fixes ob' :: "'a :: pspace_storable"
assumes x: "updateObject ob' = updateObject_default ob'"
assumes z: "\<And>s. obj_at' P ptr s
\<Longrightarrow> map_to_ctes ((ksPSpace s) (ptr \<mapsto> injectKO ob')) = map_to_ctes (ksPSpace s)"
assumes t: "is_other_obj_relation_type (a_type ob)"
assumes b: "\<And>ko. P ko \<Longrightarrow> objBits ko = objBits ob'"
assumes e: "\<And>ko. P ko \<Longrightarrow> exst_same' (injectKO ko) (injectKO ob')"
assumes P: "\<And>(v::'a::pspace_storable). (1 :: word32) < 2 ^ (objBits v)"
shows "other_obj_relation ob (injectKO (ob' :: 'a :: pspace_storable)) \<Longrightarrow>
corres dc (obj_at (\<lambda>ko. a_type ko = a_type ob) ptr and obj_at (same_caps ob) ptr)
(obj_at' (P :: 'a \<Rightarrow> bool) ptr)
(set_object ptr ob) (setObject ptr ob')"
supply image_cong_simp [cong del]
apply (rule corres_no_failI)
apply (rule no_fail_pre)
apply wp
apply (rule x)
apply (clarsimp simp: b elim!: obj_at'_weakenE)
apply (unfold set_object_def setObject_def)
apply (clarsimp simp: in_monad split_def bind_def gets_def get_def Bex_def
put_def return_def modify_def get_object_def x
projectKOs obj_at_def
updateObject_default_def in_magnitude_check [OF _ P])
apply (rename_tac ko)
apply (clarsimp simp add: state_relation_def z)
apply (clarsimp simp add: caps_of_state_after_update cte_wp_at_after_update
swp_def fun_upd_def obj_at_def)
apply (subst conj_assoc[symmetric])
apply (rule conjI[rotated])
apply (clarsimp simp add: ghost_relation_def)
apply (erule_tac x=ptr in allE)+
apply (clarsimp simp: obj_at_def a_type_def
split: Structures_A.kernel_object.splits if_split_asm)
apply (simp split: arch_kernel_obj.splits if_splits)
apply (fold fun_upd_def)
apply (simp only: pspace_relation_def pspace_dom_update dom_fun_upd2 simp_thms)
apply (elim conjE)
apply (frule bspec, erule domI)
apply (rule conjI)
apply (rule ballI, drule(1) bspec)
apply (drule domD)
apply (clarsimp simp: is_other_obj_relation_type t)
apply (drule(1) bspec)
apply clarsimp
apply (frule_tac ko'=ko and x'=ptr in obj_relation_cut_same_type,
(fastforce simp add: is_other_obj_relation_type t)+)
apply (erule disjE)
apply (simp add: is_other_obj_relation_type t)
apply (erule disjE)
apply (insert t,
clarsimp simp: is_other_obj_relation_type_CapTable a_type_def)
apply (erule disjE)
apply (insert t,
clarsimp simp: is_other_obj_relation_type_UserData a_type_def)
apply (insert t,
clarsimp simp: is_other_obj_relation_type_DeviceData a_type_def)
apply (simp only: ekheap_relation_def)
apply (rule ballI, drule(1) bspec)
apply (drule domD)
apply (insert e)
apply atomize
apply (clarsimp simp: obj_at'_def)
apply (erule_tac x=obj in allE)
apply (clarsimp simp: projectKO_eq project_inject)
apply (case_tac ob;
simp_all add: a_type_def other_obj_relation_def etcb_relation_def
is_other_obj_relation_type t exst_same_def)
by (clarsimp simp: is_other_obj_relation_type t exst_same_def
split: Structures_A.kernel_object.splits Structures_H.kernel_object.splits
ARM_A.arch_kernel_obj.splits)+
lemmas obj_at_simps = obj_at_def obj_at'_def projectKOs map_to_ctes_upd_other
is_other_obj_relation_type_def
a_type_def objBits_simps other_obj_relation_def
archObjSize_def pageBits_def
lemma setEndpoint_corres [corres]:
"ep_relation e e' \<Longrightarrow>
corres dc (ep_at ptr) (ep_at' ptr)
(set_endpoint ptr e) (setEndpoint ptr e')"
apply (simp add: set_simple_ko_def setEndpoint_def is_ep_def[symmetric])
apply (corresK_search search: setObject_other_corres[where P="\<lambda>_. True"])
apply (corresKsimp wp: get_object_ret get_object_wp)+
by (fastforce simp: is_ep obj_at_simps objBits_defs partial_inv_def)
lemma setNotification_corres [corres]:
"ntfn_relation ae ae' \<Longrightarrow>
corres dc (ntfn_at ptr) (ntfn_at' ptr)
(set_notification ptr ae) (setNotification ptr ae')"
apply (simp add: set_simple_ko_def setNotification_def is_ntfn_def[symmetric])
apply (corresK_search search: setObject_other_corres[where P="\<lambda>_. True"])
apply (corresKsimp wp: get_object_ret get_object_wp)+
by (fastforce simp: is_ntfn obj_at_simps objBits_defs partial_inv_def)
lemma no_fail_getNotification [wp]:
"no_fail (ntfn_at' ptr) (getNotification ptr)"
apply (simp add: getNotification_def getObject_def
split_def)
apply (rule no_fail_pre)
apply wp
apply (clarsimp simp add: obj_at'_def projectKOs objBits_simps'
lookupAround2_known1)
apply (erule(1) ps_clear_lookupAround2)
apply simp
apply (simp add: field_simps)
apply (erule is_aligned_no_wrap')
apply (simp add: word_bits_conv)
apply (clarsimp split: option.split_asm simp: objBits_simps' archObjSize_def)
done
lemma getNotification_corres:
"corres ntfn_relation (ntfn_at ptr) (ntfn_at' ptr)
(get_notification ptr) (getNotification ptr)"
apply (rule corres_no_failI)
apply wp
apply (simp add: get_simple_ko_def getNotification_def get_object_def
getObject_def bind_assoc)
apply (clarsimp simp: in_monad split_def bind_def gets_def get_def return_def)
apply (clarsimp simp: assert_def fail_def obj_at_def return_def is_ntfn partial_inv_def)
apply (clarsimp simp: loadObject_default_def in_monad projectKOs
in_magnitude_check objBits_simps')
apply (clarsimp simp add: state_relation_def pspace_relation_def)
apply (drule bspec)
apply blast
apply (simp add: other_obj_relation_def)
done
lemma setObject_ko_wp_at:
fixes v :: "'a :: pspace_storable"
assumes R: "\<And>ko s x y n. (updateObject v ko p y n s)
= (updateObject_default v ko p y n s)"
assumes n: "\<And>v' :: 'a. objBits v' = n"
assumes m: "(1 :: word32) < 2 ^ n"
shows "\<lbrace>\<lambda>s. obj_at' (\<lambda>x :: 'a. True) p s \<longrightarrow>
P (ko_wp_at' (if p = p' then K (P' (injectKO v)) else P')p' s)\<rbrace>
setObject p v
\<lbrace>\<lambda>rv s. P (ko_wp_at' P' p' s)\<rbrace>"
apply (clarsimp simp: setObject_def valid_def in_monad
ko_wp_at'_def split_def
R updateObject_default_def
projectKOs obj_at'_real_def
split del: if_split)
apply (clarsimp simp: project_inject objBits_def[symmetric] n
in_magnitude_check [OF _ m]
elim!: rsubst[where P=P]
split del: if_split)
apply (rule iffI)
apply (clarsimp simp: n ps_clear_upd objBits_def[symmetric]
split: if_split_asm)
apply (clarsimp simp: n project_inject objBits_def[symmetric]
ps_clear_upd
split: if_split_asm)
done
lemma typ_at'_valid_obj'_lift:
assumes P: "\<And>P T p. \<lbrace>\<lambda>s. P (typ_at' T p s)\<rbrace> f \<lbrace>\<lambda>rv s. P (typ_at' T p s)\<rbrace>"
notes [wp] = hoare_vcg_all_lift hoare_vcg_imp_lift hoare_vcg_const_Ball_lift typ_at_lifts [OF P]
shows "\<lbrace>\<lambda>s. valid_obj' obj s\<rbrace> f \<lbrace>\<lambda>rv s. valid_obj' obj s\<rbrace>"
apply (cases obj; simp add: valid_obj'_def hoare_TrueI)
apply (rename_tac endpoint)
apply (case_tac endpoint; simp add: valid_ep'_def, wp)
apply (rename_tac notification)
apply (case_tac "ntfnObj notification";
simp add: valid_ntfn'_def valid_bound_tcb'_def split: option.splits,
(wpsimp|rule conjI)+)
apply (rename_tac tcb)
apply (case_tac "tcbState tcb";
simp add: valid_tcb'_def valid_tcb_state'_def split_def valid_bound_ntfn'_def
split: option.splits,
wpsimp)
apply (wpsimp simp: valid_cte'_def)
apply (rename_tac arch_kernel_object)
apply (case_tac arch_kernel_object; wpsimp)
done
lemmas setObject_valid_obj = typ_at'_valid_obj'_lift [OF setObject_typ_at']
lemma setObject_valid_objs':
assumes x: "\<And>x n ko s ko' s'.
\<lbrakk> (ko', s') \<in> fst (updateObject val ko ptr x n s); P s;
valid_obj' ko s; lookupAround2 ptr (ksPSpace s) = (Some (x, ko), n) \<rbrakk>
\<Longrightarrow> valid_obj' ko' s"
shows "\<lbrace>valid_objs' and P\<rbrace> setObject ptr val \<lbrace>\<lambda>rv. valid_objs'\<rbrace>"
apply (clarsimp simp: valid_def)
apply (subgoal_tac "\<forall>ko. valid_obj' ko s \<longrightarrow> valid_obj' ko b")
defer
apply clarsimp
apply (erule(1) use_valid [OF _ setObject_valid_obj])
apply (clarsimp simp: setObject_def split_def in_monad
lookupAround2_char1)
apply (simp add: valid_objs'_def)
apply clarsimp
apply (drule spec, erule mp)
apply (drule(1) x)
apply (simp add: ranI)
apply (simp add: prod_eqI lookupAround2_char1)
apply (clarsimp elim!: ranE split: if_split_asm simp: ranI)
done
lemma setObject_iflive':
fixes v :: "'a :: pspace_storable"
assumes R: "\<And>ko s x y n. (updateObject v ko ptr y n s)
= (updateObject_default v ko ptr y n s)"
assumes n: "\<And>x :: 'a. objBits x = n"
assumes m: "(1 :: word32) < 2 ^ n"
assumes x: "\<And>x n tcb s t. \<lbrakk> t \<in> fst (updateObject v (KOTCB tcb) ptr x n s); P s;
lookupAround2 ptr (ksPSpace s) = (Some (x, KOTCB tcb), n) \<rbrakk>
\<Longrightarrow> \<exists>tcb'. t = (KOTCB tcb', s) \<and> (\<forall>(getF, setF) \<in> ran tcb_cte_cases. getF tcb' = getF tcb)"
assumes y: "\<And>x n cte s. fst (updateObject v (KOCTE cte) ptr x n s) = {}"
shows "\<lbrace>\<lambda>s. if_live_then_nonz_cap' s \<and> (live' (injectKO v) \<longrightarrow> ex_nonz_cap_to' ptr s) \<and> P s\<rbrace>
setObject ptr v
\<lbrace>\<lambda>rv s. if_live_then_nonz_cap' s\<rbrace>"
unfolding if_live_then_nonz_cap'_def ex_nonz_cap_to'_def
apply (rule hoare_pre)
apply (simp only: imp_conv_disj)
apply (wp hoare_vcg_all_lift hoare_vcg_disj_lift)
apply (rule setObject_ko_wp_at [OF R n m])
apply (rule hoare_vcg_ex_lift)
apply (rule setObject_cte_wp_at'[where Q = P, OF x y])
apply assumption+
apply clarsimp
apply (clarsimp simp: ko_wp_at'_def)
done
lemma setObject_qs[wp]:
assumes x: "\<And>q n obj. \<lbrace>\<lambda>s. P (ksReadyQueues s)\<rbrace> updateObject v obj p q n \<lbrace>\<lambda>rv s. P (ksReadyQueues s)\<rbrace>"
shows "\<lbrace>\<lambda>s. P (ksReadyQueues s)\<rbrace> setObject p v \<lbrace>\<lambda>rv s. P (ksReadyQueues s)\<rbrace>"
apply (simp add: setObject_def split_def)
apply (wp x | simp)+
done
lemma setObject_qsL1[wp]:
assumes x: "\<And>q n obj. \<lbrace>\<lambda>s. P (ksReadyQueuesL1Bitmap s)\<rbrace> updateObject v obj p q n \<lbrace>\<lambda>rv s. P (ksReadyQueuesL1Bitmap s)\<rbrace>"
shows "\<lbrace>\<lambda>s. P (ksReadyQueuesL1Bitmap s)\<rbrace> setObject p v \<lbrace>\<lambda>rv s. P (ksReadyQueuesL1Bitmap s)\<rbrace>"
apply (simp add: setObject_def split_def)
apply (wp x | simp)+
done
lemma setObject_qsL2[wp]:
assumes x: "\<And>q n obj. \<lbrace>\<lambda>s. P (ksReadyQueuesL2Bitmap s)\<rbrace> updateObject v obj p q n \<lbrace>\<lambda>rv s. P (ksReadyQueuesL2Bitmap s)\<rbrace>"
shows "\<lbrace>\<lambda>s. P (ksReadyQueuesL2Bitmap s)\<rbrace> setObject p v \<lbrace>\<lambda>rv s. P (ksReadyQueuesL2Bitmap s)\<rbrace>"
apply (simp add: setObject_def split_def)
apply (wp x | simp)+
done
lemma setObject_ifunsafe':
fixes v :: "'a :: pspace_storable"
assumes x: "\<And>x n tcb s t. \<lbrakk> t \<in> fst (updateObject v (KOTCB tcb) ptr x n s); P s;
lookupAround2 ptr (ksPSpace s) = (Some (x, KOTCB tcb), n) \<rbrakk>
\<Longrightarrow> \<exists>tcb'. t = (KOTCB tcb', s) \<and> (\<forall>(getF, setF) \<in> ran tcb_cte_cases. getF tcb' = getF tcb)"
assumes y: "\<And>x n cte s. fst (updateObject v (KOCTE cte) ptr x n s) = {}"
assumes z: "\<And>P. \<lbrace>\<lambda>s. P (intStateIRQNode (ksInterruptState s))\<rbrace>
setObject ptr v \<lbrace>\<lambda>rv s. P (intStateIRQNode (ksInterruptState s))\<rbrace>"
shows "\<lbrace>\<lambda>s. if_unsafe_then_cap' s \<and> P s\<rbrace>
setObject ptr v
\<lbrace>\<lambda>rv s. if_unsafe_then_cap' s\<rbrace>"
apply (simp only: if_unsafe_then_cap'_def ex_cte_cap_to'_def
cte_wp_at_ctes_of)
apply (rule hoare_use_eq_irq_node' [OF z])
apply (rule setObject_ctes_of [OF x y], assumption+)
done
lemma setObject_it[wp]:
assumes x: "\<And>p q n ko. \<lbrace>\<lambda>s. P (ksIdleThread s)\<rbrace> updateObject val p q n ko \<lbrace>\<lambda>rv s. P (ksIdleThread s)\<rbrace>"
shows "\<lbrace>\<lambda>s. P (ksIdleThread s)\<rbrace> setObject t val \<lbrace>\<lambda>rv s. P (ksIdleThread s)\<rbrace>"
apply (simp add: setObject_def split_def)
apply (wp x | simp)+
done
\<comment>\<open>
`idle_tcb_ps val` asserts that `val` is a pspace_storable value
which corresponds to an idle TCB.
\<close>
definition idle_tcb_ps :: "('a :: pspace_storable) \<Rightarrow> bool" where
"idle_tcb_ps val \<equiv> (\<exists>tcb. projectKO_opt (injectKO val) = Some tcb \<and> idle_tcb' tcb)"
lemma setObject_idle':
fixes v :: "'a :: pspace_storable"
assumes R: "\<And>ko s x y n. (updateObject v ko ptr y n s)
= (updateObject_default v ko ptr y n s)"
assumes n: "\<And>x :: 'a. objBits x = n"
assumes m: "(1 :: word32) < 2 ^ n"
assumes z: "\<And>P p q n ko.
\<lbrace>\<lambda>s. P (ksIdleThread s)\<rbrace> updateObject v p q n ko
\<lbrace>\<lambda>rv s. P (ksIdleThread s)\<rbrace>"
shows "\<lbrace>\<lambda>s. valid_idle' s \<and>
(ptr = ksIdleThread s
\<longrightarrow> (\<exists>val :: 'a. idle_tcb_ps val)
\<longrightarrow> idle_tcb_ps v)\<rbrace>
setObject ptr v
\<lbrace>\<lambda>rv s. valid_idle' s\<rbrace>"
apply (simp add: valid_idle'_def pred_tcb_at'_def o_def)
apply (rule hoare_pre)
apply (rule hoare_lift_Pf2 [where f="ksIdleThread"])
apply (simp add: pred_tcb_at'_def obj_at'_real_def)
apply (rule setObject_ko_wp_at [OF R n m])
apply (wp z)
apply (clarsimp simp add: pred_tcb_at'_def obj_at'_real_def ko_wp_at'_def idle_tcb_ps_def)
apply (clarsimp simp add: project_inject)
apply (drule_tac x=obja in spec, simp)
done
lemma setObject_no_0_obj' [wp]:
"\<lbrace>no_0_obj'\<rbrace> setObject p v \<lbrace>\<lambda>r. no_0_obj'\<rbrace>"
apply (clarsimp simp: setObject_def split_def)
apply (clarsimp simp: valid_def no_0_obj'_def ko_wp_at'_def in_monad
lookupAround2_char1 ps_clear_upd)
done
lemma valid_updateCapDataI:
"s \<turnstile>' c \<Longrightarrow> s \<turnstile>' updateCapData b x c"
apply (unfold updateCapData_def Let_def ARM_H.updateCapData_def)
apply (cases c)
apply (simp_all add: isCap_defs valid_cap'_def capUntypedPtr_def isCap_simps
capAligned_def word_size word_bits_def word_bw_assocs)
done
lemma no_fail_threadGet [wp]:
"no_fail (tcb_at' t) (threadGet f t)"
by (simp add: threadGet_def, wp)
lemma no_fail_getThreadState [wp]:
"no_fail (tcb_at' t) (getThreadState t)"
by (simp add: getThreadState_def, wp)
lemma no_fail_setObject_tcb [wp]:
"no_fail (tcb_at' t) (setObject t (t'::tcb))"
apply (rule no_fail_pre, wp)
apply (rule ext)+
apply simp
apply (simp add: objBits_simps)
done
lemma no_fail_threadSet [wp]:
"no_fail (tcb_at' t) (threadSet f t)"
apply (simp add: threadSet_def)
apply (rule no_fail_pre, wp)
apply simp
done
lemma dmo_return' [simp]:
"doMachineOp (return x) = return x"
apply (simp add: doMachineOp_def select_f_def return_def gets_def get_def
bind_def modify_def put_def)
done
lemma dmo_storeWordVM' [simp]:
"doMachineOp (storeWordVM x y) = return ()"
by (simp add: storeWordVM_def)
declare mapM_x_return [simp]
lemma no_fail_dmo' [wp]:
"no_fail P f \<Longrightarrow> no_fail (P o ksMachineState) (doMachineOp f)"
apply (simp add: doMachineOp_def split_def)
apply (rule no_fail_pre, wp)
apply simp
apply (simp add: no_fail_def)
done
lemma setEndpoint_nosch[wp]:
"\<lbrace>\<lambda>s. P (ksSchedulerAction s)\<rbrace>
setEndpoint val ptr
\<lbrace>\<lambda>rv s. P (ksSchedulerAction s)\<rbrace>"
apply (simp add: setEndpoint_def)
apply (rule setObject_nosch)
apply (simp add: updateObject_default_def)
apply wp
apply simp
done
lemma setNotification_nosch[wp]:
"\<lbrace>\<lambda>s. P (ksSchedulerAction s)\<rbrace>
setNotification val ptr
\<lbrace>\<lambda>rv s. P (ksSchedulerAction s)\<rbrace>"
apply (simp add: setNotification_def)
apply (rule setObject_nosch)
apply (simp add: updateObject_default_def)
apply wp
apply simp
done
lemma set_ep_valid_objs':
"\<lbrace>valid_objs' and valid_ep' ep\<rbrace>
setEndpoint epptr ep
\<lbrace>\<lambda>r s. valid_objs' s\<rbrace>"
apply (simp add: setEndpoint_def)
apply (rule setObject_valid_objs')
apply (clarsimp simp: updateObject_default_def in_monad
projectKOs valid_obj'_def)
done
lemma set_ep_ctes_of[wp]:
"\<lbrace>\<lambda>s. P (ctes_of s)\<rbrace> setEndpoint p val \<lbrace>\<lambda>rv s. P (ctes_of s)\<rbrace>"
apply (simp add: setEndpoint_def)
apply (rule setObject_ctes_of[where Q="\<top>", simplified])
apply (clarsimp simp: updateObject_default_def in_monad
projectKOs)
apply (clarsimp simp: updateObject_default_def bind_def
projectKOs)
done
lemma set_ep_valid_mdb' [wp]:
"\<lbrace>valid_mdb'\<rbrace>
setObject epptr (ep::endpoint)
\<lbrace>\<lambda>_. valid_mdb'\<rbrace>"
apply (simp add: valid_mdb'_def)
apply (rule set_ep_ctes_of[simplified setEndpoint_def])
done
lemma setEndpoint_valid_mdb':
"\<lbrace>valid_mdb'\<rbrace> setEndpoint p v \<lbrace>\<lambda>rv. valid_mdb'\<rbrace>"
unfolding setEndpoint_def
by (rule set_ep_valid_mdb')
lemma set_ep_valid_pspace'[wp]:
"\<lbrace>valid_pspace' and valid_ep' ep\<rbrace>
setEndpoint epptr ep
\<lbrace>\<lambda>r. valid_pspace'\<rbrace>"
apply (simp add: valid_pspace'_def)
apply (wp set_ep_aligned' [simplified] set_ep_valid_objs')
apply (wp hoare_vcg_conj_lift)
apply (simp add: setEndpoint_def)
apply (wp setEndpoint_valid_mdb')+
apply auto
done
lemma set_ep_valid_bitmapQ[wp]:
"\<lbrace>Invariants_H.valid_bitmapQ\<rbrace> setEndpoint epptr ep \<lbrace>\<lambda>rv. Invariants_H.valid_bitmapQ\<rbrace>"
apply (unfold setEndpoint_def)
apply (rule setObject_ep_pre)
apply (simp add: bitmapQ_defs setObject_def split_def)
apply (wp hoare_Ball_helper hoare_vcg_all_lift updateObject_default_inv | simp add: bitmapQ_def)+
done
lemma set_ep_bitmapQ_no_L1_orphans[wp]:
"\<lbrace> bitmapQ_no_L1_orphans \<rbrace> setEndpoint epptr ep \<lbrace>\<lambda>rv. bitmapQ_no_L1_orphans \<rbrace>"
apply (unfold setEndpoint_def)
apply (rule setObject_ep_pre)
apply (simp add: bitmapQ_defs setObject_def split_def)
apply (wp hoare_Ball_helper hoare_vcg_all_lift updateObject_default_inv | simp add: bitmapQ_def)+
done
lemma set_ep_bitmapQ_no_L2_orphans[wp]:
"\<lbrace> bitmapQ_no_L2_orphans \<rbrace> setEndpoint epptr ep \<lbrace>\<lambda>rv. bitmapQ_no_L2_orphans \<rbrace>"
apply (unfold setEndpoint_def)
apply (rule setObject_ep_pre)
apply (simp add: bitmapQ_defs setObject_def split_def)
apply (wp hoare_Ball_helper hoare_vcg_all_lift updateObject_default_inv | simp add: bitmapQ_def)+
done
lemma set_ep_valid_queues[wp]:
"\<lbrace>Invariants_H.valid_queues\<rbrace> setEndpoint epptr ep \<lbrace>\<lambda>rv. Invariants_H.valid_queues\<rbrace>"
apply (simp add: Invariants_H.valid_queues_def)
apply (wp hoare_vcg_conj_lift)
apply (simp add: setEndpoint_def valid_queues_no_bitmap_def)
apply (wp hoare_Ball_helper hoare_vcg_all_lift)
apply (rule obj_at_setObject2)
apply (clarsimp simp: updateObject_default_def in_monad)
apply (wp updateObject_default_inv set_ep_valid_bitmapQ[unfolded setEndpoint_def]
| simp add: valid_queues_no_bitmap_def)+
done
lemma set_ep_valid_queues'[wp]:
"\<lbrace>valid_queues'\<rbrace> setEndpoint epptr ep \<lbrace>\<lambda>rv. valid_queues'\<rbrace>"
apply (unfold setEndpoint_def)
apply (simp only: valid_queues'_def imp_conv_disj
obj_at'_real_def)
apply (wp hoare_vcg_all_lift hoare_vcg_disj_lift)
apply (rule setObject_ko_wp_at)
apply simp
apply (simp add: objBits_simps')
apply simp
apply (wp updateObject_default_inv | simp)+
apply (clarsimp simp: projectKOs ko_wp_at'_def)
done
lemma ct_in_state_thread_state_lift':
assumes ct: "\<And>P. \<lbrace>\<lambda>s. P (ksCurThread s)\<rbrace> f \<lbrace>\<lambda>_ s. P (ksCurThread s)\<rbrace>"
assumes st: "\<And>t. \<lbrace>st_tcb_at' P t\<rbrace> f \<lbrace>\<lambda>_. st_tcb_at' P t\<rbrace>"
shows "\<lbrace>ct_in_state' P\<rbrace> f \<lbrace>\<lambda>_. ct_in_state' P\<rbrace>"
apply (clarsimp simp: ct_in_state'_def)
apply (clarsimp simp: valid_def)
apply (frule (1) use_valid [OF _ ct])
apply (drule (1) use_valid [OF _ st], assumption)
done
lemma sch_act_wf_lift:
assumes tcb: "\<And>P t. \<lbrace>st_tcb_at' P t\<rbrace> f \<lbrace>\<lambda>rv. st_tcb_at' P t\<rbrace>"
assumes tcb_cd: "\<And>P t. \<lbrace> tcb_in_cur_domain' t\<rbrace> f \<lbrace>\<lambda>_ . tcb_in_cur_domain' t \<rbrace>"
assumes kCT: "\<And>P. \<lbrace>\<lambda>s. P (ksCurThread s)\<rbrace> f \<lbrace>\<lambda>_ s. P (ksCurThread s)\<rbrace>"
assumes ksA: "\<And>P. \<lbrace>\<lambda>s. P (ksSchedulerAction s)\<rbrace> f \<lbrace>\<lambda>_ s. P (ksSchedulerAction s)\<rbrace>"
shows
"\<lbrace>\<lambda>s. sch_act_wf (ksSchedulerAction s) s\<rbrace>
f
\<lbrace>\<lambda>rv s. sch_act_wf (ksSchedulerAction s) s\<rbrace>"
apply (clarsimp simp: valid_def)
apply (frule (1) use_valid [OF _ ksA])
apply (case_tac "ksSchedulerAction b", simp_all)
apply (drule (2) use_valid [OF _ ct_in_state_thread_state_lift' [OF kCT tcb]])
apply (clarsimp)
apply (rule conjI)
apply (drule (2) use_valid [OF _ tcb])
apply (drule (2) use_valid [OF _ tcb_cd])
done
lemma tcb_in_cur_domain'_lift:
assumes a: "\<And>P. \<lbrace>\<lambda>s. P (ksCurDomain s)\<rbrace> f \<lbrace>\<lambda>_ s. P (ksCurDomain s)\<rbrace>"
assumes b: "\<And>x. \<lbrace>obj_at' (\<lambda>tcb. x = tcbDomain tcb) t\<rbrace> f \<lbrace>\<lambda>_. obj_at' (\<lambda>tcb. x = tcbDomain tcb) t\<rbrace>"
shows "\<lbrace> tcb_in_cur_domain' t \<rbrace> f \<lbrace> \<lambda>_. tcb_in_cur_domain' t \<rbrace>"
apply (simp add: tcb_in_cur_domain'_def)
apply (rule_tac f="ksCurDomain" in hoare_lift_Pf)
apply (rule b)
apply (rule a)
done
lemma ct_idle_or_in_cur_domain'_lift:
assumes a: "\<And>P. \<lbrace>\<lambda>s. P (ksCurDomain s)\<rbrace> f \<lbrace>\<lambda>_ s. P (ksCurDomain s)\<rbrace>"
assumes b: "\<And>P. \<lbrace>\<lambda>s. P (ksSchedulerAction s)\<rbrace> f \<lbrace>\<lambda>_ s. P (ksSchedulerAction s)\<rbrace>"
assumes c: "\<And>P. \<lbrace>\<lambda>s. P (ksIdleThread s)\<rbrace> f \<lbrace>\<lambda>_ s. P (ksIdleThread s)\<rbrace>"
assumes d: "\<And>P. \<lbrace>\<lambda>s. P (ksCurThread s)\<rbrace> f \<lbrace>\<lambda>_ s. P (ksCurThread s)\<rbrace>"
assumes e: "\<And>d a t t'. \<lbrace>\<lambda>s. t = t' \<or> obj_at' (\<lambda>tcb. d = tcbDomain tcb) t s\<rbrace>
f
\<lbrace>\<lambda>_ s. t = t' \<or> obj_at' (\<lambda>tcb. d = tcbDomain tcb) t s\<rbrace>"
shows "\<lbrace> ct_idle_or_in_cur_domain' \<rbrace> f \<lbrace> \<lambda>_. ct_idle_or_in_cur_domain' \<rbrace>"
apply (simp add: ct_idle_or_in_cur_domain'_def tcb_in_cur_domain'_def)
apply (rule_tac f="ksCurThread" in hoare_lift_Pf)
apply (rule_tac f="ksIdleThread" in hoare_lift_Pf)
apply (rule_tac f="ksSchedulerAction" in hoare_lift_Pf)
apply (rule_tac f="ksCurDomain" in hoare_lift_Pf)
apply (wp hoare_vcg_imp_lift)
apply (rule e)
apply simp
apply (rule a)
apply (rule b)
apply (rule c)
apply (rule d)
done
lemma setObject_ep_obj_at'_tcb[wp]:
"\<lbrace>obj_at' (P :: tcb \<Rightarrow> bool) t \<rbrace> setObject ptr (e::endpoint) \<lbrace>\<lambda>_. obj_at' (P :: tcb \<Rightarrow> bool) t\<rbrace>"
apply (rule obj_at_setObject2)
apply (clarsimp simp: updateObject_default_def in_monad)
done
lemma setObject_ep_cur_domain[wp]:
"\<lbrace>\<lambda>s. P (ksCurDomain s)\<rbrace> setObject ptr (e::endpoint) \<lbrace>\<lambda>_ s. P (ksCurDomain s)\<rbrace>"
apply (simp add: setObject_def split_def)
apply (wp updateObject_default_inv | simp)+
done
lemma setEndpoint_tcb_in_cur_domain'[wp]:
"\<lbrace>tcb_in_cur_domain' t\<rbrace> setEndpoint epptr ep \<lbrace>\<lambda>_. tcb_in_cur_domain' t\<rbrace>"
apply (clarsimp simp: setEndpoint_def)
apply (rule tcb_in_cur_domain'_lift; wp)
done
lemma setEndpoint_obj_at'_tcb[wp]:
"\<lbrace>obj_at' (P :: tcb \<Rightarrow> bool) t \<rbrace> setEndpoint ptr (e::endpoint) \<lbrace>\<lambda>_. obj_at' (P :: tcb \<Rightarrow> bool) t\<rbrace>"
by (clarsimp simp: setEndpoint_def, wp)
lemma set_ep_sch_act_wf[wp]:
"\<lbrace>\<lambda>s. sch_act_wf (ksSchedulerAction s) s\<rbrace>
setEndpoint epptr ep
\<lbrace>\<lambda>rv s. sch_act_wf (ksSchedulerAction s) s\<rbrace>"
apply (wp sch_act_wf_lift)
apply (simp add: setEndpoint_def split_def setObject_def
| wp updateObject_default_inv)+
done
lemma setObject_state_refs_of':
assumes x: "updateObject val = updateObject_default val"
assumes y: "(1 :: word32) < 2 ^ objBits val"
shows
"\<lbrace>\<lambda>s. P ((state_refs_of' s) (ptr := refs_of' (injectKO val)))\<rbrace>
setObject ptr val
\<lbrace>\<lambda>rv s. P (state_refs_of' s)\<rbrace>"
apply (clarsimp simp: setObject_def valid_def in_monad split_def
updateObject_default_def x in_magnitude_check
projectKOs y
elim!: rsubst[where P=P] intro!: ext
split del: if_split cong: option.case_cong if_cong)
apply (clarsimp simp: state_refs_of'_def objBits_def[symmetric]
ps_clear_upd
cong: if_cong option.case_cong)
done
lemma setObject_state_refs_of_eq:
assumes x: "\<And>s s' obj obj' ptr' ptr''.
(obj', s') \<in> fst (updateObject val obj ptr ptr' ptr'' s)
\<Longrightarrow> refs_of' obj' = refs_of' obj"
shows
"\<lbrace>\<lambda>s. P (state_refs_of' s)\<rbrace>
setObject ptr val
\<lbrace>\<lambda>rv s. P (state_refs_of' s)\<rbrace>"
apply (clarsimp simp: setObject_def valid_def in_monad split_def
updateObject_default_def in_magnitude_check
projectKOs lookupAround2_char1
elim!: rsubst[where P=P] intro!: ext
split del: if_split cong: option.case_cong if_cong)
apply (frule x, drule updateObject_objBitsKO)
apply (simp add: state_refs_of'_def ps_clear_upd
cong: option.case_cong if_cong)
done
lemma set_ep_state_refs_of'[wp]:
"\<lbrace>\<lambda>s. P ((state_refs_of' s) (epptr := ep_q_refs_of' ep))\<rbrace>
setEndpoint epptr ep
\<lbrace>\<lambda>rv s. P (state_refs_of' s)\<rbrace>"
unfolding setEndpoint_def
by (wp setObject_state_refs_of',
simp_all add: objBits_simps' fun_upd_def[symmetric])
lemma set_ntfn_ctes_of[wp]:
"\<lbrace>\<lambda>s. P (ctes_of s)\<rbrace> setNotification p val \<lbrace>\<lambda>rv s. P (ctes_of s)\<rbrace>"
apply (simp add: setNotification_def)
apply (rule setObject_ctes_of[where Q="\<top>", simplified])
apply (clarsimp simp: updateObject_default_def in_monad
projectKOs)
apply (clarsimp simp: updateObject_default_def bind_def
projectKOs)
done
lemma set_ntfn_valid_mdb' [wp]:
"\<lbrace>valid_mdb'\<rbrace>
setObject epptr (ntfn::Structures_H.notification)
\<lbrace>\<lambda>_. valid_mdb'\<rbrace>"
apply (simp add: valid_mdb'_def)
apply (rule set_ntfn_ctes_of[simplified setNotification_def])
done
lemma set_ntfn_valid_objs':
"\<lbrace>valid_objs' and valid_ntfn' ntfn\<rbrace>
setNotification p ntfn
\<lbrace>\<lambda>r s. valid_objs' s\<rbrace>"
apply (simp add: setNotification_def)
apply (rule setObject_valid_objs')
apply (clarsimp simp: updateObject_default_def in_monad
valid_obj'_def)
done
lemma set_ntfn_valid_pspace'[wp]:
"\<lbrace>valid_pspace' and valid_ntfn' ntfn\<rbrace>
setNotification p ntfn
\<lbrace>\<lambda>r. valid_pspace'\<rbrace>"
apply (simp add: valid_pspace'_def)
apply (wp set_ntfn_aligned' [simplified] set_ntfn_valid_objs')
apply (simp add: setNotification_def,wp)
apply auto
done
lemma set_ntfn_valid_bitmapQ[wp]:
"\<lbrace>Invariants_H.valid_bitmapQ\<rbrace> setNotification p ntfn \<lbrace>\<lambda>rv. Invariants_H.valid_bitmapQ\<rbrace>"
apply (unfold setNotification_def)
apply (rule setObject_ntfn_pre)
apply (simp add: bitmapQ_defs setObject_def split_def)
apply (wp hoare_Ball_helper hoare_vcg_all_lift updateObject_default_inv | simp)+
done
lemma set_ntfn_bitmapQ_no_L1_orphans[wp]:
"\<lbrace> bitmapQ_no_L1_orphans \<rbrace> setNotification p ntfn \<lbrace>\<lambda>rv. bitmapQ_no_L1_orphans \<rbrace>"
apply (unfold setNotification_def)
apply (rule setObject_ntfn_pre)
apply (simp add: bitmapQ_defs setObject_def split_def)
apply (wp hoare_Ball_helper hoare_vcg_all_lift updateObject_default_inv | simp)+
done
lemma set_ntfn_bitmapQ_no_L2_orphans[wp]:
"\<lbrace> bitmapQ_no_L2_orphans \<rbrace> setNotification p ntfn \<lbrace>\<lambda>rv. bitmapQ_no_L2_orphans \<rbrace>"
apply (unfold setNotification_def)
apply (rule setObject_ntfn_pre)
apply (simp add: bitmapQ_defs setObject_def split_def)
apply (wp hoare_Ball_helper hoare_vcg_all_lift updateObject_default_inv | simp)+
done
lemma set_ntfn_valid_queues[wp]:
"\<lbrace>Invariants_H.valid_queues\<rbrace> setNotification p ntfn \<lbrace>\<lambda>rv. Invariants_H.valid_queues\<rbrace>"
apply (simp add: Invariants_H.valid_queues_def)
apply (rule hoare_pre)
apply (wp hoare_vcg_conj_lift)
apply (simp add: setNotification_def valid_queues_no_bitmap_def)
apply (wp hoare_Ball_helper hoare_vcg_all_lift)
apply (rule obj_at_setObject2)
apply (clarsimp simp: updateObject_default_def in_monad)
apply (wp updateObject_default_inv set_ep_valid_bitmapQ[unfolded setEndpoint_def]
| simp add: valid_queues_no_bitmap_def)+
done
lemma set_ntfn_valid_queues'[wp]:
"\<lbrace>valid_queues'\<rbrace> setNotification p ntfn \<lbrace>\<lambda>rv. valid_queues'\<rbrace>"
apply (unfold setNotification_def)
apply (rule setObject_ntfn_pre)
apply (simp only: valid_queues'_def imp_conv_disj
obj_at'_real_def)
apply (wp hoare_vcg_all_lift hoare_vcg_disj_lift)
apply (rule setObject_ko_wp_at)
apply simp
apply (simp add: objBits_simps')
apply simp
apply (wp updateObject_default_inv | simp)+
apply (clarsimp simp: projectKOs ko_wp_at'_def)
done
lemma set_ntfn_state_refs_of'[wp]:
"\<lbrace>\<lambda>s. P ((state_refs_of' s) (epptr := ntfn_q_refs_of' (ntfnObj ntfn)
\<union> ntfn_bound_refs' (ntfnBoundTCB ntfn)))\<rbrace>
setNotification epptr ntfn
\<lbrace>\<lambda>rv s. P (state_refs_of' s)\<rbrace>"
unfolding setNotification_def
by (wp setObject_state_refs_of',
simp_all add: objBits_simps' fun_upd_def)
lemma setNotification_pred_tcb_at'[wp]:
"\<lbrace>pred_tcb_at' proj P t\<rbrace> setNotification ptr val \<lbrace>\<lambda>rv. pred_tcb_at' proj P t\<rbrace>"
apply (simp add: pred_tcb_at'_def setNotification_def)
apply (rule obj_at_setObject2)
apply simp
apply (clarsimp simp: updateObject_default_def in_monad)
done
lemma setObject_ntfn_cur_domain[wp]:
"\<lbrace> \<lambda>s. P (ksCurDomain s) \<rbrace> setObject ptr (ntfn::Structures_H.notification) \<lbrace> \<lambda>_s . P (ksCurDomain s) \<rbrace>"
apply (clarsimp simp: setObject_def split_def)
apply (wp updateObject_default_inv | simp)+
done
lemma setObject_ntfn_obj_at'_tcb[wp]:
"\<lbrace>obj_at' (P :: tcb \<Rightarrow> bool) t \<rbrace> setObject ptr (ntfn::Structures_H.notification) \<lbrace>\<lambda>_. obj_at' (P :: tcb \<Rightarrow> bool) t\<rbrace>"
apply (rule obj_at_setObject2)
apply (clarsimp simp: updateObject_default_def in_monad)
done
lemma setNotification_ksCurDomain[wp]:
"\<lbrace> \<lambda>s. P (ksCurDomain s) \<rbrace> setNotification ptr (ntfn::Structures_H.notification) \<lbrace> \<lambda>_s . P (ksCurDomain s) \<rbrace>"
apply (simp add: setNotification_def)
apply wp
done
lemma setNotification_tcb_in_cur_domain'[wp]:
"\<lbrace>tcb_in_cur_domain' t\<rbrace> setNotification epptr ep \<lbrace>\<lambda>_. tcb_in_cur_domain' t\<rbrace>"
apply (clarsimp simp: setNotification_def)
apply (rule tcb_in_cur_domain'_lift; wp)
done
lemma set_ntfn_sch_act_wf[wp]:
"\<lbrace>\<lambda>s. sch_act_wf (ksSchedulerAction s) s\<rbrace>
setNotification ntfnptr ntfn
\<lbrace>\<lambda>rv s. sch_act_wf (ksSchedulerAction s) s\<rbrace>"
apply (wp sch_act_wf_lift | clarsimp simp: setNotification_def)+
apply (simp add: setNotification_def split_def setObject_def
| wp updateObject_default_inv)+
done
lemmas cur_tcb_lift =
hoare_lift_Pf [where f = ksCurThread and P = tcb_at', folded cur_tcb'_def]
lemma set_ntfn_cur_tcb'[wp]:
"\<lbrace>cur_tcb'\<rbrace> setNotification ptr ntfn \<lbrace>\<lambda>rv. cur_tcb'\<rbrace>"
apply (wp cur_tcb_lift)
apply (simp add: setNotification_def setObject_def split_def)
apply (wp updateObject_default_inv | simp)+
done
lemma setEndpoint_typ_at'[wp]:
"\<lbrace>\<lambda>s. P (typ_at' T p s)\<rbrace> setEndpoint ptr val \<lbrace>\<lambda>rv s. P (typ_at' T p s)\<rbrace>"
unfolding setEndpoint_def
by (rule setObject_typ_at')
lemmas setEndpoint_typ_ats[wp] = typ_at_lifts [OF setEndpoint_typ_at']
lemma get_ep_sp':
"\<lbrace>P\<rbrace> getEndpoint r \<lbrace>\<lambda>t. P and ko_at' t r\<rbrace>"
by (clarsimp simp: getEndpoint_def getObject_def loadObject_default_def
projectKOs in_monad valid_def obj_at'_def objBits_simps'
in_magnitude_check split_def)
lemma setEndpoint_cur_tcb'[wp]:
"\<lbrace>cur_tcb'\<rbrace> setEndpoint p v \<lbrace>\<lambda>rv. cur_tcb'\<rbrace>"
apply (wp cur_tcb_lift)
apply (simp add: setEndpoint_def setObject_def split_def)
apply (wp updateObject_default_inv | simp)+
done
lemma setEndpoint_iflive'[wp]:
"\<lbrace>\<lambda>s. if_live_then_nonz_cap' s
\<and> (v \<noteq> IdleEP \<longrightarrow> ex_nonz_cap_to' p s)\<rbrace>
setEndpoint p v
\<lbrace>\<lambda>rv. if_live_then_nonz_cap'\<rbrace>"
unfolding setEndpoint_def
apply (wp setObject_iflive'[where P="\<top>"])
apply simp
apply (simp add: objBits_simps')
apply simp
apply (clarsimp simp: updateObject_default_def in_monad projectKOs)
apply (clarsimp simp: updateObject_default_def in_monad
projectKOs bind_def)
apply clarsimp
done
declare setEndpoint_cte_wp_at'[wp]
lemma ex_nonz_cap_to_pres':
assumes y: "\<And>P p. \<lbrace>cte_wp_at' P p\<rbrace> f \<lbrace>\<lambda>rv. cte_wp_at' P p\<rbrace>"
shows "\<lbrace>ex_nonz_cap_to' p\<rbrace> f \<lbrace>\<lambda>rv. ex_nonz_cap_to' p\<rbrace>"
apply (simp only: ex_nonz_cap_to'_def)
apply (intro hoare_vcg_disj_lift hoare_vcg_ex_lift
y hoare_vcg_all_lift)
done
lemma setEndpoint_cap_to'[wp]:
"\<lbrace>ex_nonz_cap_to' p\<rbrace> setEndpoint p' v \<lbrace>\<lambda>rv. ex_nonz_cap_to' p\<rbrace>"
by (wp ex_nonz_cap_to_pres')
lemma setEndpoint_ifunsafe'[wp]:
"\<lbrace>if_unsafe_then_cap'\<rbrace> setEndpoint p v \<lbrace>\<lambda>rv. if_unsafe_then_cap'\<rbrace>"
unfolding setEndpoint_def
apply (rule setObject_ifunsafe'[where P="\<top>", simplified])
apply (clarsimp simp: updateObject_default_def in_monad projectKOs
intro!: equals0I)+
apply (simp add: setObject_def split_def)
apply (wp updateObject_default_inv | simp)+
done
lemma setEndpoint_idle'[wp]:
"\<lbrace>\<lambda>s. valid_idle' s\<rbrace>
setEndpoint p v
\<lbrace>\<lambda>_. valid_idle'\<rbrace>"
unfolding setEndpoint_def
apply (wp setObject_idle')
apply (simp add: objBits_simps' updateObject_default_inv)+
apply (clarsimp simp: projectKOs idle_tcb_ps_def)
done
crunch it[wp]: setEndpoint "\<lambda>s. P (ksIdleThread s)"
(simp: updateObject_default_inv)
lemma setObject_ksPSpace_only:
"\<lbrakk> \<And>p q n ko. \<lbrace>P\<rbrace> updateObject val p q n ko \<lbrace>\<lambda>rv. P \<rbrace>;
\<And>f s. P (ksPSpace_update f s) = P s \<rbrakk>
\<Longrightarrow> \<lbrace>P\<rbrace> setObject ptr val \<lbrace>\<lambda>rv. P\<rbrace>"
apply (simp add: setObject_def split_def)
apply (wp | simp | assumption)+
done
lemma setObject_ksMachine:
"\<lbrakk> \<And>p q n ko. \<lbrace>\<lambda>s. P (ksMachineState s)\<rbrace> updateObject val p q n ko \<lbrace>\<lambda>rv s. P (ksMachineState s)\<rbrace> \<rbrakk>
\<Longrightarrow> \<lbrace>\<lambda>s. P (ksMachineState s)\<rbrace> setObject ptr val \<lbrace>\<lambda>rv s. P (ksMachineState s)\<rbrace>"
by (simp add: setObject_ksPSpace_only)
lemma setObject_ksInterrupt:
"\<lbrakk> \<And>p q n ko. \<lbrace>\<lambda>s. P (ksInterruptState s)\<rbrace> updateObject val p q n ko \<lbrace>\<lambda>rv s. P (ksInterruptState s)\<rbrace> \<rbrakk>
\<Longrightarrow> \<lbrace>\<lambda>s. P (ksInterruptState s)\<rbrace> setObject ptr val \<lbrace>\<lambda>rv s. P (ksInterruptState s)\<rbrace>"
by (simp add: setObject_ksPSpace_only)
lemma valid_irq_handlers_lift':
assumes x: "\<And>P. \<lbrace>\<lambda>s. P (cteCaps_of s)\<rbrace> f \<lbrace>\<lambda>rv s. P (cteCaps_of s)\<rbrace>"
assumes y: "\<And>P. \<lbrace>\<lambda>s. P (ksInterruptState s)\<rbrace> f \<lbrace>\<lambda>rv s. P (ksInterruptState s)\<rbrace>"
shows "\<lbrace>valid_irq_handlers'\<rbrace> f \<lbrace>\<lambda>rv. valid_irq_handlers'\<rbrace>"
apply (simp add: valid_irq_handlers'_def irq_issued'_def)
apply (rule hoare_use_eq [where f=cteCaps_of, OF x y])
done
lemmas valid_irq_handlers_lift'' = valid_irq_handlers_lift' [unfolded cteCaps_of_def]
crunch ksInterruptState[wp]: setEndpoint "\<lambda>s. P (ksInterruptState s)"
(wp: setObject_ksInterrupt updateObject_default_inv)
lemmas setEndpoint_irq_handlers[wp]
= valid_irq_handlers_lift'' [OF set_ep_ctes_of setEndpoint_ksInterruptState]
declare set_ep_arch' [wp]
lemma set_ep_maxObj [wp]:
"\<lbrace>\<lambda>s. P (gsMaxObjectSize s)\<rbrace> setEndpoint ptr val \<lbrace>\<lambda>rv s. P (gsMaxObjectSize s)\<rbrace>"
by (simp add: setEndpoint_def | wp setObject_ksPSpace_only updateObject_default_inv)+
lemma valid_global_refs_lift':
assumes ctes: "\<And>P. \<lbrace>\<lambda>s. P (ctes_of s)\<rbrace> f \<lbrace>\<lambda>_ s. P (ctes_of s)\<rbrace>"
assumes arch: "\<And>P. \<lbrace>\<lambda>s. P (ksArchState s)\<rbrace> f \<lbrace>\<lambda>_ s. P (ksArchState s)\<rbrace>"
assumes idle: "\<And>P. \<lbrace>\<lambda>s. P (ksIdleThread s)\<rbrace> f \<lbrace>\<lambda>_ s. P (ksIdleThread s)\<rbrace>"
assumes irqn: "\<And>P. \<lbrace>\<lambda>s. P (irq_node' s)\<rbrace> f \<lbrace>\<lambda>_ s. P (irq_node' s)\<rbrace>"
assumes maxObj: "\<And>P. \<lbrace>\<lambda>s. P (gsMaxObjectSize s)\<rbrace> f \<lbrace>\<lambda>_ s. P (gsMaxObjectSize s)\<rbrace>"
shows "\<lbrace>valid_global_refs'\<rbrace> f \<lbrace>\<lambda>_. valid_global_refs'\<rbrace>"
apply (simp add: valid_global_refs'_def valid_refs'_def global_refs'_def valid_cap_sizes'_def)
apply (rule hoare_lift_Pf [where f="ksArchState"])
apply (rule hoare_lift_Pf [where f="ksIdleThread"])
apply (rule hoare_lift_Pf [where f="irq_node'"])
apply (rule hoare_lift_Pf [where f="gsMaxObjectSize"])
apply (wp ctes hoare_vcg_const_Ball_lift arch idle irqn maxObj)+
done
lemma valid_arch_state_lift':
assumes typs: "\<And>T p P. \<lbrace>\<lambda>s. P (typ_at' T p s)\<rbrace> f \<lbrace>\<lambda>_ s. P (typ_at' T p s)\<rbrace>"
assumes arch: "\<And>P. \<lbrace>\<lambda>s. P (ksArchState s)\<rbrace> f \<lbrace>\<lambda>_ s. P (ksArchState s)\<rbrace>"
shows "\<lbrace>valid_arch_state'\<rbrace> f \<lbrace>\<lambda>_. valid_arch_state'\<rbrace>"
apply (simp add: valid_arch_state'_def valid_asid_table'_def
valid_global_pts'_def page_directory_at'_def
page_table_at'_def
All_less_Ball)
apply (rule hoare_lift_Pf [where f="ksArchState"])
apply (wp typs hoare_vcg_const_Ball_lift arch typ_at_lifts)+
done
lemma setObject_ep_ct:
"\<lbrace>\<lambda>s. P (ksCurThread s)\<rbrace> setObject p (e::endpoint) \<lbrace>\<lambda>_ s. P (ksCurThread s)\<rbrace>"
apply (simp add: setObject_def updateObject_ep_eta split_def)
apply (wp updateObject_default_inv | simp)+
done
lemma setObject_ntfn_ct:
"\<lbrace>\<lambda>s. P (ksCurThread s)\<rbrace> setObject p (e::Structures_H.notification)
\<lbrace>\<lambda>_ s. P (ksCurThread s)\<rbrace>"
apply (simp add: setObject_def split_def)
apply (wp updateObject_default_inv | simp)+
done
lemma get_ntfn_sp':
"\<lbrace>P\<rbrace> getNotification r \<lbrace>\<lambda>t. P and ko_at' t r\<rbrace>"
by (clarsimp simp: getNotification_def getObject_def loadObject_default_def
projectKOs in_monad valid_def obj_at'_def objBits_simps'
in_magnitude_check split_def)
lemma set_ntfn_pred_tcb_at' [wp]:
"\<lbrace> pred_tcb_at' proj P t \<rbrace>
setNotification ep v
\<lbrace> \<lambda>rv. pred_tcb_at' proj P t \<rbrace>"
apply (simp add: setNotification_def pred_tcb_at'_def)
apply (rule obj_at_setObject2)
apply (clarsimp simp add: updateObject_default_def in_monad)
done
lemma set_ntfn_iflive'[wp]:
"\<lbrace>\<lambda>s. if_live_then_nonz_cap' s
\<and> (live' (KONotification v) \<longrightarrow> ex_nonz_cap_to' p s)\<rbrace>
setNotification p v
\<lbrace>\<lambda>rv. if_live_then_nonz_cap'\<rbrace>"
apply (simp add: setNotification_def)
apply (wp setObject_iflive'[where P="\<top>"])
apply simp
apply (simp add: objBits_simps)
apply (simp add: objBits_simps')
apply (clarsimp simp: updateObject_default_def in_monad projectKOs)
apply (clarsimp simp: updateObject_default_def
projectKOs bind_def)
apply clarsimp
done
declare setNotification_cte_wp_at'[wp]
lemma set_ntfn_cap_to'[wp]:
"\<lbrace>ex_nonz_cap_to' p\<rbrace> setNotification p' v \<lbrace>\<lambda>rv. ex_nonz_cap_to' p\<rbrace>"
by (wp ex_nonz_cap_to_pres')
lemma setNotification_ifunsafe'[wp]:
"\<lbrace>if_unsafe_then_cap'\<rbrace> setNotification p v \<lbrace>\<lambda>rv. if_unsafe_then_cap'\<rbrace>"
unfolding setNotification_def
apply (rule setObject_ifunsafe'[where P="\<top>", simplified])
apply (clarsimp simp: updateObject_default_def in_monad projectKOs
intro!: equals0I)+
apply (simp add: setObject_def split_def)
apply (wp updateObject_default_inv | simp)+
done
lemma setNotification_idle'[wp]:
"\<lbrace>\<lambda>s. valid_idle' s\<rbrace> setNotification p v \<lbrace>\<lambda>rv. valid_idle'\<rbrace>"
unfolding setNotification_def
apply (wp setObject_idle')
apply (simp add: objBits_simps' updateObject_default_inv)+
apply (clarsimp simp: projectKOs idle_tcb_ps_def)
done
crunch it[wp]: setNotification "\<lambda>s. P (ksIdleThread s)"
(wp: updateObject_default_inv)
lemma set_ntfn_arch' [wp]:
"\<lbrace>\<lambda>s. P (ksArchState s)\<rbrace> setNotification ntfn p \<lbrace>\<lambda>_ s. P (ksArchState s)\<rbrace>"
apply (simp add: setNotification_def setObject_def split_def)
apply (wp updateObject_default_inv|simp)+
done
lemma set_ntfn_ksInterrupt[wp]:
"\<lbrace>\<lambda>s. P (ksInterruptState s)\<rbrace> setNotification ptr val \<lbrace>\<lambda>rv s. P (ksInterruptState s)\<rbrace>"
by (simp add: setNotification_def | wp setObject_ksInterrupt updateObject_default_inv)+
lemma set_ntfn_ksMachine[wp]:
"\<lbrace>\<lambda>s. P (ksMachineState s)\<rbrace> setNotification ptr val \<lbrace>\<lambda>rv s. P (ksMachineState s)\<rbrace>"
by (simp add: setNotification_def | wp setObject_ksMachine updateObject_default_inv)+
lemma set_ntfn_maxObj [wp]:
"\<lbrace>\<lambda>s. P (gsMaxObjectSize s)\<rbrace> setNotification ptr val \<lbrace>\<lambda>rv s. P (gsMaxObjectSize s)\<rbrace>"
by (simp add: setNotification_def | wp setObject_ksPSpace_only updateObject_default_inv)+
lemma set_ntfn_global_refs' [wp]:
"\<lbrace>valid_global_refs'\<rbrace> setNotification ptr val \<lbrace>\<lambda>_. valid_global_refs'\<rbrace>"
by (rule valid_global_refs_lift'; wp)
crunch typ_at' [wp]: setNotification "\<lambda>s. P (typ_at' T p s)"
lemma set_ntfn_valid_arch' [wp]:
"\<lbrace>valid_arch_state'\<rbrace> setNotification ptr val \<lbrace>\<lambda>_. valid_arch_state'\<rbrace>"
by (rule valid_arch_state_lift'; wp)
lemmas valid_irq_node_lift =
hoare_use_eq_irq_node' [OF _ typ_at_lift_valid_irq_node']
lemmas untyped_ranges_zero_lift
= hoare_use_eq[where f="gsUntypedZeroRanges"
and Q="\<lambda>v s. untyped_ranges_zero_inv (f s) v" for f]
lemma valid_irq_states_lift':
assumes x: "\<And>P. \<lbrace>\<lambda>s. P (intStateIRQTable (ksInterruptState s))\<rbrace> f \<lbrace>\<lambda>rv s. P (intStateIRQTable (ksInterruptState s))\<rbrace>"
assumes y: "\<And>P. \<lbrace>\<lambda>s. P (irq_masks (ksMachineState s))\<rbrace> f \<lbrace>\<lambda>rv s. P (irq_masks (ksMachineState s))\<rbrace>"
shows "\<lbrace>valid_irq_states'\<rbrace> f \<lbrace>\<lambda>rv. valid_irq_states'\<rbrace>"
apply (rule hoare_use_eq [where f="\<lambda>s. irq_masks (ksMachineState s)"], rule y)
apply (rule hoare_use_eq [where f="\<lambda>s. intStateIRQTable (ksInterruptState s)"], rule x)
apply wp
done
lemmas set_ntfn_irq_handlers'[wp] = valid_irq_handlers_lift'' [OF set_ntfn_ctes_of set_ntfn_ksInterrupt]
lemmas set_ntfn_irq_states' [wp] = valid_irq_states_lift' [OF set_ntfn_ksInterrupt set_ntfn_ksMachine]
lemma valid_pde_mappings'_def2:
"valid_pde_mappings' =
(\<lambda>s. \<forall>x. pde_at' x s \<longrightarrow> obj_at' (valid_pde_mapping' (x && mask pdBits)) x s)"
apply (clarsimp simp: valid_pde_mappings'_def typ_at_to_obj_at_arches)
apply (rule ext, rule iff_allI)
apply (clarsimp simp: obj_at'_def projectKOs)
apply (auto simp add: objBits_simps archObjSize_def)
done
lemma valid_pde_mappings_lift':
assumes x: "\<And>P T p. \<lbrace>\<lambda>s. P (typ_at' T p s)\<rbrace> f \<lbrace>\<lambda>rv s. P (typ_at' T p s)\<rbrace>"
assumes y: "\<And>x. \<lbrace>obj_at' (valid_pde_mapping' (x && mask pdBits)) x\<rbrace>
f \<lbrace>\<lambda>rv. obj_at' (valid_pde_mapping' (x && mask pdBits)) x\<rbrace>"
shows "\<lbrace>valid_pde_mappings'\<rbrace> f \<lbrace>\<lambda>rv. valid_pde_mappings'\<rbrace>"
apply (simp only: valid_pde_mappings'_def2 imp_conv_disj)
apply (rule hoare_vcg_all_lift hoare_vcg_disj_lift x y)+
done
lemma set_ntfn_valid_pde_mappings'[wp]:
"\<lbrace>valid_pde_mappings'\<rbrace> setNotification ptr val \<lbrace>\<lambda>rv. valid_pde_mappings'\<rbrace>"
apply (rule valid_pde_mappings_lift')
apply wp
apply (simp add: setNotification_def)
apply (rule obj_at_setObject2)
apply (clarsimp simp: updateObject_default_def in_monad)
done
lemma set_ntfn_vms'[wp]:
"\<lbrace>valid_machine_state'\<rbrace> setNotification ptr val \<lbrace>\<lambda>rv. valid_machine_state'\<rbrace>"
apply (simp add: setNotification_def valid_machine_state'_def pointerInDeviceData_def pointerInUserData_def)
apply (intro hoare_vcg_all_lift hoare_vcg_disj_lift)
by (wp setObject_typ_at_inv setObject_ksMachine updateObject_default_inv |
simp)+
lemma irqs_masked_lift:
assumes "\<And>P. \<lbrace>\<lambda>s. P (intStateIRQTable (ksInterruptState s))\<rbrace> f
\<lbrace>\<lambda>rv s. P (intStateIRQTable (ksInterruptState s))\<rbrace>"
shows "\<lbrace>irqs_masked'\<rbrace> f \<lbrace>\<lambda>_. irqs_masked'\<rbrace>"
apply (simp add: irqs_masked'_def)
apply (wp assms)
done
lemma setObject_pspace_domain_valid[wp]:
"\<lbrace>pspace_domain_valid\<rbrace>
setObject ptr val
\<lbrace>\<lambda>rv. pspace_domain_valid\<rbrace>"
apply (clarsimp simp: setObject_def split_def pspace_domain_valid_def
valid_def in_monad
split: if_split_asm)
apply (drule updateObject_objBitsKO)
apply (clarsimp simp: lookupAround2_char1)
done
crunches setNotification, setEndpoint
for pspace_domain_valid[wp]: "pspace_domain_valid"
lemma ct_not_inQ_lift:
assumes sch_act: "\<And>P. \<lbrace>\<lambda>s. P (ksSchedulerAction s)\<rbrace> f \<lbrace>\<lambda>_ s. P (ksSchedulerAction s)\<rbrace>"
and not_inQ: "\<lbrace>\<lambda>s. obj_at' (Not \<circ> tcbQueued) (ksCurThread s) s\<rbrace>
f \<lbrace>\<lambda>_ s. obj_at' (Not \<circ> tcbQueued) (ksCurThread s) s\<rbrace>"
shows "\<lbrace>ct_not_inQ\<rbrace> f \<lbrace>\<lambda>_. ct_not_inQ\<rbrace>"
unfolding ct_not_inQ_def
by (rule hoare_convert_imp [OF sch_act not_inQ])
lemma setNotification_ct_not_inQ[wp]:
"\<lbrace>ct_not_inQ\<rbrace> setNotification ptr rval \<lbrace>\<lambda>_. ct_not_inQ\<rbrace>"
apply (rule ct_not_inQ_lift [OF setNotification_nosch])
apply (simp add: setNotification_def ct_not_inQ_def)
apply (rule hoare_weaken_pre)
apply (wps setObject_ntfn_ct)
apply (rule obj_at_setObject2)
apply (clarsimp simp add: updateObject_default_def in_monad)+
done
lemma setNotification_ksCurThread[wp]:
"\<lbrace>\<lambda>s. P (ksCurThread s)\<rbrace> setNotification a b \<lbrace>\<lambda>rv s. P (ksCurThread s)\<rbrace>"
apply (simp add: setNotification_def setObject_def split_def)
apply (wp updateObject_default_inv | simp)+
done
lemma setNotification_ksDomSchedule[wp]:
"\<lbrace>\<lambda>s. P (ksDomSchedule s)\<rbrace> setNotification a b \<lbrace>\<lambda>rv s. P (ksDomSchedule s)\<rbrace>"
apply (simp add: setNotification_def setObject_def split_def)
apply (wp updateObject_default_inv | simp)+
done
lemma setNotification_ksDomScheduleId[wp]:
"\<lbrace>\<lambda>s. P (ksDomScheduleIdx s)\<rbrace> setNotification a b \<lbrace>\<lambda>rv s. P (ksDomScheduleIdx s)\<rbrace>"
apply (simp add: setNotification_def setObject_def split_def)
apply (wp updateObject_default_inv | simp)+
done
lemma setNotification_ct_idle_or_in_cur_domain'[wp]:
"\<lbrace> ct_idle_or_in_cur_domain' \<rbrace> setNotification ptr ntfn \<lbrace> \<lambda>_. ct_idle_or_in_cur_domain' \<rbrace>"
apply (rule ct_idle_or_in_cur_domain'_lift)
apply (wp hoare_vcg_disj_lift| rule obj_at_setObject2
| clarsimp simp: updateObject_default_def in_monad setNotification_def)+
done
crunch gsUntypedZeroRanges[wp]: setNotification "\<lambda>s. P (gsUntypedZeroRanges s)"
(wp: setObject_ksPSpace_only updateObject_default_inv)
lemma set_ntfn_minor_invs':
"\<lbrace>invs' and obj_at' (\<lambda>ntfn. ntfn_q_refs_of' (ntfnObj ntfn) = ntfn_q_refs_of' (ntfnObj val)
\<and> ntfn_bound_refs' (ntfnBoundTCB ntfn) = ntfn_bound_refs' (ntfnBoundTCB val))
ptr
and valid_ntfn' val
and (\<lambda>s. live' (KONotification val) \<longrightarrow> ex_nonz_cap_to' ptr s)
and (\<lambda>s. ptr \<noteq> ksIdleThread s) \<rbrace>
setNotification ptr val
\<lbrace>\<lambda>rv. invs'\<rbrace>"
apply (clarsimp simp add: invs'_def valid_state'_def cteCaps_of_def)
apply (wp irqs_masked_lift valid_irq_node_lift untyped_ranges_zero_lift,
simp_all add: o_def)
apply (clarsimp elim!: rsubst[where P=sym_refs]
intro!: ext
dest!: obj_at_state_refs_ofD')+
done
lemma getEndpoint_wp:
"\<lbrace>\<lambda>s. \<forall>ep. ko_at' ep e s \<longrightarrow> P ep s\<rbrace> getEndpoint e \<lbrace>P\<rbrace>"
apply (rule hoare_strengthen_post)
apply (rule get_ep_sp')
apply simp
done
lemma getNotification_wp:
"\<lbrace>\<lambda>s. \<forall>ntfn. ko_at' ntfn e s \<longrightarrow> P ntfn s\<rbrace> getNotification e \<lbrace>P\<rbrace>"
apply (rule hoare_strengthen_post)
apply (rule get_ntfn_sp')
apply simp
done
lemma ep_redux_simps':
"ep_q_refs_of' (case xs of [] \<Rightarrow> IdleEP | y # ys \<Rightarrow> SendEP xs)
= (set xs \<times> {EPSend})"
"ep_q_refs_of' (case xs of [] \<Rightarrow> IdleEP | y # ys \<Rightarrow> RecvEP xs)
= (set xs \<times> {EPRecv})"
"ntfn_q_refs_of' (case xs of [] \<Rightarrow> IdleNtfn | y # ys \<Rightarrow> WaitingNtfn xs)
= (set xs \<times> {NTFNSignal})"
by (fastforce split: list.splits
simp: valid_ep_def valid_ntfn_def
intro!: ext)+
(* There are two wp rules for preserving valid_ioc over set_object.
First, the more involved rule for CNodes and TCBs *)
(* Second, the simpler rule suitable for all objects except CNodes and TCBs. *)
lemma valid_refs'_def2:
"valid_refs' R (ctes_of s) = (\<forall>cref. \<not>cte_wp_at' (\<lambda>c. R \<inter> capRange (cteCap c) \<noteq> {}) cref s)"
by (auto simp: valid_refs'_def cte_wp_at_ctes_of ran_def)
lemma idle_is_global [intro!]:
"ksIdleThread s \<in> global_refs' s"
by (simp add: global_refs'_def)
lemma valid_globals_cte_wpD':
"\<lbrakk> valid_global_refs' s; cte_wp_at' P p s \<rbrakk>
\<Longrightarrow> \<exists>cte. P cte \<and> ksIdleThread s \<notin> capRange (cteCap cte)"
by (fastforce simp: valid_global_refs'_def valid_refs'_def cte_wp_at_ctes_of)
lemma dmo_aligned'[wp]:
"\<lbrace>pspace_aligned'\<rbrace> doMachineOp f \<lbrace>\<lambda>_. pspace_aligned'\<rbrace>"
apply (simp add: doMachineOp_def split_def)
apply wp
apply clarsimp
done
lemma dmo_distinct'[wp]:
"\<lbrace>pspace_distinct'\<rbrace> doMachineOp f \<lbrace>\<lambda>_. pspace_distinct'\<rbrace>"
apply (simp add: doMachineOp_def split_def)
apply wp
apply clarsimp
done
lemma dmo_valid_objs'[wp]:
"\<lbrace>valid_objs'\<rbrace> doMachineOp f \<lbrace>\<lambda>_. valid_objs'\<rbrace>"
apply (simp add: doMachineOp_def split_def)
apply wp
apply clarsimp
done
lemma dmo_inv':
assumes R: "\<And>P. \<lbrace>P\<rbrace> f \<lbrace>\<lambda>_. P\<rbrace>"
shows "\<lbrace>P\<rbrace> doMachineOp f \<lbrace>\<lambda>_. P\<rbrace>"
apply (simp add: doMachineOp_def split_def)
apply wp
apply clarsimp
apply (drule in_inv_by_hoareD [OF R])
apply simp
done
crunch cte_wp_at'2[wp]: doMachineOp "\<lambda>s. P (cte_wp_at' P' p s)"
crunch typ_at'[wp]: doMachineOp "\<lambda>s. P (typ_at' T p s)"
lemmas doMachineOp_typ_ats[wp] = typ_at_lifts [OF doMachineOp_typ_at']
lemma doMachineOp_invs_bits[wp]:
"\<lbrace>valid_pspace'\<rbrace> doMachineOp m \<lbrace>\<lambda>rv. valid_pspace'\<rbrace>"
"\<lbrace>\<lambda>s. sch_act_wf (ksSchedulerAction s) s\<rbrace>
doMachineOp m \<lbrace>\<lambda>rv s. sch_act_wf (ksSchedulerAction s) s\<rbrace>"
"\<lbrace>Invariants_H.valid_queues\<rbrace> doMachineOp m \<lbrace>\<lambda>rv. Invariants_H.valid_queues\<rbrace>"
"\<lbrace>valid_queues'\<rbrace> doMachineOp m \<lbrace>\<lambda>rv. valid_queues'\<rbrace>"
"\<lbrace>\<lambda>s. P (state_refs_of' s)\<rbrace>
doMachineOp m
\<lbrace>\<lambda>rv s. P (state_refs_of' s)\<rbrace>"
"\<lbrace>if_live_then_nonz_cap'\<rbrace> doMachineOp m \<lbrace>\<lambda>rv. if_live_then_nonz_cap'\<rbrace>"
"\<lbrace>cur_tcb'\<rbrace> doMachineOp m \<lbrace>\<lambda>rv. cur_tcb'\<rbrace>"
"\<lbrace>if_unsafe_then_cap'\<rbrace> doMachineOp m \<lbrace>\<lambda>rv. if_unsafe_then_cap'\<rbrace>"
by (simp add: doMachineOp_def split_def
valid_pspace'_def valid_queues_def valid_queues_no_bitmap_def bitmapQ_defs
| wp cur_tcb_lift sch_act_wf_lift tcb_in_cur_domain'_lift
| fastforce elim: state_refs_of'_pspaceI)+
crunch cte_wp_at'[wp]: doMachineOp "\<lambda>s. P (cte_wp_at' P' p s)"
crunch obj_at'[wp]: doMachineOp "\<lambda>s. P (obj_at' P' p s)"
crunch it[wp]: doMachineOp "\<lambda>s. P (ksIdleThread s)"
crunch idle'[wp]: doMachineOp "valid_idle'"
(wp: crunch_wps simp: crunch_simps valid_idle'_pspace_itI)
crunch pde_mappings'[wp]: doMachineOp "valid_pde_mappings'"
lemma setEndpoint_ksMachine:
"\<lbrace>\<lambda>s. P (ksMachineState s)\<rbrace> setEndpoint ptr val \<lbrace>\<lambda>rv s. P (ksMachineState s)\<rbrace>"
by (simp add: setEndpoint_def | wp setObject_ksMachine updateObject_default_inv)+
lemmas setEndpoint_valid_irq_states' =
valid_irq_states_lift' [OF setEndpoint_ksInterruptState setEndpoint_ksMachine]
lemma setEndpoint_ct':
"\<lbrace>\<lambda>s. P (ksCurThread s)\<rbrace> setEndpoint a b \<lbrace>\<lambda>rv s. P (ksCurThread s)\<rbrace>"
apply (simp add: setEndpoint_def setObject_def split_def)
apply (wp updateObject_default_inv | simp)+
done
lemmas setEndpoint_valid_globals[wp]
= valid_global_refs_lift' [OF set_ep_ctes_of set_ep_arch'
setEndpoint_it setEndpoint_ksInterruptState]
end
end