lh-l4v/proof/refine/ARM_HYP/VSpace_R.thy

5339 lines
250 KiB
Plaintext

(*
* Copyright 2014, General Dynamics C4 Systems
*
* SPDX-License-Identifier: GPL-2.0-only
*)
(*
ARM VSpace refinement
*)
theory VSpace_R
imports TcbAcc_R
begin
context Arch begin global_naming ARM (*FIXME: arch_split*)
lemmas store_pte_typ_ats[wp] = store_pte_typ_ats abs_atyp_at_lifts[OF store_pte_typ_at]
lemmas store_pde_typ_ats[wp] = store_pde_typ_ats abs_atyp_at_lifts[OF store_pde_typ_at]
end
context begin interpretation Arch . (*FIXME: arch_split*)
lemma option_case_all_conv:
"(case x of None \<Rightarrow> True | Some v \<Rightarrow> P v) = (\<forall>v. x = Some v \<longrightarrow> P v)"
by (auto split: option.split)
lemma cteCaps_of_ctes_of_lift:
"(\<And>P. \<lbrace>\<lambda>s. P (ctes_of s)\<rbrace> f \<lbrace>\<lambda>_ s. P (ctes_of s)\<rbrace>) \<Longrightarrow> \<lbrace>\<lambda>s. P (cteCaps_of s) \<rbrace> f \<lbrace>\<lambda>_ s. P (cteCaps_of s)\<rbrace>"
unfolding cteCaps_of_def .
abbreviation
"injectKOS \<equiv> (injectKO :: ('a :: pspace_storable) \<Rightarrow> kernel_object)"
definition
"pd_at_asid' pd asid \<equiv> \<lambda>s. \<exists>ap pool.
armKSASIDTable (ksArchState s) (ucast (asid_high_bits_of asid)) = Some ap \<and>
ko_at' (ASIDPool pool) ap s \<and> pool (asid && mask asid_low_bits) = Some pd \<and>
page_directory_at' pd s"
defs checkPDASIDMapMembership_def:
"checkPDASIDMapMembership pd asids
\<equiv> stateAssert (\<lambda>s. pd \<notin> ran ((option_map snd o armKSASIDMap (ksArchState s) |` (- set asids)))) []"
crunches checkPDAt, getIRQState
for inv[wp]: P
lemma findPDForASID_pd_at_wp:
"\<lbrace>\<lambda>s. \<forall>pd. (page_directory_at' pd s \<longrightarrow> pd_at_asid' pd asid s)
\<longrightarrow> P pd s\<rbrace> findPDForASID asid \<lbrace>P\<rbrace>,-"
apply (simp add: findPDForASID_def assertE_def
cong: option.case_cong
split del: if_split)
apply (rule hoare_pre)
apply (wp getASID_wp | wpc | simp add: o_def split del: if_split)+
apply (clarsimp simp: pd_at_asid'_def)
apply (case_tac ko, simp)
apply (subst(asm) inv_f_f)
apply (rule inj_onI, simp+)
apply fastforce
done
lemma findPDForASIDAssert_pd_at_wp:
"\<lbrace>(\<lambda>s. \<forall>pd. pd_at_asid' pd asid s
\<and> pd \<notin> ran ((option_map snd o armKSASIDMap (ksArchState s) |` (- {asid})))
\<longrightarrow> P pd s)\<rbrace>
findPDForASIDAssert asid \<lbrace>P\<rbrace>"
apply (simp add: findPDForASIDAssert_def const_def
checkPDAt_def checkPDUniqueToASID_def
checkPDASIDMapMembership_def)
apply (rule hoare_pre, wp getPDE_wp findPDForASID_pd_at_wp)
apply simp
done
crunch inv[wp]: findPDForASIDAssert "P"
(simp: const_def crunch_simps wp: loadObject_default_inv crunch_wps ignore_del: getObject)
lemma pspace_relation_pd:
assumes p: "pspace_relation (kheap a) (ksPSpace c)"
assumes pa: "pspace_aligned a"
assumes pad: "pspace_aligned' c" "pspace_distinct' c"
assumes t: "page_directory_at p a"
shows "page_directory_at' p c" using assms pd_aligned [OF pa t]
apply (clarsimp simp: obj_at_def)
apply (drule(1) pspace_relation_absD)
apply (clarsimp split: Structures_A.kernel_object.split_asm
if_split_asm arch_kernel_obj.split_asm)
apply (clarsimp simp: page_directory_at'_def vspace_bits_defs
typ_at_to_obj_at_arches)
apply (drule_tac x="ucast y" in spec, clarsimp)
apply (simp add: ucast_ucast_mask iffD2 [OF mask_eq_iff_w2p] word_size)
apply (clarsimp simp add: pde_relation_def)
apply (drule(2) aligned_distinct_pde_atI')
apply (erule obj_at'_weakenE)
apply simp
done
lemma find_pd_for_asid_eq_helper:
"\<lbrakk> vspace_at_asid asid pd s; valid_vspace_objs s;
asid \<noteq> 0; pspace_aligned s \<rbrakk>
\<Longrightarrow> find_pd_for_asid asid s = returnOk pd s
\<and> page_directory_at pd s \<and> is_aligned pd pdBits"
apply (clarsimp simp: vspace_at_asid_def valid_vspace_objs_def)
apply (frule spec, drule mp, erule exI)
apply (clarsimp simp: vs_asid_refs_def graph_of_def
elim!: vs_lookupE)
apply (erule rtranclE)
apply simp
apply (clarsimp dest!: vs_lookup1D)
apply (erule rtranclE)
defer
apply (drule vs_lookup1_trans_is_append')
apply (clarsimp dest!: vs_lookup1D)
apply (clarsimp dest!: vs_lookup1D)
apply (drule spec, drule mp, rule exI,
rule vs_lookupI[unfolded vs_asid_refs_def])
apply (rule image_eqI[OF refl])
apply (erule graph_ofI)
apply clarsimp
apply (rule rtrancl.intros(1))
apply (clarsimp simp: vs_refs_def graph_of_def
split: Structures_A.kernel_object.splits
arch_kernel_obj.splits)
apply (clarsimp simp: obj_at_def)
apply (drule bspec, erule ranI)
apply clarsimp
apply (drule ucast_up_inj, simp)
apply (simp add: find_pd_for_asid_def bind_assoc
word_neq_0_conv[symmetric] liftE_bindE)
apply (simp add: exec_gets liftE_bindE bind_assoc
get_asid_pool_def get_object_def)
apply (simp add: mask_asid_low_bits_ucast_ucast)
apply (drule ucast_up_inj, simp)
apply (clarsimp simp: returnOk_def get_pde_def
get_pd_def get_object_def
bind_assoc)
apply (frule(1) pspace_alignedD[where p=pd])
apply (simp add: pdBits_def pageBits_def)
done
lemma find_pd_for_asid_assert_eq:
"\<lbrakk> vspace_at_asid asid pd s; valid_vspace_objs s;
asid \<noteq> 0; pspace_aligned s \<rbrakk>
\<Longrightarrow> find_pd_for_asid_assert asid s = return pd s"
apply (drule(3) find_pd_for_asid_eq_helper)
apply (simp add: find_pd_for_asid_assert_def
catch_def bind_assoc)
apply (clarsimp simp: returnOk_def obj_at_def
a_type_def
cong: bind_apply_cong)
apply (clarsimp split: Structures_A.kernel_object.splits
arch_kernel_obj.splits if_split_asm)
apply (simp add: get_pde_def get_pd_def get_object_def
bind_assoc is_aligned_neg_mask_eq
pd_bits_def pdBits_def)
apply (simp add: exec_gets)
done
lemma find_pd_for_asid_valids:
"\<lbrace> vspace_at_asid asid pd and valid_vspace_objs
and pspace_aligned and K (asid \<noteq> 0) \<rbrace>
find_pd_for_asid asid \<lbrace>\<lambda>rv s. pde_at rv s\<rbrace>,-"
"\<lbrace> vspace_at_asid asid pd and valid_vspace_objs
and pspace_aligned and K (asid \<noteq> 0)
and K (is_aligned pd pdBits \<longrightarrow> P pd) \<rbrace>
find_pd_for_asid asid \<lbrace>\<lambda>rv s. P rv\<rbrace>,-"
"\<lbrace> vspace_at_asid asid pd and valid_vspace_objs
and pspace_aligned and K (asid \<noteq> 0)
and pd_at_uniq asid pd \<rbrace>
find_pd_for_asid asid \<lbrace>\<lambda>rv s. pd_at_uniq asid rv s\<rbrace>,-"
"\<lbrace> vspace_at_asid asid pd and valid_vspace_objs
and pspace_aligned and K (asid \<noteq> 0) \<rbrace>
find_pd_for_asid asid -,\<lbrace>\<bottom>\<bottom>\<rbrace>"
apply (simp_all add: validE_def validE_R_def validE_E_def
valid_def split: sum.split)
apply (auto simp: returnOk_def return_def
pde_at_def pd_bits_def pdBits_def
pageBits_def is_aligned_neg_mask_eq
dest!: find_pd_for_asid_eq_helper
elim!: is_aligned_weaken)
done
lemma asidBits_asid_bits[simp]:
"asidBits = asid_bits"
by (simp add: asid_bits_def asidBits_def
asidHighBits_def asid_low_bits_def)
lemma findPDForASIDAssert_corres:
"corres (\<lambda>rv rv'. rv = pd \<and> rv' = pd)
(K (asid \<noteq> 0 \<and> asid \<le> mask asid_bits)
and pspace_aligned and pspace_distinct
and valid_vspace_objs and valid_asid_map
and vspace_at_asid asid pd and pd_at_uniq asid pd)
(pspace_aligned' and pspace_distinct' and no_0_obj')
(find_pd_for_asid_assert asid)
(findPDForASIDAssert asid)"
apply (simp add: find_pd_for_asid_assert_def const_def
findPDForASIDAssert_def liftM_def)
apply (rule corres_guard_imp)
apply (rule corres_split_eqr)
apply (rule corres_split_catch[OF find_pd_for_asid_corres'[where pd=pd]])
apply (rule_tac P="\<bottom>" and P'="\<top>" in corres_inst)
apply (simp add: corres_fail)
apply (wp find_pd_for_asid_valids[where pd=pd])+
apply (rule_tac F="is_aligned pda pdBits
\<and> pda = pd" in corres_gen_asm)
apply (clarsimp simp add: is_aligned_mask[symmetric])
apply (rule_tac P="pde_at pd and pd_at_uniq asid pd
and pspace_aligned and pspace_distinct
and vspace_at_asid asid pd and valid_asid_map"
and P'="pspace_aligned' and pspace_distinct'"
in stronger_corres_guard_imp)
apply (rule corres_symb_exec_l[where P="pde_at pd and pd_at_uniq asid pd
and valid_asid_map and vspace_at_asid asid pd"])
apply (rule corres_symb_exec_r[where P'="page_directory_at' pd"])
apply (simp add: checkPDUniqueToASID_def ran_option_map
checkPDASIDMapMembership_def)
apply (rule_tac P'="pd_at_uniq asid pd" in corres_stateAssert_implied)
apply (simp add: gets_def bind_assoc[symmetric]
stateAssert_def[symmetric, where L="[]"])
apply (rule_tac P'="valid_asid_map and vspace_at_asid asid pd"
in corres_stateAssert_implied)
apply (rule corres_trivial, simp)
apply (clarsimp simp: state_relation_def arch_state_relation_def
valid_asid_map_def
split: option.split)
apply (drule bspec, erule graph_ofI)
apply clarsimp
apply (drule(1) pd_at_asid_unique2)
apply simp
apply (clarsimp simp: state_relation_def arch_state_relation_def
pd_at_uniq_def ran_option_map)
apply wp+
apply (simp add: checkPDAt_def stateAssert_def)
apply (rule no_fail_pre, wp)
apply simp
apply (clarsimp simp: pde_at_def obj_at_def a_type_def)
apply (clarsimp split: Structures_A.kernel_object.splits
arch_kernel_obj.splits if_split_asm)
apply (simp add: get_pde_def exs_valid_def bind_def return_def
get_pd_def get_object_def simpler_gets_def)
apply wp
apply simp
apply (simp add: get_pde_def get_pd_def)
apply (rule no_fail_pre)
apply (wp get_object_wp | wpc)+
apply (clarsimp simp: pde_at_def obj_at_def a_type_def)
apply (clarsimp split: Structures_A.kernel_object.splits
arch_kernel_obj.splits if_split_asm)
apply simp
apply (clarsimp simp: state_relation_def)
apply (erule(3) pspace_relation_pd)
apply (simp add: pde_at_def pd_bits_def pdBits_def)
apply (wp find_pd_for_asid_valids[where pd=pd])+
apply (clarsimp simp: word_neq_0_conv)
apply simp
done
lemma findPDForASIDAssert_known_corres:
"corres r P P' f (g pd) \<Longrightarrow>
corres r (vspace_at_asid asid pd and pd_at_uniq asid pd
and valid_vspace_objs and valid_asid_map
and pspace_aligned and pspace_distinct
and K (asid \<noteq> 0 \<and> asid \<le> mask asid_bits) and P)
(P' and pspace_aligned' and pspace_distinct' and no_0_obj')
f (findPDForASIDAssert asid >>= g)"
apply (subst return_bind[symmetric])
apply (subst corres_cong [OF refl refl _ refl refl])
apply (rule bind_apply_cong [OF _ refl])
apply clarsimp
apply (erule(3) find_pd_for_asid_assert_eq[symmetric])
apply (rule corres_guard_imp)
apply (rule corres_split[OF findPDForASIDAssert_corres[where pd=pd]])
apply simp
apply wp+
apply clarsimp
apply simp
done
lemma loadHWASID_corres:
"corres (=)
(valid_vspace_objs and pspace_distinct
and pspace_aligned and valid_asid_map
and vspace_at_asid a pd
and (\<lambda>s. \<forall>pd. vspace_at_asid a pd s \<longrightarrow> pd_at_uniq a pd s)
and K (a \<noteq> 0 \<and> a \<le> mask asid_bits))
(pspace_aligned' and pspace_distinct' and no_0_obj')
(load_hw_asid a) (loadHWASID a)"
apply (simp add: load_hw_asid_def loadHWASID_def)
apply (rule_tac r'="(=)" in corres_underlying_split [OF _ _ gets_sp gets_sp])
apply (clarsimp simp: state_relation_def arch_state_relation_def)
apply (case_tac "rv' a")
apply simp
apply (rule corres_guard_imp)
apply (rule_tac pd=pd in findPDForASIDAssert_known_corres)
apply (rule corres_trivial, simp)
apply clarsimp
apply clarsimp
apply clarsimp
apply (rule corres_guard_imp)
apply (rule_tac pd=b in findPDForASIDAssert_known_corres)
apply (rule corres_trivial, simp)
apply (clarsimp simp: valid_arch_state_def valid_asid_map_def)
apply (drule subsetD, erule domI)
apply (drule bspec, erule graph_ofI)
apply clarsimp
apply simp
done
crunch inv[wp]: loadHWASID "P"
(wp: crunch_wps)
lemma storeHWASID_corres:
"corres dc
(vspace_at_asid a pd and pd_at_uniq a pd
and valid_vspace_objs and pspace_distinct
and pspace_aligned and K (a \<noteq> 0 \<and> a \<le> mask asid_bits)
and valid_asid_map)
(pspace_aligned' and pspace_distinct' and no_0_obj')
(store_hw_asid a h) (storeHWASID a h)"
apply (simp add: store_hw_asid_def storeHWASID_def)
apply (rule corres_guard_imp)
apply (rule corres_split[OF findPDForASIDAssert_corres[where pd=pd]])
apply (rule corres_split_eqr)
apply (rule corres_trivial)
apply (clarsimp simp: state_relation_def arch_state_relation_def)
apply (rule corres_split)
apply (rule corres_trivial, rule corres_modify)
apply (clarsimp simp: state_relation_def)
apply (simp add: arch_state_relation_def)
apply (rule ext)
apply simp
apply (rule corres_split_eqr)
apply (rule corres_trivial)
apply (clarsimp simp: state_relation_def arch_state_relation_def)
apply (rule corres_trivial, rule corres_modify)
apply (clarsimp simp: state_relation_def arch_state_relation_def)
apply (rule ext)
apply simp
apply (wp | simp)+
done
lemma invalidateASID_corres:
"corres dc
(valid_asid_map and valid_vspace_objs
and pspace_aligned and pspace_distinct
and vspace_at_asid a pd and pd_at_uniq a pd
and K (a \<noteq> 0 \<and> a \<le> mask asid_bits))
(pspace_aligned' and pspace_distinct' and no_0_obj')
(invalidate_asid a) (invalidateASID a)"
(is "corres dc ?P ?P' ?f ?f'")
apply (simp add: invalidate_asid_def invalidateASID_def)
apply (rule corres_guard_imp)
apply (rule_tac pd=pd in findPDForASIDAssert_known_corres)
apply (rule_tac P="?P" and P'="?P'" in corres_inst)
apply (rule_tac r'="(=)" in corres_underlying_split [OF _ _ gets_sp gets_sp])
apply (clarsimp simp: state_relation_def arch_state_relation_def)
apply (rule corres_modify)
apply (simp add: state_relation_def arch_state_relation_def
fun_upd_def)
apply simp
apply simp
done
lemma invalidate_asid_ext_corres:
"corres dc
(\<lambda>s. \<exists>pd. valid_asid_map s \<and> valid_vspace_objs s
\<and> pspace_aligned s \<and> pspace_distinct s
\<and> vspace_at_asid a pd s \<and> pd_at_uniq a pd s
\<and> a \<noteq> 0 \<and> a \<le> mask asid_bits)
(pspace_aligned' and pspace_distinct' and no_0_obj')
(invalidate_asid a) (invalidateASID a)"
apply (insert invalidateASID_corres)
apply (clarsimp simp: corres_underlying_def)
apply fastforce
done
lemma invalidateHWASIDEntry_corres:
"corres dc \<top> \<top> (invalidate_hw_asid_entry a) (invalidateHWASIDEntry a)"
apply (simp add: invalidate_hw_asid_entry_def invalidateHWASIDEntry_def)
apply (rule corres_guard_imp)
apply (rule corres_split_eqr)
apply (rule corres_trivial)
apply (clarsimp simp: state_relation_def arch_state_relation_def)
apply (rule corres_trivial, rule corres_modify)
apply (clarsimp simp: state_relation_def arch_state_relation_def)
apply (rule ext)
apply (wp | clarsimp)+
done
lemma findFreeHWASID_corres:
"corres (=)
(valid_asid_map and valid_vspace_objs
and pspace_aligned and pspace_distinct
and (unique_table_refs o caps_of_state)
and valid_vs_lookup and valid_arch_state
and valid_global_objs)
(pspace_aligned' and pspace_distinct' and no_0_obj')
find_free_hw_asid findFreeHWASID"
apply (simp add: find_free_hw_asid_def findFreeHWASID_def)
apply (rule corres_guard_imp)
apply (rule corres_split_eqr[OF corres_trivial])
apply (clarsimp simp: arch_state_relation_def state_relation_def)
apply (rule corres_split_eqr[OF corres_trivial])
apply (clarsimp simp: arch_state_relation_def state_relation_def)
apply (subgoal_tac "take (length [minBound .e. maxBound :: hardware_asid])
([next_asid .e. maxBound] @ [minBound .e. next_asid])
= [next_asid .e. maxBound] @ init [minBound .e. next_asid]")
apply (cut_tac option="find (\<lambda>a. hw_asid_table a = None)
([next_asid .e. maxBound] @ init [minBound .e. next_asid])"
in option.nchotomy[rule_format])
apply (erule corres_disj_division)
apply (clarsimp split del: if_split)
apply (rule corres_split[OF invalidate_asid_ext_corres])
apply (rule corres_underlying_split [where r'=dc])
apply (rule corres_trivial, rule corres_machine_op)
apply (rule corres_no_failI)
apply (rule no_fail_invalidateLocalTLB_ASID)
apply fastforce
apply (rule corres_split)
apply (rule invalidateHWASIDEntry_corres)
apply (rule corres_split)
apply (rule corres_trivial)
apply (rule corres_modify)
apply (simp add: minBound_word maxBound_word
state_relation_def arch_state_relation_def)
apply (rule corres_trivial)
apply simp
apply (wp | simp split del: if_split)+
apply (rule corres_trivial, clarsimp)
apply (cut_tac x=next_asid in leq_maxBound)
apply (simp only: word_le_nat_alt)
apply (simp add: init_def upto_enum_word
minBound_word
del: upt.simps)
apply wp+
apply (clarsimp dest!: findNoneD)
apply (drule bspec, rule UnI1, simp, rule order_refl)
apply (clarsimp simp: valid_arch_state_def)
apply (frule(1) is_inv_SomeD)
apply (clarsimp simp: valid_asid_map_def)
apply (frule bspec, erule graph_ofI, clarsimp)
apply (frule pd_at_asid_uniq, simp_all add: valid_asid_map_def valid_arch_state_def)[1]
apply (drule subsetD, erule domI)
apply simp
apply fastforce
apply clarsimp
done
crunch aligned'[wp]: findFreeHWASID "pspace_aligned'"
(simp: crunch_simps)
crunch distinct'[wp]: findFreeHWASID "pspace_distinct'"
(simp: crunch_simps)
crunch no_0_obj'[wp]: getHWASID "no_0_obj'"
lemma getHWASID_corres:
"corres (=)
(vspace_at_asid a pd and K (a \<noteq> 0 \<and> a \<le> mask asid_bits)
and unique_table_refs o caps_of_state
and valid_vs_lookup
and valid_asid_map and valid_vspace_objs
and pspace_aligned and pspace_distinct
and valid_arch_state)
(pspace_aligned' and pspace_distinct' and no_0_obj')
(get_hw_asid a) (getHWASID a)"
apply (simp add: get_hw_asid_def getHWASID_def)
apply (rule corres_guard_imp)
apply (rule corres_split_eqr[OF loadHWASID_corres[where pd=pd]])
apply (case_tac maybe_hw_asid, simp_all)[1]
apply (rule corres_split_eqr[OF findFreeHWASID_corres])
apply (rule corres_split[OF storeHWASID_corres[where pd=pd]])
apply (rule corres_trivial, simp)
apply (wp load_hw_asid_wp | simp)+
apply (simp add: pd_at_asid_uniq valid_global_objs_def)
apply simp
done
lemma armv_contextSwitch_corres:
"corres dc
(vspace_at_asid a pd and K (a \<noteq> 0 \<and> a \<le> mask asid_bits)
and unique_table_refs o caps_of_state
and valid_vs_lookup
and valid_asid_map and valid_vspace_objs
and pspace_aligned and pspace_distinct
and valid_arch_state)
(pspace_aligned' and pspace_distinct' and no_0_obj')
(arm_context_switch pd a) (armv_contextSwitch pd a)"
apply (simp add: arm_context_switch_def armv_contextSwitch_def armv_contextSwitch_HWASID_def)
apply (rule corres_guard_imp)
apply (rule corres_split_eqr[OF getHWASID_corres[where pd=pd]])
apply (rule corres_machine_op)
apply (rule corres_rel_imp)
apply (rule corres_underlying_trivial)
apply (rule no_fail_pre)
apply wpsimp+
done
(* setObject for VCPU invariant preservation *)
lemma setObject_vcpu_cur_domain[wp]:
"setObject ptr (vcpu::vcpu) \<lbrace>\<lambda>s. P (ksCurDomain s)\<rbrace>"
by (wpsimp wp: updateObject_default_inv simp: setObject_def)
lemma setObject_vcpu_ct[wp]:
"setObject ptr (vcpu::vcpu) \<lbrace>\<lambda>s. P (ksCurThread s)\<rbrace>"
by (wpsimp wp: updateObject_default_inv simp: setObject_def)
lemma setObject_vcpu_it[wp]:
"setObject ptr (vcpu::vcpu) \<lbrace>\<lambda>s. P (ksIdleThread s)\<rbrace>"
by (wpsimp wp: updateObject_default_inv simp: setObject_def)
lemma setObject_vcpu_sched[wp]:
"setObject ptr (vcpu::vcpu) \<lbrace>\<lambda>s. P (ksSchedulerAction s)\<rbrace>"
by (wpsimp wp: updateObject_default_inv simp: setObject_def)
lemma setObject_vcpu_L1[wp]:
"setObject ptr (vcpu::vcpu) \<lbrace>\<lambda>s. P (ksReadyQueuesL1Bitmap s)\<rbrace>"
by (wpsimp wp: updateObject_default_inv simp: setObject_def)
lemma setObject_vcpu_L2[wp]:
"setObject ptr (vcpu::vcpu) \<lbrace>\<lambda>s. P (ksReadyQueuesL2Bitmap s)\<rbrace>"
by (wpsimp wp: updateObject_default_inv simp: setObject_def)
lemma setObject_vcpu_ksInt[wp]:
"setObject ptr (vcpu::vcpu) \<lbrace>\<lambda>s. P (ksInterruptState s)\<rbrace>"
by (wpsimp wp: updateObject_default_inv simp: setObject_def)
lemma setObject_vcpu_ksArch[wp]:
"setObject ptr (vcpu::vcpu) \<lbrace>\<lambda>s. P (ksArchState s)\<rbrace>"
by (wpsimp wp: updateObject_default_inv simp: setObject_def)
lemma setObject_vcpu_gs[wp]:
"setObject ptr (vcpu::vcpu) \<lbrace>\<lambda>s. P (gsMaxObjectSize s)\<rbrace>"
by (wpsimp wp: updateObject_default_inv simp: setObject_def)
lemma setObject_vcpu_maschine_state[wp]:
"setObject ptr (vcpu::vcpu) \<lbrace>\<lambda>s. P (ksMachineState s)\<rbrace>"
by (wpsimp wp: updateObject_default_inv simp: setObject_def)
lemma setObject_vcpu_ksDomSchedule[wp]:
"setObject ptr (vcpu::vcpu) \<lbrace>\<lambda>s. P (ksDomSchedule s)\<rbrace>"
by (wpsimp wp: updateObject_default_inv simp: setObject_def)
lemma setObject_vcpu_ksDomScheduleIdx[wp]:
"setObject ptr (vcpu::vcpu) \<lbrace>\<lambda>s. P (ksDomScheduleIdx s)\<rbrace>"
by (wpsimp wp: updateObject_default_inv simp: setObject_def)
lemma setObject_vcpu_gsUntypedZeroRanges[wp]:
"setObject ptr (vcpu::vcpu) \<lbrace>\<lambda>s. P (gsUntypedZeroRanges s)\<rbrace>"
by (wpsimp wp: updateObject_default_inv simp: setObject_def)
lemma setObject_vcpu_ctes_of[wp]:
"\<lbrace> \<lambda>s. P (ctes_of s)\<rbrace> setObject p (t :: vcpu) \<lbrace>\<lambda>_ s. P (ctes_of s)\<rbrace>"
apply (rule ctes_of_from_cte_wp_at[where Q="\<top>", simplified])
apply (wp setObject_cte_wp_at2'[where Q="\<top>"])
apply (clarsimp simp: updateObject_default_def in_monad
projectKO_opts_defs projectKOs)
apply (rule equals0I)
apply (clarsimp simp: updateObject_default_def in_monad
projectKOs projectKO_opts_defs)
apply simp
done
lemma setObject_vcpu_untyped_ranges_zero'[wp]:
"setObject ptr (vcpu::vcpu) \<lbrace>untyped_ranges_zero'\<rbrace>"
by (rule hoare_lift_Pf[where f=cteCaps_of]; wp cteCaps_of_ctes_of_lift)
lemma setVCPU_if_live[wp]:
"\<lbrace>\<lambda>s. if_live_then_nonz_cap' s \<and> (live' (injectKOS vcpu) \<longrightarrow> ex_nonz_cap_to' v s)\<rbrace>
setObject v (vcpu::vcpu) \<lbrace>\<lambda>_. if_live_then_nonz_cap'\<rbrace>"
apply (wpsimp wp: setObject_iflive' [where P=\<top>]
| simp add: objBits_simps archObjSize_def vcpu_bits_def pageBits_def)+
apply (clarsimp simp: updateObject_default_def in_monad projectKOs)
apply (clarsimp simp: updateObject_default_def in_monad projectKOs bind_def)
apply simp
done
lemma setVCPU_if_unsafe[wp]:
"setObject v (vcpu::vcpu) \<lbrace>if_unsafe_then_cap'\<rbrace>"
apply (wp setObject_ifunsafe')
apply (clarsimp simp: updateObject_default_def in_monad projectKOs)
apply (clarsimp simp: updateObject_default_def in_monad projectKOs bind_def)
apply wp
apply simp
done
lemma projectKO_opt_no_vcpu[simp]:
"projectKO_opt (KOArch (KOVCPU v)) = (None::'a::no_vcpu option)"
by (rule ccontr) (simp add: project_koType not_vcpu[symmetric])
lemma setObject_vcpu_obj_at'_no_vcpu[wp]:
"setObject ptr (v::vcpu) \<lbrace>\<lambda>s. P (obj_at' (P'::'a::no_vcpu \<Rightarrow> bool) t s)\<rbrace>"
apply (wp setObject_ko_wp_at[where
P'="\<lambda>ko. \<exists>obj. projectKO_opt ko = Some obj \<and> P' (obj::'a::no_vcpu)" for P',
folded obj_at'_real_def])
apply (clarsimp simp: updateObject_default_def in_monad not_vcpu[symmetric])
apply (simp add: objBits_simps archObjSize_def)
apply (simp add: vcpu_bits_def pageBits_def)
apply (clarsimp split del: if_split)
apply (erule rsubst[where P=P])
apply normalise_obj_at'
apply (clarsimp simp: obj_at'_real_def ko_wp_at'_def projectKOs)
done
lemmas setVCPU_pred_tcb'[wp] =
setObject_vcpu_obj_at'_no_vcpu
[where P'="\<lambda>ko. P (proj (tcb_to_itcb' ko))" for P proj, folded pred_tcb_at'_def]
lemma setVCPU_valid_idle'[wp]:
"setObject v (vcpu::vcpu) \<lbrace>valid_idle'\<rbrace>"
unfolding valid_idle'_def by (rule hoare_lift_Pf[where f=ksIdleThread]; wp)
lemma setVCPU_ksQ[wp]:
"\<lbrace>\<lambda>s. P (ksReadyQueues s)\<rbrace> setObject p (v::vcpu) \<lbrace>\<lambda>rv s. P (ksReadyQueues s)\<rbrace>"
by (wp setObject_qs updateObject_default_inv | simp)+
lemma setVCPU_valid_queues'[wp]:
"setObject v (vcpu::vcpu) \<lbrace>valid_queues'\<rbrace>"
unfolding valid_queues'_def
by (rule hoare_lift_Pf[where f=ksReadyQueues]; wp hoare_vcg_all_lift updateObject_default_inv)
lemma setVCPU_ct_not_inQ[wp]:
"setObject v (vcpu::vcpu) \<lbrace>ct_not_inQ\<rbrace>"
apply (wp ct_not_inQ_lift)
apply (rule hoare_lift_Pf[where f=ksCurThread]; wp)
apply assumption
done
lemma handleVMFault_corres:
"corres (fr \<oplus> dc) (tcb_at thread) (tcb_at' thread)
(handle_vm_fault thread fault) (handleVMFault thread fault)"
apply (simp add: ARM_HYP_H.handleVMFault_def)
apply (cases fault)
apply simp
apply (rule corres_guard_imp)
apply (rule corres_splitEE, simp,
rule corres_machine_op [where r="(=)"],
rule corres_Id refl, rule refl, simp, simp)+
apply (rule corres_trivial)
apply (simp add: arch_fault_map_def)
apply wpsimp+
apply (rule corres_guard_imp)
apply (rule corres_splitEE,simp)
apply (rule asUser_corres')
apply (rule corres_no_failI [where R="(=)"])
apply (rule no_fail_getRestartPC)
apply fastforce
apply (rule corres_splitEE,simp,
rule corres_machine_op [where r="(=)"],
rule corres_Id refl, rule refl, simp, simp)+
apply (rule corres_trivial, simp add: arch_fault_map_def)
apply wpsimp+
done
lemma flushSpace_corres:
"corres dc
(K (asid \<le> mask asid_bits \<and> asid \<noteq> 0)
and valid_asid_map and valid_vspace_objs
and pspace_aligned and pspace_distinct
and unique_table_refs o caps_of_state
and valid_vs_lookup
and valid_arch_state and vspace_at_asid asid pd)
(pspace_aligned' and pspace_distinct' and no_0_obj')
(flush_space asid) (flushSpace asid)"
apply (simp add: flushSpace_def flush_space_def)
apply (rule corres_guard_imp)
apply (rule corres_split)
apply (rule loadHWASID_corres[where pd=pd])
apply (rule corres_split[where R="\<lambda>_. \<top>" and R'="\<lambda>_. \<top>"])
apply (rule corres_machine_op [where r=dc])
apply (rule corres_Id, rule refl, simp)
apply (rule no_fail_cleanCaches_PoU)
apply (case_tac maybe_hw_asid)
apply simp
apply clarsimp
apply (rule corres_machine_op)
apply (rule corres_Id, rule refl, simp)
apply (rule no_fail_invalidateLocalTLB_ASID)
apply wp+
apply clarsimp
apply (simp add: pd_at_asid_uniq)
apply simp
done
lemma invalidateTLBByASID_corres:
"corres dc
(K (asid \<le> mask asid_bits \<and> asid \<noteq> 0)
and valid_asid_map and valid_vspace_objs
and pspace_aligned and pspace_distinct
and unique_table_refs o caps_of_state
and valid_vs_lookup
and valid_arch_state and vspace_at_asid asid pd)
(pspace_aligned' and pspace_distinct' and no_0_obj')
(invalidate_tlb_by_asid asid) (invalidateTLBByASID asid)"
apply (simp add: invalidate_tlb_by_asid_def invalidateTLBByASID_def)
apply (rule corres_guard_imp)
apply (rule corres_split[where R="\<lambda>_. \<top>" and R'="\<lambda>_. \<top>"])
apply (rule loadHWASID_corres[where pd=pd])
apply (case_tac maybe_hw_asid)
apply simp
apply clarsimp
apply (rule corres_machine_op)
apply (rule corres_Id, rule refl, simp)
apply (rule no_fail_invalidateLocalTLB_ASID)
apply wp+
apply clarsimp
apply (simp add: pd_at_asid_uniq)
apply simp
done
lemma invalidate_tlb_by_asid_corres_ex:
"corres dc
(\<lambda>s. asid \<le> mask asid_bits \<and> asid \<noteq> 0
\<and> valid_asid_map s \<and> valid_vspace_objs s
\<and> pspace_aligned s \<and> pspace_distinct s
\<and> unique_table_refs (caps_of_state s)
\<and> valid_global_objs s \<and> valid_vs_lookup s
\<and> valid_arch_state s \<and> (\<exists>pd. vspace_at_asid asid pd s))
(pspace_aligned' and pspace_distinct' and no_0_obj')
(invalidate_tlb_by_asid asid) (invalidateTLBByASID asid)"
apply (rule corres_name_pre, clarsimp)
apply (rule corres_guard_imp)
apply (rule_tac pd=pd in invalidateTLBByASID_corres)
apply simp+
done
lemma state_relation_asid_map:
"(s, s') \<in> state_relation \<Longrightarrow> armKSASIDMap (ksArchState s') = arm_asid_map (arch_state s)"
by (simp add: state_relation_def arch_state_relation_def)
lemma find_pd_for_asid_pd_at_asid_again:
"\<lbrace>\<lambda>s. (\<forall>pd. vspace_at_asid asid pd s \<longrightarrow> P pd s)
\<and> (\<forall>ex. (\<forall>pd. \<not> vspace_at_asid asid pd s) \<longrightarrow> Q ex s)
\<and> valid_vspace_objs s \<and> pspace_aligned s \<and> asid \<noteq> 0\<rbrace>
find_pd_for_asid asid
\<lbrace>P\<rbrace>,\<lbrace>Q\<rbrace>"
apply (unfold validE_def, rule hoare_name_pre_state, fold validE_def)
apply (case_tac "\<exists>pd. vspace_at_asid asid pd s")
apply clarsimp
apply (rule_tac Q="\<lambda>rv s'. s' = s \<and> rv = pd" and E="\<bottom>\<bottom>" in hoare_post_impErr)
apply (rule hoare_pre, wp find_pd_for_asid_valids)
apply fastforce
apply simp+
apply (rule_tac Q="\<lambda>rv s'. s' = s \<and> vspace_at_asid asid rv s'"
and E="\<lambda>rv s'. s' = s" in hoare_post_impErr)
apply (rule hoare_pre, wp)
apply clarsimp+
done
(* TODO: maybe move? *)
lemma mapM_mapM_x: "do y \<leftarrow> mapM f l;
g
od =
do mapM_x f l;
g
od"
by (simp add: mapM_x_mapM)
(* TODO: move *)
lemma getObject_ko_at_vcpu [wp]:
"\<lbrace>\<top>\<rbrace> getObject p \<lbrace>\<lambda>rv::vcpu. ko_at' rv p\<rbrace>"
by (rule getObject_ko_at | simp add: objBits_simps archObjSize_def vcpu_bits_def pageBits_def)+
lemma corres_gets_gicvcpu_numlistregs:
"corres (=) \<top> \<top> (gets (arm_gicvcpu_numlistregs \<circ> arch_state))
(gets (armKSGICVCPUNumListRegs \<circ> ksArchState))"
by (simp add: state_relation_def arch_state_relation_def)
lemmas corres_split_forward = corres_underlying_split[rule_format, where Q="\<lambda>_. P" and P=P and Q'="\<lambda>_. P'" and P'=P' for P P']
lemma setObject_VCPU_corres:
"vcpu_relation vcpuObj vcpuObj'
\<Longrightarrow> corres dc (vcpu_at vcpu)
(vcpu_at' vcpu)
(set_vcpu vcpu vcpuObj)
(setObject vcpu vcpuObj')"
apply (simp add: set_vcpu_def)
apply (rule corres_guard_imp)
apply (rule setObject_other_corres [where P="\<lambda>ko::vcpu. True"], simp)
apply (clarsimp simp: obj_at'_def projectKOs)
apply (erule map_to_ctes_upd_other, simp, simp)
apply (simp add: a_type_def is_other_obj_relation_type_def)
apply (simp add: objBits_simps archObjSize_def)
apply simp
apply (simp add: objBits_simps archObjSize_def vcpu_bits_def pageBits_def)
apply (simp add: other_obj_relation_def asid_pool_relation_def)
apply (clarsimp simp: typ_at_to_obj_at'[symmetric] obj_at_def exs_valid_def
assert_def a_type_def return_def fail_def)
apply (fastforce split: Structures_A.kernel_object.split_asm if_split_asm)
apply (simp add: typ_at_to_obj_at_arches)
done
crunches
vgicUpdate, vgicUpdateLR, vcpuWriteReg, vcpuReadReg, vcpuRestoreRegRange, vcpuSaveRegRange,
vcpuSave
for typ_at'[wp]: "\<lambda>s. P (typ_at' T p s)"
and no_0_obj'[wp]: no_0_obj'
and vcpu_at'[wp]: "\<lambda>s. P (vcpu_at' p s)"
(wp: crunch_wps ignore_del: setObject)
lemma vcpuUpdate_corres[corres]:
"\<forall>v1 v2. vcpu_relation v1 v2 \<longrightarrow> vcpu_relation (f v1) (f' v2) \<Longrightarrow>
corres dc (vcpu_at v) (vcpu_at' v)
(vcpu_update v f) (vcpuUpdate v f')"
by (corresKsimp corres: getObject_vcpu_corres setObject_VCPU_corres
simp: vcpu_update_def vcpuUpdate_def vcpu_relation_def)
lemma vgicUpdate_corres[corres]:
"\<forall>vgic vgic'. vgic_map vgic = vgic' \<longrightarrow> vgic_map (f vgic) = (f' vgic')
\<Longrightarrow> corres dc (vcpu_at v) (vcpu_at' v) (vgic_update v f) (vgicUpdate v f')"
by (corresKsimp simp: vgic_update_def vgicUpdate_def vcpu_relation_def)
lemma vgicUpdateLR_corres[corres]:
"corres dc (vcpu_at v) (vcpu_at' v)
(vgic_update_lr v idx val) (vgicUpdateLR v idx val)"
by (corresKsimp simp: vgic_update_lr_def vgicUpdateLR_def vgic_map_def)
lemma vcpuReadReg_corres[corres]:
"corres (=) (vcpu_at v) (vcpu_at' v and no_0_obj')
(vcpu_read_reg v r) (vcpuReadReg v r)"
apply (simp add: vcpu_read_reg_def vcpuReadReg_def)
apply (rule corres_guard_imp)
apply (rule corres_assert_gen_asm2)
apply (rule corres_underlying_split[OF getObject_vcpu_corres])
apply (wpsimp simp: vcpu_relation_def)+
done
lemma vcpuWriteReg_corres[corres]:
"corres dc (vcpu_at v) (vcpu_at' v and no_0_obj')
(vcpu_write_reg v r val) (vcpuWriteReg v r val)"
apply (simp add: vcpu_write_reg_def vcpuWriteReg_def)
apply (rule corres_guard_imp)
apply (rule corres_assert_gen_asm2)
apply (rule vcpuUpdate_corres)
apply (fastforce simp: vcpu_relation_def)+
done
lemma vcpuSaveReg_corres[corres]:
"corres dc (vcpu_at v) (vcpu_at' v and no_0_obj')
(vcpu_save_reg v r) (vcpuSaveReg v r)"
apply (clarsimp simp: vcpu_save_reg_def vcpuSaveReg_def)
apply (rule corres_guard_imp)
apply (rule corres_assert_gen_asm2)
apply (rule corres_split[OF corres_machine_op[where r="(=)"]])
apply (rule corres_Id; simp)
apply (rule vcpuUpdate_corres, fastforce simp: vcpu_relation_def vgic_map_def)
apply wpsimp+
done
lemma vcpuSaveRegRange_corres[corres]:
"corres dc (vcpu_at v) (vcpu_at' v and no_0_obj')
(vcpu_save_reg_range v rf rt) (vcpuSaveRegRange v rf rt)"
apply (clarsimp simp: vcpu_save_reg_range_def vcpuSaveRegRange_def)
apply (rule corres_mapM_x[OF _ _ _ _ subset_refl])
apply (wpsimp wp: vcpuSaveReg_corres)+
done
lemma vcpuRestoreReg_corres[corres]:
"corres dc (vcpu_at v) (vcpu_at' v and no_0_obj')
(vcpu_restore_reg v r) (vcpuRestoreReg v r)"
apply (clarsimp simp: vcpu_restore_reg_def vcpuRestoreReg_def)
apply (rule corres_guard_imp)
apply (rule corres_assert_gen_asm2)
apply (rule corres_split[OF getObject_vcpu_corres])
apply (rule corres_machine_op)
apply (rule corres_Id)
apply (fastforce simp: vcpu_relation_def)
apply (wpsimp wp: corres_Id simp: vcpu_relation_def vgic_map_def)+
done
lemma vcpuRestoreRegRange_corres[corres]:
"corres dc (vcpu_at v) (vcpu_at' v and no_0_obj')
(vcpu_restore_reg_range v rf rt) (vcpuRestoreRegRange v rf rt)"
apply (clarsimp simp: vcpu_restore_reg_range_def vcpuRestoreRegRange_def)
apply (rule corres_mapM_x[OF _ _ _ _ subset_refl])
apply (wpsimp wp: vcpuRestoreReg_corres)+
done
lemma saveVirtTimer_corres[corres]:
"corres dc (vcpu_at vcpu_ptr) (vcpu_at' vcpu_ptr and no_0_obj')
(save_virt_timer vcpu_ptr) (saveVirtTimer vcpu_ptr)"
unfolding save_virt_timer_def saveVirtTimer_def
apply (rule corres_guard_imp)
apply (rule corres_split_dc[OF vcpuSaveReg_corres], simp)
apply (rule corres_split_dc[OF corres_machine_op], (rule corres_Id; simp))
apply (rule corres_split_eqr[OF corres_machine_op], (rule corres_Id; simp))+
apply (rule corres_split_dc[OF vcpuWriteReg_corres], simp)+
apply (rule corres_split_eqr[OF corres_machine_op])
apply (rule corres_Id; simp)
apply (fold dc_def)
apply (rule vcpuUpdate_corres)
apply (simp add: vcpu_relation_def)
apply wpsimp+
done
lemma isIRQActive_corres:
"corres (=) \<top> \<top> (is_irq_active irqVTimerEvent) (isIRQActive irqVTimerEvent)"
apply (clarsimp simp: isIRQActive_def getIRQState_def is_irq_active_def get_irq_state_def)
apply (clarsimp simp: is_irq_active_def isIRQActive_def
get_irq_state_def irq_state_relation_def
getIRQState_def getInterruptState_def
state_relation_def interrupt_state_relation_def)
apply (fastforce split: irq_state.splits irqstate.splits)
done
lemma restoreVirtTimer_corres[corres]:
"corres dc (vcpu_at vcpu_ptr) (vcpu_at' vcpu_ptr and no_0_obj')
(restore_virt_timer vcpu_ptr) (restoreVirtTimer vcpu_ptr)"
unfolding restore_virt_timer_def restoreVirtTimer_def IRQ_def
apply (rule corres_guard_imp)
apply (rule corres_split_eqr[OF vcpuReadReg_corres], simp)
apply (rule corres_split_eqr[OF vcpuReadReg_corres])
apply (rule corres_split_eqr[OF corres_machine_op], (rule corres_Id; simp))+
apply (rule corres_split[OF getObject_vcpu_corres])
apply (rule corres_split_eqr[OF vcpuReadReg_corres])
apply (rule corres_split_eqr[OF vcpuReadReg_corres])
apply (clarsimp simp: vcpu_relation_def)
apply (rule corres_split_dc[OF vcpuWriteReg_corres])+
apply (rule corres_split_dc[OF corres_machine_op])
apply (rule corres_Id; simp)
apply (rule corres_split_eqr[OF isIRQActive_corres])
apply (rule corres_split_dc[OF corres_when], simp)
apply (simp add: irq_vppi_event_index_def irqVPPIEventIndex_def IRQ_def)
apply (rule corres_machine_op, simp)
apply (rule corres_Id; wpsimp)
apply (rule vcpuRestoreReg_corres)
apply (wpsimp simp: if_apply_def2 isIRQActive_def)+
done
lemma vcpuSave_corres:
"corres dc (vcpu_at (fst cvcpu)) (vcpu_at' (fst cvcpu) and no_0_obj')
(vcpu_save (Some cvcpu)) (vcpuSave (Some cvcpu))"
supply no_fail_isb[wp] no_fail_dsb[wp]
apply (clarsimp simp add: vcpu_save_def vcpuSave_def armvVCPUSave_def)
apply (cases cvcpu, clarsimp, rename_tac v active)
apply (rule corres_guard_imp)
apply (rule corres_split_dc[OF corres_machine_op])
apply (rule corres_Id; wpsimp)
apply (rule corres_split[where r'=dc])
apply (rule corres_when, simp)
apply (rule corres_split[OF vcpuSaveReg_corres])
apply (rule corres_split_eqr[OF corres_machine_op])
apply (rule corres_Id; wpsimp)
apply (rule corres_split[OF vgicUpdate_corres])
apply (clarsimp simp: vgic_map_def)
apply (rule saveVirtTimer_corres)
apply wpsimp+
apply (rule corres_split_eqr[OF corres_machine_op])
apply (rule corres_Id; wpsimp)
apply (rule corres_split[OF vgicUpdate_corres])
apply (clarsimp simp: vgic_map_def)
apply (rule corres_split_eqr[OF corres_machine_op])
apply (rule corres_Id; wpsimp)
apply (rule corres_split[OF vgicUpdate_corres])
apply (clarsimp simp: vgic_map_def)
apply (rule corres_split_eqr)
apply (rule corres_trivial)
apply (fastforce simp add: state_relation_def arch_state_relation_def)
apply (simp add: mapM_discarded)
apply (rule corres_split[OF corres_mapM_x[OF _ _ _ _ subset_refl]])
apply (rule corres_split_eqr[OF corres_machine_op])
apply (rule corres_Id; wpsimp)
apply (clarsimp, fold dc_def)
apply (rule vgicUpdateLR_corres)
apply wpsimp+
apply (rule corres_split[OF vcpuSaveRegRange_corres])
apply (rule corres_machine_op)
apply (rule corres_Id; wpsimp)
apply (wpsimp wp: mapM_x_wp_inv hoare_vcg_imp_lift'
simp: if_apply_def2)+
done
lemma vcpuDisable_corres:
"corres dc (\<lambda>s. (\<exists>v. vcpuopt = Some v) \<longrightarrow> vcpu_at (the vcpuopt) s)
(\<lambda>s. ((\<exists>v. vcpuopt = Some v) \<longrightarrow> vcpu_at' (the vcpuopt) s) \<and> no_0_obj' s)
(vcpu_disable vcpuopt)
(vcpuDisable vcpuopt)"
(* FIXME these should be in wp/simp sets *)
supply no_fail_isb[wp] no_fail_dsb[wp] empty_fail_isb[wp,simp] empty_fail_dsb[wp,simp]
apply (cases vcpuopt; clarsimp simp: vcpu_disable_def vcpuDisable_def)
(* no current VCPU *)
subgoal
apply (clarsimp simp: doMachineOp_bind do_machine_op_bind empty_fail_cond)
apply (rule corres_guard_imp)
apply (rule corres_split_dc[OF corres_machine_op]
| rule corres_machine_op corres_Id
| wpsimp)+
done
(* have current VCPU *)
apply (rename_tac vcpu)
apply (clarsimp simp: doMachineOp_bind do_machine_op_bind bind_assoc IRQ_def)
apply (rule corres_guard_imp)
apply (rule corres_split_dc[OF corres_machine_op])
apply (rule corres_Id; wpsimp)
apply (rule corres_split_eqr[OF corres_machine_op])
apply (rule corres_Id; wpsimp)
apply (rule corres_split_dc[OF vgicUpdate_corres])
apply (clarsimp simp: vgic_map_def)
apply (rule corres_split_dc[OF vcpuSaveReg_corres])
apply (rule corres_split_dc[OF corres_machine_op]
corres_split_dc[OF saveVirtTimer_corres]
| rule corres_machine_op corres_Id
| wpsimp)+
done
lemma vcpuEnable_corres:
"corres dc (vcpu_at vcpu) (vcpu_at' vcpu and no_0_obj')
(vcpu_enable vcpu) (vcpuEnable vcpu)"
(* FIXME these should be in wp/simp sets *)
supply no_fail_isb[wp] no_fail_dsb[wp] empty_fail_isb[wp,simp] empty_fail_dsb[wp,simp]
apply (simp add: vcpu_enable_def vcpuEnable_def doMachineOp_bind do_machine_op_bind bind_assoc)
apply (rule corres_guard_imp)
apply (rule corres_split_dc[OF vcpuRestoreReg_corres])+
apply (rule corres_split[OF getObject_vcpu_corres], rename_tac vcpu')
apply (case_tac vcpu')
apply (rule corres_split_dc[OF corres_machine_op]
| rule corres_machine_op corres_Id restoreVirtTimer_corres
| wpsimp simp: vcpu_relation_def vgic_map_def)+
done
lemma vcpuRestore_corres:
"corres dc (vcpu_at vcpu)
(vcpu_at' vcpu and no_0_obj')
(vcpu_restore vcpu)
(vcpuRestore vcpu)"
(* FIXME these should be in wp/simp sets *)
supply no_fail_isb[wp] no_fail_dsb[wp] empty_fail_isb[wp,simp] empty_fail_dsb[wp,simp]
apply (simp add: vcpu_restore_def vcpuRestore_def gicVCPUMaxNumLR_def)
apply (rule corres_guard_imp)
apply (rule corres_split_dc[OF corres_machine_op]
| (rule corres_machine_op corres_Id; wpsimp))+
apply (rule corres_split[OF getObject_vcpu_corres], rename_tac vcpu')
apply (rule corres_split[OF corres_gets_gicvcpu_numlistregs])
apply (case_tac vcpu'
, clarsimp simp: comp_def vcpu_relation_def vgic_map_def mapM_x_mapM
uncurry_def split_def mapM_map_simp)
apply (simp add: doMachineOp_bind do_machine_op_bind bind_assoc empty_fail_cond)
apply (rule corres_split_dc[OF corres_machine_op])
apply (rule corres_Id; wpsimp)
apply (rule corres_split_dc[OF corres_machine_op])
apply (rule corres_Id; wpsimp)
apply (rule corres_split)
apply (rule corres_machine_op, rule corres_Id; wpsimp wp: no_fail_mapM)
apply (rule corres_split_dc[OF vcpuRestoreRegRange_corres])
apply (rule vcpuEnable_corres)
apply wpsimp+
done
crunches
vcpuUpdate for vcpu_at'[wp]: "\<lambda>s. P (vcpu_at' p s)"
lemma vcpuSwitch_corres:
assumes "vcpu' = vcpu"
shows
"corres dc (\<lambda>s. (vcpu \<noteq> None \<longrightarrow> vcpu_at (the vcpu) s) \<and>
((arm_current_vcpu \<circ> arch_state) s \<noteq> None
\<longrightarrow> vcpu_at ((fst \<circ> the \<circ> arm_current_vcpu \<circ> arch_state) s) s))
(\<lambda>s. (vcpu' \<noteq> None \<longrightarrow> vcpu_at' (the vcpu') s) \<and>
((armHSCurVCPU \<circ> ksArchState) s \<noteq> None
\<longrightarrow> vcpu_at' ((fst \<circ> the \<circ> armHSCurVCPU \<circ> ksArchState) s) s) \<and>
no_0_obj' s)
(vcpu_switch vcpu)
(vcpuSwitch vcpu')"
proof -
have modify_current_vcpu:
"\<And>a b. corres dc \<top> \<top> (modify (\<lambda>s. s\<lparr>arch_state := arch_state s\<lparr>arm_current_vcpu := Some (a, b)\<rparr>\<rparr>))
(modifyArchState (armHSCurVCPU_update (\<lambda>_. Some (a, b))))"
by (clarsimp simp add: modifyArchState_def state_relation_def arch_state_relation_def
intro!: corres_modify)
have get_current_vcpu: "corres (=) \<top> \<top> (gets (arm_current_vcpu \<circ> arch_state))
(gets (armHSCurVCPU \<circ> ksArchState))"
apply clarsimp
apply (rule_tac P = "(arm_current_vcpu (arch_state s)) = (armHSCurVCPU (ksArchState s'))"
in TrueE;
simp add: state_relation_def arch_state_relation_def)
done
show ?thesis
apply (simp add: vcpu_switch_def vcpuSwitch_def assms)
apply (cases vcpu)
apply (all \<open>simp, rule corres_underlying_split[OF _ _ gets_sp gets_sp],
rule corres_guard_imp[OF get_current_vcpu TrueI TrueI],
rename_tac rv rv', case_tac rv ;
clarsimp simp add: when_def\<close>)
apply (rule corres_machine_op[OF corres_underlying_trivial[OF no_fail_isb]] TrueI TrueI
vcpuDisable_corres modify_current_vcpu
vcpuEnable_corres
vcpuRestore_corres
vcpuSave_corres
hoare_post_taut conjI
corres_underlying_split corres_guard_imp
| clarsimp simp add: when_def | wpsimp | assumption)+
done
qed
lemma aligned_distinct_relation_vcpu_atI'[elim]:
"\<lbrakk> vcpu_at p s; pspace_relation (kheap s) (ksPSpace s');
pspace_aligned' s'; pspace_distinct' s' \<rbrakk>
\<Longrightarrow> vcpu_at' p s'"
apply (clarsimp simp add: pde_at_def obj_at_def a_type_def)
apply (simp split: Structures_A.kernel_object.split_asm
if_split_asm arch_kernel_obj.split_asm)
apply (drule(1) pspace_relation_absD)
apply (clarsimp simp: other_obj_relation_def)
apply (case_tac z ; simp)
apply (rename_tac vcpu)
apply (case_tac vcpu; simp)
apply (clarsimp simp: vcpu_relation_def obj_at'_def typ_at'_def ko_wp_at'_def projectKOs)
apply (fastforce simp add: pspace_aligned'_def pspace_distinct'_def dom_def)
done
lemma vcpuSwitch_corres':
assumes "vcpu' = vcpu"
shows
"corres dc (\<lambda>s. (vcpu \<noteq> None \<longrightarrow> vcpu_at (the vcpu) s) \<and>
((arm_current_vcpu \<circ> arch_state) s \<noteq> None
\<longrightarrow> vcpu_at ((fst \<circ> the \<circ> arm_current_vcpu \<circ> arch_state) s) s))
(pspace_aligned' and pspace_distinct' and no_0_obj')
(vcpu_switch vcpu)
(vcpuSwitch vcpu')"
apply (rule stronger_corres_guard_imp,
rule vcpuSwitch_corres[OF assms])
apply simp
apply (simp add: assms)
apply (rule conjI)
apply clarsimp
apply (rule aligned_distinct_relation_vcpu_atI' ; clarsimp simp add: state_relation_def, assumption?)
apply (clarsimp simp add: state_relation_def arch_state_relation_def)
apply (rule aligned_distinct_relation_vcpu_atI'; assumption)
done
lemma no_fail_setCurrentPDPL2: "no_fail \<top> (setCurrentPDPL2 w)"
by (simp add: set_current_pd_def setCurrentPDPL2_def)
lemma setCurrentPD_corres:
"addr = addr' \<Longrightarrow> corres dc \<top> \<top> (do_machine_op (set_current_pd addr)) (doMachineOp (setCurrentPD addr'))"
apply (simp add: setCurrentPD_def set_current_pd_def)
apply (rule corres_machine_op)
apply (rule corres_guard_imp)
apply (rule corres_rel_imp)
apply (rule corres_underlying_trivial)
apply (rule no_fail_setCurrentPDPL2)
apply simp+
done
crunch tcb_at'[wp]: armv_contextSwitch "tcb_at' t"
crunch ko_at'[wp]: armv_contextSwitch "ko_at' p t"
crunch tcb_at[wp]: arm_context_switch "tcb_at p"
crunch ko_at[wp]: arm_context_switch "ko_at p t"
crunch pspace_distinct'[wp]: getHWASID "pspace_distinct'"
crunch pspace_aligned'[wp]: getHWASID "pspace_aligned'"
(* TODO: move CSpaceInv_AI *)
lemma assert_get_tcb_ko':
shows "\<lbrace>P\<rbrace> gets_the (get_tcb thread) \<lbrace>\<lambda>t. P and ko_at (TCB t) thread\<rbrace>"
by (clarsimp simp: valid_def in_monad gets_the_def get_tcb_def
obj_at_def
split: option.splits Structures_A.kernel_object.splits)
lemma valid_objs_valid_tcb: "\<lbrakk> valid_objs s ; ko_at (TCB t) p s \<rbrakk> \<Longrightarrow> valid_tcb p t s"
by (fastforce simp add: valid_objs_def valid_obj_def obj_at_def)
lemma valid_objs_valid_tcb': "\<lbrakk> valid_objs' s ; ko_at' (t :: tcb) p s \<rbrakk> \<Longrightarrow> valid_tcb' t s"
by (fastforce simp add: obj_at'_def ran_def valid_obj'_def projectKOs valid_objs'_def)
lemma setVMRoot_corres:
"corres dc (tcb_at t and valid_arch_state and valid_objs and valid_asid_map
and unique_table_refs o caps_of_state and valid_vs_lookup
and pspace_aligned and pspace_distinct
and valid_vspace_objs)
(pspace_aligned' and pspace_distinct'
and valid_arch_state' and tcb_at' t and no_0_obj')
(set_vm_root t) (setVMRoot t)"
proof -
have Q: "\<And>P P'. corres dc P P'
(throwError ExceptionTypes_A.lookup_failure.InvalidRoot <catch>
(\<lambda>_. do global_us_pd \<leftarrow> gets (arm_us_global_pd \<circ> arch_state);
do_machine_op $ set_current_pd $ addrFromKPPtr global_us_pd
od))
(throwError Fault_H.lookup_failure.InvalidRoot <catch>
(\<lambda>_ . do globalPD \<leftarrow> gets (armUSGlobalPD \<circ> ksArchState);
doMachineOp $ setCurrentPD $ addrFromKPPtr globalPD
od))"
apply (rule corres_guard_imp)
apply (rule corres_split_catch [where f=lfr])
apply (rule corres_trivial)
apply (subst corres_throwError, simp add: lookup_failure_map_def)
apply (rule corres_underlying_split [where P=\<top> and P'=\<top> and r'="(=)"])
apply (clarsimp simp: state_relation_def arch_state_relation_def)
apply (simp, rule setCurrentPD_corres, rule refl)
apply wpsimp+
done
have valid_tcb_vcpu: "\<And>s t p v.\<lbrakk> valid_tcb p t s; tcb_vcpu (tcb_arch t) = Some v \<rbrakk>
\<Longrightarrow> vcpu_at v s"
by (clarsimp simp add: valid_tcb_def valid_arch_tcb_def)
have valid_arch_state_curr_vcpu:
"\<And>a b s. \<lbrakk>valid_arch_state s; arm_current_vcpu (arch_state s) = Some (a, b)\<rbrakk>
\<Longrightarrow> vcpu_at a s"
by (clarsimp simp add: valid_arch_state_def obj_at_def is_vcpu_def)
show ?thesis
unfolding set_vm_root_def setVMRoot_def locateSlot_conv
getThreadVSpaceRoot_def
apply (rule corres_guard_imp)
apply (rule corres_underlying_split [where r'="(=) \<circ> cte_map"])
apply (simp add: tcbVTableSlot_def cte_map_def objBits_def cte_level_bits_def
objBitsKO_def tcb_cnode_index_def to_bl_1)
apply (rule_tac R="\<lambda>thread_root. valid_arch_state and valid_asid_map and
valid_vspace_objs and valid_vs_lookup and
unique_table_refs o caps_of_state and
valid_objs and
tcb_at t and
pspace_aligned and pspace_distinct and
cte_wp_at ((=) thread_root) thread_root_slot"
and R'="\<lambda>thread_root. pspace_aligned' and pspace_distinct' and no_0_obj' and tcb_at' t"
in corres_split[OF getSlotCap_corres])
apply simp
apply (case_tac rv, simp_all add: isCap_simps Q[simplified])[1]
apply (rename_tac arch_cap)
apply (case_tac arch_cap, simp_all add: isCap_simps Q[simplified])[1]
apply (rename_tac word option)
apply (case_tac option, simp_all add: Q[simplified])[1]
apply (clarsimp simp: cap_asid_def)
apply (rule corres_guard_imp)
apply (rule corres_split_catch [where f=lfr])
apply (rule corres_split_eqrE[OF find_pd_for_asid_corres])
apply simp
apply (rule whenE_throwError_corres)
apply (simp add: lookup_failure_map_def)
apply simp
apply simp
apply (rule armv_contextSwitch_corres)
apply simp
apply (wpsimp wp: assert_get_tcb_ko' find_pd_for_asid_pd_at_asid_again
simp: armv_contextSwitch_def if_apply_def2
| wp (once) hoare_drop_imps)+
apply (simp add: checkPDNotInASIDMap_def
checkPDASIDMapMembership_def)
apply (rule_tac P'="(Not \<circ> vspace_at_asid aa word) and K (aa \<le> mask asid_bits)
and pd_at_uniq aa word
and valid_asid_map and valid_vs_lookup
and (unique_table_refs o caps_of_state)
and valid_vspace_objs
and valid_arch_state"
in corres_stateAssert_implied)
apply (rule corres_underlying_split [where P=\<top> and P'=\<top> and r'="(=)"])
apply (clarsimp simp: state_relation_def arch_state_relation_def)
apply (rule setCurrentPD_corres, simp)
apply wp+
apply (clarsimp simp: restrict_map_def state_relation_asid_map
elim!: ranE)
apply (frule(1) valid_asid_mapD)
apply (case_tac "x = aa")
apply clarsimp
apply (clarsimp simp: pd_at_uniq_def restrict_map_def)
apply (erule notE, rule_tac a=x in ranI)
apply simp
apply ((wp find_pd_for_asid_pd_at_asid_again
| simp add: if_apply_def2 | wp (once) hoare_drop_imps)+)
apply clarsimp
apply (frule page_directory_cap_pd_at_uniq, simp+)
apply (frule(1) cte_wp_at_valid_objs_valid_cap)
apply (clarsimp simp: valid_cap_def mask_def
word_neq_0_conv)
apply (drule(1) pd_at_asid_unique2, simp)
apply simp+
apply (wp get_cap_wp | simp)+
apply (clarsimp simp: tcb_at_cte_at_1 [simplified])
apply simp
done
qed
lemma invalidateTLBByASID_invs'[wp]:
"\<lbrace>invs'\<rbrace> invalidateTLBByASID param_a \<lbrace>\<lambda>_. invs'\<rbrace>"
apply (clarsimp simp: invalidateTLBByASID_def loadHWASID_def
| wp dmo_invs' no_irq_invalidateLocalTLB_ASID no_irq | wpc)+
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply (clarsimp simp: invalidateLocalTLB_ASID_def machine_op_lift_def
machine_rest_lift_def split_def | wp)+
done
crunches flushSpace
for aligned' [wp]: pspace_aligned'
and distinct' [wp]: pspace_distinct'
and valid_arch' [wp]: valid_arch_state'
and cur_tcb' [wp]: cur_tcb'
lemma get_asid_pool_corres_inv':
"corres (\<lambda>p. (\<lambda>p'. p = p' o ucast) \<circ> inv ASIDPool)
(asid_pool_at p) (pspace_aligned' and pspace_distinct')
(get_asid_pool p) (getObject p)"
apply (rule corres_rel_imp)
apply (rule getObject_ASIDPool_corres')
apply simp
done
lemma loadHWASID_wp [wp]:
"\<lbrace>\<lambda>s. P (option_map fst (armKSASIDMap (ksArchState s) asid)) s\<rbrace>
loadHWASID asid \<lbrace>P\<rbrace>"
apply (simp add: loadHWASID_def)
apply (wp findPDForASIDAssert_pd_at_wp
| wpc | simp | wp (once) hoare_drop_imps)+
apply (auto split: option.split)
done
lemma invalidateASIDEntry_corres:
"corres dc (valid_vspace_objs and valid_asid_map
and K (asid \<le> mask asid_bits \<and> asid \<noteq> 0)
and vspace_at_asid asid pd and valid_vs_lookup
and unique_table_refs o caps_of_state
and valid_arch_state
and pspace_aligned and pspace_distinct)
(pspace_aligned' and pspace_distinct' and no_0_obj')
(invalidate_asid_entry asid) (invalidateASIDEntry asid)"
apply (simp add: invalidate_asid_entry_def invalidateASIDEntry_def)
apply (rule corres_guard_imp)
apply (rule corres_split[OF loadHWASID_corres[where pd=pd]])
apply (rule corres_split[OF corres_when])
apply simp
apply simp
apply (rule invalidateHWASIDEntry_corres)
apply (rule invalidateASID_corres[where pd=pd])
apply (wp load_hw_asid_wp
| clarsimp cong: if_cong)+
apply (simp add: pd_at_asid_uniq)
apply simp
done
crunch aligned'[wp]: invalidateASID "pspace_aligned'"
crunch distinct'[wp]: invalidateASID "pspace_distinct'"
lemma invalidateASID_cur' [wp]:
"\<lbrace>cur_tcb'\<rbrace> invalidateASID x \<lbrace>\<lambda>_. cur_tcb'\<rbrace>"
by (simp add: invalidateASID_def|wp)+
crunch aligned' [wp]: invalidateASIDEntry pspace_aligned'
crunch distinct' [wp]: invalidateASIDEntry pspace_distinct'
crunch cur' [wp]: invalidateASIDEntry cur_tcb'
lemma invalidateASID_valid_arch_state [wp]:
"\<lbrace>valid_arch_state'\<rbrace> invalidateASIDEntry x \<lbrace>\<lambda>_. valid_arch_state'\<rbrace>"
supply option.case_cong_weak[cong]
apply (simp add: invalidateASID_def
invalidateASIDEntry_def invalidateHWASIDEntry_def)
apply (wp | simp)+
apply (clarsimp simp: valid_arch_state'_def simp del: fun_upd_apply)
apply (rule conjI)
apply (clarsimp simp: is_inv_None_upd fun_upd_def[symmetric] comp_upd_simp
inj_on_fun_upd_elsewhere valid_asid_map'_def)
apply (auto elim!: subset_inj_on dest!: ran_del_subset split: option.splits)
done
crunches vcpuDisable, vcpuEnable, vcpuSave, vcpuRestore
for no_0_obj'[wp]: no_0_obj'
(simp: crunch_simps wp: crunch_wps getObject_inv_vcpu loadObject_default_inv)
lemma vcpuSwitch_no_0_obj'[wp]: "\<lbrace>no_0_obj'\<rbrace> vcpuSwitch v \<lbrace>\<lambda>_. no_0_obj'\<rbrace>"
by (wpsimp simp: vcpuSwitch_def modifyArchState_def | assumption)+
crunch no_0_obj'[wp]: deleteASID "no_0_obj'"
(simp: crunch_simps
wp: crunch_wps getObject_inv loadObject_default_inv)
lemma deleteASID_corres:
"corres dc
(invs and valid_etcbs and K (asid \<le> mask asid_bits \<and> asid \<noteq> 0))
(pspace_aligned' and pspace_distinct' and no_0_obj'
and valid_arch_state' and cur_tcb')
(delete_asid asid pd) (deleteASID asid pd)"
apply (simp add: delete_asid_def deleteASID_def)
apply (rule corres_guard_imp)
apply (rule corres_split[OF corres_gets_asid])
apply (case_tac "asid_table (asid_high_bits_of asid)", simp)
apply clarsimp
apply (rule_tac P="\<lambda>s. asid_high_bits_of asid \<in> dom (asidTable o ucast) \<longrightarrow>
asid_pool_at (the ((asidTable o ucast) (asid_high_bits_of asid))) s" and
P'="pspace_aligned' and pspace_distinct'" and
Q="invs and valid_etcbs and K (asid \<le> mask asid_bits \<and> asid \<noteq> 0) and
(\<lambda>s. arm_asid_table (arch_state s) = asidTable \<circ> ucast)" in
corres_split)
apply (simp add: dom_def)
apply (rule get_asid_pool_corres_inv')
apply (rule corres_when, simp add: mask_asid_low_bits_ucast_ucast)
apply (rule corres_split[OF flushSpace_corres[where pd=pd]])
apply (rule corres_split[OF invalidateASIDEntry_corres[where pd=pd]])
apply (rule_tac P="asid_pool_at (the (asidTable (ucast (asid_high_bits_of asid))))
and valid_etcbs"
and P'="pspace_aligned' and pspace_distinct'"
in corres_split)
apply (simp del: fun_upd_apply)
apply (rule setObject_ASIDPool_corres')
apply (simp add: inv_def mask_asid_low_bits_ucast_ucast)
apply (rule ext)
apply (clarsimp simp: o_def)
apply (erule notE)
apply (erule ucast_ucast_eq, simp, simp)
apply (rule corres_split[OF getCurThread_corres])
apply simp
apply (rule setVMRoot_corres)
apply wp+
apply (simp del: fun_upd_apply)
apply (fold cur_tcb_def)
apply (wp set_asid_pool_asid_map_unmap
set_asid_pool_vspace_objs_unmap_single
set_asid_pool_vs_lookup_unmap')+
apply simp
apply (fold cur_tcb'_def)
apply (wp invalidate_asid_entry_invalidates)+
apply (wp | clarsimp simp: o_def)+
apply (subgoal_tac "vspace_at_asid asid pd s")
apply (auto simp: obj_at_def a_type_def graph_of_def
split: if_split_asm)[1]
apply (simp add: vspace_at_asid_def)
apply (rule vs_lookupI)
apply (simp add: vs_asid_refs_def)
apply (rule image_eqI[OF refl])
apply (erule graph_ofI)
apply (rule r_into_rtrancl)
apply simp
apply (erule vs_lookup1I [OF _ _ refl])
apply (simp add: vs_refs_def)
apply (rule image_eqI[rotated], erule graph_ofI)
apply (simp add: mask_asid_low_bits_ucast_ucast)
apply wp
apply (simp add: o_def)
apply (wp getASID_wp)
apply clarsimp
apply assumption
apply wp+
apply clarsimp
apply (clarsimp simp: valid_arch_state_def valid_asid_table_def
dest!: invs_arch_state)
apply blast
apply (clarsimp simp: valid_arch_state'_def valid_asid_table'_def)
done
lemma valid_arch_state_unmap_strg':
"valid_arch_state' s \<longrightarrow>
valid_arch_state' (s\<lparr>ksArchState :=
armKSASIDTable_update (\<lambda>_. (armKSASIDTable (ksArchState s))(ptr := None))
(ksArchState s)\<rparr>)"
apply (simp add: valid_arch_state'_def valid_asid_table'_def)
apply (auto simp: ran_def split: if_split_asm option.splits)
done
crunch armKSASIDTable_inv[wp]: invalidateASIDEntry
"\<lambda>s. P (armKSASIDTable (ksArchState s))"
crunch armKSASIDTable_inv[wp]: flushSpace
"\<lambda>s. P (armKSASIDTable (ksArchState s))"
lemma deleteASIDPool_corres:
"corres dc
(invs and K (is_aligned base asid_low_bits
\<and> base \<le> mask asid_bits)
and asid_pool_at ptr)
(pspace_aligned' and pspace_distinct' and no_0_obj'
and valid_arch_state' and cur_tcb')
(delete_asid_pool base ptr) (deleteASIDPool base ptr)"
apply (simp add: delete_asid_pool_def deleteASIDPool_def)
apply (rule corres_assume_pre, simp add: is_aligned_mask
cong: corres_weak_cong)
apply (thin_tac P for P)+
apply (rule corres_guard_imp)
apply (rule corres_split[OF corres_gets_asid])
apply (rule corres_when)
apply simp
apply (simp add: liftM_def)
apply (rule corres_split[OF getObject_ASIDPool_corres'])
apply (rule corres_split)
apply (rule corres_mapM [where r=dc and r'=dc], simp, simp)
prefer 5
apply (rule order_refl)
apply (drule_tac t="inv f x \<circ> g" for f x g in sym)
apply (rule_tac P="invs and
ko_at (ArchObj (arch_kernel_obj.ASIDPool pool)) ptr and
[VSRef (ucast (asid_high_bits_of base)) None] \<rhd> ptr and
K (is_aligned base asid_low_bits
\<and> base \<le> mask asid_bits)"
and P'="pspace_aligned' and pspace_distinct' and no_0_obj'"
in corres_guard_imp)
apply (rule corres_when)
apply (clarsimp simp: ucast_ucast_low_bits)
apply simp
apply (rule_tac pd1="the (pool (ucast xa))"
in corres_split[OF flushSpace_corres])
apply (rule_tac pd="the (pool (ucast xa))"
in invalidateASIDEntry_corres)
apply wp
apply clarsimp
apply wp+
apply (clarsimp simp: invs_def valid_state_def
valid_arch_caps_def valid_pspace_def
vspace_at_asid_def cong: conj_cong)
apply (rule conjI)
apply (clarsimp simp: mask_def asid_low_bits_word_bits
elim!: is_alignedE)
apply (subgoal_tac "of_nat q < (2 ^ asid_high_bits :: word32)")
apply (subst mult.commute, rule word_add_offset_less)
apply assumption
apply assumption
apply (simp add: asid_bits_def word_bits_def)
apply (erule order_less_le_trans)
apply (simp add: word_bits_def asid_low_bits_def asid_high_bits_def)
apply (simp add: asid_bits_def asid_high_bits_def asid_low_bits_def)
apply (drule word_power_less_diff)
apply (drule of_nat_mono_maybe[where 'a=32, rotated])
apply (simp add: word_bits_def asid_low_bits_def)
apply (subst word_unat_power, simp)
apply (simp add: asid_bits_def word_bits_def)
apply (simp add: asid_low_bits_def word_bits_def)
apply (simp add: asid_bits_def asid_low_bits_def asid_high_bits_def)
apply (subst conj_commute, rule context_conjI)
apply (erule vs_lookup_trancl_step)
apply (rule r_into_trancl)
apply (erule vs_lookup1I)
apply (simp add: vs_refs_def)
apply (rule image_eqI[rotated])
apply (rule graph_ofI, simp)
apply clarsimp
apply fastforce
apply (simp add: add_mask_eq asid_low_bits_word_bits
ucast_ucast_mask asid_low_bits_def[symmetric]
asid_high_bits_of_def)
apply (rule conjI)
apply (rule sym)
apply (simp add: is_aligned_add_helper[THEN conjunct1]
mask_eq_iff_w2p asid_low_bits_def word_size)
apply (rule_tac f="\<lambda>a. a && mask n" for n in arg_cong)
apply (rule shiftr_eq_mask_eq)
apply (simp add: is_aligned_add_helper is_aligned_neg_mask_eq)
apply clarsimp
apply (subgoal_tac "base \<le> base + xa")
apply (simp add: valid_vs_lookup_def asid_high_bits_of_def)
subgoal by (fastforce intro: vs_lookup_pages_vs_lookupI)
apply (erule is_aligned_no_wrap')
apply (simp add: asid_low_bits_word_bits)
apply (simp add: asid_low_bits_word_bits)
apply clarsimp
apply ((wp|clarsimp simp: o_def)+)[3]
apply (rule corres_split)
apply (rule corres_modify [where P=\<top> and P'=\<top>])
apply (simp add: state_relation_def arch_state_relation_def)
apply (rule ext)
apply clarsimp
apply (erule notE)
apply (rule word_eqI[rule_format])
apply (drule_tac x1="ucast xa" in bang_eq [THEN iffD1])
apply (erule_tac x=n in allE)
apply (simp add: word_size nth_ucast)
apply (rule corres_split)
apply (rule getCurThread_corres)
apply (simp only:)
apply (rule setVMRoot_corres)
apply wp+
apply (rule_tac R="\<lambda>_ s. rv = arm_asid_table (arch_state s)"
in hoare_post_add)
apply (drule sym, simp only: )
apply (drule sym, simp only: )
apply (thin_tac "P" for P)+
apply (simp only: pred_conj_def cong: conj_cong)
apply simp
apply (fold cur_tcb_def)
apply (strengthen valid_arch_state_unmap_strg
valid_vspace_objs_unmap_strg
valid_asid_map_unmap
valid_vs_lookup_unmap_strg, simp)
apply (rule hoare_vcg_conj_lift,
(rule mapM_invalidate[where ptr=ptr])?,
((wp mapM_wp' | simp)+)[1])+
apply (rule_tac R="\<lambda>_ s. rv' = armKSASIDTable (ksArchState s)"
in hoare_post_add)
apply (simp only: pred_conj_def cong: conj_cong)
apply simp
apply (strengthen valid_arch_state_unmap_strg')
apply (fold cur_tcb'_def)
apply (wp mapM_wp')+
apply (clarsimp simp: cur_tcb'_def)
apply (simp add: o_def pred_conj_def)
apply wp
apply (wp getASID_wp)+
apply (clarsimp simp: conj_comms)
apply (auto simp: vs_lookup_def intro: vs_asid_refsI)[1]
apply clarsimp
done
lemma setVMRootForFlush_corres:
"corres (=)
(cur_tcb and vspace_at_asid asid pd
and K (asid \<noteq> 0 \<and> asid \<le> mask asid_bits)
and valid_asid_map and valid_vs_lookup
and valid_vspace_objs
and unique_table_refs o caps_of_state
and valid_arch_state
and pspace_aligned and pspace_distinct)
(pspace_aligned' and pspace_distinct' and no_0_obj')
(set_vm_root_for_flush pd asid)
(setVMRootForFlush pd asid)"
proof -
have X: "corres (=) (vspace_at_asid asid pd and K (asid \<noteq> 0 \<and> asid \<le> mask asid_bits)
and valid_asid_map and valid_vs_lookup
and valid_vspace_objs
and unique_table_refs o caps_of_state
and valid_arch_state
and pspace_aligned and pspace_distinct)
(pspace_aligned' and pspace_distinct' and no_0_obj')
(do arm_context_switch pd asid;
return True
od)
(do armv_contextSwitch pd asid;
return True
od)"
apply (rule corres_guard_imp)
apply (rule corres_split[OF armv_contextSwitch_corres])
apply (rule corres_trivial)
apply (wp | simp)+
done
show ?thesis
apply (simp add: set_vm_root_for_flush_def setVMRootForFlush_def getThreadVSpaceRoot_def locateSlot_conv)
apply (rule corres_guard_imp)
apply (rule corres_split[OF getCurThread_corres])
apply (rule corres_split [where R="\<lambda>_. vspace_at_asid asid pd and K (asid \<noteq> 0 \<and> asid \<le> mask asid_bits)
and valid_asid_map and valid_vs_lookup
and valid_vspace_objs
and unique_table_refs o caps_of_state
and valid_arch_state
and pspace_aligned and pspace_distinct"
and R'="\<lambda>_. pspace_aligned' and pspace_distinct' and no_0_obj'",
OF getSlotCap_corres])
apply (simp add: cte_map_def objBits_simps tcb_cnode_index_def
tcbVTableSlot_def to_bl_1 cte_level_bits_def)
apply (case_tac "isArchObjectCap rv' \<and>
isPageDirectoryCap (capCap rv') \<and>
capPDMappedASID (capCap rv') \<noteq> None \<and>
capPDBasePtr (capCap rv') = pd")
apply (case_tac rv, simp_all add: isCap_simps)[1]
apply (rename_tac arch_cap)
apply (case_tac arch_cap, auto)[1]
apply (case_tac rv, simp_all add: isCap_simps[simplified] X[simplified])[1]
apply (rename_tac arch_cap)
apply (case_tac arch_cap, auto simp: X[simplified] split: option.splits)[1]
apply wp+
apply (clarsimp simp: cur_tcb_def)
apply (erule tcb_at_cte_at)
apply (simp add: tcb_cap_cases_def)
apply clarsimp
done
qed
crunch typ_at' [wp]: armv_contextSwitch "\<lambda>s. P (typ_at' T p s)"
(simp: crunch_simps)
crunch typ_at' [wp]: findPDForASID "\<lambda>s. P (typ_at' T p s)"
(wp: crunch_wps getObject_inv simp: crunch_simps loadObject_default_def)
crunches vcpuEnable, vcpuDisable, vcpuSave, vcpuRestore
for typ_at' [wp]: "\<lambda>s. P (typ_at' T p s)"
(simp: crunch_simps
wp: crunch_wps getObject_inv loadObject_default_inv)
lemma vcpuSwitch_typ_at'[wp]:
"\<lbrace>\<lambda>s. P (typ_at' T p s)\<rbrace> vcpuSwitch param_a \<lbrace>\<lambda>_ s. P (typ_at' T p s) \<rbrace>"
by (wpsimp simp: vcpuSwitch_def modifyArchState_def | assumption)+
crunch typ_at' [wp]: setVMRoot "\<lambda>s. P (typ_at' T p s)"
(simp: crunch_simps
wp: crunch_wps getObject_inv loadObject_default_inv)
lemmas setVMRoot_typ_ats [wp] = typ_at_lifts [OF setVMRoot_typ_at']
lemmas loadHWASID_typ_ats [wp] = typ_at_lifts [OF loadHWASID_inv]
crunch typ_at' [wp]: setVMRootForFlush "\<lambda>s. P (typ_at' T p s)"
(wp: hoare_drop_imps)
lemmas setVMRootForFlush_typ_ats' [wp] = typ_at_lifts [OF setVMRootForFlush_typ_at']
crunch aligned' [wp]: setVMRootForFlush pspace_aligned'
(wp: hoare_drop_imps)
crunch distinct' [wp]: setVMRootForFlush pspace_distinct'
(wp: hoare_drop_imps)
crunch cur' [wp]: setVMRootForFlush cur_tcb'
(wp: hoare_drop_imps)
lemma findPDForASID_inv2:
"\<lbrace>\<lambda>s. asid \<noteq> 0 \<and> asid \<le> mask asid_bits \<longrightarrow> P s\<rbrace> findPDForASID asid \<lbrace>\<lambda>rv. P\<rbrace>"
apply (cases "asid \<noteq> 0 \<and> asid \<le> mask asid_bits")
apply (simp add: findPDForASID_inv)
apply (simp add: findPDForASID_def assertE_def asidRange_def mask_def)
apply clarsimp
done
lemma storeHWASID_valid_arch' [wp]:
"\<lbrace>valid_arch_state' and
(\<lambda>s. armKSASIDMap (ksArchState s) asid = None \<and>
armKSHWASIDTable (ksArchState s) hw_asid = None)\<rbrace>
storeHWASID asid hw_asid
\<lbrace>\<lambda>_. valid_arch_state'\<rbrace>"
supply image_cong_simp [cong del]
apply (simp add: storeHWASID_def)
apply wp
prefer 2
apply assumption
apply (simp add: valid_arch_state'_def comp_upd_simp fun_upd_def[symmetric] cong: option.case_cong)
apply wp
apply (simp add: findPDForASIDAssert_def const_def
checkPDUniqueToASID_def checkPDASIDMapMembership_def)
apply wp
apply (rule_tac Q'="\<lambda>rv s. valid_asid_map' (armKSASIDMap (ksArchState s))
\<and> asid \<noteq> 0 \<and> asid \<le> mask asid_bits
\<and> armKSGICVCPUNumListRegs (ksArchState s) \<le> max_armKSGICVCPUNumListRegs"
in hoare_post_imp_R)
apply (wp findPDForASID_inv2)+
apply clarsimp
apply (clarsimp simp: valid_asid_map'_def)
apply (subst conj_commute, rule context_conjI)
apply clarsimp
apply (rule ccontr, erule notE, rule_tac a=x in ranI)
apply (simp add: restrict_map_def)
apply (erule(1) inj_on_fun_updI2)
apply clarsimp
apply (frule is_inv_NoneD[rotated], simp)
apply (simp add: ran_def)
apply (simp add: is_inv_def)
done
lemma storeHWASID_obj_at [wp]:
"\<lbrace>\<lambda>s. P (obj_at' P' t s)\<rbrace> storeHWASID x y \<lbrace>\<lambda>rv s. P (obj_at' P' t s)\<rbrace>"
apply (simp add: storeHWASID_def)
apply (wp | simp)+
done
lemma findFreeHWASID_obj_at [wp]:
"\<lbrace>\<lambda>s. P (obj_at' P' t s)\<rbrace> findFreeHWASID \<lbrace>\<lambda>rv s. P (obj_at' P' t s)\<rbrace>"
apply (simp add: findFreeHWASID_def invalidateASID_def
invalidateHWASIDEntry_def bind_assoc
cong: option.case_cong)
apply (wp doMachineOp_obj_at|wpc|simp)+
done
lemma findFreeHWASID_valid_arch [wp]:
"\<lbrace>valid_arch_state'\<rbrace> findFreeHWASID \<lbrace>\<lambda>_. valid_arch_state'\<rbrace>"
apply (simp add: findFreeHWASID_def invalidateHWASIDEntry_def
invalidateASID_def doMachineOp_def split_def
cong: option.case_cong)
apply (wp|wpc|simp split del: if_split)+
apply (clarsimp simp: valid_arch_state'_def fun_upd_def[symmetric]
comp_upd_simp valid_asid_map'_def cong: option.case_cong)
apply (frule is_inv_inj)
apply (drule findNoneD)
apply (drule_tac x="armKSNextASID (ksArchState s)" in bspec)
apply clarsimp
apply (clarsimp simp: is_inv_def ran_upd[folded fun_upd_def]
dom_option_map inj_on_fun_upd_elsewhere)
apply (rule conjI)
apply clarsimp
apply (drule_tac x="x" and y="armKSNextASID (ksArchState s)" in inj_onD)
apply simp
apply blast
apply blast
apply simp
apply (rule conjI)
apply (erule subset_inj_on, clarsimp)
apply (erule order_trans[rotated])
apply clarsimp
done
lemma findFreeHWASID_None_map [wp]:
"\<lbrace>\<lambda>s. armKSASIDMap (ksArchState s) asid = None\<rbrace>
findFreeHWASID
\<lbrace>\<lambda>rv s. armKSASIDMap (ksArchState s) asid = None\<rbrace>"
apply (simp add: findFreeHWASID_def invalidateHWASIDEntry_def invalidateASID_def
doMachineOp_def split_def
cong: option.case_cong)
apply (rule hoare_pre)
apply (wp|wpc|simp split del: if_split)+
apply auto
done
lemma findFreeHWASID_None_HWTable [wp]:
"\<lbrace>\<top>\<rbrace> findFreeHWASID \<lbrace>\<lambda>rv s. armKSHWASIDTable (ksArchState s) rv = None\<rbrace>"
apply (simp add: findFreeHWASID_def invalidateHWASIDEntry_def invalidateASID_def
doMachineOp_def
cong: option.case_cong)
apply (wp|wpc|simp)+
apply (auto dest!: findSomeD)
done
lemma getHWASID_valid_arch':
"\<lbrace>valid_arch_state'\<rbrace>
getHWASID asid \<lbrace>\<lambda>_. valid_arch_state'\<rbrace>"
apply (simp add: getHWASID_def)
apply (wp | wpc | simp)+
done
crunch valid_arch' [wp]: setVMRootForFlush "valid_arch_state'"
(wp: hoare_drop_imps)
lemma load_hw_asid_corres2:
"corres (=)
(valid_vspace_objs and pspace_distinct and pspace_aligned
and valid_asid_map and vspace_at_asid a pd
and valid_vs_lookup and valid_global_objs
and unique_table_refs o caps_of_state
and valid_arch_state and K (a \<noteq> 0 \<and> a \<le> mask asid_bits))
(pspace_aligned' and pspace_distinct' and no_0_obj')
(load_hw_asid a) (loadHWASID a)"
apply (rule stronger_corres_guard_imp)
apply (rule loadHWASID_corres[where pd=pd])
apply (clarsimp simp: pd_at_asid_uniq)
apply simp
done
crunch no_0_obj'[wp]: flushTable "no_0_obj'"
(wp: crunch_wps simp: crunch_simps)
lemma flushTable_corres:
"corres dc
(pspace_aligned and valid_objs and valid_arch_state and
cur_tcb and vspace_at_asid asid pd and valid_asid_map and valid_vspace_objs and
pspace_aligned and pspace_distinct and valid_vs_lookup
and unique_table_refs o caps_of_state and
K (is_aligned vptr (pageBitsForSize ARMSection) \<and> asid \<le> mask asid_bits \<and> asid \<noteq> 0))
(pspace_aligned' and pspace_distinct' and no_0_obj' and
valid_arch_state' and cur_tcb')
(flush_table pd asid vptr ptr)
(flushTable pd asid vptr)"
apply (simp add: flush_table_def flushTable_def)
apply (rule corres_assume_pre)
apply (simp add: ptBits_def pt_bits_def pageBits_def is_aligned_mask cong: corres_weak_cong)
apply (thin_tac "P" for P)+
apply (rule corres_guard_imp)
apply (rule corres_split[OF setVMRootForFlush_corres])
apply (rule corres_split[OF load_hw_asid_corres2[where pd=pd]])
apply (clarsimp cong: corres_weak_cong)
apply (rule corres_when, rule refl)
apply (rule corres_split[where r' = dc, OF corres_machine_op corres_when])
apply (rule corres_Id[OF refl])
apply simp
apply (rule no_fail_invalidateLocalTLB_ASID)
apply simp
apply (rule corres_split[OF getCurThread_corres])
apply (simp, rule setVMRoot_corres)
apply ((wp mapM_wp' hoare_vcg_const_imp_lift get_pte_wp getPTE_wp|
wpc|simp|fold cur_tcb_def cur_tcb'_def)+)[4]
apply (wpsimp wp: hoare_drop_imps | fold cur_tcb_def cur_tcb'_def)+
apply (wpsimp wp: hoare_post_taut load_hw_asid_wp simp: valid_global_objs_def
| rule hoare_drop_imps)+
done
lemma flushPage_corres:
"corres dc
(K (is_aligned vptr pageBits \<and> asid \<le> mask asid_bits \<and> asid \<noteq> 0) and
cur_tcb and valid_arch_state and valid_objs and
vspace_at_asid asid pd and valid_asid_map and valid_vspace_objs and
valid_vs_lookup and valid_global_objs and
unique_table_refs o caps_of_state and
pspace_aligned and pspace_distinct)
(pspace_aligned' and pspace_distinct' and no_0_obj'
and valid_arch_state' and cur_tcb')
(flush_page pageSize pd asid vptr)
(flushPage pageSize pd asid vptr)"
apply (clarsimp simp: flush_page_def flushPage_def)
apply (rule corres_assume_pre)
apply (simp add: is_aligned_mask cong: corres_weak_cong)
apply (thin_tac P for P)+
apply (rule corres_guard_imp)
apply (rule corres_split[OF setVMRootForFlush_corres])
apply (rule corres_split[OF load_hw_asid_corres2[where pd=pd]])
apply (clarsimp cong: corres_weak_cong)
apply (rule corres_when, rule refl)
apply (rule corres_split[OF corres_machine_op [where r=dc]])
apply (rule corres_Id, rule refl, simp)
apply (rule no_fail_pre, wp no_fail_invalidateLocalTLB_VAASID)
apply simp
apply (rule corres_when, rule refl)
apply (rule corres_split[OF getCurThread_corres])
apply simp
apply (rule setVMRoot_corres)
apply wp+
apply (simp add: cur_tcb_def [symmetric] cur_tcb'_def [symmetric])
apply (wpsimp wp: hoare_post_taut load_hw_asid_wp simp: valid_global_objs_def
| rule hoare_drop_imps
| fold cur_tcb_def cur_tcb'_def)+
done
crunch typ_at' [wp]: flushTable "\<lambda>s. P (typ_at' T p s)"
(simp: assertE_def when_def wp: crunch_wps)
lemmas flushTable_typ_ats' [wp] = typ_at_lifts [OF flushTable_typ_at']
lemmas findPDForASID_typ_ats' [wp] = typ_at_lifts [OF findPDForASID_inv]
crunch inv [wp]: findPDForASID P
(simp: assertE_def whenE_def loadObject_default_def
wp: crunch_wps getObject_inv)
crunches vcpuEnable, vcpuSave, vcpuDisable, vcpuRestore
for pspace_aligned'[wp]: pspace_aligned'
(simp: crunch_simps wp: crunch_wps getObject_inv_vcpu loadObject_default_inv)
lemma vcpuSwitch_aligned'[wp]: "\<lbrace>pspace_aligned'\<rbrace> vcpuSwitch param_a \<lbrace>\<lambda>_. pspace_aligned'\<rbrace>"
by (wpsimp simp: vcpuSwitch_def modifyArchState_def | assumption)+
crunches vcpuEnable, vcpuSave, vcpuDisable, vcpuRestore
for pspace_distinct'[wp]: pspace_distinct'
(simp: crunch_simps wp: crunch_wps getObject_inv_vcpu loadObject_default_inv)
lemma vcpuSwitch_distinct'[wp]: "\<lbrace>pspace_distinct'\<rbrace> vcpuSwitch param_a \<lbrace>\<lambda>_. pspace_distinct'\<rbrace>"
by (wpsimp simp: vcpuSwitch_def modifyArchState_def | assumption)+
crunch aligned'[wp]: unmapPageTable "pspace_aligned'"
(simp: crunch_simps
wp: crunch_wps getObject_inv loadObject_default_inv)
crunch distinct'[wp]: unmapPageTable "pspace_distinct'"
(simp: crunch_simps
wp: crunch_wps getObject_inv loadObject_default_inv)
lemma pageTableMapped_corres:
"corres (=) (valid_arch_state and valid_vspace_objs and pspace_aligned
and K (asid \<noteq> 0 \<and> asid \<le> mask asid_bits))
(pspace_aligned' and pspace_distinct' and no_0_obj')
(page_table_mapped asid vaddr pt)
(pageTableMapped asid vaddr pt)"
apply (simp add: page_table_mapped_def pageTableMapped_def)
apply (rule corres_guard_imp)
apply (rule corres_split_catch)
apply (rule corres_split_eqrE[OF find_pd_for_asid_corres])
apply simp
apply (simp add: liftE_bindE)
apply (rule corres_split[OF getObject_PDE_corres'])
apply (rule corres_trivial)
apply (case_tac rv,
simp_all add: returnOk_def pde_relation_aligned_def
split:if_splits ARM_HYP_H.pde.splits)[1]
apply (wp | simp add: lookup_pd_slot_def Let_def)+
apply (simp add: word_neq_0_conv)
apply simp
done
lemma storePDE_ko_wp_vcpu_at'[wp]:
"storePDE p pde \<lbrace>\<lambda>s. P (ko_wp_at' (is_vcpu' and hyp_live') p' s)\<rbrace>"
apply (clarsimp simp: storePDE_def)
apply (wp hoare_drop_imps setObject_ko_wp_at, simp, simp add: objBits_simps archObjSize_def)
apply (simp add: pde_bits_def)
apply (clarsimp split del: if_split)
apply (erule_tac P=P in rsubst)
apply (clarsimp simp: ko_wp_at'_def obj_at'_def projectKOs is_vcpu'_def)
done
lemma storePTE_ko_wp_vcpu_at'[wp]:
"storePTE p pde \<lbrace>\<lambda>s. P (ko_wp_at' (is_vcpu' and hyp_live') p' s)\<rbrace>"
apply (clarsimp simp: storePTE_def)
apply (wp hoare_drop_imps setObject_ko_wp_at, simp, simp add: objBits_simps archObjSize_def)
apply (simp add: pte_bits_def)
apply (clarsimp split del: if_split)
apply (erule_tac P=P in rsubst)
apply (clarsimp simp: ko_wp_at'_def obj_at'_def projectKOs is_vcpu'_def)
done
crunch inv[wp]: pageTableMapped "P"
(wp: loadObject_default_inv)
crunch no_0_obj'[wp]: storePDE no_0_obj'
(wp: setObject_cte_wp_at2' headM_inv hoare_drop_imp)
crunch no_0_obj'[wp]: storePTE no_0_obj'
(wp: setObject_cte_wp_at2' headM_inv hoare_drop_imp)
lemma storePDE_valid_arch'[wp]: "\<lbrace>valid_arch_state'\<rbrace> storePDE param_a param_b \<lbrace>\<lambda>_. valid_arch_state'\<rbrace>"
by (wpsimp wp: setObject_cte_wp_at2' headM_inv hoare_drop_imp simp: storePDE_def)
lemma storePTE_valid_arch'[wp]: "\<lbrace>valid_arch_state'\<rbrace> storePTE param_a param_b \<lbrace>\<lambda>_. valid_arch_state'\<rbrace>"
by (wpsimp wp: setObject_cte_wp_at2' headM_inv hoare_drop_imp simp: storePTE_def)
lemma storePDE_cur_tcb'[wp]: "\<lbrace>cur_tcb'\<rbrace> storePDE param_a param_b \<lbrace>\<lambda>_. cur_tcb'\<rbrace>"
by (wpsimp wp: setObject_cte_wp_at2' headM_inv hoare_drop_imp simp: storePDE_def)
lemma storePTE_cur_tcb'[wp]: "\<lbrace>cur_tcb'\<rbrace> storePTE param_a param_b \<lbrace>\<lambda>_. cur_tcb'\<rbrace>"
by (wpsimp wp: setObject_cte_wp_at2' headM_inv hoare_drop_imp simp: storePTE_def)
lemma unmapPageTable_corres:
"corres dc
(invs and valid_etcbs and page_table_at pt and
K (0 < asid \<and> is_aligned vptr 21 \<and> asid \<le> mask asid_bits))
(valid_arch_state' and pspace_aligned' and pspace_distinct'
and no_0_obj' and cur_tcb' and valid_objs')
(unmap_page_table asid vptr pt)
(unmapPageTable asid vptr pt)"
apply (clarsimp simp: unmapPageTable_def unmap_page_table_def ignoreFailure_def const_def cong: option.case_cong)
apply (rule corres_guard_imp)
apply (rule corres_split_eqr[OF pageTableMapped_corres])
apply (simp add: case_option_If2 split del: if_split)
apply (rule corres_if2[OF refl])
apply (rule corres_split)
apply (rule storePDE_corres')
apply (simp add:pde_relation_aligned_def)
apply (rule corres_split[OF corres_machine_op])
apply (rule corres_Id, rule refl, simp)
apply (wp no_fail_cleanByVA_PoU)
apply (rule flushTable_corres)
apply (wpsimp wp: store_pde_pd_at_asid store_pde_vspace_objs_invalid)+
apply (rule hoare_vcg_conj_lift)
apply (simp add: store_pde_def)
apply (wp set_pd_vs_lookup_unmap)+
apply (rule corres_trivial, simp)
apply (wp page_table_mapped_wp)
apply (wp hoare_drop_imps)[1]
apply (clarsimp simp: invs_def valid_state_def valid_pspace_def valid_arch_caps_def
Word.word_gt_0)
apply (frule (1) page_directory_pde_at_lookupI)
apply (auto elim: simp: empty_table_def valid_pde_mappings_def pde_ref_def obj_at_def
vs_refs_pages_def graph_of_def split: if_splits)
done
crunch typ_at' [wp]: flushPage "\<lambda>s. P (typ_at' T p s)"
(wp: crunch_wps hoare_drop_imps)
lemmas flushPage_typ_ats' [wp] = typ_at_lifts [OF flushPage_typ_at']
lemma valid_objs_valid_vcpu': "\<lbrakk> valid_objs' s ; ko_at' (t :: vcpu) p s \<rbrakk> \<Longrightarrow> valid_vcpu' t s"
by (fastforce simp add: obj_at'_def ran_def valid_obj'_def projectKOs valid_objs'_def)
lemma setObject_vcpu_no_tcb_update:
"\<lbrakk> vcpuTCBPtr (f vcpu) = vcpuTCBPtr vcpu \<rbrakk>
\<Longrightarrow> \<lbrace> valid_objs' and ko_at' (vcpu :: vcpu) p\<rbrace> setObject p (f vcpu) \<lbrace> \<lambda>_. valid_objs' \<rbrace>"
apply (rule_tac Q="valid_objs' and (ko_at' vcpu p and valid_obj' (KOArch (KOVCPU vcpu)))" in hoare_pre_imp)
apply (clarsimp)
apply (frule valid_objs_valid_vcpu')
apply assumption+
apply (simp add: valid_obj'_def)
apply (rule setObject_valid_objs')
apply (clarsimp simp add: obj_at'_def projectKOs)
apply (frule updateObject_default_result)
apply (clarsimp simp add: projectKOs valid_obj'_def valid_vcpu'_def)
done
lemma vcpuUpdate_valid_objs'[wp]:
"\<forall>vcpu. vcpuTCBPtr (f vcpu) = vcpuTCBPtr vcpu \<Longrightarrow>
\<lbrace>valid_objs'\<rbrace> vcpuUpdate vr f \<lbrace>\<lambda>_. valid_objs'\<rbrace>"
apply (wpsimp simp: vcpuUpdate_def)
apply (rule_tac vcpu=vcpu in setObject_vcpu_no_tcb_update)
apply wpsimp+
done
crunches
vgicUpdate, vcpuSaveReg, vgicUpdateLR, vcpuSaveRegRange, vcpuSave,
vcpuDisable, vcpuEnable, vcpuRestore, vcpuSwitch
for valid_objs'[wp]: valid_objs'
and ksCurDomain[wp]: "\<lambda>s. P (ksCurDomain s)"
(wp: mapM_wp_inv simp: mapM_x_mapM)
crunch valid_objs' [wp]: flushPage "valid_objs'"
(wp: crunch_wps hoare_drop_imps simp: crunch_simps)
crunch inv: lookupPTSlot "P"
(wp: loadObject_default_inv)
crunch aligned' [wp]: unmapPage pspace_aligned'
(wp: crunch_wps simp: crunch_simps)
crunch distinct' [wp]: unmapPage pspace_distinct'
(wp: crunch_wps simp: crunch_simps)
lemma corres_split_strengthen_ftE:
"\<lbrakk> corres (ftr \<oplus> r') P P' f j;
\<And>rv rv'. r' rv rv' \<Longrightarrow> corres (ftr' \<oplus> r) (R rv) (R' rv') (g rv) (k rv');
\<lbrace>Q\<rbrace> f \<lbrace>R\<rbrace>,-; \<lbrace>Q'\<rbrace> j \<lbrace>R'\<rbrace>,- \<rbrakk>
\<Longrightarrow> corres (dc \<oplus> r) (P and Q) (P' and Q') (f >>=E (\<lambda>rv. g rv)) (j >>=E (\<lambda>rv'. k rv'))"
apply (rule_tac r'=r' in corres_splitEE)
apply (erule corres_rel_imp)
apply (case_tac x, auto)[1]
apply (rule corres_rel_imp, assumption)
apply (case_tac x, auto)[1]
apply (simp add: validE_R_def)+
done
lemma checkMappingPPtr_corres:
"corres (dc \<oplus> dc)
((case slotptr of Inl ptr \<Rightarrow> pte_at ptr | Inr ptr \<Rightarrow> pde_at ptr) and
(\<lambda>s. (case slotptr of Inl ptr \<Rightarrow> is_aligned ptr (pg_entry_align sz)
| Inr ptr \<Rightarrow> is_aligned ptr (pg_entry_align sz))))
(pspace_aligned' and pspace_distinct')
(throw_on_false v (check_mapping_pptr pptr sz slotptr))
(checkMappingPPtr pptr sz slotptr)"
apply (rule corres_gen_asm)
apply (simp add: throw_on_false_def liftE_bindE check_mapping_pptr_def
checkMappingPPtr_def)
apply (cases slotptr, simp_all add: liftE_bindE)
apply (rule corres_guard_imp)
apply (rule corres_split[OF getObject_PTE_corres'])
apply (rule corres_trivial)
subgoal by (cases sz,
auto simp add: is_aligned_mask[symmetric]
is_aligned_shiftr pg_entry_align_def pte_bits_def
unlessE_def returnOk_def pte_relation_aligned_def
split: ARM_A.pte.split if_splits ARM_HYP_H.pte.split )
apply wp+
apply simp
apply (simp add:is_aligned_mask[symmetric] is_aligned_shiftr pg_entry_align_def)
apply (rule corres_guard_imp)
apply (rule corres_split[OF getObject_PDE_corres'])
apply (rule corres_trivial)
subgoal by (cases sz,
auto simp add: is_aligned_mask[symmetric]
is_aligned_shiftr pg_entry_align_def pde_bits_def
unlessE_def returnOk_def pde_relation_aligned_def
split: ARM_A.pde.split if_splits ARM_HYP_H.pde.split )
apply wp+
apply simp+
done
crunch inv[wp]: checkMappingPPtr "P"
(wp: crunch_wps loadObject_default_inv simp: crunch_simps)
lemma store_pte_pd_at_asid[wp]:
"\<lbrace>vspace_at_asid asid pd\<rbrace>
store_pte p pte \<lbrace>\<lambda>_. vspace_at_asid asid pd\<rbrace>"
apply (simp add: store_pte_def set_pd_def set_object_def vspace_at_asid_def)
apply (wp get_object_wp)
apply clarsimp
done
lemma is_aligned_dvd_k: "\<lbrakk> 2 ^ m * (k :: nat) = 2 ^ n ; is_aligned p n \<rbrakk> \<Longrightarrow> is_aligned p m"
apply (simp add: is_aligned_def)
apply (rule dvd_mult_left[where b=k])
apply (drule sym)
apply simp
done
lemma unmapPage_corres:
"corres dc (invs and valid_etcbs and
K (valid_unmap sz (asid,vptr) \<and> vptr < kernel_base \<and> asid \<le> mask asid_bits))
(valid_objs' and valid_arch_state' and pspace_aligned' and
pspace_distinct' and no_0_obj' and cur_tcb')
(unmap_page sz asid vptr pptr)
(unmapPage sz asid vptr pptr)"
apply (clarsimp simp: unmap_page_def unmapPage_def ignoreFailure_def const_def)
apply (rule corres_guard_imp)
apply (rule corres_split_catch [where E="\<lambda>_. \<top>" and E'="\<lambda>_. \<top>"])
apply (rule corres_split_strengthen_ftE[where ftr'=dc],
rule find_pd_for_asid_corres[OF refl])
apply (rule corres_splitEE)
apply (rule_tac F = "vptr < kernel_base" in corres_gen_asm)
apply (rule_tac P="\<exists>\<rhd> pd and page_directory_at pd and vspace_at_asid asid pd
and (\<exists>\<rhd> (lookup_pd_slot pd vptr && ~~ mask pd_bits))
and valid_arch_state and valid_vspace_objs
and equal_kernel_mappings
and pspace_aligned and valid_etcbs and
K (valid_unmap sz (asid,vptr) )" and
P'="pspace_aligned' and pspace_distinct'" in corres_inst)
apply clarsimp
apply (rename_tac pd)
apply (cases sz, simp_all)[1]
apply (rule corres_guard_imp)
apply (rule_tac F = "vptr < kernel_base" in corres_gen_asm)
apply (rule corres_split_strengthen_ftE[OF lookupPTSlot_corres])
apply simp
apply (rule corres_splitEE[OF checkMappingPPtr_corres])
apply simp
apply (rule corres_split[OF storePTE_corres'])
apply (clarsimp simp: pte_relation_aligned_def)
apply (rule corres_machine_op)
apply (rule corres_Id, rule refl, simp)
apply (rule no_fail_cleanByVA_PoU)
apply (wp hoare_drop_imps lookup_pt_slot_inv
lookupPTSlot_inv lookup_pt_slot_is_aligned
| simp add: valid_global_objs_def)+
apply (clarsimp simp: page_directory_pde_at_lookupI
page_directory_at_aligned_pd_bits vmsz_aligned_def)
apply (simp add:valid_unmap_def pageBits_def)+
apply (rule corres_guard_imp)
apply (rule corres_split_strengthen_ftE[OF lookupPTSlot_corres])
apply (rule_tac F="is_aligned p 7" in corres_gen_asm)
apply (simp add: is_aligned_mask[symmetric])
apply (rule corres_split_strengthen_ftE[OF checkMappingPPtr_corres])
apply simp
apply (rule corres_split[OF corres_mapM])
prefer 8
apply (rule corres_machine_op)
apply (clarsimp simp: last_byte_pte_def objBits_simps archObjSize_def)
apply (rule corres_Id, rule refl, simp)
apply (rule no_fail_cleanCacheRange_PoU)
prefer 7
apply (rule order_refl)
apply simp
apply simp
apply clarsimp
apply (rule_tac P="(\<lambda>s. \<forall>x\<in>set largePagePTEOffsets. pte_at (x + pa) s) and pspace_aligned and valid_etcbs"
and P'="pspace_aligned' and pspace_distinct'"
in corres_guard_imp)
apply (rule storePTE_corres', simp add:pte_relation_aligned_def)
apply clarsimp
apply clarsimp
apply (wp store_pte_typ_at hoare_vcg_const_Ball_lift | clarsimp | wp (once) hoare_drop_imps)+
(* this is dumb... *)
apply (subst mult_is_add.mult_commute)
apply (wpsimp wp: lookup_pt_slot_ptes lookup_pt_slot_inv lookupPTSlot_inv
lookup_pt_slot_is_aligned lookup_pt_slot_is_aligned_6
simp: largePagePTEOffsets_def pte_bits_def)+
apply (clarsimp simp: page_directory_pde_at_lookupI vmsz_aligned_def pd_aligned
pd_bits_def pageBits_def valid_unmap_def valid_global_objs_def
page_directory_at_aligned_pd_bits pde_bits_def)
apply (simp add:pd_bits_def pageBits_def)
apply (rule corres_guard_imp)
apply (rule corres_split_strengthen_ftE[OF checkMappingPPtr_corres])
apply simp
apply (rule corres_split[OF storePDE_corres'])
apply (simp add: pde_relation_aligned_def)
apply (rule corres_machine_op)
apply (rule corres_Id, rule refl, simp)
apply (rule no_fail_cleanByVA_PoU)
apply (rule wp_post_taut)+
apply (wp | simp add:pde_relation_aligned_def
| wp (once) hoare_drop_imps)+
apply (clarsimp simp: page_directory_pde_at_lookupI
pg_entry_align_def)
apply (clarsimp simp:lookup_pd_slot_def)
apply (clarsimp simp add: pd_bits_def pageBits_def
word_bits_conv pt_bits_def pde_bits_def)
apply (rule is_aligned_add[rotated])
apply (rule is_aligned_shift)
apply (clarsimp simp add: obj_at_def pspace_aligned_def Ball_def dom_def)
apply (erule_tac x=pd in allE)
apply (clarsimp simp add: pd_bits_def pde_bits_def)
apply (rule is_aligned_dvd_k[where k=2048 and n=14]; clarsimp)
apply clarsimp
apply (simp add:pd_bits_def pageBits_def)
apply (rule corres_guard_imp)
apply (rule corres_split_strengthen_ftE[OF checkMappingPPtr_corres])
apply (rule_tac F="is_aligned (lookup_pd_slot pd vptr) 7"
in corres_gen_asm)
apply (simp add: is_aligned_mask[symmetric])
apply (rule corres_split)
apply (rule_tac P="page_directory_at pd and pspace_aligned and valid_etcbs
and K (valid_unmap sz (asid, vptr))"
in corres_mapM [where r=dc], simp, simp)
prefer 5
apply (rule order_refl)
apply clarsimp
apply (rule corres_guard_imp, rule storePDE_corres')
apply (simp add:pde_relation_aligned_def)+
apply clarsimp
apply (rule pde_at_aligned_vptr)
apply (simp add: superSectionPDEOffsets_def pde_bits_def)+
apply (simp add: lookup_pd_slot_def vspace_bits_defs)
apply (simp add: valid_unmap_def)
apply assumption
apply (wp | simp | wp (once) hoare_drop_imps)+
apply (rule corres_machine_op)
apply (clarsimp simp: last_byte_pde_def objBits_simps archObjSize_def)
apply (rule corres_Id, rule refl, simp)
apply (rule no_fail_cleanCacheRange_PoU)
apply (wpsimp | wp (once) hoare_drop_imps)+
apply (clarsimp simp: valid_unmap_def page_directory_pde_at_lookupI
lookup_pd_slot_aligned_6 pg_entry_align_def
pd_aligned vmsz_aligned_def)
apply simp
apply clarsimp
apply (rule flushPage_corres)
apply wp
apply (rule_tac Q'="\<lambda>_. invs and vspace_at_asid asid pda" in hoare_post_imp_R)
apply (wpsimp wp: lookup_pt_slot_inv lookup_pt_slot_cap_to2' lookup_pt_slot_cap_to_multiple2
store_pde_invs_unmap store_pde_pd_at_asid mapM_swp_store_pde_invs_unmap
simp: largePagePTEOffsets_def pte_bits_def
| wp hoare_drop_imps
| wp mapM_wp' | assumption)+
apply auto[1]
apply (wpsimp wp: hoare_vcg_const_imp_lift_R lookupPTSlot_inv
| strengthen not_in_global_refs_vs_lookup
page_directory_at_lookup_mask_aligned_strg
page_directory_at_lookup_mask_add_aligned_strg
| wp hoare_vcg_const_Ball_lift_R mapM_wp')+
apply (clarsimp simp add: valid_unmap_def valid_asid_def)
apply (case_tac sz)
apply (auto simp: invs_def valid_state_def
valid_arch_state_def pageBits_def
superSectionPDEOffsets_def pde_bits_def
valid_arch_caps_def vmsz_aligned_def)
done
definition
"flush_type_map type \<equiv> case type of
ARM_A.flush_type.Clean \<Rightarrow> ARM_HYP_H.flush_type.Clean
| ARM_A.flush_type.Invalidate \<Rightarrow> ARM_HYP_H.flush_type.Invalidate
| ARM_A.flush_type.CleanInvalidate \<Rightarrow> ARM_HYP_H.flush_type.CleanInvalidate
| ARM_A.flush_type.Unify \<Rightarrow> ARM_HYP_H.flush_type.Unify"
lemma doFlush_corres:
"corres_underlying Id nf nf' dc \<top> \<top>
(do_flush typ start end pstart) (doFlush (flush_type_map typ) start end pstart)"
apply (simp add: do_flush_def doFlush_def)
apply (cases "typ", simp_all add: flush_type_map_def Let_def)
apply (rule corres_Id [where r=dc], rule refl, simp)
apply (wp no_fail_cleanCacheRange_RAM)
apply (rule corres_Id [where r=dc], rule refl, simp)
apply (wp no_fail_invalidateCacheRange_RAM)
apply (rule corres_Id [where r=dc], rule refl, simp)
apply (wp no_fail_cleanInvalidateCacheRange_RAM)
apply (rule corres_Id [where r=dc], rule refl, simp)
apply (rule no_fail_pre, wp add: no_fail_cleanCacheRange_PoU no_fail_invalidateCacheRange_I
no_fail_dsb no_fail_isb del: no_irq)
apply clarsimp
done
definition
"page_directory_invocation_map pdi pdi' \<equiv> case pdi of
ARM_A.PageDirectoryNothing \<Rightarrow> pdi' = PageDirectoryNothing
| ARM_A.PageDirectoryFlush typ start end pstart pd asid \<Rightarrow>
pdi' = PageDirectoryFlush (flush_type_map typ) start end pstart pd asid"
lemma performPageDirectoryInvocation_corres:
"page_directory_invocation_map pdi pdi' \<Longrightarrow>
corres dc (invs and valid_pdi pdi)
(valid_objs' and pspace_aligned' and pspace_distinct' and no_0_obj'
and cur_tcb' and valid_arch_state')
(perform_page_directory_invocation pdi) (performPageDirectoryInvocation pdi')"
apply (simp add: perform_page_directory_invocation_def performPageDirectoryInvocation_def)
apply (cases pdi)
apply (clarsimp simp: page_directory_invocation_map_def)
apply (rule corres_guard_imp)
apply (rule corres_when, simp)
apply (rule corres_split[OF setVMRootForFlush_corres])
apply (rule corres_split[OF corres_machine_op])
apply (rule doFlush_corres)
apply (rule corres_when, simp)
apply (rule corres_split[OF getCurThread_corres])
apply clarsimp
apply (rule setVMRoot_corres)
apply wp+
apply (simp add: cur_tcb_def[symmetric])
apply (wp hoare_drop_imps)
apply (simp add: cur_tcb'_def[symmetric])
apply (wp hoare_drop_imps)+
apply clarsimp
apply (auto simp: valid_pdi_def)[2]
apply (clarsimp simp: page_directory_invocation_map_def)
done
definition
"page_invocation_map pgi pgi' \<equiv> case pgi of
ARM_A.PageMap a c ptr m \<Rightarrow>
\<exists>c' m'. pgi' = PageMap a c' (cte_map ptr) m' \<and>
cap_relation c c' \<and>
mapping_map m m'
| ARM_A.PageUnmap c ptr \<Rightarrow>
\<exists>c'. pgi' = PageUnmap c' (cte_map ptr) \<and>
acap_relation c c'
| ARM_A.PageFlush typ start end pstart pd asid \<Rightarrow>
pgi' = PageFlush (flush_type_map typ) start end pstart pd asid
| ARM_A.PageGetAddr ptr \<Rightarrow>
pgi' = PageGetAddr ptr"
definition
"valid_pde_slots' m \<equiv> case m of Inl (pte, xs) \<Rightarrow> True
| Inr (pde, xs) \<Rightarrow> \<forall>x \<in> set xs. valid_pde_mapping' (x && mask pdBits) pde"
definition
"vs_entry_align obj \<equiv>
case obj of KOArch (KOPTE pte) \<Rightarrow> pte_align' pte
| KOArch (KOPDE pde) \<Rightarrow> pde_align' pde
| _ \<Rightarrow> 0"
definition "valid_slots_duplicated' \<equiv> \<lambda>m s. case m of
Inl (pte, xs) \<Rightarrow> (case pte of
pte.LargePagePTE _ _ _ _ \<Rightarrow> \<exists>p. xs = [p, p+8 .e. p + mask 7] \<and> is_aligned p 7
\<and> page_table_at' (p && ~~ mask ptBits) s
| _ \<Rightarrow> \<exists>p. xs = [p] \<and> ko_wp_at' (\<lambda>ko. vs_entry_align ko = 0) p s
\<and> page_table_at' (p && ~~ mask ptBits) s)
| Inr (pde, xs) \<Rightarrow> (case pde of
pde.SuperSectionPDE _ _ _ _ \<Rightarrow> \<exists>p. xs = [p, p+8 .e. p + mask 7] \<and> is_aligned p 7
\<and> page_directory_at' (p && ~~ mask pdBits) s
| _ \<Rightarrow> \<exists>p. xs = [p] \<and> ko_wp_at' (\<lambda>ko. vs_entry_align ko = 0) p s
\<and> page_directory_at' (p && ~~ mask pdBits) s)"
lemma valid_slots_duplicated_pteD':
assumes "valid_slots_duplicated' (Inl (pte, xs)) s"
shows "(is_aligned (hd xs >> pte_bits) (pte_align' pte))
\<and> (\<forall>p \<in> set (tl xs). \<not> is_aligned (p >> pte_bits) (pte_align' pte))"
proof -
have is_aligned_estimate:
"\<And>x. is_aligned (x::word32) 4 \<Longrightarrow> x \<noteq> 0 \<Longrightarrow> 2 ^ 4 \<le> x"
apply (simp add:is_aligned_mask mask_def)
apply word_bitwise
apply auto
done
show ?thesis
using assms
apply -
apply (clarsimp simp:valid_slots_duplicated'_def pte_bits_def
split:ARM_HYP_H.pte.splits)
apply (subgoal_tac "p \<le> p + mask 7")
apply (clarsimp simp:upto_enum_step_def not_less vspace_bits_defs)
apply (intro conjI impI,simp)
apply (simp add:hd_map_simp mask_def is_aligned_shiftr upto_enum_word vspace_bits_defs)
apply (clarsimp simp:mask_def upto_enum_word vspace_bits_defs)
apply (subst (asm) tl_map_simp upto_enum_word)
apply simp
apply (clarsimp simp:image_def)
apply (cut_tac w = "of_nat x :: word32" in shiftl_t2n[where n = pte_bits,simplified,symmetric])
apply (clarsimp simp:field_simps)
apply (drule is_aligned_shiftl[where n = 7 and m = 3, simplified])
apply (subst (asm) shiftr_shiftl1)
apply simp
apply (simp add: tl_nat_list_simp pte_bits_def)
apply (subst (asm) is_aligned_neg_mask_eq)
apply (erule aligned_add_aligned[OF _ is_aligned_shiftl_self])
apply simp
apply (drule(1) is_aligned_addD1)
apply (drule_tac w = "(of_nat x::word32) << 3" in
is_aligned_shiftr[where n = 4 and m = 3,simplified])
apply (clarsimp simp: shiftl_shiftr_id word_of_nat_less)+
apply (drule is_aligned_estimate)
apply (rule of_nat_neq_0)
apply simp
apply simp
apply (drule unat_le_helper)
apply simp
apply (erule is_aligned_no_wrap')
apply (simp add:mask_def)
done
qed
lemma valid_slots_duplicated_pdeD':
assumes "valid_slots_duplicated' (Inr (pde, xs)) s"
shows "(is_aligned (hd xs >> pde_bits) (pde_align' pde))
\<and> (\<forall>p \<in> set (tl xs). \<not> is_aligned (p >> pde_bits) (pde_align' pde))"
proof -
have is_aligned_estimate:
"\<And>x. is_aligned (x::word32) 4 \<Longrightarrow> x \<noteq> 0 \<Longrightarrow> 2 ^ 4 \<le> x"
apply (simp add:is_aligned_mask mask_def)
apply word_bitwise
apply auto
done
show ?thesis
using assms
apply -
apply (clarsimp simp:valid_slots_duplicated'_def pte_bits_def
split:ARM_HYP_H.pde.splits)
apply (subgoal_tac "p \<le> p + mask 7")
apply (clarsimp simp:upto_enum_step_def not_less)
apply (intro conjI impI,simp)
apply (simp add:hd_map_simp mask_def is_aligned_shiftr upto_enum_word pde_bits_def)
apply (clarsimp simp:mask_def upto_enum_word)
apply (subst (asm) tl_map_simp upto_enum_word)
apply simp
apply (clarsimp simp:image_def)
apply (cut_tac w = "of_nat x :: word32" in shiftl_t2n[where n = 3,simplified,symmetric])
apply (clarsimp simp:field_simps vspace_bits_defs)
apply (drule is_aligned_shiftl[where n = 7 and m = 3,simplified])
apply (subst (asm) shiftr_shiftl1)
apply simp
apply (simp add: tl_nat_list_simp)
apply (subst (asm) is_aligned_neg_mask_eq)
apply (erule aligned_add_aligned[OF _ is_aligned_shiftl_self])
apply simp
apply (drule(1) is_aligned_addD1)
apply (drule_tac w = "(of_nat x::word32) << 3" in
is_aligned_shiftr[where n = 4 and m = 3,simplified])
apply (clarsimp simp: shiftl_shiftr_id word_of_nat_less)+
apply (drule is_aligned_estimate)
apply (rule of_nat_neq_0)
apply simp
apply simp
apply (drule unat_le_helper)
apply simp
apply (erule is_aligned_no_wrap')
apply (simp add:mask_def)
done
qed
lemma setCTE_vs_entry_align[wp]:
"\<lbrace>\<lambda>s. ko_wp_at' (\<lambda>ko. P (vs_entry_align ko)) p s\<rbrace>
setCTE ptr cte
\<lbrace>\<lambda>rv. ko_wp_at' (\<lambda>ko. P (vs_entry_align ko)) p\<rbrace>"
apply (clarsimp simp: setCTE_def setObject_def split_def
valid_def in_monad ko_wp_at'_def
split del: if_split
elim!: rsubst[where P=P])
apply (drule(1) updateObject_cte_is_tcb_or_cte [OF _ refl, rotated])
apply (elim exE conjE disjE)
apply (clarsimp simp: ps_clear_upd objBits_simps
lookupAround2_char1)
apply (simp add:vs_entry_align_def)
apply (clarsimp simp: ps_clear_upd objBits_simps vs_entry_align_def)
done
lemma updateCap_vs_entry_align[wp]:
"\<lbrace>ko_wp_at' (\<lambda>ko. P (vs_entry_align ko)) p \<rbrace> updateCap ptr cap
\<lbrace>\<lambda>rv. ko_wp_at' (\<lambda>ko. P (vs_entry_align ko)) p\<rbrace>"
apply (simp add:updateCap_def)
apply wp
done
lemma valid_slots_duplicated_updateCap[wp]:
"\<lbrace>valid_slots_duplicated' m'\<rbrace> updateCap cap c'
\<lbrace>\<lambda>rv s. valid_slots_duplicated' m' s\<rbrace>"
apply (case_tac m')
apply (simp_all add:valid_slots_duplicated'_def)
apply (case_tac a,case_tac aa,simp_all)
apply (wp hoare_vcg_ex_lift)+
apply (case_tac b,case_tac a,simp_all)
apply (wp hoare_vcg_ex_lift)+
done
definition
"valid_page_inv' pgi \<equiv> case pgi of
PageMap asid cap ptr m \<Rightarrow>
cte_wp_at' (is_arch_update' cap) ptr and valid_slots' m and valid_cap' cap
and K (valid_pde_slots' m) and (valid_slots_duplicated' m)
| PageUnmap cap ptr \<Rightarrow>
\<lambda>s. \<exists>d r R sz m. cap = PageCap d r R sz m \<and>
cte_wp_at' (is_arch_update' (ArchObjectCap cap)) ptr s \<and>
s \<turnstile>' (ArchObjectCap cap)
| PageFlush typ start end pstart pd asid \<Rightarrow> \<top>
| PageGetAddr ptr \<Rightarrow> \<top>"
crunch ctes[wp]: doMachineOp "\<lambda>s. P (ctes_of s)"
lemma setObject_vcpu_cte_wp_at'[wp]:
"\<lbrace>\<lambda>s. P (cte_wp_at' P' p s)\<rbrace>
setObject ptr (vcpu::vcpu)
\<lbrace>\<lambda>rv s. P (cte_wp_at' P' p s)\<rbrace>"
apply (wp setObject_cte_wp_at2'[where Q="\<top>"])
apply (clarsimp simp: updateObject_default_def in_monad
projectKO_opts_defs projectKOs)
apply (rule equals0I)
apply (clarsimp simp: updateObject_default_def in_monad
projectKOs projectKO_opts_defs)
apply simp
done
crunches vcpuSave, vcpuRestore, vcpuDisable, vcpuEnable
for ctes[wp]: "\<lambda>s. P (ctes_of s)"
(simp: crunch_simps wp: crunch_wps getObject_inv_vcpu loadObject_default_inv)
lemma vcpuSwitch_ctes[wp]: "\<lbrace>\<lambda>s. P (ctes_of s)\<rbrace> vcpuSwitch vcpu \<lbrace>\<lambda>_ s. P (ctes_of s)\<rbrace>"
by (wpsimp simp: vcpuSwitch_def modifyArchState_def | assumption)+
crunch ctes [wp]: unmapPage "\<lambda>s. P (ctes_of s)"
(simp: crunch_simps
wp: crunch_wps loadObject_default_inv getObject_inv)
lemma triple_set_zip_eq:
"(a, b, c) \<in> set (zip ys (zip ys xs)) \<Longrightarrow> a = b \<and> a \<in> set ys"
apply (induct ys arbitrary: xs; clarsimp)
apply (case_tac xs, auto)
done
lemma corres_store_pde_with_invalid_tail:
"\<lbrakk> \<forall>slot \<in>set ys. \<not> is_aligned (slot >> pde_bits) (pde_align' ab); length ys < 2^word_bits \<rbrakk>
\<Longrightarrow>corres dc ((\<lambda>s. \<forall>y\<in> set ys. pde_at y s) and pspace_aligned and valid_etcbs)
(pspace_aligned' and pspace_distinct')
(mapM (swp store_pde ARM_A.pde.InvalidPDE) ys)
(mapM (\<lambda>(slot, i). storePDE slot (addPDEOffset ab i)) (zip ys [1.e.of_nat (length ys)]))"
apply (rule_tac S ="{(x,y). x = fst y \<and> x \<in> set ys}" in corres_mapM[where r = dc and r' = dc])
apply simp
apply simp
apply clarsimp
apply (rule corres_guard_imp)
apply (rule storePDE_corres')
apply (drule bspec)
apply simp
apply (simp add:pde_relation_aligned_def addPDEOffset_def)
apply (auto split: pde.splits)[1]
apply (drule bspec,simp)
apply simp
apply simp
apply (wpsimp wp: hoare_vcg_ball_lift)+
apply (simp add: word_bits_def unat_of_nat_word_bits)
apply (fastforce dest: triple_set_zip_eq)
done
lemma corres_store_pte_with_invalid_tail:
"\<lbrakk> \<forall>slot\<in> set ys. \<not> is_aligned (slot >> pte_bits) (pte_align' aa); length ys < 2^word_bits\<rbrakk>
\<Longrightarrow> corres dc ((\<lambda>s. \<forall>y\<in>set ys. pte_at y s) and pspace_aligned and valid_etcbs)
(pspace_aligned' and pspace_distinct')
(mapM (swp store_pte ARM_A.pte.InvalidPTE) ys)
(mapM (\<lambda>(slot, i). storePTE slot (addPTEOffset aa i)) (zip ys [1.e.of_nat (length ys)]))"
apply (rule_tac S ="{(x,y). x = fst y \<and> x \<in> set ys}" in corres_mapM[where r = dc and r' = dc])
apply simp
apply simp
apply clarsimp
apply (rule corres_guard_imp)
apply (rule storePTE_corres')
apply (drule bspec)
apply simp
apply (simp add:pte_relation_aligned_def addPTEOffset_def)
apply (auto split: pte.splits)[1]
apply (drule bspec,simp)
apply simp
apply simp
apply (wpsimp wp: hoare_vcg_ball_lift)+
apply (simp add: word_bits_def unat_of_nat_word_bits)
apply (fastforce dest: triple_set_zip_eq)
done
lemma updateCap_valid_slots'[wp]:
"\<lbrace>valid_slots' x2\<rbrace> updateCap cte cte' \<lbrace>\<lambda>_ s. valid_slots' x2 s \<rbrace>"
apply (case_tac x2)
apply (clarsimp simp:valid_slots'_def)
apply (wp hoare_vcg_ball_lift)
apply (clarsimp simp:valid_slots'_def)
apply (wp hoare_vcg_ball_lift)
done
lemma pteCheckIfMapped_corres:
"corres (=) (pte_at slot) ((\<lambda>s. vs_valid_duplicates' (ksPSpace s)) and pspace_aligned' and pspace_distinct') (pte_check_if_mapped slot) (pteCheckIfMapped slot)"
apply (simp add: pte_check_if_mapped_def pteCheckIfMapped_def)
apply (rule corres_guard_imp)
apply (rule corres_split[OF get_master_pte_corres', simplified])
apply (rule corres_return[where P="pte_at slot" and
P'="pspace_aligned' and pspace_distinct'", THEN iffD2])
apply (clarsimp simp: master_pte_relation_def isLargePage_def' split: if_split_asm)
apply (case_tac pt, simp_all)[1]
apply wp+
apply (simp)
apply simp
done
lemma pdeCheckIfMapped_corres:
"corres (=) (pde_at slot) ((\<lambda>s. vs_valid_duplicates' (ksPSpace s)) and pspace_aligned' and pspace_distinct') (pde_check_if_mapped slot) (pdeCheckIfMapped slot)"
apply (simp add: pde_check_if_mapped_def pdeCheckIfMapped_def)
apply (rule corres_guard_imp)
apply (rule corres_split[OF get_master_pde_corres', simplified])
apply (rule corres_return[where P="pde_at slot" and
P'="pspace_aligned' and pspace_distinct'", THEN iffD2])
apply (clarsimp simp: master_pde_relation_def isSuperSection_def' split: if_split_asm)
apply (case_tac pd, simp_all)[1]
apply wp+
apply (clarsimp simp: pte_relation_aligned_def split: if_split_asm)
apply simp
done
crunch valid_asid_map[wp]: store_pte "valid_asid_map"
lemma set_cap_pd_at_asid [wp]:
"\<lbrace>vspace_at_asid asid pd\<rbrace> set_cap t st \<lbrace>\<lambda>rv. vspace_at_asid asid pd\<rbrace>"
apply (simp add: vspace_at_asid_def)
apply wp
done
lemma set_cap_valid_slots_inv[wp]:
"\<lbrace>valid_slots m\<rbrace> set_cap t st \<lbrace>\<lambda>rv. valid_slots m\<rbrace>"
by (cases m, (clarsimp simp: valid_slots_def, wp hoare_vcg_ball_lift set_cap.vs_lookup set_cap_typ_ats)+)
lemma set_cap_same_refs_inv[wp]:
"\<lbrace>\<lambda>s. same_refs m cap s\<rbrace> set_cap t st \<lbrace>\<lambda>rv s. same_refs m cap s\<rbrace>"
by (cases m, (clarsimp simp: same_refs_def, wp)+)
definition
"valid_page_map_inv asid cap ptr m \<equiv> (\<lambda>s. caps_of_state s ptr = Some cap) and same_refs m cap and
valid_slots m and
valid_cap cap and
K (is_pg_cap cap \<and> empty_refs m \<and> asid \<le> mask asid_bits \<and> asid \<noteq> 0) and
(\<lambda>s. \<exists>sl. cte_wp_at (parent_for_refs m) sl s) and
(\<lambda>s. \<exists>pd. vspace_at_asid asid pd s)"
lemma set_cap_valid_page_map_inv:
"\<lbrace>valid_page_inv (ARM_A.page_invocation.PageMap asid cap slot m)\<rbrace> set_cap cap slot \<lbrace>\<lambda>rv. valid_page_map_inv asid cap slot m\<rbrace>"
apply (simp add: valid_page_inv_def valid_page_map_inv_def)
apply (wp set_cap_cte_wp_at_cases hoare_vcg_ex_lift| simp)+
apply clarsimp
apply (rule conjI, fastforce simp: cte_wp_at_def)
apply (rule_tac x=a in exI, rule_tac x=b in exI)
apply (subgoal_tac "(a,b) \<noteq> slot")
apply clarsimp
apply (clarsimp simp: cte_wp_at_def parent_for_refs_def)
apply (auto simp: is_pt_cap_def is_pg_cap_def is_pd_cap_def split: sum.splits)
done
lemma setCTE_valid_duplicates'[wp]:
"\<lbrace>\<lambda>s. vs_valid_duplicates' (ksPSpace s)\<rbrace>
setCTE p cte \<lbrace>\<lambda>rv s. vs_valid_duplicates' (ksPSpace s)\<rbrace>"
apply (simp add:setCTE_def)
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)
apply (frule pspace_storable_class.updateObject_type[where v = cte,simplified])
apply (clarsimp simp:ObjectInstances_H.updateObject_cte assert_def bind_def
alignCheck_def in_monad when_def alignError_def magnitudeCheck_def
assert_opt_def return_def fail_def typeError_def
split:if_splits option.splits Structures_H.kernel_object.splits)
apply (erule valid_duplicates'_non_pd_pt_I[rotated 3],simp+)+
done
crunch valid_duplicates'[wp]: updateCap "\<lambda>s. vs_valid_duplicates' (ksPSpace s)"
(wp: crunch_wps
simp: crunch_simps unless_def)
lemma message_info_to_data_eqv:
"wordFromMessageInfo (message_info_map mi) = message_info_to_data mi"
apply (cases mi)
apply (simp add: wordFromMessageInfo_def
msgLengthBits_def msgExtraCapBits_def msgMaxExtraCaps_def
shiftL_nat)
done
lemma message_info_from_data_eqv:
"message_info_map (data_to_message_info rv) = messageInfoFromWord rv"
by (auto simp: data_to_message_info_def messageInfoFromWord_def Let_def not_less
msgLengthBits_def msgExtraCapBits_def msgMaxExtraCaps_def mask_def
shiftL_nat msgMaxLength_def msgLabelBits_def)
lemma setMessageInfo_corres:
"mi' = message_info_map mi \<Longrightarrow>
corres dc (tcb_at t) (tcb_at' t)
(set_message_info t mi) (setMessageInfo t mi')"
apply (simp add: setMessageInfo_def set_message_info_def)
apply (subgoal_tac "wordFromMessageInfo (message_info_map mi) =
message_info_to_data mi")
apply (simp add: asUser_setRegister_corres msg_info_register_def
msgInfoRegister_def)
apply (simp add: message_info_to_data_eqv)
done
lemma set_mi_invs'[wp]: "\<lbrace>invs' and tcb_at' t\<rbrace> setMessageInfo t a \<lbrace>\<lambda>x. invs'\<rbrace>"
by (simp add: setMessageInfo_def) wp
lemma set_mi_tcb' [wp]:
"\<lbrace> tcb_at' t \<rbrace> setMessageInfo receiver msg \<lbrace>\<lambda>rv. tcb_at' t\<rbrace>"
by (simp add: setMessageInfo_def) wp
lemma setMRs_typ_at':
"\<lbrace>\<lambda>s. P (typ_at' T p s)\<rbrace> setMRs receiver recv_buf mrs \<lbrace>\<lambda>rv s. P (typ_at' T p s)\<rbrace>"
by (simp add: setMRs_def zipWithM_x_mapM split_def, wp crunch_wps)
lemmas setMRs_typ_at_lifts[wp] = typ_at_lifts [OF setMRs_typ_at']
lemma set_mrs_invs'[wp]:
"\<lbrace> invs' and tcb_at' receiver \<rbrace> setMRs receiver recv_buf mrs \<lbrace>\<lambda>rv. invs' \<rbrace>"
apply (simp add: setMRs_def)
apply (wp dmo_invs' no_irq_mapM no_irq_storeWord crunch_wps|
simp add: zipWithM_x_mapM split_def)+
done
lemma same_refs_vs_cap_ref_eq:
assumes "valid_slots entries s"
assumes "same_refs entries cap s"
assumes "same_refs entries cap' s"
shows "vs_cap_ref cap = vs_cap_ref cap'"
using assms
apply (cases entries; clarsimp simp: same_refs_def valid_slots_def)
apply (all \<open>rename_tac pte slots p; case_tac slots; clarsimp\<close>)
done
lemma addPAddr_0[simp]:
"addPAddr p 0 = p"
by (cases p; simp add: addPAddr_def fromPAddr_def)
lemma addPTEOffset_0[simp]:
"addPTEOffset pte 0 = pte"
by (cases pte; simp add: addPTEOffset_def pteFrame_def pteFrame_update_def)
lemma addPDEOffset_0[simp]:
"addPDEOffset pde 0 = pde"
by (cases pde; simp add: addPDEOffset_def pdeFrame_def pdeFrame_update_def)
lemma zip_cons_idx[simp]:
"length ys < 2 ^ LENGTH('a) \<Longrightarrow>
zip (y # ys) [0.e.of_nat (length ys)] = (y,0) # zip ys [1.e.of_nat (length ys)::'a::len word]"
by (clarsimp simp: upto_enum_def unat_of_nat_eq not_le Suc_le_eq upto_0_to_n2)
lemma valid_slots_duplicated'_length_Inl:
"valid_slots_duplicated' (Inl (a, b)) s
\<Longrightarrow> length b = (case a of LargePagePTE _ _ _ _ \<Rightarrow> 16 | _ \<Rightarrow> 1)"
by (auto simp: valid_slots_duplicated'_def upto_enum_step_def upto_enum_def mask_def
dest: is_aligned_no_overflow'
split: pte.splits)
lemma valid_slots_duplicated'_length_Inr:
"valid_slots_duplicated' (Inr (a, b)) s
\<Longrightarrow> length b = (case a of SuperSectionPDE _ _ _ _ \<Rightarrow> 16 | _ \<Rightarrow> 1)"
by (auto simp: valid_slots_duplicated'_def upto_enum_step_def upto_enum_def mask_def
dest: is_aligned_no_overflow'
split: pde.splits)
lemma performPageInvocation_corres:
assumes "page_invocation_map pgi pgi'"
shows "corres (=) (invs and valid_etcbs and valid_page_inv pgi)
(invs' and valid_page_inv' pgi' and (\<lambda>s. vs_valid_duplicates' (ksPSpace s)))
(perform_page_invocation pgi) (performPageInvocation pgi')"
proof -
have pull_out_P:
"\<And>P s Q c p. P s \<and> (\<forall>c. caps_of_state s p = Some c \<longrightarrow> Q s c) \<longrightarrow> (\<forall>c. caps_of_state s p = Some c \<longrightarrow> P s \<and> Q s c)"
by blast
show ?thesis
using assms
apply (cases pgi)
apply (rename_tac word cap prod sum)
\<comment> \<open>PageMap\<close>
apply (clarsimp simp: perform_page_invocation_def performPageInvocation_def page_invocation_map_def)
apply (rule corres_guard_imp)
apply (rule_tac R="\<lambda>_. invs and (valid_page_map_inv word cap (a,b) sum) and valid_etcbs
and (\<lambda>s. caps_of_state s (a,b) = Some cap)"
and R'="\<lambda>_. invs' and valid_slots' m' and pspace_aligned' and valid_slots_duplicated' m'
and pspace_distinct' and (\<lambda>s. vs_valid_duplicates' (ksPSpace s))" in corres_split)
apply (erule updateCap_same_master)
apply (case_tac sum, case_tac aa)
apply (rename_tac slots)
apply (clarsimp simp: mapping_map_def valid_slots'_def valid_slots_def valid_page_inv_def
neq_Nil_conv valid_page_map_inv_def)
apply (rule corres_name_pre)
apply (subgoal_tac "length slots \<le> 16")
prefer 2
apply clarsimp
apply (drule valid_slots_duplicated'_length_Inl)
apply (fastforce split: pte.splits)
apply (clarsimp simp: mapM_Cons bind_assoc split del: if_split)
apply (rule corres_guard_imp)
apply (rule corres_split[OF pteCheckIfMapped_corres])
apply (rule corres_split[OF storePTE_corres'])
apply (clarsimp simp: pte_relation_aligned_def)
apply (clarsimp dest!: valid_slots_duplicated_pteD')
apply (rule corres_split[where r' = dc, OF corres_store_pte_with_invalid_tail])
apply (clarsimp simp: pte_relation_aligned_def)
apply (clarsimp dest!: valid_slots_duplicated_pteD')
apply (clarsimp simp: word_bits_def)
apply (rule corres_split[where r'=dc, OF corres_machine_op[OF corres_Id]])
apply (simp add: last_byte_pte_def objBits_simps archObjSize_def)
apply simp
apply (rule no_fail_cleanCacheRange_PoU)
apply (rule corres_split[where r'=dc, OF _ corres_return_eq_same[OF refl]])
apply (clarsimp simp add: when_def)
apply (rule invalidate_tlb_by_asid_corres_ex)
apply wp
apply wp
apply (wpsimp, safe; wpsimp wp: hoare_vcg_ex_lift)
apply wpsimp
apply (rule_tac Q="\<lambda>_. K (word \<le> mask asid_bits \<and> word \<noteq> 0) and invs
and (\<lambda>s. \<exists>pd. vspace_at_asid word pd s)" in hoare_strengthen_post)
prefer 2
apply auto[1]
apply (wp mapM_swp_store_pte_invs[where pte="ARM_A.pte.InvalidPTE", simplified]
hoare_vcg_ex_lift)
apply (wp mapM_UNIV_wp
| clarsimp simp add: swp_def split: prod.split simp del: fun_upd_apply)+
apply (clarsimp simp del: fun_upd_apply simp add: cte_wp_at_caps_of_state)
apply (wp add: hoare_vcg_const_Ball_lift store_pte_typ_at store_pte_cte_wp_at
hoare_vcg_ex_lift)+
apply (wp | simp add: pteCheckIfMapped_def)+
apply (clarsimp simp: cte_wp_at_caps_of_state valid_slots_def parent_for_refs_def
empty_refs_def invs_psp_aligned
simp del: fun_upd_apply)
apply (rule conjI)
apply (rule_tac x=aa in exI, rule_tac x=ba in exI)
apply (clarsimp simp: is_pt_cap_def cap_asid_def image_def neq_Nil_conv Collect_disj_eq
split: Structures_A.cap.splits arch_cap.splits option.splits)
apply (rule conjI)
apply clarsimp
apply (drule same_refs_lD)
apply (rule_tac x=a in exI, rule_tac x=b in exI)
apply clarify
apply (drule_tac x=refa in spec)
apply (clarsimp simp add: vspace_bits_defs)
apply (rule conjI[rotated])
apply (fold_subgoals (prefix))[3]
subgoal apply (unfold_subgoals) by (fastforce simp add: vspace_bits_defs)+
apply (case_tac ba)
apply (rename_tac slots)
apply (clarsimp simp: mapping_map_def valid_slots_def valid_slots'_def neq_Nil_conv
valid_page_inv_def valid_page_map_inv_def)
apply (rule corres_name_pre)
apply (subgoal_tac "length slots \<le> 16")
prefer 2
apply clarsimp
apply (drule valid_slots_duplicated'_length_Inr)
apply (fastforce split: pde.splits)
apply (clarsimp simp:mapM_Cons bind_assoc split del:if_split)
apply (rule corres_guard_imp)
apply (rule corres_split[OF pdeCheckIfMapped_corres])
apply (rule corres_split[OF storePDE_corres'])
apply (clarsimp simp: pde_relation_aligned_def)
apply (clarsimp dest!: valid_slots_duplicated_pdeD')
apply (rule corres_split[where r'=dc, OF corres_store_pde_with_invalid_tail])
apply (clarsimp simp: pde_relation_aligned_def)
apply (clarsimp dest!: valid_slots_duplicated_pdeD')
apply (simp add: word_bits_def)
apply (rule corres_split[where r'=dc,OF corres_machine_op[OF corres_Id]])
apply (simp add: last_byte_pde_def objBits_simps archObjSize_def)
apply simp
apply (rule no_fail_cleanCacheRange_PoU)
apply (rule corres_split[where r'=dc, OF _ corres_return_eq_same[OF refl]])
apply (clarsimp simp: when_def)
apply (rule invalidate_tlb_by_asid_corres_ex)
apply wp
apply wp
apply (wpsimp, safe ; wpsimp wp: hoare_vcg_ex_lift)
apply wpsimp
apply (rule_tac Q="\<lambda>_. K (word \<le> mask asid_bits \<and> word \<noteq> 0) and invs
and (\<lambda>s. \<exists>pd. vspace_at_asid word pd s)" in hoare_strengthen_post)
prefer 2
apply auto[1]
apply (wp mapM_swp_store_pde_invs_unmap[where pde="ARM_A.pde.InvalidPDE", simplified]
hoare_vcg_ex_lift)
apply (wp mapM_UNIV_wp store_pde_pd_at_asid | clarsimp simp add: swp_def)+
apply (clarsimp simp add: cte_wp_at_caps_of_state simp del: fun_upd_apply)
apply (wp hoare_vcg_const_Ball_lift store_pde_typ_at hoare_vcg_ex_lift store_pde_pd_at_asid)
apply (rule hoare_vcg_conj_lift)
apply (rule_tac slots="y # ys" in store_pde_invs_unmap')
apply (wp hoare_vcg_const_Ball_lift store_pde_pd_at_asid hoare_vcg_ex_lift)
apply (wp | simp add: pdeCheckIfMapped_def)+
apply (clarsimp simp add: cte_wp_at_caps_of_state valid_slots_def parent_for_refs_def
empty_refs_def invs_psp_aligned
simp del: fun_upd_apply)
apply (rule conjI, rule_tac x=ref in exI, clarsimp)
apply (rule conjI)
apply (rule_tac x=aa in exI, rule_tac x=ba in exI)
apply (auto simp add: arch_cap_fun_lift_def)[1]
apply (rule conjI)
apply (rule_tac x=a in exI, rule_tac x=b in exI, auto simp: same_refs_def)[1]
apply (rule conjI)
apply (clarsimp simp: pde_at_def obj_at_def
caps_of_state_cteD'[where P=\<top>, simplified])
apply (drule_tac cap="cap.ArchObjectCap acap" and ptr="(aa,ba)"
in valid_global_refsD[OF invs_valid_global_refs])
apply assumption+
apply (clarsimp simp: cap_range_def)
apply (rule conjI)
apply (clarsimp simp: pde_at_def obj_at_def a_type_def)
apply (clarsimp split: Structures_A.kernel_object.split_asm if_split_asm
ARM_A.arch_kernel_obj.splits)
apply (rule conjI[rotated], fastforce)
apply (erule ballEI)
apply (clarsimp simp: pde_at_def obj_at_def
caps_of_state_cteD'[where P=\<top>, simplified])
apply (drule_tac cap="cap.ArchObjectCap acap" and ptr="(aa,ba)"
in valid_global_refsD[OF invs_valid_global_refs])
apply assumption+
apply (drule_tac x=x in imageI[where f="\<lambda>x. x && ~~ mask pd_bits"])
apply (drule (1) subsetD)
apply (clarsimp simp: cap_range_def)
apply clarsimp
apply (wp arch_update_cap_invs_map set_cap_valid_page_map_inv)
apply (wp arch_update_updateCap_invs)
apply (clarsimp simp: invs_valid_objs invs_psp_aligned invs_distinct valid_page_inv_def
cte_wp_at_caps_of_state is_arch_update_def is_cap_simps
cap_master_cap_simps)
apply (erule (3) subst[OF same_refs_vs_cap_ref_eq, rotated 2])
apply (clarsimp simp: invs_pspace_aligned' invs_pspace_distinct' valid_page_inv'_def cte_wp_at'_def)
\<comment> \<open>PageUnmap\<close>
apply (clarsimp simp: performPageInvocation_def perform_page_invocation_def
page_invocation_map_def)
apply (rule corres_assume_pre)
apply (clarsimp simp: valid_page_inv_def valid_page_inv'_def isCap_simps is_page_cap_def
cong: option.case_cong prod.case_cong)
apply (case_tac m)
apply simp
apply (rule corres_guard_imp)
apply (rule corres_split[where r'="acap_relation"])
apply simp
apply (rule corres_rel_imp)
apply (rule get_cap_corres_all_rights_P[where P=is_arch_cap], rule refl)
apply (clarsimp simp: is_cap_simps)
apply (rule corres_split[where r'=dc, OF _ corres_return_eq_same[OF refl]])
apply (rule_tac F="is_page_cap cap" in corres_gen_asm)
apply (rule updateCap_same_master)
apply (clarsimp simp: is_page_cap_def update_map_data_def)
apply (wp get_cap_wp getSlotCap_wp)+
apply (clarsimp simp: cte_wp_at_caps_of_state)
apply (clarsimp simp: cap_rights_update_def acap_rights_update_def update_map_data_def is_cap_simps)
apply auto[1]
apply (auto simp: cte_wp_at_ctes_of)[1]
apply clarsimp
apply (rule corres_guard_imp)
apply (rule corres_split)
apply (rule unmapPage_corres)
apply (rule corres_split[where r'=acap_relation])
apply simp
apply (rule corres_rel_imp)
apply (rule get_cap_corres_all_rights_P[where P=is_arch_cap], rule refl)
apply (clarsimp simp: is_cap_simps)
apply (rule corres_split[where r'=dc, OF _ corres_return_eq_same[OF refl]])
apply (rule_tac F="is_page_cap cap" in corres_gen_asm)
apply (rule updateCap_same_master)
apply (clarsimp simp: is_page_cap_def update_map_data_def)
apply (wp get_cap_wp getSlotCap_wp)+
apply (simp add: cte_wp_at_caps_of_state)
apply (strengthen pull_out_P)+
apply wp
apply (simp add: cte_wp_at_ctes_of)
apply wp
apply (clarsimp simp: valid_unmap_def cte_wp_at_caps_of_state is_cap_simps
split: cap.splits arch_cap.splits)
apply (clarsimp simp: cap_rights_update_def is_page_cap_def cap_master_cap_simps
update_map_data_def acap_rights_update_def valid_cap_def mask_def)
apply auto[1]
apply (auto simp: cte_wp_at_ctes_of)[1]
\<comment> \<open>PageFlush\<close>
apply (clarsimp simp: performPageInvocation_def perform_page_invocation_def
page_invocation_map_def)
apply (rule corres_guard_imp)
apply (rule corres_split[where r'=dc, OF _ corres_return_eq_same[OF refl]])
apply (rule corres_when, simp)
apply (rule corres_split[OF setVMRootForFlush_corres])
apply (rule corres_split[OF corres_machine_op])
apply (rule doFlush_corres)
apply (rule corres_when, simp)
apply (rule corres_split[OF getCurThread_corres])
apply simp
apply (rule setVMRoot_corres)
apply wp+
apply (simp add: cur_tcb_def [symmetric] cur_tcb'_def [symmetric])
apply (wp hoare_drop_imps)
apply (simp add: cur_tcb_def [symmetric] cur_tcb'_def [symmetric])
apply (wp hoare_drop_imps)+
apply (auto simp: valid_page_inv_def invs_vspace_objs[simplified])[2]
\<comment> \<open>PageGetAddr\<close>
apply (clarsimp simp: perform_page_invocation_def performPageInvocation_def page_invocation_map_def fromPAddr_def)
done
qed
definition
"page_table_invocation_map pti pti' \<equiv> case pti of
ARM_A.PageTableMap cap ptr pde p \<Rightarrow>
\<exists>cap' pde'. pti' = PageTableMap cap' (cte_map ptr) pde' p \<and>
cap_relation cap cap' \<and>
pde_relation' pde pde' \<and> is_aligned (p >> pde_bits) (pde_align' pde')
| ARM_A.PageTableUnmap cap ptr \<Rightarrow>
\<exists>cap'. pti' = PageTableUnmap cap' (cte_map ptr) \<and>
cap_relation cap (ArchObjectCap cap')"
definition
"valid_pti' pti \<equiv> case pti of
PageTableMap cap slot pde pdeSlot \<Rightarrow>
cte_wp_at' (is_arch_update' cap) slot and
ko_wp_at' (\<lambda>ko. vs_entry_align ko = 0) pdeSlot and
valid_cap' cap and
valid_pde' pde and
K (valid_pde_mapping' (pdeSlot && mask pdBits) pde \<and> vs_entry_align (KOArch (KOPDE pde)) = 0)
| PageTableUnmap cap slot \<Rightarrow> cte_wp_at' (is_arch_update' (ArchObjectCap cap)) slot
and valid_cap' (ArchObjectCap cap)
and K (isPageTableCap cap)"
lemma clear_page_table_corres:
"corres dc (pspace_aligned and page_table_at p and valid_etcbs)
(pspace_aligned' and pspace_distinct')
(mapM_x (swp store_pte ARM_A.InvalidPTE)
[p , p + 8 .e. p + 2 ^ ptBits - 1])
(mapM_x (swp storePTE ARM_HYP_H.InvalidPTE)
[p , p + 8 .e. p + 2 ^ ptBits - 1])"
apply (rule_tac F="is_aligned p ptBits" in corres_req)
apply (clarsimp simp: obj_at_def a_type_def)
apply (clarsimp split: Structures_A.kernel_object.split_asm if_split_asm
arch_kernel_obj.split_asm)
apply (drule(1) pspace_alignedD)
apply (simp add: ptBits_def pageBits_def)
apply (simp add: upto_enum_step_subtract[where x=p and y="p + 8"]
is_aligned_no_overflow vspace_bits_defs
upto_enum_step_red[where us=2, simplified]
mapM_x_mapM liftM_def[symmetric])
apply (rule corres_guard_imp,
rule_tac r'=dc and S="(=)"
and Q="\<lambda>xs s. \<forall>x \<in> set xs. pte_at x s \<and> pspace_aligned s \<and> valid_etcbs s"
and Q'="\<lambda>xs. pspace_aligned' and pspace_distinct'"
in corres_mapM_list_all2, simp_all)
apply (rule corres_guard_imp, rule storePTE_corres')
apply (simp add:pte_relation_aligned_def)+
apply (wp hoare_vcg_const_Ball_lift | simp)+
apply (simp add: list_all2_refl)
apply (clarsimp simp: upto_enum_step_def)
apply (erule page_table_pte_atI[simplified shiftl_t2n mult.commute, simplified vspace_bits_defs, simplified])
apply (simp add: ptBits_def pageBits_def pt_bits_def word_less_nat_alt word_le_nat_alt unat_of_nat)
apply simp
done
crunch typ_at'[wp]: unmapPageTable "\<lambda>s. P (typ_at' T p s)"
lemmas unmapPageTable_typ_ats[wp] = typ_at_lifts[OF unmapPageTable_typ_at']
lemma performPageTableInvocation_corres:
"page_table_invocation_map pti pti' \<Longrightarrow>
corres dc
(invs and valid_etcbs and valid_pti pti)
(invs' and valid_pti' pti')
(perform_page_table_invocation pti)
(performPageTableInvocation pti')"
(is "?mp \<Longrightarrow> corres dc ?P ?P' ?f ?g")
apply (simp add: perform_page_table_invocation_def performPageTableInvocation_def)
apply (cases pti)
apply (clarsimp simp: page_table_invocation_map_def)
apply (rule corres_guard_imp)
apply (rule corres_split[OF updateCap_same_master])
apply assumption
apply (rule corres_split)
apply (rule storePDE_corres')
apply (simp add: pde_relation_aligned_def)
apply (rule corres_machine_op)
apply (rule corres_Id, rule refl, simp)
apply (rule no_fail_cleanByVA_PoU)
apply (wp set_cap_typ_at)+
apply (clarsimp simp: valid_pti_def cte_wp_at_caps_of_state is_arch_update_def)
apply (clarsimp simp: is_cap_simps cap_master_cap_simps
dest!: cap_master_cap_eqDs)
apply auto[1]
apply (clarsimp simp: cte_wp_at_ctes_of valid_pti'_def)
apply auto[1]
apply (clarsimp simp:valid_pde_mapping'_def split:ARM_HYP_H.pde.split)
apply (rename_tac cap a b)
apply (clarsimp simp: page_table_invocation_map_def)
apply (rule_tac F="is_pt_cap cap" in corres_req)
apply (clarsimp simp: valid_pti_def)
apply (clarsimp simp: is_pt_cap_def split_def
vspace_bits_defs objBits_simps archObjSize_def
cong: option.case_cong)
apply (simp add: case_option_If2 getSlotCap_def split del: if_split)
apply (rule corres_guard_imp)
apply (rule corres_split_nor)
apply (rule corres_if[OF refl])
apply (rule corres_split[OF unmapPageTable_corres])
apply (rule corres_split_nor)
apply (rule clear_page_table_corres[simplified ptBits_def pteBits_def, simplified])
apply (rule corres_machine_op, rule corres_Id)
apply simp+
apply wp+
apply (rule corres_trivial, simp)
apply (simp add: liftM_def)
apply (rule corres_split[OF get_cap_corres])
apply (rule_tac F="is_pt_cap x" in corres_gen_asm)
apply (rule updateCap_same_master)
apply (clarsimp simp: is_pt_cap_def update_map_data_def)
apply ((wp get_cap_wp)+)[2]
apply (simp add: cte_wp_at_caps_of_state pred_conj_def
split del: if_split)
apply (rule hoare_lift_Pf2[where f=caps_of_state])
apply (wp hoare_vcg_all_lift hoare_vcg_const_imp_lift
mapM_x_wp' | simp split del: if_split)+
apply (clarsimp simp: valid_pti_def cte_wp_at_caps_of_state
cap_master_cap_simps
update_map_data_def is_cap_simps
cap_rights_update_def acap_rights_update_def
dest!: cap_master_cap_eqDs)
apply (auto simp: valid_cap_def mask_def cap_master_cap_def
cap_rights_update_def acap_rights_update_def
split: option.split_asm)[1]
apply (auto simp: valid_pti'_def cte_wp_at_ctes_of)
done
definition
"asid_pool_invocation_map ap \<equiv> case ap of
asid_pool_invocation.Assign asid p slot \<Rightarrow> Assign asid p (cte_map slot)"
definition
"isPDCap cap \<equiv> \<exists>p asid. cap = ArchObjectCap (PageDirectoryCap p asid)"
definition
"valid_apinv' ap \<equiv> case ap of Assign asid p slot \<Rightarrow>
asid_pool_at' p and cte_wp_at' (isPDCap o cteCap) slot and K
(0 < asid \<and> asid \<le> 2^asid_bits - 1)"
definition (* ARMHYP: need review *)
"valid_vcpuinv' vi \<equiv> case vi of
VCPUSetTCB v t \<Rightarrow> vcpu_at' v and tcb_at' t and ex_nonz_cap_to' v and ex_nonz_cap_to' t
| VCPUInjectIRQ v n q \<Rightarrow> vcpu_at' v
| VCPUReadRegister v rg \<Rightarrow> vcpu_at' v
| VCPUWriteRegister v _ _ \<Rightarrow> vcpu_at' v
| VCPUAckVPPI v _ \<Rightarrow> vcpu_at' v"
lemma performASIDPoolInvocation_corres:
"ap' = asid_pool_invocation_map ap \<Longrightarrow>
corres dc
(valid_objs and pspace_aligned and pspace_distinct and valid_apinv ap and valid_etcbs)
(pspace_aligned' and pspace_distinct' and valid_apinv' ap')
(perform_asid_pool_invocation ap)
(performASIDPoolInvocation ap')"
apply (clarsimp simp: perform_asid_pool_invocation_def performASIDPoolInvocation_def)
apply (cases ap, simp add: asid_pool_invocation_map_def)
apply (rename_tac word1 word2 prod)
apply (rule corres_guard_imp)
apply (rule corres_split[OF getSlotCap_corres])
apply simp
apply (rule_tac F="\<exists>p asid. rv = Structures_A.ArchObjectCap (ARM_A.PageDirectoryCap p asid)" in corres_gen_asm)
apply clarsimp
apply (rule_tac Q="valid_objs and pspace_aligned and pspace_distinct and asid_pool_at word2 and valid_etcbs and
cte_wp_at (\<lambda>c. cap_master_cap c =
cap_master_cap (cap.ArchObjectCap (arch_cap.PageDirectoryCap p asid))) (a,b)"
in corres_split)
apply simp
apply (rule get_asid_pool_corres_inv')
apply (rule corres_split)
apply (rule updateCap_same_master)
apply simp
apply (rule corres_rel_imp)
apply simp
apply (rule setObject_ASIDPool_corres)
apply (simp add: inv_def)
apply (rule ext)
apply (clarsimp simp: mask_asid_low_bits_ucast_ucast)
apply (drule ucast_ucast_eq, simp, simp, simp)
apply assumption
apply (wp set_cap_typ_at)+
apply clarsimp
apply (erule cte_wp_at_weakenE)
apply (clarsimp simp: is_cap_simps cap_master_cap_simps dest!: cap_master_cap_eqDs)
apply (wp getASID_wp)
apply (wp get_cap_wp getCTE_wp)+
apply (clarsimp simp: valid_apinv_def cte_wp_at_def cap_master_cap_def is_pd_cap_def obj_at_def)
apply (clarsimp simp: a_type_def)
apply (clarsimp simp: cte_wp_at_ctes_of valid_apinv'_def)
done
lemma armv_contextSwitch_obj_at' [wp]:
"\<lbrace>\<lambda>s. P (obj_at' P' t s)\<rbrace> armv_contextSwitch pd a \<lbrace>\<lambda>rv s. P (obj_at' P' t s)\<rbrace>"
apply (simp add: armv_contextSwitch_def armv_contextSwitch_HWASID_def getHWASID_def)
apply (wp doMachineOp_obj_at|wpc|simp)+
done
crunches vcpuSave, vcpuDisable, vcpuEnable, vcpuRestore
for obj_at'_no_vcpu[wp]: "\<lambda>s. P (obj_at' (P' :: ('a :: no_vcpu) \<Rightarrow> bool) t s)"
(simp: crunch_simps wp: crunch_wps)
lemma vcpuSwitch_obj_at'_no_vcpu[wp]:
"vcpuSwitch param_a \<lbrace>\<lambda>s. P (obj_at' (P' :: ('a :: no_vcpu) \<Rightarrow> bool) t s)\<rbrace>"
by (wpsimp simp: vcpuSwitch_def modifyArchState_def | assumption)+
crunch obj_at'_no_vcpu[wp]: setVMRoot "\<lambda>s. P (obj_at' (P' :: ('a :: no_vcpu) \<Rightarrow> bool) t s)"
(simp: crunch_simps)
lemma storeHWASID_invs:
"\<lbrace>invs' and
(\<lambda>s. armKSASIDMap (ksArchState s) asid = None \<and>
armKSHWASIDTable (ksArchState s) hw_asid = None)\<rbrace>
storeHWASID asid hw_asid
\<lbrace>\<lambda>x. invs'\<rbrace>"
apply (rule hoare_add_post)
apply (rule storeHWASID_valid_arch')
apply fastforce
apply (simp add: storeHWASID_def)
apply (wp findPDForASIDAssert_pd_at_wp)
apply (clarsimp simp: invs'_def valid_state'_def valid_arch_state'_def
valid_global_refs'_def global_refs'_def valid_machine_state'_def
ct_not_inQ_def ct_idle_or_in_cur_domain'_def tcb_in_cur_domain'_def)
done
lemma storeHWASID_invs_no_cicd':
"\<lbrace>invs_no_cicd' and
(\<lambda>s. armKSASIDMap (ksArchState s) asid = None \<and>
armKSHWASIDTable (ksArchState s) hw_asid = None)\<rbrace>
storeHWASID asid hw_asid
\<lbrace>\<lambda>x. invs_no_cicd'\<rbrace>"
apply (rule hoare_add_post)
apply (rule storeHWASID_valid_arch')
apply (fastforce simp: all_invs_but_ct_idle_or_in_cur_domain'_def)
apply (simp add: storeHWASID_def)
apply (wp findPDForASIDAssert_pd_at_wp)
apply (clarsimp simp: all_invs_but_ct_idle_or_in_cur_domain'_def valid_state'_def valid_arch_state'_def
valid_global_refs'_def global_refs'_def valid_machine_state'_def
ct_not_inQ_def ct_idle_or_in_cur_domain'_def tcb_in_cur_domain'_def)
done
lemma findFreeHWASID_invs:
"\<lbrace>invs'\<rbrace> findFreeHWASID \<lbrace>\<lambda>asid. invs'\<rbrace>"
apply (rule hoare_add_post)
apply (rule findFreeHWASID_valid_arch)
apply fastforce
apply (simp add: findFreeHWASID_def invalidateHWASIDEntry_def invalidateASID_def
doMachineOp_def split_def
cong: option.case_cong)
apply (wp findPDForASIDAssert_pd_at_wp | wpc)+
apply (clarsimp simp: invs'_def valid_state'_def valid_arch_state'_def
valid_global_refs'_def global_refs'_def valid_machine_state'_def
ct_not_inQ_def
split del: if_split)
apply (intro conjI)
apply (fastforce dest: no_irq_use [OF no_irq_invalidateLocalTLB_ASID])
apply clarsimp
apply (drule_tac x=p in spec)
apply (drule use_valid)
apply (rule_tac p=p in invalidateLocalTLB_ASID_underlying_memory)
apply blast
apply clarsimp
done
lemma findFreeHWASID_invs_no_cicd':
"\<lbrace>invs_no_cicd'\<rbrace> findFreeHWASID \<lbrace>\<lambda>asid. invs_no_cicd'\<rbrace>"
apply (rule hoare_add_post)
apply (rule findFreeHWASID_valid_arch)
apply (fastforce simp: all_invs_but_ct_idle_or_in_cur_domain'_def)
apply (simp add: findFreeHWASID_def invalidateHWASIDEntry_def invalidateASID_def
doMachineOp_def split_def
cong: option.case_cong)
apply (wp findPDForASIDAssert_pd_at_wp | wpc)+
apply (clarsimp simp: all_invs_but_ct_idle_or_in_cur_domain'_def valid_state'_def valid_arch_state'_def
valid_global_refs'_def global_refs'_def valid_machine_state'_def
ct_not_inQ_def
split del: if_split)
apply (intro conjI)
apply (fastforce dest: no_irq_use [OF no_irq_invalidateLocalTLB_ASID])
apply clarsimp
apply (drule_tac x=p in spec)
apply (drule use_valid)
apply (rule_tac p=p in invalidateLocalTLB_ASID_underlying_memory)
apply blast
apply clarsimp
done
lemma getHWASID_invs [wp]:
"\<lbrace>invs'\<rbrace> getHWASID asid \<lbrace>\<lambda>hw_asid. invs'\<rbrace>"
apply (simp add: getHWASID_def)
apply (wp storeHWASID_invs findFreeHWASID_invs|wpc)+
apply simp
done
lemma getHWASID_invs_no_cicd':
"\<lbrace>invs_no_cicd'\<rbrace> getHWASID asid \<lbrace>\<lambda>hw_asid. invs_no_cicd'\<rbrace>"
apply (simp add: getHWASID_def)
apply (wp storeHWASID_invs_no_cicd' findFreeHWASID_invs_no_cicd'|wpc)+
apply simp
done
lemmas armv_ctxt_sw_defs = armv_contextSwitch_HWASID_def writeContextIDAndPD_def
lemma no_irq_armv_contextSwitch_HWASID:
"no_irq (armv_contextSwitch_HWASID pd hwasid)"
apply (simp add: armv_contextSwitch_HWASID_def)
apply (wp no_irq_writeContextIDAndPD)
done
lemma armv_contextSwitch_invs [wp]:
"\<lbrace>invs'\<rbrace> armv_contextSwitch pd asid \<lbrace>\<lambda>rv. invs'\<rbrace>"
apply (simp add: armv_contextSwitch_def)
apply (wp dmo_invs' no_irq_armv_contextSwitch_HWASID no_irq)
apply (rule hoare_post_imp[rotated], rule getHWASID_invs)
apply clarsimp
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply (simp add: machine_op_lift_def machine_rest_lift_def split_def armv_ctxt_sw_defs
| wp)+
done
lemma armv_contextSwitch_invs_no_cicd':
"\<lbrace>invs_no_cicd'\<rbrace> armv_contextSwitch pd asid \<lbrace>\<lambda>rv. invs_no_cicd'\<rbrace>"
apply (simp add: armv_contextSwitch_def armv_contextSwitch_HWASID_def)
apply (wp dmo_invs_no_cicd' no_irq_writeContextIDAndPD no_irq)
apply (rule hoare_post_imp[rotated], rule getHWASID_invs_no_cicd')
apply clarsimp
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply (clarsimp simp: machine_op_lift_def machine_rest_lift_def split_def armv_ctxt_sw_defs | wp)+
done
lemma no_irq_setCurrentPD: "no_irq (setCurrentPD addr)"
by (simp add: setCurrentPD_def setCurrentPDPL2_def)
lemma dmo_setCurrentPD_invs'[wp]:
"\<lbrace>invs'\<rbrace> doMachineOp (setCurrentPD addr) \<lbrace>\<lambda>rv. invs'\<rbrace>"
apply (wp dmo_invs' no_irq_setCurrentPD no_irq)
apply clarsimp
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply (clarsimp simp: setCurrentPD_def machine_op_lift_def writeTTBR0_def dsb_def isb_def
setCurrentPDPL2_def machine_rest_lift_def split_def | wp)+
done
lemma dmo_setCurrentPD_invs_no_cicd':
"\<lbrace>invs_no_cicd'\<rbrace> doMachineOp (setCurrentPD addr) \<lbrace>\<lambda>rv. invs_no_cicd'\<rbrace>"
apply (wp dmo_invs_no_cicd' no_irq_setCurrentPD no_irq)
apply clarsimp
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply (clarsimp simp: setCurrentPD_def machine_op_lift_def writeTTBR0_def dsb_def isb_def
machine_rest_lift_def split_def setCurrentPDPL2_def| wp)+
done
lemma valid_irq_node_lift_asm:
assumes x: "\<And>P. \<lbrace>\<lambda>s. P (irq_node' s)\<rbrace> f \<lbrace>\<lambda>rv s. P (irq_node' s)\<rbrace>"
assumes y: "\<And>p. \<lbrace>real_cte_at' p and Q\<rbrace> f \<lbrace>\<lambda>rv. real_cte_at' p\<rbrace>"
shows "\<lbrace>\<lambda>s. valid_irq_node' (irq_node' s) s \<and> Q s\<rbrace> f \<lbrace>\<lambda>rv s. valid_irq_node' (irq_node' s) s\<rbrace>"
apply (simp add: valid_irq_node'_def)
apply (rule hoare_pre)
apply (rule hoare_use_eq_irq_node' [OF x])
apply (wp hoare_vcg_all_lift y)
apply simp
done
crunches storeWordUser, armv_contextSwitch, doMachineOp
for ksQ[wp]: "\<lambda>s. P (ksReadyQueues s)"
crunches
vcpuDisable, vcpuRestore, vcpuEnable, vgicUpdateLR, vcpuWriteReg, vcpuReadReg,
vcpuRestoreRegRange, vcpuSaveRegRange
for ksQ[wp]: "\<lambda>s. P (ksReadyQueues s)"
(wp: crunch_wps)
lemma vcpuSave_ksQ[wp]:
"\<lbrace>\<lambda>s. P (ksReadyQueues s)\<rbrace> vcpuSave param_a \<lbrace>\<lambda>_ s. P (ksReadyQueues s)\<rbrace>"
supply option.case_cong_weak[cong]
apply (wpsimp simp: vcpuSave_def modifyArchState_def armvVCPUSave_def | simp)+
apply (rule_tac S="set gicIndices" in mapM_x_wp)
apply wpsimp+
done
lemma vcpuSwitch_ksQ[wp]:
"\<lbrace>\<lambda>s. P (ksReadyQueues s)\<rbrace> vcpuSwitch param_a \<lbrace>\<lambda>_ s. P (ksReadyQueues s)\<rbrace>"
by (wpsimp simp: vcpuSwitch_def modifyArchState_def | simp)+
lemma setVMRoot_ksQ[wp]:
"\<lbrace>\<lambda>s. P (ksReadyQueues s)\<rbrace> setVMRoot param_a \<lbrace>\<lambda>_ s. P (ksReadyQueues s)\<rbrace>"
apply (simp add: setVMRoot_def getThreadVSpaceRoot_def)
apply (rule hoare_pre)
apply (wp hoare_drop_imps | wpcw
| simp add: if_apply_def2 checkPDNotInASIDMap_def split del: if_split)+
done
crunch ksIdleThread[wp]: storeWordUser "\<lambda>s. P (ksIdleThread s)"
crunch ksIdleThread[wp]: asUser "\<lambda>s. P (ksIdleThread s)"
(wp: crunch_wps simp: crunch_simps)
crunch ksQ[wp]: asUser "\<lambda>s. P (ksReadyQueues s)"
(wp: crunch_wps simp: crunch_simps)
lemma dmo_machine_op_lift_invs'[wp]:
"doMachineOp (machine_op_lift f) \<lbrace>invs'\<rbrace>"
by (wpsimp wp: dmo_invs' simp: machine_op_lift_def in_monad machine_rest_lift_def select_f_def)
lemma dmo'_gets_wp:
"\<lbrace>\<lambda>s. Q (f (ksMachineState s)) s\<rbrace> doMachineOp (gets f) \<lbrace>Q\<rbrace>"
unfolding doMachineOp_def by (wpsimp simp: in_monad)
lemma hyp_live'_vcpu_regs[simp]:
"hyp_live' (KOArch (KOVCPU (vcpuRegs_update f vcpu))) = hyp_live' (KOArch (KOVCPU vcpu))"
by (simp add: hyp_live'_def arch_live'_def)
lemma hyp_live'_vcpu_vgic[simp]:
"hyp_live' (KOArch (KOVCPU (vcpuVGIC_update f' vcpu))) = hyp_live' (KOArch (KOVCPU vcpu))"
by (simp add: hyp_live'_def arch_live'_def)
lemma hyp_live'_vcpu_VPPIMasked[simp]:
"hyp_live' (KOArch (KOVCPU (vcpuVPPIMasked_update f' vcpu))) = hyp_live' (KOArch (KOVCPU vcpu))"
by (simp add: hyp_live'_def arch_live'_def)
lemma hyp_live'_vcpu_VTimer[simp]:
"hyp_live' (KOArch (KOVCPU (vcpuVTimer_update f' vcpu))) = hyp_live' (KOArch (KOVCPU vcpu))"
by (simp add: hyp_live'_def arch_live'_def)
lemma live'_vcpu_regs[simp]:
"live' (KOArch (KOVCPU (vcpuRegs_update f vcpu))) = live' (KOArch (KOVCPU vcpu))"
by (simp add: live'_def)
lemma live'_vcpu_vgic[simp]:
"live' (KOArch (KOVCPU (vcpuVGIC_update f' vcpu))) = live' (KOArch (KOVCPU vcpu))"
by (simp add: live'_def)
lemma live'_vcpu_VPPIMasked[simp]:
"live' (KOArch (KOVCPU (vcpuVPPIMasked_update f' vcpu))) = live' (KOArch (KOVCPU vcpu))"
by (simp add: live'_def)
lemma live'_vcpu_VTimer[simp]:
"live' (KOArch (KOVCPU (vcpuVTimer_update f' vcpu))) = live' (KOArch (KOVCPU vcpu))"
by (simp add: live'_def)
lemma setVCPU_regs_vcpu_live:
"\<lbrace>ko_wp_at' (is_vcpu' and hyp_live') p and ko_at' vcpu v\<rbrace>
setObject v (vcpuRegs_update f vcpu) \<lbrace>\<lambda>_. ko_wp_at' (is_vcpu' and hyp_live') p\<rbrace>"
apply (wp setObject_ko_wp_at, simp)
apply (simp add: objBits_simps archObjSize_def)
apply (clarsimp simp: vcpu_bits_def pageBits_def)
apply (clarsimp simp: pred_conj_def is_vcpu'_def ko_wp_at'_def obj_at'_real_def projectKOs)
done
lemma setVCPU_vgic_vcpu_live[wp]:
"\<lbrace>ko_wp_at' (is_vcpu' and hyp_live') p and ko_at' vcpu v\<rbrace>
setObject v (vcpuVGIC_update f vcpu) \<lbrace>\<lambda>_. ko_wp_at' (is_vcpu' and hyp_live') p\<rbrace>"
apply (wp setObject_ko_wp_at, simp)
apply (simp add: objBits_simps archObjSize_def)
apply (clarsimp simp: vcpu_bits_def pageBits_def)
apply (clarsimp simp: pred_conj_def is_vcpu'_def ko_wp_at'_def obj_at'_real_def projectKOs)
done
lemma setVCPU_VPPIMasked_vcpu_live[wp]:
"\<lbrace>ko_wp_at' (is_vcpu' and hyp_live') p and ko_at' vcpu v\<rbrace>
setObject v (vcpuVPPIMasked_update f vcpu) \<lbrace>\<lambda>_. ko_wp_at' (is_vcpu' and hyp_live') p\<rbrace>"
apply (wp setObject_ko_wp_at, simp)
apply (simp add: objBits_simps archObjSize_def)
apply (clarsimp simp: vcpu_bits_def pageBits_def)
apply (clarsimp simp: pred_conj_def is_vcpu'_def ko_wp_at'_def obj_at'_real_def projectKOs)
done
lemma setVCPU_VTimer_vcpu_live[wp]:
"\<lbrace>ko_wp_at' (is_vcpu' and hyp_live') p and ko_at' vcpu v\<rbrace>
setObject v (vcpuVTimer_update f vcpu) \<lbrace>\<lambda>_. ko_wp_at' (is_vcpu' and hyp_live') p\<rbrace>"
apply (wp setObject_ko_wp_at, simp)
apply (simp add: objBits_simps archObjSize_def)
apply (clarsimp simp: vcpu_bits_def pageBits_def)
apply (clarsimp simp: pred_conj_def is_vcpu'_def ko_wp_at'_def obj_at'_real_def projectKOs)
done
lemma vgicUpdate_vcpu_live[wp]:
"vgicUpdate v f \<lbrace> ko_wp_at' (is_vcpu' and hyp_live') p \<rbrace>"
by (wpsimp simp: vgicUpdate_def vcpuUpdate_def wp: setVCPU_vgic_vcpu_live)
lemma setVCPU_regs_vgic_vcpu_live:
"\<lbrace>ko_wp_at' (is_vcpu' and hyp_live') p and ko_at' vcpu v\<rbrace>
setObject v (vcpuRegs_update f (vcpuVGIC_update f' vcpu)) \<lbrace>\<lambda>_. ko_wp_at' (is_vcpu' and hyp_live') p\<rbrace>"
apply (wp setObject_ko_wp_at, simp)
apply (simp add: objBits_simps archObjSize_def)
apply (clarsimp simp: vcpu_bits_def pageBits_def)
apply (clarsimp simp: pred_conj_def is_vcpu'_def ko_wp_at'_def obj_at'_real_def projectKOs)
done
(* FIXME: move *)
lemma setVCPU_regs_vgic_valid_arch':
"\<lbrace>valid_arch_state' and ko_at' vcpu v\<rbrace> setObject v (vcpuRegs_update f (vcpuVGIC_update f' vcpu)) \<lbrace>\<lambda>_. valid_arch_state'\<rbrace>"
apply (simp add: valid_arch_state'_def valid_asid_table'_def option_case_all_conv)
apply (wp hoare_vcg_imp_lift hoare_vcg_all_lift setVCPU_regs_vgic_vcpu_live
| rule hoare_lift_Pf[where f=ksArchState])+
apply (clarsimp simp: pred_conj_def o_def)
done
lemma setVCPU_regs_valid_arch':
"\<lbrace>valid_arch_state' and ko_at' vcpu v\<rbrace> setObject v (vcpuRegs_update f vcpu) \<lbrace>\<lambda>_. valid_arch_state'\<rbrace>"
apply (simp add: valid_arch_state'_def valid_asid_table'_def option_case_all_conv)
apply (wp hoare_vcg_imp_lift hoare_vcg_all_lift setVCPU_regs_vcpu_live
| rule hoare_lift_Pf[where f=ksArchState])
apply (clarsimp simp: pred_conj_def o_def)
done
lemma setVCPU_vgic_valid_arch':
"\<lbrace>valid_arch_state' and ko_at' vcpu v\<rbrace> setObject v (vcpuVGIC_update f vcpu) \<lbrace>\<lambda>_. valid_arch_state'\<rbrace>"
apply (simp add: valid_arch_state'_def valid_asid_table'_def option_case_all_conv)
apply (wp hoare_vcg_imp_lift hoare_vcg_all_lift setVCPU_vgic_vcpu_live
| rule hoare_lift_Pf[where f=ksArchState])
apply (clarsimp simp: pred_conj_def o_def)
done
lemma setVCPU_VPPIMasked_valid_arch':
"\<lbrace>valid_arch_state' and ko_at' vcpu v\<rbrace> setObject v (vcpuVPPIMasked_update f vcpu) \<lbrace>\<lambda>_. valid_arch_state'\<rbrace>"
apply (simp add: valid_arch_state'_def valid_asid_table'_def option_case_all_conv)
apply (wp hoare_vcg_imp_lift hoare_vcg_all_lift setVCPU_vgic_vcpu_live
| rule hoare_lift_Pf[where f=ksArchState])
apply (clarsimp simp: pred_conj_def o_def)
done
lemma setVCPU_VTimer_valid_arch':
"\<lbrace>valid_arch_state' and ko_at' vcpu v\<rbrace> setObject v (vcpuVTimer_update f vcpu) \<lbrace>\<lambda>_. valid_arch_state'\<rbrace>"
apply (simp add: valid_arch_state'_def valid_asid_table'_def option_case_all_conv)
apply (wp hoare_vcg_imp_lift hoare_vcg_all_lift setVCPU_vgic_vcpu_live
| rule hoare_lift_Pf[where f=ksArchState])
apply (clarsimp simp: pred_conj_def o_def)
done
lemma state_refs_of'_vcpu_empty:
"ko_at' (vcpu::vcpu) v s \<Longrightarrow> (state_refs_of' s)(v := {}) = state_refs_of' s"
by (rule ext) (clarsimp simp: state_refs_of'_def obj_at'_def projectKOs)
lemma state_hyp_refs_of'_vcpu_absorb:
"ko_at' vcpu v s \<Longrightarrow>
(state_hyp_refs_of' s)(v := vcpu_tcb_refs' (vcpuTCBPtr vcpu)) = state_hyp_refs_of' s"
by (rule ext) (clarsimp simp: state_hyp_refs_of'_def obj_at'_def projectKOs)
lemma setObject_vcpu_valid_objs':
"\<lbrace>valid_objs' and valid_vcpu' vcpu\<rbrace> setObject v vcpu \<lbrace>\<lambda>_. valid_objs'\<rbrace>"
apply (wp setObject_valid_objs'[where P="valid_vcpu' vcpu"])
apply (clarsimp simp: in_monad updateObject_default_def projectKOs valid_obj'_def)
apply simp
done
lemma setVCPU_valid_arch':
"\<lbrace>valid_arch_state' and (\<lambda>s. \<forall>a. armHSCurVCPU (ksArchState s) = Some (v,a) \<longrightarrow> hyp_live' (KOArch (KOVCPU vcpu))) \<rbrace>
setObject v (vcpu::vcpu)
\<lbrace>\<lambda>_. valid_arch_state'\<rbrace>"
apply (simp add: valid_arch_state'_def valid_asid_table'_def option_case_all_conv pred_conj_def)
apply (rule hoare_vcg_conj_lift[rotated])
apply (rule hoare_vcg_conj_lift[rotated])
apply (subst conj_commute[where P="\<forall>a. _ a \<longrightarrow> _ a"])
apply (subst conj_commute[where P="\<forall>a. _ a \<longrightarrow> _ a"])
apply (subst conj_assoc)+
apply (rule hoare_vcg_conj_lift[rotated])
apply (rule hoare_vcg_conj_lift[rotated])
apply (wp hoare_vcg_all_lift hoare_vcg_imp_lift)
apply (wpsimp wp: hoare_vcg_all_lift hoare_vcg_imp_lift setObject_ko_wp_at)
apply (simp add: objBits_simps archObjSize_def vcpu_bits_def pageBits_def)+
apply safe
apply (clarsimp simp: is_vcpu'_def ko_wp_at'_def)+
apply (wp hoare_vcg_all_lift hoare_drop_imp)+
done
lemma setVCPU_valid_queues [wp]:
"\<lbrace>valid_queues\<rbrace> setObject p (v::vcpu) \<lbrace>\<lambda>_. valid_queues\<rbrace>"
by (wp valid_queues_lift | simp add: pred_tcb_at'_def)+
crunches
vcpuDisable, vcpuRestore, vcpuEnable, vcpuUpdate, vcpuSaveRegRange, vgicUpdateLR
for valid_queues[wp]: valid_queues
(ignore: doMachineOp wp: mapM_x_wp)
lemma vcpuSave_valid_queues[wp]:
"\<lbrace>Invariants_H.valid_queues\<rbrace> vcpuSave param_a \<lbrace>\<lambda>_. Invariants_H.valid_queues\<rbrace>"
by (wpsimp simp: vcpuSave_def armvVCPUSave_def wp: mapM_x_wp cong: option.case_cong_weak | simp)+
lemma vcpuSwitch_valid_queues[wp]:
"\<lbrace>Invariants_H.valid_queues\<rbrace> vcpuSwitch param_a \<lbrace>\<lambda>_. Invariants_H.valid_queues\<rbrace>"
by (wpsimp simp: vcpuSwitch_def modifyArchState_def | simp)+
lemma isb_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> doMachineOp isb \<lbrace>\<lambda>rv. invs_no_cicd'\<rbrace>"
apply (wpsimp wp: dmo_invs_no_cicd' no_irq no_irq_isb)
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply (wpsimp simp: machine_op_lift_def machine_rest_lift_def split_def)+
done
lemma dsb_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> doMachineOp dsb \<lbrace>\<lambda>rv. invs_no_cicd'\<rbrace>"
apply (wpsimp wp: dmo_invs_no_cicd' no_irq no_irq_dsb)
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply (wpsimp simp: machine_op_lift_def machine_rest_lift_def split_def)+
done
lemma setSCTLR_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> doMachineOp (setSCTLR w) \<lbrace>\<lambda>rv. invs_no_cicd'\<rbrace>"
apply (wpsimp wp: dmo_invs_no_cicd' no_irq_setSCTLR no_irq)
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply (wpsimp simp: machine_op_lift_def setSCTLR_def
machine_rest_lift_def split_def)+
done
lemma set_gic_vcpu_ctrl_hcr_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> doMachineOp (set_gic_vcpu_ctrl_hcr w) \<lbrace>\<lambda>rv. invs_no_cicd'\<rbrace>"
apply (wpsimp wp: dmo_invs_no_cicd' no_irq_set_gic_vcpu_ctrl_hcr no_irq)
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply (wpsimp simp: machine_op_lift_def set_gic_vcpu_ctrl_hcr_def
machine_rest_lift_def split_def)+
done
lemma set_gic_vcpu_ctrl_lr_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> doMachineOp (set_gic_vcpu_ctrl_lr w x) \<lbrace>\<lambda>rv. invs_no_cicd'\<rbrace>"
apply (wpsimp wp: dmo_invs_no_cicd' no_irq_set_gic_vcpu_ctrl_lr no_irq)
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply (wpsimp simp: machine_op_lift_def set_gic_vcpu_ctrl_lr_def
machine_rest_lift_def split_def)+
done
lemma set_gic_vcpu_ctrl_apr_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> doMachineOp (set_gic_vcpu_ctrl_apr w) \<lbrace>\<lambda>rv. invs_no_cicd'\<rbrace>"
apply (wpsimp wp: dmo_invs_no_cicd' no_irq_set_gic_vcpu_ctrl_apr no_irq)
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply (wpsimp simp: machine_op_lift_def set_gic_vcpu_ctrl_apr_def
machine_rest_lift_def split_def)+
done
lemma set_gic_vcpu_ctrl_vmcr_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> doMachineOp (set_gic_vcpu_ctrl_vmcr w) \<lbrace>\<lambda>rv. invs_no_cicd'\<rbrace>"
apply (wpsimp wp: dmo_invs_no_cicd' no_irq_set_gic_vcpu_ctrl_vmcr no_irq)
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply (wpsimp simp: machine_op_lift_def set_gic_vcpu_ctrl_vmcr_def
machine_rest_lift_def split_def)+
done
lemma setHCR_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> doMachineOp (setHCR w) \<lbrace>\<lambda>rv. invs_no_cicd'\<rbrace>"
apply (wpsimp wp: dmo_invs_no_cicd' no_irq_setHCR no_irq)
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply (wpsimp simp: machine_op_lift_def setHCR_def
machine_rest_lift_def split_def)+
done
lemma get_gic_vcpu_ctrl_hcr_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> doMachineOp get_gic_vcpu_ctrl_hcr \<lbrace>\<lambda>rv. invs_no_cicd'\<rbrace>"
by (wpsimp wp: dmo_invs_no_cicd' no_irq_get_gic_vcpu_ctrl_hcr no_irq
simp: get_gic_vcpu_ctrl_hcr_def gets_def in_monad)
lemma get_gic_vcpu_ctrl_lr_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> doMachineOp (get_gic_vcpu_ctrl_lr w) \<lbrace>\<lambda>rv. invs_no_cicd'\<rbrace>"
apply (wpsimp wp: dmo_invs_no_cicd' no_irq_get_gic_vcpu_ctrl_lr no_irq)
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply (wpsimp simp: machine_op_lift_def get_gic_vcpu_ctrl_lr_def
machine_rest_lift_def split_def)+
done
lemma get_gic_vcpu_ctrl_apr_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> doMachineOp get_gic_vcpu_ctrl_apr \<lbrace>\<lambda>rv. invs_no_cicd'\<rbrace>"
by (wpsimp wp: dmo_invs_no_cicd' no_irq_get_gic_vcpu_ctrl_apr no_irq
simp: get_gic_vcpu_ctrl_apr_def gets_def in_monad)
lemma get_gic_vcpu_ctrl_vmcr_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> doMachineOp get_gic_vcpu_ctrl_vmcr \<lbrace>\<lambda>rv. invs_no_cicd'\<rbrace>"
by (wpsimp wp: dmo_invs_no_cicd' no_irq_get_gic_vcpu_ctrl_vmcr no_irq
simp: get_gic_vcpu_ctrl_vmcr_def gets_def in_monad)
lemma setVCPU_regs_r_invs_cicd':
"\<lbrace>invs_no_cicd' and ko_at' vcpu v\<rbrace>
setObject v (vcpuRegs_update (\<lambda>_. (vcpuRegs vcpu)(r:=rval)) vcpu) \<lbrace>\<lambda>_. invs_no_cicd'\<rbrace>"
unfolding valid_state'_def valid_pspace'_def valid_mdb'_def invs_no_cicd'_def
valid_machine_state'_def pointerInUserData_def pointerInDeviceData_def
supply fun_upd_apply[simp del]
apply (wpsimp wp: setObject_vcpu_no_tcb_update
[where f="\<lambda>vcpu. vcpuRegs_update (\<lambda>_. (vcpuRegs vcpu)(r:=rval)) vcpu"]
sch_act_wf_lift tcb_in_cur_domain'_lift valid_queues_lift
setObject_state_refs_of' setObject_state_hyp_refs_of' valid_global_refs_lift'
valid_irq_node_lift_asm [where Q=\<top>] valid_irq_handlers_lift'
cteCaps_of_ctes_of_lift irqs_masked_lift ct_idle_or_in_cur_domain'_lift
valid_irq_states_lift' hoare_vcg_all_lift hoare_vcg_disj_lift
valid_pde_mappings_lift' setObject_typ_at' cur_tcb_lift
setVCPU_regs_valid_arch' setVCPU_regs_vcpu_live
simp: objBits_simps archObjSize_def vcpu_bits_def pageBits_def
state_refs_of'_vcpu_empty state_hyp_refs_of'_vcpu_absorb)
apply (clarsimp simp: if_live_then_nonz_cap'_def obj_at'_real_def)
apply (fastforce simp: ko_wp_at'_def projectKOs)
done
lemma setVCPU_vgic_invs_cicd':
"\<lbrace>invs_no_cicd' and ko_at' vcpu v\<rbrace>
setObject v (vcpuVGIC_update f vcpu)
\<lbrace>\<lambda>_. invs_no_cicd'\<rbrace>"
unfolding valid_state'_def valid_pspace'_def valid_mdb'_def invs_no_cicd'_def
valid_machine_state'_def pointerInUserData_def pointerInDeviceData_def
supply fun_upd_apply[simp del]
apply (wpsimp wp: setObject_vcpu_no_tcb_update
[where f="\<lambda>vcpu. (vcpuVGIC_update f vcpu)"]
sch_act_wf_lift tcb_in_cur_domain'_lift valid_queues_lift
setObject_state_refs_of' setObject_state_hyp_refs_of' valid_global_refs_lift'
valid_irq_node_lift_asm [where Q=\<top>] valid_irq_handlers_lift'
cteCaps_of_ctes_of_lift irqs_masked_lift ct_idle_or_in_cur_domain'_lift
valid_irq_states_lift' hoare_vcg_all_lift hoare_vcg_disj_lift
valid_pde_mappings_lift' setObject_typ_at' cur_tcb_lift
setVCPU_vgic_valid_arch'
simp: objBits_simps archObjSize_def vcpu_bits_def pageBits_def
state_refs_of'_vcpu_empty state_hyp_refs_of'_vcpu_absorb)
apply (clarsimp simp: if_live_then_nonz_cap'_def obj_at'_real_def)
apply (fastforce simp: ko_wp_at'_def projectKOs)
done
lemma setVCPU_VPPIMasked_invs_cicd':
"\<lbrace>invs_no_cicd' and ko_at' vcpu v\<rbrace>
setObject v (vcpuVPPIMasked_update f vcpu)
\<lbrace>\<lambda>_. invs_no_cicd'\<rbrace>"
unfolding valid_state'_def valid_pspace'_def valid_mdb'_def invs_no_cicd'_def
valid_machine_state'_def pointerInUserData_def pointerInDeviceData_def
supply fun_upd_apply[simp del]
apply (wpsimp wp: setObject_vcpu_no_tcb_update
[where f="\<lambda>vcpu. (vcpuVPPIMasked_update f vcpu)"]
sch_act_wf_lift tcb_in_cur_domain'_lift valid_queues_lift
setObject_state_refs_of' setObject_state_hyp_refs_of' valid_global_refs_lift'
valid_irq_node_lift_asm [where Q=\<top>] valid_irq_handlers_lift'
cteCaps_of_ctes_of_lift irqs_masked_lift ct_idle_or_in_cur_domain'_lift
valid_irq_states_lift' hoare_vcg_all_lift hoare_vcg_disj_lift
valid_pde_mappings_lift' setObject_typ_at' cur_tcb_lift
setVCPU_VPPIMasked_valid_arch'
simp: objBits_simps archObjSize_def vcpu_bits_def pageBits_def
state_refs_of'_vcpu_empty state_hyp_refs_of'_vcpu_absorb)
apply (clarsimp simp: if_live_then_nonz_cap'_def obj_at'_real_def)
apply (fastforce simp: ko_wp_at'_def projectKOs)
done
lemma setVCPU_VTimer_invs_cicd':
"\<lbrace>invs_no_cicd' and ko_at' vcpu v\<rbrace>
setObject v (vcpuVTimer_update f vcpu)
\<lbrace>\<lambda>_. invs_no_cicd'\<rbrace>"
unfolding valid_state'_def valid_pspace'_def valid_mdb'_def invs_no_cicd'_def
valid_machine_state'_def pointerInUserData_def pointerInDeviceData_def
supply fun_upd_apply[simp del]
apply (wpsimp wp: setObject_vcpu_no_tcb_update
[where f="\<lambda>vcpu. (vcpuVTimer_update f vcpu)"]
sch_act_wf_lift tcb_in_cur_domain'_lift valid_queues_lift
setObject_state_refs_of' setObject_state_hyp_refs_of' valid_global_refs_lift'
valid_irq_node_lift_asm [where Q=\<top>] valid_irq_handlers_lift'
cteCaps_of_ctes_of_lift irqs_masked_lift ct_idle_or_in_cur_domain'_lift
valid_irq_states_lift' hoare_vcg_all_lift hoare_vcg_disj_lift
valid_pde_mappings_lift' setObject_typ_at' cur_tcb_lift
setVCPU_VTimer_valid_arch'
simp: objBits_simps archObjSize_def vcpu_bits_def pageBits_def
state_refs_of'_vcpu_empty state_hyp_refs_of'_vcpu_absorb)
apply (clarsimp simp: if_live_then_nonz_cap'_def obj_at'_real_def)
apply (fastforce simp: ko_wp_at'_def projectKOs)
done
lemma readVCPUHardwareReg_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> doMachineOp (readVCPUHardwareReg r) \<lbrace>\<lambda>rv. invs_no_cicd'\<rbrace>"
by (wpsimp wp: dmo_invs_no_cicd' no_irq_readVCPUHardwareReg no_irq
simp: readVCPUHardwareReg_def gets_def in_monad)
lemma writeVCPUHardwareReg_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> doMachineOp (writeVCPUHardwareReg r v) \<lbrace>\<lambda>rv. invs_no_cicd'\<rbrace>"
apply (wpsimp wp: dmo_invs_no_cicd' no_irq_writeVCPUHardwareReg no_irq)
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply (wpsimp simp: machine_op_lift_def writeVCPUHardwareReg_def
machine_rest_lift_def split_def)+
done
lemma vgicUpdate_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> vgicUpdate f v \<lbrace>\<lambda>_. invs_no_cicd'\<rbrace>"
by (wpsimp simp: vgicUpdate_def vcpuUpdate_def wp: setVCPU_vgic_invs_cicd')
lemma vcpuRestoreReg_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> vcpuRestoreReg v r \<lbrace>\<lambda>_. invs_no_cicd'\<rbrace>"
by (wpsimp simp: vcpuRestoreReg_def | subst doMachineOp_bind | rule empty_fail_bind)+
lemma vcpuReadReg_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> vcpuReadReg v r \<lbrace>\<lambda>_. invs_no_cicd'\<rbrace>"
by (wpsimp simp: vcpuReadReg_def | subst doMachineOp_bind | rule empty_fail_bind)+
lemma vcpuSaveReg_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> vcpuSaveReg v r \<lbrace>\<lambda>_. invs_no_cicd'\<rbrace>"
by (wpsimp simp: vcpuSaveReg_def vcpuUpdate_def wp: setVCPU_regs_r_invs_cicd'
| subst doMachineOp_bind | rule empty_fail_bind)+
lemma vcpuWriteReg_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> vcpuWriteReg vcpu_ptr r v \<lbrace>\<lambda>_. invs_no_cicd'\<rbrace>"
by (wpsimp simp: vcpuWriteReg_def vcpuUpdate_def wp: setVCPU_regs_r_invs_cicd'
| subst doMachineOp_bind | rule empty_fail_bind)+
crunches vcpuRestoreRegRange, vcpuSaveRegRange, vgicUpdateLR
for invs_no_cicd'[wp]: invs_no_cicd'
(wp: mapM_x_wp ignore: loadObject)
lemma maskInterrupt_irq_states':
"\<lbrace>valid_irq_states'
and (\<lambda>s. \<not>b \<longrightarrow> intStateIRQTable (ksInterruptState s) irq \<noteq> irqstate.IRQInactive)\<rbrace>
doMachineOp (maskInterrupt b irq)
\<lbrace>\<lambda>rv. valid_irq_states'\<rbrace>"
by (wpsimp wp: dmo_maskInterrupt)
(auto simp add: valid_irq_states_def valid_irq_masks'_def)
lemma maskInterrupt_invs_no_cicd':
"\<lbrace>invs_no_cicd'
and (\<lambda>s. \<not>b \<longrightarrow> intStateIRQTable (ksInterruptState s) irq \<noteq> irqstate.IRQInactive)\<rbrace>
doMachineOp (maskInterrupt b irq)
\<lbrace>\<lambda>rv. invs_no_cicd'\<rbrace>"
by (wpsimp wp: maskInterrupt_irq_states' dmo_maskInterrupt simp: invs_no_cicd'_def)
(auto simp: valid_irq_states_def valid_irq_masks'_def valid_machine_state'_def
ct_not_inQ_def)
lemma getIRQState_wp:
"\<lbrace>\<lambda>s. P (intStateIRQTable (ksInterruptState s) irq) s \<rbrace> getIRQState irq \<lbrace>\<lambda>rv s. P rv s\<rbrace>"
unfolding getIRQState_def getInterruptState_def
by (wpsimp simp: comp_def)
lemma saveVirtTimer_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> saveVirtTimer vcpu_ptr \<lbrace>\<lambda>_. invs_no_cicd'\<rbrace>"
by (wpsimp simp: saveVirtTimer_def vcpuUpdate_def read_cntpct_def get_cntv_off_64_def
get_cntv_cval_64_def
wp: setVCPU_VTimer_invs_cicd' dmo'_gets_wp)+
lemma set_cntv_off_64_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> doMachineOp (set_cntv_off_64 v) \<lbrace>\<lambda>rv. invs_no_cicd'\<rbrace>"
apply (wpsimp wp: dmo_invs_no_cicd' no_irq)
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply (wpsimp simp: machine_op_lift_def set_cntv_off_64_def
machine_rest_lift_def split_def)+
done
lemma set_cntv_cval_64_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> doMachineOp (set_cntv_cval_64 v) \<lbrace>\<lambda>rv. invs_no_cicd'\<rbrace>"
apply (wpsimp wp: dmo_invs_no_cicd' no_irq)
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply (wpsimp simp: machine_op_lift_def set_cntv_cval_64_def
machine_rest_lift_def split_def)+
done
lemma restoreVirtTimer_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> restoreVirtTimer vcpu_ptr \<lbrace>\<lambda>_. invs_no_cicd'\<rbrace>"
by (wpsimp simp: restoreVirtTimer_def vcpuUpdate_def read_cntpct_def if_apply_def2
isIRQActive_def
wp: setVCPU_VTimer_invs_cicd' maskInterrupt_invs_no_cicd' getIRQState_wp dmo'_gets_wp)
lemma vcpuEnable_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> vcpuEnable v \<lbrace>\<lambda>_. invs_no_cicd'\<rbrace>"
by (wpsimp simp: vcpuEnable_def | subst doMachineOp_bind | rule empty_fail_bind)+
lemma dmo_maskInterrupt_True_invs_no_cicd'[wp]:
"doMachineOp (maskInterrupt True irq) \<lbrace>invs_no_cicd'\<rbrace>"
apply (wp dmo_maskInterrupt)
apply (clarsimp simp: invs_no_cicd'_def valid_state'_def)
apply (simp add: valid_irq_masks'_def valid_machine_state'_def
ct_not_inQ_def ct_idle_or_in_cur_domain'_def tcb_in_cur_domain'_def)
done
lemma vcpuDisable_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> vcpuDisable v \<lbrace>\<lambda>_. invs_no_cicd'\<rbrace>"
by (wpsimp wp: doMachineOp_typ_ats
simp: vcpuDisable_def valid_vcpu'_def doMachineOp_typ_at' split: option.splits
| subst doMachineOp_bind | rule empty_fail_bind conjI)+
lemma vcpuRestore_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> vcpuRestore v \<lbrace>\<lambda>_. invs_no_cicd'\<rbrace>"
including no_pre
apply (wpsimp simp: vcpuRestore_def uncurry_def split_def doMachineOp_mapM_x gets_wp
| subst doMachineOp_bind | rule empty_fail_bind)+
apply (rule_tac S="(\<lambda>i. (of_nat i, vgicLR (vcpuVGIC vcpu) i)) ` {0..<numListRegs+1}" in mapM_x_wp)
apply wpsimp
apply (auto simp: image_def gicVCPUMaxNumLR_def)[1]
apply wpsimp+
done
lemma vcpuSave_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> vcpuSave v \<lbrace>\<lambda>_. invs_no_cicd'\<rbrace>"
by (wpsimp simp: vcpuSave_def armvVCPUSave_def wp: mapM_x_wp cong: option.case_cong_weak
| assumption)+
lemma valid_arch_state'_armHSCurVCPU_update[simp]:
"ko_wp_at' (is_vcpu' and hyp_live') v s \<Longrightarrow>
valid_arch_state' s \<Longrightarrow> valid_arch_state' (s\<lparr>ksArchState := armHSCurVCPU_update (\<lambda>_. Some (v, b)) (ksArchState s)\<rparr>)"
by (clarsimp simp: invs'_def valid_state'_def valid_queues_def valid_queues_no_bitmap_def
bitmapQ_defs valid_global_refs'_def valid_arch_state'_def global_refs'_def
valid_queues'_def valid_irq_node'_def valid_irq_handlers'_def
irq_issued'_def irqs_masked'_def valid_machine_state'_def
cur_tcb'_def)
lemma dmo_vcpu_hyp:
"\<lbrace>ko_wp_at' (is_vcpu' and hyp_live') v\<rbrace> doMachineOp f \<lbrace>\<lambda>_. ko_wp_at' (is_vcpu' and hyp_live') v\<rbrace>"
by (wpsimp simp: doMachineOp_def)
lemma vcpuSaveReg_hyp[wp]:
"\<lbrace>ko_wp_at' (is_vcpu' and hyp_live') v \<rbrace> vcpuSaveReg v' r \<lbrace>\<lambda>_. ko_wp_at' (is_vcpu' and hyp_live') v\<rbrace>"
by (wpsimp simp: vcpuSaveReg_def vcpuUpdate_def wp: setVCPU_regs_vcpu_live dmo_vcpu_hyp)
lemma vcpuWriteReg_hyp[wp]:
"\<lbrace>ko_wp_at' (is_vcpu' and hyp_live') v \<rbrace> vcpuWriteReg v' r val \<lbrace>\<lambda>_. ko_wp_at' (is_vcpu' and hyp_live') v\<rbrace>"
by (wpsimp simp: vcpuWriteReg_def vcpuUpdate_def wp: setVCPU_regs_vcpu_live dmo_vcpu_hyp)
crunches
vcpuRestoreRegRange, vcpuSaveRegRange, vgicUpdateLR, vcpuReadReg
for hyp[wp]: "ko_wp_at' (is_vcpu' and hyp_live') v"
(wp: crunch_wps setVCPU_regs_vcpu_live dmo_vcpu_hyp)
lemma saveVirtTimer_hyp[wp]:
"saveVirtTimer vcpu_ptr \<lbrace>ko_wp_at' (is_vcpu' and hyp_live') v\<rbrace>"
by (wpsimp simp: saveVirtTimer_def vcpuUpdate_def wp: dmo_vcpu_hyp vgicUpdate_vcpu_live)
lemma restoreVirtTimer_hyp[wp]:
"restoreVirtTimer vcpu_ptr \<lbrace>ko_wp_at' (is_vcpu' and hyp_live') v\<rbrace>"
by (wpsimp simp: restoreVirtTimer_def vcpuUpdate_def isIRQActive_def
wp: dmo_vcpu_hyp vgicUpdate_vcpu_live)
lemma vcpuDisable_hyp[wp]:
"\<lbrace>ko_wp_at' (is_vcpu' and hyp_live') v\<rbrace> vcpuDisable (Some x) \<lbrace>\<lambda>_. ko_wp_at' (is_vcpu' and hyp_live') v\<rbrace>"
by (wpsimp simp: vcpuDisable_def wp: dmo_vcpu_hyp vgicUpdate_vcpu_live | subst doMachineOp_bind | rule empty_fail_bind)+
lemma vcpuEnable_hyp[wp]:
"\<lbrace>ko_wp_at' (is_vcpu' and hyp_live') v\<rbrace> vcpuEnable x \<lbrace>\<lambda>_. ko_wp_at' (is_vcpu' and hyp_live') v\<rbrace>"
by (wpsimp simp: vcpuEnable_def wp: dmo_vcpu_hyp | subst doMachineOp_bind | rule empty_fail_bind)+
lemma vcpuRestore_hyp[wp]:
"\<lbrace>ko_wp_at' (is_vcpu' and hyp_live') v\<rbrace> vcpuRestore x \<lbrace>\<lambda>_. ko_wp_at' (is_vcpu' and hyp_live') v\<rbrace>"
by (wpsimp simp: vcpuRestore_def wp: dmo_vcpu_hyp | subst doMachineOp_bind | rule empty_fail_bind)+
lemma getObject_vcpu_ko_at':
"(vcpu::vcpu, s') \<in> fst (getObject p s) \<Longrightarrow> s' = s \<and> ko_at' vcpu p s"
apply (rule context_conjI)
apply (drule use_valid, rule getObject_inv[where P="(=) s"]; simp add: loadObject_default_inv)
apply (drule use_valid, rule getObject_ko_at; clarsimp simp: obj_at_simps vcpu_bits_def)
done
lemma vcpuSave_hyp[wp]:
"\<lbrace>ko_wp_at' (is_vcpu' and hyp_live') v\<rbrace> vcpuSave (Some (x, b)) \<lbrace>\<lambda>_. ko_wp_at' (is_vcpu' and hyp_live') v\<rbrace>"
apply (wpsimp simp: vcpuSave_def armvVCPUSave_def
wp: dmo_vcpu_hyp | subst doMachineOp_bind | rule empty_fail_bind)+
apply (rule_tac S="set [0..<numListRegs]" in mapM_x_wp)
by (wpsimp wp: dmo_vcpu_hyp | subst doMachineOp_bind | rule empty_fail_bind)+
lemma vcpuUpdate_valid_arch_state'[wp]:
"\<forall>vcpu. vcpuTCBPtr (f vcpu) = vcpuTCBPtr vcpu \<Longrightarrow>
\<lbrace>valid_arch_state'\<rbrace> vcpuUpdate vr f \<lbrace>\<lambda>_. valid_arch_state'\<rbrace>"
including no_pre
apply (wpsimp simp: vcpuUpdate_def
wp: setVCPU_valid_arch')
by (clarsimp simp: valid_def in_monad hyp_live'_def arch_live'_def valid_arch_state'_def
obj_at'_real_def ko_wp_at'_def projectKOs is_vcpu'_def
dest!: getObject_vcpu_ko_at')+
crunches vgicUpdateLR, vcpuSave, vcpuDisable, vcpuEnable, vcpuRestore
for valid_arch_state'[wp]: valid_arch_state'
(wp: crunch_wps ignore: doMachineOp)
lemma vcpuSwitch_valid_arch_state'[wp]:
"\<lbrace>valid_arch_state' and (case v of None \<Rightarrow> \<top> | Some x \<Rightarrow> ko_wp_at' (is_vcpu' and hyp_live') x)\<rbrace>
vcpuSwitch v \<lbrace>\<lambda>_. valid_arch_state'\<rbrace>"
apply (wpsimp simp: vcpuSwitch_def modifyArchState_def
wp: vcpuDisable_hyp[simplified pred_conj_def] vcpuSave_hyp[unfolded pred_conj_def]
dmo_vcpu_hyp vcpuSave_valid_arch_state'
| strengthen valid_arch_state'_armHSCurVCPU_update | simp)+
apply (auto simp: valid_arch_state'_def pred_conj_def)
done
lemma invs_no_cicd'_armHSCurVCPU_update[simp]:
"ko_wp_at' (is_vcpu' and hyp_live') v s \<Longrightarrow> invs_no_cicd' s \<Longrightarrow>
invs_no_cicd' (s\<lparr>ksArchState := armHSCurVCPU_update (\<lambda>_. Some (v, b)) (ksArchState s)\<rparr>)"
by (clarsimp simp: invs_no_cicd'_def valid_state'_def valid_queues_def valid_queues_no_bitmap_def
bitmapQ_defs valid_global_refs'_def valid_arch_state'_def global_refs'_def
valid_queues'_def valid_irq_node'_def valid_irq_handlers'_def
irq_issued'_def irqs_masked'_def valid_machine_state'_def
cur_tcb'_def)
lemma invs'_armHSCurVCPU_update[simp]:
"ko_wp_at' (is_vcpu' and hyp_live') v s \<Longrightarrow>
invs' s \<Longrightarrow> invs' (s\<lparr>ksArchState := armHSCurVCPU_update (\<lambda>_. Some (v, b)) (ksArchState s)\<rparr>)"
apply (clarsimp simp: invs'_def valid_state'_def valid_queues_def valid_queues_no_bitmap_def
bitmapQ_defs valid_global_refs'_def valid_arch_state'_def global_refs'_def
valid_queues'_def valid_irq_node'_def valid_irq_handlers'_def
irq_issued'_def irqs_masked'_def valid_machine_state'_def
cur_tcb'_def)
done
lemma armHSCurVCPU_None_invs'[wp]:
"modifyArchState (armHSCurVCPU_update Map.empty) \<lbrace>invs'\<rbrace>"
apply (wpsimp simp: modifyArchState_def)
by (clarsimp simp: invs'_def valid_state'_def valid_machine_state'_def
ct_idle_or_in_cur_domain'_def tcb_in_cur_domain'_def
valid_arch_state'_def valid_global_refs'_def global_refs'_def)
lemma setVCPU_vgic_invs':
"\<lbrace>invs' and ko_at' vcpu v\<rbrace>
setObject v (vcpuVGIC_update f vcpu) \<lbrace>\<lambda>_. invs'\<rbrace>"
unfolding invs'_def valid_state'_def valid_pspace'_def valid_mdb'_def
valid_machine_state'_def pointerInUserData_def pointerInDeviceData_def
supply fun_upd_apply[simp del]
apply (wpsimp wp: setObject_vcpu_no_tcb_update
[where f="\<lambda>vcpu. vcpuVGIC_update f vcpu"]
sch_act_wf_lift tcb_in_cur_domain'_lift valid_queues_lift
setObject_state_refs_of' setObject_state_hyp_refs_of' valid_global_refs_lift'
valid_irq_node_lift_asm [where Q=\<top>] valid_irq_handlers_lift'
cteCaps_of_ctes_of_lift irqs_masked_lift ct_idle_or_in_cur_domain'_lift
valid_irq_states_lift' hoare_vcg_all_lift hoare_vcg_disj_lift
valid_pde_mappings_lift' setObject_typ_at' cur_tcb_lift
setVCPU_vgic_valid_arch'
simp: objBits_simps archObjSize_def vcpu_bits_def pageBits_def
state_refs_of'_vcpu_empty state_hyp_refs_of'_vcpu_absorb)
apply (clarsimp simp: if_live_then_nonz_cap'_def obj_at'_real_def)
apply (fastforce simp: ko_wp_at'_def projectKOs)
done
lemma setVCPU_regs_invs':
"\<lbrace>invs' and ko_at' vcpu v\<rbrace> setObject v (vcpuRegs_update f vcpu) \<lbrace>\<lambda>_. invs'\<rbrace>"
unfolding invs'_def valid_state'_def valid_pspace'_def valid_mdb'_def
valid_machine_state'_def pointerInUserData_def pointerInDeviceData_def
supply fun_upd_apply[simp del]
apply (wpsimp wp: setObject_vcpu_no_tcb_update
[where f="\<lambda>vcpu. vcpuRegs_update f vcpu"]
sch_act_wf_lift tcb_in_cur_domain'_lift valid_queues_lift
setObject_state_refs_of' setObject_state_hyp_refs_of' valid_global_refs_lift'
valid_irq_node_lift_asm [where Q=\<top>] valid_irq_handlers_lift'
cteCaps_of_ctes_of_lift irqs_masked_lift ct_idle_or_in_cur_domain'_lift
valid_irq_states_lift' hoare_vcg_all_lift hoare_vcg_disj_lift
valid_pde_mappings_lift' setObject_typ_at' cur_tcb_lift
setVCPU_regs_valid_arch'
simp: objBits_simps archObjSize_def vcpu_bits_def pageBits_def
state_refs_of'_vcpu_empty state_hyp_refs_of'_vcpu_absorb)
apply (clarsimp simp: if_live_then_nonz_cap'_def obj_at'_real_def)
apply (fastforce simp: ko_wp_at'_def projectKOs)
done
lemma setVCPU_VPPIMasked_invs':
"\<lbrace>invs' and ko_at' vcpu v\<rbrace> setObject v (vcpuVPPIMasked_update f vcpu) \<lbrace>\<lambda>_. invs'\<rbrace>"
unfolding invs'_def valid_state'_def valid_pspace'_def valid_mdb'_def
valid_machine_state'_def pointerInUserData_def pointerInDeviceData_def
supply fun_upd_apply[simp del]
apply (wpsimp wp: setObject_vcpu_no_tcb_update
[where f="\<lambda>vcpu. vcpuVPPIMasked_update f vcpu"]
sch_act_wf_lift tcb_in_cur_domain'_lift valid_queues_lift
setObject_state_refs_of' setObject_state_hyp_refs_of' valid_global_refs_lift'
valid_irq_node_lift_asm [where Q=\<top>] valid_irq_handlers_lift'
cteCaps_of_ctes_of_lift irqs_masked_lift ct_idle_or_in_cur_domain'_lift
valid_irq_states_lift' hoare_vcg_all_lift hoare_vcg_disj_lift
valid_pde_mappings_lift' setObject_typ_at' cur_tcb_lift
setVCPU_VPPIMasked_valid_arch'
simp: objBits_simps archObjSize_def vcpu_bits_def pageBits_def
state_refs_of'_vcpu_empty state_hyp_refs_of'_vcpu_absorb)
apply (clarsimp simp: if_live_then_nonz_cap'_def obj_at'_real_def)
apply (fastforce simp: ko_wp_at'_def projectKOs)
done
lemma setVCPU_VTimer_invs':
"\<lbrace>invs' and ko_at' vcpu v\<rbrace> setObject v (vcpuVTimer_update f vcpu) \<lbrace>\<lambda>_. invs'\<rbrace>"
unfolding invs'_def valid_state'_def valid_pspace'_def valid_mdb'_def
valid_machine_state'_def pointerInUserData_def pointerInDeviceData_def
supply fun_upd_apply[simp del]
apply (wpsimp wp: setObject_vcpu_no_tcb_update
[where f="\<lambda>vcpu. vcpuVTimer_update f vcpu"]
sch_act_wf_lift tcb_in_cur_domain'_lift valid_queues_lift
setObject_state_refs_of' setObject_state_hyp_refs_of' valid_global_refs_lift'
valid_irq_node_lift_asm [where Q=\<top>] valid_irq_handlers_lift'
cteCaps_of_ctes_of_lift irqs_masked_lift ct_idle_or_in_cur_domain'_lift
valid_irq_states_lift' hoare_vcg_all_lift hoare_vcg_disj_lift
valid_pde_mappings_lift' setObject_typ_at' cur_tcb_lift
setVCPU_VTimer_valid_arch'
simp: objBits_simps archObjSize_def vcpu_bits_def pageBits_def
state_refs_of'_vcpu_empty state_hyp_refs_of'_vcpu_absorb)
apply (clarsimp simp: if_live_then_nonz_cap'_def obj_at'_real_def)
apply (fastforce simp: ko_wp_at'_def projectKOs)
done
lemma read_writeVCPUHardwareReg_invs'[wp]:
"\<lbrace>invs'\<rbrace> doMachineOp (writeVCPUHardwareReg r v) \<lbrace>\<lambda>rv. invs'\<rbrace>"
"\<lbrace>invs'\<rbrace> doMachineOp (readVCPUHardwareReg r) \<lbrace>\<lambda>rv. invs'\<rbrace>"
by ((wpsimp wp: dmo_invs' no_irq no_irq_writeVCPUHardwareReg)
, drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p" in use_valid
, (wpsimp simp: writeVCPUHardwareReg_def readVCPUHardwareReg_def)+)+
lemma vcpuWriteReg_invs'[wp]:
"vcpuWriteReg vcpu_ptr r v \<lbrace>invs'\<rbrace>"
by (wpsimp simp: vcpuWriteReg_def vcpuUpdate_def wp: setVCPU_regs_invs')
lemma vcpuSaveReg_invs'[wp]:
"vcpuSaveReg v r \<lbrace>invs'\<rbrace>"
by (wpsimp simp: vcpuSaveReg_def vcpuUpdate_def wp: setVCPU_regs_invs')
lemma saveVirtTimer_invs'[wp]:
"saveVirtTimer vcpu_ptr \<lbrace>invs'\<rbrace>"
unfolding saveVirtTimer_def
by (wpsimp wp: dmo'_gets_wp setVCPU_vgic_invs' setVCPU_regs_invs' dmo_maskInterrupt_True
setVCPU_VTimer_invs'
simp: doMachineOp_bind vcpuUpdate_def read_cntpct_def get_cntv_off_64_def
get_cntv_cval_64_def)
lemma vcpuDisable_invs'[wp]:
"vcpuDisable v \<lbrace>invs'\<rbrace>"
unfolding vcpuDisable_def isb_def setHCR_def setSCTLR_def set_gic_vcpu_ctrl_hcr_def
getSCTLR_def get_gic_vcpu_ctrl_hcr_def dsb_def vgicUpdate_def vcpuUpdate_def
vcpuSaveReg_def
by (wpsimp wp: dmo'_gets_wp setVCPU_vgic_invs' setVCPU_regs_invs' dmo_maskInterrupt_True
simp: doMachineOp_bind empty_fail_cond)
lemma vcpuInvalidateActive_invs'[wp]:
"vcpuInvalidateActive \<lbrace>invs'\<rbrace>"
unfolding vcpuInvalidateActive_def by wpsimp
lemma dmo_set_gic_vcpu_ctrl_hcr_invs'[wp]:
"\<lbrace>invs'\<rbrace> doMachineOp (set_gic_vcpu_ctrl_hcr addr) \<lbrace>\<lambda>rv. invs'\<rbrace>"
apply (wp dmo_invs' no_irq_set_gic_vcpu_ctrl_hcr no_irq)
apply clarsimp
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply (wpsimp simp: set_gic_vcpu_ctrl_hcr_def)+
done
lemma dmo_set_gic_vcpu_ctrl_apr_invs'[wp]:
"\<lbrace>invs'\<rbrace> doMachineOp (set_gic_vcpu_ctrl_apr addr) \<lbrace>\<lambda>rv. invs'\<rbrace>"
apply (wp dmo_invs' no_irq_set_gic_vcpu_ctrl_apr no_irq)
apply clarsimp
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply (wpsimp simp: set_gic_vcpu_ctrl_apr_def)+
done
lemma dmo_set_gic_vcpu_ctrl_vmcr_invs'[wp]:
"\<lbrace>invs'\<rbrace> doMachineOp (set_gic_vcpu_ctrl_vmcr addr) \<lbrace>\<lambda>rv. invs'\<rbrace>"
apply (wp dmo_invs' no_irq_set_gic_vcpu_ctrl_vmcr no_irq)
apply clarsimp
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply (wpsimp simp: set_gic_vcpu_ctrl_vmcr_def)+
done
lemma dmo_set_gic_vcpu_ctrl_lr_invs'[wp]:
"\<lbrace>invs'\<rbrace> doMachineOp (set_gic_vcpu_ctrl_lr addr w) \<lbrace>\<lambda>rv. invs'\<rbrace>"
apply (wp dmo_invs' no_irq_set_gic_vcpu_ctrl_lr no_irq)
apply clarsimp
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply (wpsimp simp: set_gic_vcpu_ctrl_lr_def)+
done
lemma dmo_get_gic_vcpu_ctrl_lr_invs'[wp]:
"\<lbrace>invs'\<rbrace> doMachineOp (get_gic_vcpu_ctrl_lr addr) \<lbrace>\<lambda>rv. invs'\<rbrace>"
apply (wp dmo_invs' no_irq_get_gic_vcpu_ctrl_lr no_irq)
apply clarsimp
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply (wpsimp simp: get_gic_vcpu_ctrl_lr_def)+
done
lemma dmo_setSCTLR_invs'[wp]:
"\<lbrace>invs'\<rbrace> doMachineOp (setSCTLR addr) \<lbrace>\<lambda>rv. invs'\<rbrace>"
apply (wp dmo_invs' no_irq_setSCTLR no_irq)
apply clarsimp
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply (wpsimp simp: setSCTLR_def)+
done
lemma dmo_setHCR_invs'[wp]:
"\<lbrace>invs'\<rbrace> doMachineOp (setHCR addr) \<lbrace>\<lambda>rv. invs'\<rbrace>"
apply (wp dmo_invs' no_irq_setHCR no_irq)
apply clarsimp
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply (wpsimp simp: setHCR_def)+
done
lemma dmo_isb_invs'[wp]:
"\<lbrace>invs'\<rbrace> doMachineOp isb \<lbrace>\<lambda>rv. invs'\<rbrace>"
apply (wp dmo_invs' no_irq_isb no_irq)
apply clarsimp
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply wpsimp+
done
lemma dmo_dsb_invs'[wp]:
"\<lbrace>invs'\<rbrace> doMachineOp dsb \<lbrace>\<lambda>rv. invs'\<rbrace>"
apply (wp dmo_invs' no_irq_dsb no_irq)
apply clarsimp
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply wpsimp+
done
crunches
vcpuRestoreReg, vcpuRestoreRegRange, vcpuSaveReg, vcpuSaveRegRange, vgicUpdateLR, vcpuReadReg
for invs'[wp]: invs'
(wp: crunch_wps setVCPU_regs_invs' setVCPU_vgic_invs' simp: vcpuUpdate_def
ignore: doMachineOp vcpuUpdate)
lemma maskInterrupt_invs':
"\<lbrace>invs'
and (\<lambda>s. \<not>b \<longrightarrow> intStateIRQTable (ksInterruptState s) irq \<noteq> irqstate.IRQInactive)\<rbrace>
doMachineOp (maskInterrupt b irq)
\<lbrace>\<lambda>rv. invs'\<rbrace>"
by (wpsimp wp: maskInterrupt_irq_states' dmo_maskInterrupt simp: invs'_def valid_state'_def)
(auto simp: valid_irq_states_def valid_irq_masks'_def valid_machine_state'_def
ct_not_inQ_def ct_idle_or_in_cur_domain'_def tcb_in_cur_domain'_def)
lemma restoreVirtTimer_invs'[wp]:
"restoreVirtTimer vcpu_ptr \<lbrace> invs'\<rbrace>"
unfolding restoreVirtTimer_def
by (wpsimp wp: maskInterrupt_invs' getIRQState_wp dmo'_gets_wp dmo_machine_op_lift_invs'
simp: IRQ_def if_apply_def2 set_cntv_off_64_def read_cntpct_def set_cntv_cval_64_def
isIRQActive_def)
lemma vcpuEnable_invs'[wp]:
"vcpuEnable v \<lbrace> invs'\<rbrace>"
unfolding vcpuEnable_def
by (wpsimp | subst doMachineOp_bind | rule empty_fail_bind)+
lemma vcpuRestore_invs'[wp]:
"\<lbrace>invs'\<rbrace> vcpuRestore v \<lbrace>\<lambda>_. invs'\<rbrace>"
unfolding vcpuRestore_def
by (wpsimp simp: vcpuRestore_def uncurry_def split_def doMachineOp_mapM_x
wp: mapM_x_wp[OF _ subset_refl]
| subst doMachineOp_bind | rule empty_fail_bind)+
lemma vcpuSave_invs':
"\<lbrace>invs'\<rbrace> vcpuSave v \<lbrace>\<lambda>_. invs'\<rbrace>"
by (wpsimp simp: vcpuSave_def doMachineOp_mapM armvVCPUSave_def
get_gic_vcpu_ctrl_apr_def get_gic_vcpu_ctrl_vmcr_def
get_gic_vcpu_ctrl_hcr_def getSCTLR_def
wp: dmo'_gets_wp vgicUpdate_invs' mapM_x_wp[OF _ subset_refl])
lemma vcpuSwitch_invs'[wp]:
"\<lbrace>invs' and (case v of None \<Rightarrow> \<top> | Some x \<Rightarrow> ko_wp_at' (is_vcpu' and hyp_live') x)\<rbrace>
vcpuSwitch v \<lbrace>\<lambda>_. invs'\<rbrace>"
apply (wpsimp simp: vcpuSwitch_def modifyArchState_def
wp: vcpuDisable_hyp[simplified pred_conj_def] vcpuSave_hyp[unfolded pred_conj_def]
dmo_isb_invs' dmo_vcpu_hyp vcpuSave_invs'
| strengthen invs'_armHSCurVCPU_update | simp)+
apply (auto simp: invs'_def valid_state'_def valid_arch_state'_def pred_conj_def)
done
lemma vcpuSwitch_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd' and (case v of None \<Rightarrow> \<top> | Some x \<Rightarrow> ko_wp_at' (is_vcpu' and hyp_live') x)\<rbrace>
vcpuSwitch v \<lbrace>\<lambda>_. invs_no_cicd'\<rbrace>"
apply (wpsimp simp: vcpuSwitch_def modifyArchState_def
wp: vcpuDisable_hyp[simplified pred_conj_def] vcpuSave_hyp[unfolded pred_conj_def]
gets_wp vcpuSave_invs_no_cicd'
dmo_isb_invs' dmo_vcpu_hyp
| strengthen invs_no_cicd'_armHSCurVCPU_update | simp)+
apply (auto simp: invs_no_cicd'_def valid_state'_def valid_arch_state'_def pred_conj_def)
done
crunch valid_arch_state'[wp]: checkPDNotInASIDMap valid_arch_state'
crunch valid_arch_state'[wp]: findPDForASID valid_arch_state'
crunch valid_arch_state'[wp]: armv_contextSwitch valid_arch_state'
crunch ko_wp_at'[wp]: armv_contextSwitch "ko_wp_at' P' t"
lemma valid_case_option_post_wp':
"(\<And>x. \<lbrace>P x\<rbrace> f \<lbrace>\<lambda>rv. Q x\<rbrace>) \<Longrightarrow>
\<lbrace>case ep of Some x \<Rightarrow> P x | _ \<Rightarrow> \<lambda>_. True\<rbrace>
f \<lbrace>\<lambda>rv. case ep of Some x \<Rightarrow> Q x | _ \<Rightarrow> \<lambda>_. True\<rbrace>"
by (cases ep, simp_all add: hoare_vcg_prop)
abbreviation
"live_vcpu_at_tcb p s \<equiv> \<exists>x. ko_at' x p s \<and>
(case atcbVCPUPtr (tcbArch x) of None \<Rightarrow> \<lambda>_. True
| Some x \<Rightarrow> ko_wp_at' (is_vcpu' and hyp_live') x) s"
lemma setVMRoot_valid_arch_state'[wp]:
"\<lbrace>valid_arch_state' and live_vcpu_at_tcb p\<rbrace>
setVMRoot p
\<lbrace>\<lambda>rv. valid_arch_state'\<rbrace>"
apply (simp add: setVMRoot_def getThreadVSpaceRoot_def)
apply ((wpsimp wp: hoare_vcg_ex_lift hoare_drop_imps
getObject_tcb_wp valid_case_option_post_wp'
simp: if_apply_def2
| wp hoare_vcg_all_lift)+)
done
lemma modifyArchState_hyp[wp]:
"modifyArchState x \<lbrace>ko_wp_at' (is_vcpu' and hyp_live') v\<rbrace>"
by (wpsimp simp: modifyArchState_def wp: | subst doMachineOp_bind)+
lemma vcpuSwitch_hyp[wp]:
"vcpuSwitch x \<lbrace>ko_wp_at' (is_vcpu' and hyp_live') v\<rbrace>"
apply (simp add: vcpuSwitch_def)
apply wpc
apply wpsimp
apply wpsimp
apply (clarsimp simp: ko_wp_at'_def)
done
lemma switchToThread_valid_arch_state[wp]:
"\<lbrace>valid_arch_state' and live_vcpu_at_tcb p\<rbrace> ARM_HYP_H.switchToThread p \<lbrace>\<lambda>_. valid_arch_state'\<rbrace>"
apply (simp add: ARM_HYP_H.switchToThread_def)
by (wpsimp wp: hoare_vcg_ex_lift getObject_tcb_wp valid_case_option_post_wp')+
crunches switchToThread
for valid_arch_state'[wp]: valid_arch_state'
(wp: hoare_vcg_ex_lift)
lemma getObject_tcb_hyp_sym_refs:
"\<lbrace>\<lambda>s. sym_refs (state_hyp_refs_of' s)\<rbrace> getObject p
\<lbrace>\<lambda>rv. case atcbVCPUPtr (tcbArch rv) of None \<Rightarrow> \<lambda>_. True
| Some x \<Rightarrow> ko_wp_at' (is_vcpu' and hyp_live') x\<rbrace>"
apply (wpsimp wp: getObject_tcb_wp)
apply (clarsimp simp: typ_at_tcb'[symmetric] typ_at'_def ko_wp_at'_def[of _ p]
split: option.splits)
apply (case_tac ko; simp)
apply (rename_tac tcb)
apply (rule_tac x=tcb in exI; rule conjI, clarsimp simp: obj_at'_def projectKOs)
apply (clarsimp, rule context_conjI, clarsimp simp: obj_at'_def projectKOs)
apply (drule ko_at_state_hyp_refs_ofD')
apply (simp add: hyp_refs_of'_def sym_refs_def)
apply (erule_tac x=p in allE, simp)
apply (drule state_hyp_refs_of'_elemD)
apply (clarsimp simp: hyp_refs_of_rev')
apply (simp add: ko_wp_at'_def, erule exE,
clarsimp simp: is_vcpu'_def hyp_live'_def arch_live'_def)
done
lemma setVMRoot_invs'[wp]:
"\<lbrace>invs'\<rbrace> setVMRoot p \<lbrace>\<lambda>rv. invs'\<rbrace>"
apply (simp add: setVMRoot_def getThreadVSpaceRoot_def)
apply (wp hoare_drop_imps getObject_tcb_hyp_sym_refs
| wpcw
| simp add: if_apply_def2 checkPDNotInASIDMap_def split del: if_split)+
done
lemma setVMRoot_invs_no_cicd'[wp]:
"\<lbrace>invs_no_cicd'\<rbrace> setVMRoot p \<lbrace>\<lambda>rv. invs_no_cicd'\<rbrace>"
apply (simp add: setVMRoot_def getThreadVSpaceRoot_def)
apply (wp hoare_drop_imps getObject_tcb_hyp_sym_refs
armv_contextSwitch_invs_no_cicd' getHWASID_invs_no_cicd'
dmo_setCurrentPD_invs_no_cicd'
| wpcw
| simp add: if_apply_def2 checkPDNotInASIDMap_def split del: if_split)+
done
crunches
vgicUpdateLR, vcpuWriteReg, vcpuReadReg, vcpuRestoreRegRange, vcpuSaveRegRange, vcpuSave,
vcpuSwitch
for nosch[wp]: "\<lambda>s. P (ksSchedulerAction s)"
and it'[wp]: "\<lambda>s. P (ksIdleThread s)"
(ignore: doMachineOp wp: crunch_wps)
crunch nosch [wp]: setVMRoot "\<lambda>s. P (ksSchedulerAction s)"
(wp: crunch_wps getObject_inv simp: crunch_simps
loadObject_default_def)
crunch it' [wp]: findPDForASID "\<lambda>s. P (ksIdleThread s)"
(simp: crunch_simps loadObject_default_def wp: getObject_inv)
crunch it' [wp]: deleteASIDPool "\<lambda>s. P (ksIdleThread s)"
(simp: crunch_simps loadObject_default_def wp: getObject_inv mapM_wp')
crunch it' [wp]: lookupPTSlot "\<lambda>s. P (ksIdleThread s)"
(simp: crunch_simps loadObject_default_def wp: getObject_inv)
lemma storePTE_it'[wp]: "\<lbrace>\<lambda>s. P (ksIdleThread s)\<rbrace> storePTE param_a param_b \<lbrace>\<lambda>_ s. P (ksIdleThread s)\<rbrace>"
by (wpsimp wp: headM_inv hoare_drop_imp simp: storePTE_def updateObject_default_def)
lemma storePDE_it'[wp]: "\<lbrace>\<lambda>s. P (ksIdleThread s)\<rbrace> storePDE param_a param_b \<lbrace>\<lambda>_ s. P (ksIdleThread s)\<rbrace>"
by (wpsimp wp: headM_inv hoare_drop_imp simp: storePDE_def updateObject_default_def)
crunch it' [wp]: flushTable "\<lambda>s. P (ksIdleThread s)"
(simp: crunch_simps loadObject_default_def
wp: setObject_idle' hoare_drop_imps mapM_wp')
crunch it' [wp]: deleteASID "\<lambda>s. P (ksIdleThread s)"
(simp: crunch_simps loadObject_default_def updateObject_default_def
wp: getObject_inv)
lemma valid_slots_lift':
assumes t: "\<And>T p. \<lbrace>typ_at' T p\<rbrace> f \<lbrace>\<lambda>rv. typ_at' T p\<rbrace>"
shows "\<lbrace>valid_slots' x\<rbrace> f \<lbrace>\<lambda>rv. valid_slots' x\<rbrace>"
apply (clarsimp simp: valid_slots'_def split: sum.splits prod.splits)
apply safe
apply (rule hoare_pre, wp hoare_vcg_const_Ball_lift t valid_pde_lift' valid_pte_lift', simp)+
done
crunch typ_at' [wp]: performPageTableInvocation "\<lambda>s. P (typ_at' T p s)"
(wp: crunch_wps)
crunch typ_at' [wp]: performPageDirectoryInvocation "\<lambda>s. P (typ_at' T p s)"
(wp: crunch_wps)
crunch typ_at' [wp]: performPageInvocation "\<lambda>s. P (typ_at' T p s)"
(wp: crunch_wps)
crunch typ_at' [wp]: performASIDPoolInvocation "\<lambda>s. P (typ_at' T p s)"
(wp: getObject_cte_inv getASID_wp)
lemmas performPageTableInvocation_typ_ats' [wp] =
typ_at_lifts [OF performPageTableInvocation_typ_at']
lemmas performPageDirectoryInvocation_typ_ats' [wp] =
typ_at_lifts [OF performPageDirectoryInvocation_typ_at']
lemmas performPageInvocation_typ_ats' [wp] =
typ_at_lifts [OF performPageInvocation_typ_at']
lemmas performASIDPoolInvocation_typ_ats' [wp] =
typ_at_lifts [OF performASIDPoolInvocation_typ_at']
lemma storePDE_pred_tcb_at' [wp]:
"\<lbrace>pred_tcb_at' proj P t\<rbrace> storePDE p pde \<lbrace>\<lambda>_. pred_tcb_at' proj P t\<rbrace>"
apply (simp add: pred_tcb_at'_def storePDE_def)
apply (wp hoare_drop_imp obj_at_setObject2)
apply (clarsimp simp add: updateObject_default_def in_monad)
apply (clarsimp simp: obj_at'_def tcb_to_itcb'_def)
done
lemma storePTE_pred_tcb_at' [wp]:
"\<lbrace>pred_tcb_at' proj P t\<rbrace> storePTE p pte \<lbrace>\<lambda>_. pred_tcb_at' proj P t\<rbrace>"
apply (simp add: storePTE_def pred_tcb_at'_def)
apply (wp hoare_drop_imp obj_at_setObject2)
apply (clarsimp simp add: updateObject_default_def in_monad)
apply (clarsimp simp: obj_at'_def tcb_to_itcb'_def)
done
lemma setASID_pred_tcb_at' [wp]:
"\<lbrace>pred_tcb_at' proj P t\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>_. pred_tcb_at' proj P t\<rbrace>"
apply (simp add: pred_tcb_at'_def)
apply (rule obj_at_setObject2)
apply (clarsimp simp add: updateObject_default_def in_monad)
done
lemma dmo_ct[wp]:
"\<lbrace>\<lambda>s. P (ksCurThread s)\<rbrace> doMachineOp m \<lbrace>\<lambda>rv s. P (ksCurThread s)\<rbrace>"
apply (simp add: doMachineOp_def split_def)
apply wp
apply clarsimp
done
lemma storePDE_valid_mdb [wp]:
"\<lbrace>valid_mdb'\<rbrace> storePDE p pde \<lbrace>\<lambda>rv. valid_mdb'\<rbrace>"
by (simp add: valid_mdb'_def) wp
lemma storePDE_nosch[wp]:
"\<lbrace>\<lambda>s. P (ksSchedulerAction s)\<rbrace> storePDE param_a param_b \<lbrace>\<lambda>_ s. P (ksSchedulerAction s)\<rbrace>"
by (wpsimp wp: setObject_nosch headM_inv hoare_drop_imp simp: storePDE_def updateObject_default_def)
lemma storePDE_ksQ[wp]:
"\<lbrace>\<lambda>s. P (ksReadyQueues s)\<rbrace> storePDE param_a param_b \<lbrace>\<lambda>_ s. P (ksReadyQueues s)\<rbrace>"
by (wpsimp wp: headM_inv hoare_drop_imp simp: storePDE_def updateObject_default_def)
lemma storePDE_inQ[wp]:
"\<lbrace>\<lambda>s. P (obj_at' (inQ d p) t s)\<rbrace> storePDE ptr pde \<lbrace>\<lambda>rv s. P (obj_at' (inQ d p) t s)\<rbrace>"
apply (simp add: obj_at'_real_def storePDE_def)
apply (wp setObject_ko_wp_at hoare_drop_imp | simp add: objBits_simps archObjSize_def vspace_bits_defs)+
apply (clarsimp simp: projectKOs obj_at'_def ko_wp_at'_def)
done
lemma storePDE_nordL1[wp]:
"\<lbrace>\<lambda>s. P (ksReadyQueuesL1Bitmap s)\<rbrace> storePDE param_a param_b \<lbrace>\<lambda>_ s. P (ksReadyQueuesL1Bitmap s)\<rbrace>"
by (wpsimp wp: headM_inv hoare_drop_imp simp: storePDE_def updateObject_default_def)
lemma storePDE_nordL2[wp]:
"\<lbrace>\<lambda>s. P (ksReadyQueuesL2Bitmap s)\<rbrace> storePDE param_a param_b \<lbrace>\<lambda>_ s. P (ksReadyQueuesL2Bitmap s)\<rbrace>"
by (wpsimp wp: headM_inv hoare_drop_imp simp: storePDE_def updateObject_default_def)
lemma storePDE_valid_queues [wp]:
"\<lbrace>Invariants_H.valid_queues\<rbrace> storePDE p pde \<lbrace>\<lambda>_. Invariants_H.valid_queues\<rbrace>"
by (wp valid_queues_lift | simp add: pred_tcb_at'_def)+
lemma storePDE_valid_queues' [wp]:
"\<lbrace>valid_queues'\<rbrace> storePDE p pde \<lbrace>\<lambda>_. valid_queues'\<rbrace>"
by (wp valid_queues_lift')
lemma storePDE_iflive [wp]:
"\<lbrace>if_live_then_nonz_cap'\<rbrace> storePDE p pde \<lbrace>\<lambda>rv. if_live_then_nonz_cap'\<rbrace>"
apply (wpsimp simp: storePDE_def objBits_simps archObjSize_def vspace_bits_defs
wp: hoare_drop_imp setObject_iflive' [where P=\<top>])
apply (auto simp: updateObject_default_def in_monad live'_def hyp_live'_def arch_live'_def projectKOs)
done
lemma setObject_pde_ksInt [wp]:
"\<lbrace>\<lambda>s. P (ksInterruptState s)\<rbrace> setObject p (pde::pde) \<lbrace>\<lambda>_. \<lambda>s. P (ksInterruptState s)\<rbrace>"
by (wp setObject_ksInterrupt updateObject_default_inv|simp)+
lemma storePDE_ksInterruptState[wp]:
"\<lbrace>\<lambda>s. P (ksInterruptState s)\<rbrace> storePDE param_a param_b \<lbrace>\<lambda>_ s. P (ksInterruptState s)\<rbrace>"
by (wpsimp wp: headM_inv hoare_drop_imp simp: storePDE_def updateObject_default_def)
lemma storePDE_ifunsafe [wp]:
"\<lbrace>if_unsafe_then_cap'\<rbrace> storePDE p pde \<lbrace>\<lambda>rv. if_unsafe_then_cap'\<rbrace>"
apply (simp add: storePDE_def)
apply (wp setObject_ifunsafe'[where P=\<top>] hoare_drop_imp, simp)
apply (auto simp: updateObject_default_def in_monad projectKOs)[2]
apply wp
apply simp
done
method valid_idle'_setObject uses simp =
simp add: valid_idle'_def, rule hoare_lift_Pf [where f="ksIdleThread"]; wpsimp?;
(wpsimp wp: obj_at_setObject2[where P="idle_tcb'", simplified] hoare_drop_imp
simp: simp
| clarsimp dest!: updateObject_default_result)+
lemma storePDE_idle [wp]:
"\<lbrace>valid_idle'\<rbrace> storePDE p pde \<lbrace>\<lambda>rv. valid_idle'\<rbrace>" by (valid_idle'_setObject simp: storePDE_def)
lemma storePDE_arch'[wp]:
"\<lbrace>\<lambda>s. P (ksArchState s)\<rbrace> storePDE param_a param_b \<lbrace>\<lambda>_ s. P (ksArchState s)\<rbrace>"
by (wpsimp wp: headM_inv hoare_drop_imp simp: storePDE_def updateObject_default_def)
lemma storePDE_cur'[wp]:
"\<lbrace>\<lambda>s. P (ksCurThread s)\<rbrace> storePDE param_a param_b \<lbrace>\<lambda>_ s. P (ksCurThread s)\<rbrace>"
by (wpsimp wp: headM_inv hoare_drop_imp simp: storePDE_def updateObject_default_def)
lemma storePDE_irq_states' [wp]:
"\<lbrace>valid_irq_states'\<rbrace> storePDE pde p \<lbrace>\<lambda>_. valid_irq_states'\<rbrace>"
apply (simp add: storePDE_def)
apply (wpsimp wp: valid_irq_states_lift' dmo_lift' no_irq_storeWord setObject_ksMachine
updateObject_default_inv hoare_drop_imp)
done
lemma storePDE_pde_mappings'[wp]:
"\<lbrace>valid_pde_mappings' and K (valid_pde_mapping' (p && mask pdBits) pde)\<rbrace>
storePDE p pde
\<lbrace>\<lambda>rv. valid_pde_mappings'\<rbrace>"
apply (rule hoare_gen_asm)
apply (wp valid_pde_mappings_lift')
apply (rule hoare_post_imp)
apply (simp only: obj_at'_real_def)
apply (simp add: storePDE_def)
apply (wp setObject_ko_wp_at hoare_drop_imp)
apply simp
apply (simp add: objBits_simps archObjSize_def vspace_bits_defs)
apply simp
apply (clarsimp simp: obj_at'_def ko_wp_at'_def projectKOs)
apply assumption
done
lemma setObject_pde_machine_state[wp]:
"\<lbrace>\<lambda>s. P (ksMachineState s)\<rbrace> setObject t (v::pde) \<lbrace>\<lambda>rv s. P (ksMachineState s)\<rbrace>"
apply (simp add: setObject_def split_def)
apply (wp updateObject_default_inv | simp)+
done
lemma storePDE_machine_state[wp]:
"\<lbrace>\<lambda>s. P (ksMachineState s)\<rbrace> storePDE p pde \<lbrace>\<lambda>rv s. P (ksMachineState s)\<rbrace>"
by (wpsimp wp: headM_inv hoare_drop_imp simp: storePDE_def updateObject_default_def)
lemma storePDE_vms'[wp]:
"\<lbrace>valid_machine_state'\<rbrace> storePDE p pde \<lbrace>\<lambda>_. valid_machine_state'\<rbrace>"
by (wpsimp simp: valid_machine_state'_def pointerInUserData_def pointerInDeviceData_def
wp: setObject_typ_at_inv setObject_ksMachine updateObject_default_inv hoare_vcg_all_lift hoare_vcg_disj_lift)
crunch pspace_domain_valid[wp]: storePDE "pspace_domain_valid"
(wp: hoare_drop_imp)
lemma storePDE_ct_not_inQ[wp]:
"\<lbrace>ct_not_inQ\<rbrace> storePDE p pde \<lbrace>\<lambda>_. ct_not_inQ\<rbrace>"
apply (rule ct_not_inQ_lift [OF storePDE_nosch])
apply (wpsimp simp: storePDE_def updateObject_default_def wp: hoare_drop_imp)
apply (wps setObject_PDE_ct)
apply (wpsimp wp: obj_at_setObject2 simp: updateObject_default_def in_monad)+
done
lemma setObject_pde_cur_domain[wp]:
"\<lbrace>\<lambda>s. P (ksCurDomain s)\<rbrace> setObject t (v::pde) \<lbrace>\<lambda>rv s. P (ksCurDomain s)\<rbrace>"
apply (simp add: setObject_def split_def)
apply (wp updateObject_default_inv | simp)+
done
lemma setObject_pde_ksDomSchedule[wp]:
"\<lbrace>\<lambda>s. P (ksDomSchedule s)\<rbrace> setObject t (v::pde) \<lbrace>\<lambda>rv s. P (ksDomSchedule s)\<rbrace>"
apply (simp add: setObject_def split_def)
apply (wp updateObject_default_inv | simp)+
done
lemma storePDE_cur_domain[wp]:
"\<lbrace>\<lambda>s. P (ksCurDomain s)\<rbrace> storePDE p pde \<lbrace>\<lambda>rv s. P (ksCurDomain s)\<rbrace>"
by (wpsimp wp: headM_inv hoare_drop_imp simp: storePDE_def updateObject_default_def)
lemma storePDE_ksDomSchedule[wp]:
"\<lbrace>\<lambda>s. P (ksDomSchedule s)\<rbrace> storePDE p pde \<lbrace>\<lambda>rv s. P (ksDomSchedule s)\<rbrace>"
by (wpsimp wp: headM_inv hoare_drop_imp simp: storePDE_def updateObject_default_def)
lemma storePDE_tcb_obj_at'[wp]:
"\<lbrace>obj_at' (P::tcb \<Rightarrow> bool) t\<rbrace> storePDE p pde \<lbrace>\<lambda>_. obj_at' P t\<rbrace>"
by (wpsimp wp: hoare_drop_imp obj_at_setObject2 simp: storePDE_def updateObject_default_def in_monad)
lemma storePDE_tcb_in_cur_domain'[wp]:
"\<lbrace>tcb_in_cur_domain' t\<rbrace> storePDE p pde \<lbrace>\<lambda>_. tcb_in_cur_domain' t\<rbrace>"
by (wp tcb_in_cur_domain'_lift)
lemma storePDE_ct_idle_or_in_cur_domain'[wp]:
"\<lbrace>ct_idle_or_in_cur_domain'\<rbrace> storePDE p pde \<lbrace>\<lambda>_. ct_idle_or_in_cur_domain'\<rbrace>"
by (wp ct_idle_or_in_cur_domain'_lift hoare_vcg_disj_lift)
lemma setObject_pte_ksDomScheduleIdx [wp]:
"\<lbrace>\<lambda>s. P (ksDomScheduleIdx s)\<rbrace> setObject p (pte::pte) \<lbrace>\<lambda>_. \<lambda>s. P (ksDomScheduleIdx s)\<rbrace>"
by (wp updateObject_default_inv|simp add:setObject_def | wpc)+
lemma setObject_pde_ksDomScheduleIdx [wp]:
"\<lbrace>\<lambda>s. P (ksDomScheduleIdx s)\<rbrace> setObject p (pde::pde) \<lbrace>\<lambda>_. \<lambda>s. P (ksDomScheduleIdx s)\<rbrace>"
by (wp updateObject_default_inv|simp add:setObject_def | wpc)+
lemma storePDE_ksDomScheduleIdx[wp]:
"\<lbrace>\<lambda>s. P (ksDomScheduleIdx s)\<rbrace> storePDE p pde \<lbrace>\<lambda>rv s. P (ksDomScheduleIdx s)\<rbrace>"
by (wpsimp wp: headM_inv hoare_drop_imp simp: storePDE_def updateObject_default_def)
lemma storePTE_ksDomScheduleIdx[wp]:
"\<lbrace>\<lambda>s. P (ksDomScheduleIdx s)\<rbrace> storePTE p pde \<lbrace>\<lambda>rv s. P (ksDomScheduleIdx s)\<rbrace>"
by (wpsimp wp: headM_inv hoare_drop_imp simp: storePTE_def updateObject_default_def)
lemma storePDE_gsMaxObjectSize[wp]:
"\<lbrace>\<lambda>s. P (gsMaxObjectSize s)\<rbrace> storePDE p pde \<lbrace>\<lambda>rv s. P (gsMaxObjectSize s)\<rbrace>"
by (wpsimp wp: headM_inv hoare_drop_imp simp: storePDE_def updateObject_default_def setObject_def)
lemma storePTE_gsMaxObjectSize[wp]:
"\<lbrace>\<lambda>s. P (gsMaxObjectSize s)\<rbrace> storePTE p pde \<lbrace>\<lambda>rv s. P (gsMaxObjectSize s)\<rbrace>"
by (wpsimp wp: headM_inv hoare_drop_imp simp: storePTE_def updateObject_default_def setObject_def)
lemma storePDE_gsUntypedZeroRanges[wp]:
"\<lbrace>\<lambda>s. P (gsUntypedZeroRanges s)\<rbrace> storePDE p pde \<lbrace>\<lambda>rv s. P (gsUntypedZeroRanges s)\<rbrace>"
by (wpsimp wp: headM_inv hoare_drop_imp simp: storePDE_def updateObject_default_def setObject_def)
lemma storePTE_gsUntypedZeroRanges[wp]:
"\<lbrace>\<lambda>s. P (gsUntypedZeroRanges s)\<rbrace> storePTE p pde \<lbrace>\<lambda>rv s. P (gsUntypedZeroRanges s)\<rbrace>"
by (wpsimp wp: headM_inv hoare_drop_imp simp: storePTE_def updateObject_default_def setObject_def)
lemma storePDE_invs[wp]:
"\<lbrace>invs' and valid_pde' pde
and (\<lambda>s. valid_pde_mapping' (p && mask pdBits) pde)\<rbrace>
storePDE p pde
\<lbrace>\<lambda>_. invs'\<rbrace>"
apply (simp add: invs'_def valid_state'_def valid_pspace'_def)
apply (rule hoare_pre)
apply (wp sch_act_wf_lift valid_global_refs_lift'
irqs_masked_lift
valid_arch_state_lift' valid_irq_node_lift
cur_tcb_lift valid_irq_handlers_lift''
untyped_ranges_zero_lift
| simp add: cteCaps_of_def o_def)+
apply clarsimp
done
lemma storePTE_valid_mdb [wp]:
"\<lbrace>valid_mdb'\<rbrace> storePTE p pte \<lbrace>\<lambda>rv. valid_mdb'\<rbrace>"
by (simp add: valid_mdb'_def) wp
lemma storePTE_nosch[wp]:
"\<lbrace>\<lambda>s. P (ksSchedulerAction s)\<rbrace> storePTE param_a param_b \<lbrace>\<lambda>_ s. P (ksSchedulerAction s)\<rbrace>"
by (wpsimp wp: setObject_nosch headM_inv hoare_drop_imp simp: storePTE_def updateObject_default_def)
lemma storePTE_ksQ[wp]:
"\<lbrace>\<lambda>s. P (ksReadyQueues s)\<rbrace> storePTE param_a param_b \<lbrace>\<lambda>_ s. P (ksReadyQueues s)\<rbrace>"
by (wpsimp wp: headM_inv hoare_drop_imp simp: storePTE_def updateObject_default_def)
lemma storePTE_inQ[wp]:
"\<lbrace>\<lambda>s. P (obj_at' (inQ d p) t s)\<rbrace> storePTE ptr pde \<lbrace>\<lambda>rv s. P (obj_at' (inQ d p) t s)\<rbrace>"
apply (simp add: obj_at'_real_def storePTE_def)
apply (wp setObject_ko_wp_at hoare_drop_imp | simp add: objBits_simps archObjSize_def vspace_bits_defs)+
apply (clarsimp simp: projectKOs obj_at'_def ko_wp_at'_def)
done
lemma storePTE_nordL1[wp]:
"\<lbrace>\<lambda>s. P (ksReadyQueuesL1Bitmap s)\<rbrace> storePTE param_a param_b \<lbrace>\<lambda>_ s. P (ksReadyQueuesL1Bitmap s)\<rbrace>"
by (wpsimp wp: headM_inv hoare_drop_imp simp: storePTE_def updateObject_default_def)
lemma storePTE_nordL2[wp]:
"\<lbrace>\<lambda>s. P (ksReadyQueuesL2Bitmap s)\<rbrace> storePTE param_a param_b \<lbrace>\<lambda>_ s. P (ksReadyQueuesL2Bitmap s)\<rbrace>"
by (wpsimp wp: headM_inv hoare_drop_imp simp: storePTE_def updateObject_default_def)
lemma storePTE_valid_queues [wp]:
"\<lbrace>Invariants_H.valid_queues\<rbrace> storePTE p pde \<lbrace>\<lambda>_. Invariants_H.valid_queues\<rbrace>"
by (wp valid_queues_lift | simp add: pred_tcb_at'_def)+
lemma storePTE_valid_queues' [wp]:
"\<lbrace>valid_queues'\<rbrace> storePTE p pde \<lbrace>\<lambda>_. valid_queues'\<rbrace>"
by (wp valid_queues_lift')
lemma storePTE_iflive [wp]:
"\<lbrace>if_live_then_nonz_cap'\<rbrace> storePTE p pte \<lbrace>\<lambda>rv. if_live_then_nonz_cap'\<rbrace>"
apply (wpsimp simp: storePTE_def objBits_simps archObjSize_def vspace_bits_defs
wp: hoare_drop_imp setObject_iflive' [where P=\<top>])
apply (auto simp: updateObject_default_def in_monad live'_def hyp_live'_def arch_live'_def projectKOs)
done
lemma setObject_pte_ksInt [wp]:
"\<lbrace>\<lambda>s. P (ksInterruptState s)\<rbrace> setObject p (pte::pte) \<lbrace>\<lambda>_. \<lambda>s. P (ksInterruptState s)\<rbrace>"
by (wp setObject_ksInterrupt updateObject_default_inv|simp)+
lemma storePTE_ksInt'[wp]:
"\<lbrace>\<lambda>s. P (ksInterruptState s)\<rbrace> storePTE param_a param_b \<lbrace>\<lambda>_ s. P (ksInterruptState s)\<rbrace>"
by (wpsimp wp: hoare_drop_imp setObject_ksInterrupt updateObject_default_inv simp: storePTE_def)
lemma storePTE_ifunsafe [wp]:
"\<lbrace>if_unsafe_then_cap'\<rbrace> storePTE p pte \<lbrace>\<lambda>rv. if_unsafe_then_cap'\<rbrace>"
apply (simp add: storePTE_def)
apply (wp setObject_ifunsafe'[where P=\<top>] hoare_drop_imp, simp)
apply (auto simp: updateObject_default_def in_monad projectKOs)[2]
apply wp
apply simp
done
lemma storePTE_idle [wp]:
"\<lbrace>valid_idle'\<rbrace> storePTE p pte \<lbrace>\<lambda>rv. valid_idle'\<rbrace>" by (valid_idle'_setObject simp: storePTE_def)
lemma storePTE_arch'[wp]:
"\<lbrace>\<lambda>s. P (ksArchState s)\<rbrace> storePTE param_a param_b \<lbrace>\<lambda>_ s. P (ksArchState s)\<rbrace>"
by (wpsimp wp: headM_inv hoare_drop_imp simp: storePTE_def updateObject_default_def)
lemma storePTE_cur'[wp]:
"\<lbrace>\<lambda>s. P (ksCurThread s)\<rbrace> storePTE param_a param_b \<lbrace>\<lambda>_ s. P (ksCurThread s)\<rbrace>"
by (wpsimp wp: headM_inv hoare_drop_imp simp: storePTE_def updateObject_default_def)
lemma storePTE_irq_states' [wp]:
"\<lbrace>valid_irq_states'\<rbrace> storePTE pte p \<lbrace>\<lambda>_. valid_irq_states'\<rbrace>"
apply (simp add: storePTE_def)
apply (wpsimp wp: hoare_drop_imp valid_irq_states_lift' dmo_lift' no_irq_storeWord
setObject_ksMachine updateObject_default_inv)
done
lemma storePTE_valid_objs [wp]:
"\<lbrace>valid_objs' and valid_pte' pte\<rbrace> storePTE p pte \<lbrace>\<lambda>_. valid_objs'\<rbrace>"
apply (simp add: storePTE_def doMachineOp_def split_def)
apply (rule hoare_pre)
apply (wp hoare_drop_imps|wpc|simp)+
apply (rule setObject_valid_objs')
prefer 2
apply assumption
apply (clarsimp simp: updateObject_default_def in_monad)
apply (clarsimp simp: valid_obj'_def)
done
lemma storePTE_pde_mappings'[wp]:
"\<lbrace>valid_pde_mappings'\<rbrace> storePTE p pte \<lbrace>\<lambda>rv. valid_pde_mappings'\<rbrace>"
apply (wp valid_pde_mappings_lift')
apply (simp add: storePTE_def)
apply (wp hoare_drop_imp obj_at_setObject2)
apply (auto dest!: updateObject_default_result)
done
lemma setObject_pte_machine_state[wp]:
"\<lbrace>\<lambda>s. P (ksMachineState s)\<rbrace> setObject t (v::pte) \<lbrace>\<lambda>rv s. P (ksMachineState s)\<rbrace>"
apply (simp add: setObject_def split_def)
apply (wp updateObject_default_inv | simp)+
done
lemma storePTE_machine_state[wp]:
"\<lbrace>\<lambda>s. P (ksMachineState s)\<rbrace> storePTE p pde \<lbrace>\<lambda>rv s. P (ksMachineState s)\<rbrace>"
by (wpsimp wp: headM_inv hoare_drop_imp simp: storePTE_def updateObject_default_def)
lemma storePTE_vms'[wp]:
"\<lbrace>valid_machine_state'\<rbrace> storePTE p pde \<lbrace>\<lambda>_. valid_machine_state'\<rbrace>"
by (wpsimp simp: valid_machine_state'_def pointerInUserData_def pointerInDeviceData_def
wp: setObject_typ_at_inv setObject_ksMachine updateObject_default_inv hoare_vcg_all_lift hoare_vcg_disj_lift)
crunch pspace_domain_valid[wp]: storePTE "pspace_domain_valid"
(wp: hoare_drop_imp)
lemma storePTE_ct_not_inQ[wp]:
"\<lbrace>ct_not_inQ\<rbrace> storePTE p pte \<lbrace>\<lambda>_. ct_not_inQ\<rbrace>"
apply (rule ct_not_inQ_lift [OF storePTE_nosch])
apply (wpsimp simp: storePTE_def updateObject_default_def wp: hoare_drop_imp)
apply (wps setObject_PDE_ct)
apply (wpsimp wp: obj_at_setObject2 simp: updateObject_default_def in_monad)+
done
lemma setObject_pte_cur_domain[wp]:
"\<lbrace>\<lambda>s. P (ksCurDomain s)\<rbrace> setObject t (v::pte) \<lbrace>\<lambda>rv s. P (ksCurDomain s)\<rbrace>"
apply (simp add: setObject_def split_def)
apply (wp updateObject_default_inv | simp)+
done
lemma setObject_pte_ksDomSchedule[wp]:
"\<lbrace>\<lambda>s. P (ksDomSchedule s)\<rbrace> setObject t (v::pte) \<lbrace>\<lambda>rv s. P (ksDomSchedule s)\<rbrace>"
apply (simp add: setObject_def split_def)
apply (wp updateObject_default_inv | simp)+
done
lemma storePTE_cur_domain[wp]:
"\<lbrace>\<lambda>s. P (ksCurDomain s)\<rbrace> storePTE p pde \<lbrace>\<lambda>rv s. P (ksCurDomain s)\<rbrace>"
by (wpsimp wp: headM_inv hoare_drop_imp simp: storePTE_def updateObject_default_def)
lemma storePTE_ksDomSchedule[wp]:
"\<lbrace>\<lambda>s. P (ksDomSchedule s)\<rbrace> storePTE p pde \<lbrace>\<lambda>rv s. P (ksDomSchedule s)\<rbrace>"
by (wpsimp wp: headM_inv hoare_drop_imp simp: storePTE_def updateObject_default_def)
lemma storePTE_tcb_obj_at'[wp]:
"\<lbrace>obj_at' (P::tcb \<Rightarrow> bool) t\<rbrace> storePTE p pte \<lbrace>\<lambda>_. obj_at' P t\<rbrace>"
by (wpsimp wp: hoare_drop_imp obj_at_setObject2 simp: storePTE_def updateObject_default_def in_monad)
lemma storePTE_tcb_in_cur_domain'[wp]:
"\<lbrace>tcb_in_cur_domain' t\<rbrace> storePTE p pte \<lbrace>\<lambda>_. tcb_in_cur_domain' t\<rbrace>"
by (wp tcb_in_cur_domain'_lift)
lemma storePTE_ct_idle_or_in_cur_domain'[wp]:
"\<lbrace>ct_idle_or_in_cur_domain'\<rbrace> storePTE p pte \<lbrace>\<lambda>_. ct_idle_or_in_cur_domain'\<rbrace>"
by (wp ct_idle_or_in_cur_domain'_lift hoare_vcg_disj_lift)
lemma storePTE_invs [wp]:
"\<lbrace>invs' and valid_pte' pte\<rbrace> storePTE p pte \<lbrace>\<lambda>_. invs'\<rbrace>"
apply (simp add: invs'_def valid_state'_def valid_pspace'_def)
apply (wp sch_act_wf_lift valid_global_refs_lift' irqs_masked_lift
valid_arch_state_lift' valid_irq_node_lift
cur_tcb_lift valid_irq_handlers_lift''
untyped_ranges_zero_lift
| simp add: cteCaps_of_def o_def)+
apply clarsimp
done
lemma setASIDPool_valid_objs [wp]:
"\<lbrace>valid_objs' and valid_asid_pool' ap\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>_. valid_objs'\<rbrace>"
apply (rule hoare_pre)
apply (rule setObject_valid_objs')
prefer 2
apply assumption
apply (clarsimp simp: updateObject_default_def in_monad)
apply (clarsimp simp: valid_obj'_def)
done
lemma setASIDPool_valid_mdb [wp]:
"\<lbrace>valid_mdb'\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>rv. valid_mdb'\<rbrace>"
by (simp add: valid_mdb'_def) wp
lemma setASIDPool_nosch [wp]:
"\<lbrace>\<lambda>s. P (ksSchedulerAction s)\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>rv s. P (ksSchedulerAction s)\<rbrace>"
by (wp setObject_nosch updateObject_default_inv|simp)+
lemma setASIDPool_ksQ [wp]:
"\<lbrace>\<lambda>s. P (ksReadyQueues s)\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>rv s. P (ksReadyQueues s)\<rbrace>"
by (wp setObject_qs updateObject_default_inv|simp)+
lemma setASIDPool_inQ[wp]:
"\<lbrace>\<lambda>s. P (obj_at' (inQ d p) t s)\<rbrace>
setObject ptr (ap::asidpool)
\<lbrace>\<lambda>rv s. P (obj_at' (inQ d p) t s)\<rbrace>"
apply (simp add: obj_at'_real_def)
apply (wp setObject_ko_wp_at
| simp add: objBits_simps archObjSize_def)+
apply (simp add: pageBits_def)
apply (clarsimp simp: obj_at'_def ko_wp_at'_def projectKOs)
done
lemma setASIDPool_qsL1 [wp]:
"\<lbrace>\<lambda>s. P (ksReadyQueuesL1Bitmap s)\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>rv s. P (ksReadyQueuesL1Bitmap s)\<rbrace>"
by (wp setObject_qs updateObject_default_inv|simp)+
lemma setASIDPool_qsL2 [wp]:
"\<lbrace>\<lambda>s. P (ksReadyQueuesL2Bitmap s)\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>rv s. P (ksReadyQueuesL2Bitmap s)\<rbrace>"
by (wp setObject_qs updateObject_default_inv|simp)+
lemma setASIDPool_valid_queues [wp]:
"\<lbrace>Invariants_H.valid_queues\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>_. Invariants_H.valid_queues\<rbrace>"
by (wp valid_queues_lift | simp add: pred_tcb_at'_def)+
lemma setASIDPool_valid_queues' [wp]:
"\<lbrace>valid_queues'\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>_. valid_queues'\<rbrace>"
by (wp valid_queues_lift')
lemma setASIDPool_state_refs' [wp]:
"\<lbrace>\<lambda>s. P (state_refs_of' s)\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>rv s. P (state_refs_of' s)\<rbrace>"
apply (clarsimp simp: setObject_def valid_def in_monad split_def
updateObject_default_def projectKOs objBits_simps
in_magnitude_check state_refs_of'_def ps_clear_upd
elim!: rsubst[where P=P] intro!: ext
split del: if_split cong: option.case_cong if_cong)
apply (simp split: option.split)
done
lemma setASIDPool_state_hyp_refs' [wp]:
"\<lbrace>\<lambda>s. P (state_hyp_refs_of' s)\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>rv s. P (state_hyp_refs_of' s)\<rbrace>"
apply (clarsimp simp: setObject_def valid_def in_monad split_def
updateObject_default_def projectKOs objBits_simps
in_magnitude_check state_hyp_refs_of'_def ps_clear_upd
elim!: rsubst[where P=P] intro!: ext
split del: if_split cong: option.case_cong if_cong)
apply (simp split: option.split)
done
lemma setASIDPool_iflive [wp]:
"\<lbrace>if_live_then_nonz_cap'\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>rv. if_live_then_nonz_cap'\<rbrace>"
apply (rule hoare_pre)
apply (rule setObject_iflive' [where P=\<top>], simp)
apply (simp add: objBits_simps archObjSize_def)
apply (auto simp: updateObject_default_def in_monad live'_def hyp_live'_def arch_live'_def projectKOs pageBits_def)
done
lemma setASIDPool_ksInt [wp]:
"\<lbrace>\<lambda>s. P (ksInterruptState s)\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>_. \<lambda>s. P (ksInterruptState s)\<rbrace>"
by (wp setObject_ksInterrupt updateObject_default_inv|simp)+
lemma setASIDPool_ifunsafe [wp]:
"\<lbrace>if_unsafe_then_cap'\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>rv. if_unsafe_then_cap'\<rbrace>"
apply (rule hoare_pre)
apply (rule setObject_ifunsafe' [where P=\<top>], simp)
apply (auto simp: updateObject_default_def in_monad projectKOs)[2]
apply wp
apply simp
done
lemma setASIDPool_it' [wp]:
"\<lbrace>\<lambda>s. P (ksIdleThread s)\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>_. \<lambda>s. P (ksIdleThread s)\<rbrace>"
by (wp setObject_it updateObject_default_inv|simp)+
lemma setASIDPool_idle [wp]:
"\<lbrace>valid_idle'\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>rv. valid_idle'\<rbrace>" by valid_idle'_setObject
lemma setASIDPool_irq_states' [wp]:
"\<lbrace>valid_irq_states'\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>_. valid_irq_states'\<rbrace>"
apply (rule hoare_pre)
apply (rule hoare_use_eq [where f=ksInterruptState, OF setObject_ksInterrupt])
apply (simp, rule updateObject_default_inv)
apply (rule hoare_use_eq [where f=ksMachineState, OF setObject_ksMachine])
apply (simp, rule updateObject_default_inv)
apply wp
apply assumption
done
lemma setObject_asidpool_mappings'[wp]:
"\<lbrace>valid_pde_mappings'\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>rv. valid_pde_mappings'\<rbrace>"
apply (wp valid_pde_mappings_lift')
apply (rule obj_at_setObject2)
apply (clarsimp dest!: updateObject_default_result)
apply assumption
done
lemma setASIDPool_vms'[wp]:
"\<lbrace>valid_machine_state'\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>_. valid_machine_state'\<rbrace>"
apply (simp add: valid_machine_state'_def pointerInUserData_def pointerInDeviceData_def)
apply (wp setObject_typ_at_inv setObject_ksMachine updateObject_default_inv
hoare_vcg_all_lift hoare_vcg_disj_lift | simp)+
done
lemma setASIDPool_ct_not_inQ[wp]:
"\<lbrace>ct_not_inQ\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>_. ct_not_inQ\<rbrace>"
apply (rule ct_not_inQ_lift [OF setObject_nosch])
apply (simp add: updateObject_default_def | wp)+
apply (rule hoare_weaken_pre)
apply (wps setObject_ASID_ct)
apply (rule obj_at_setObject2)
apply (clarsimp simp: updateObject_default_def in_monad)+
done
lemma setObject_asidpool_cur'[wp]:
"\<lbrace>\<lambda>s. P (ksCurThread s)\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>rv s. P (ksCurThread s)\<rbrace>"
apply (simp add: setObject_def)
apply (wp | wpc | simp add: updateObject_default_def)+
done
lemma setObject_asidpool_cur_domain[wp]:
"\<lbrace>\<lambda>s. P (ksCurDomain s)\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>rv s. P (ksCurDomain s)\<rbrace>"
apply (simp add: setObject_def split_def)
apply (wp updateObject_default_inv | simp)+
done
lemma setObject_asidpool_ksDomSchedule[wp]:
"\<lbrace>\<lambda>s. P (ksDomSchedule s)\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>rv s. P (ksDomSchedule s)\<rbrace>"
apply (simp add: setObject_def split_def)
apply (wp updateObject_default_inv | simp)+
done
lemma setObject_tcb_obj_at'[wp]:
"\<lbrace>obj_at' (P::tcb \<Rightarrow> bool) t\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>_. obj_at' P t\<rbrace>"
apply (rule obj_at_setObject2)
apply (clarsimp simp add: updateObject_default_def in_monad)
done
lemma setObject_asidpool_tcb_in_cur_domain'[wp]:
"\<lbrace>tcb_in_cur_domain' t\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>_. tcb_in_cur_domain' t\<rbrace>"
by (wp tcb_in_cur_domain'_lift)
lemma setObject_asidpool_ct_idle_or_in_cur_domain'[wp]:
"\<lbrace>ct_idle_or_in_cur_domain'\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>_. ct_idle_or_in_cur_domain'\<rbrace>"
apply (rule ct_idle_or_in_cur_domain'_lift)
apply (wp hoare_vcg_disj_lift)+
done
lemma setObject_ap_ksDomScheduleIdx [wp]:
"\<lbrace>\<lambda>s. P (ksDomScheduleIdx s)\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>_. \<lambda>s. P (ksDomScheduleIdx s)\<rbrace>"
by (wp updateObject_default_inv|simp add:setObject_def | wpc)+
lemma setASIDPool_invs [wp]:
"\<lbrace>invs' and valid_asid_pool' ap\<rbrace> setObject p (ap::asidpool) \<lbrace>\<lambda>_. invs'\<rbrace>"
apply (simp add: invs'_def valid_state'_def valid_pspace'_def)
apply (wp sch_act_wf_lift valid_global_refs_lift' irqs_masked_lift
valid_irq_node_lift
cur_tcb_lift valid_irq_handlers_lift''
untyped_ranges_zero_lift
updateObject_default_inv
| simp add: cteCaps_of_def
| rule setObject_ksPSpace_only)+
apply (clarsimp simp: o_def)
done
crunches vcpuSave, vcpuRestore, vcpuDisable, vcpuEnable
for cte_wp_at'[wp]: "\<lambda>s. P (cte_wp_at' P' p s)"
(simp: crunch_simps wp: crunch_wps getObject_inv_vcpu loadObject_default_inv)
lemma vcpuSwitch_cte_wp_at'[wp]:
"\<lbrace>\<lambda>s. P (cte_wp_at' P' p s)\<rbrace> vcpuSwitch param_a \<lbrace>\<lambda>_ s. P (cte_wp_at' P' p s)\<rbrace> "
by (wpsimp simp: vcpuSwitch_def modifyArchState_def | assumption)+
crunch cte_wp_at'[wp]: unmapPageTable "\<lambda>s. P (cte_wp_at' P' p s)"
(wp: crunch_wps simp: crunch_simps)
lemmas storePDE_Invalid_invs = storePDE_invs[where pde=InvalidPDE, simplified]
lemma setVMRootForFlush_invs'[wp]: "\<lbrace>invs'\<rbrace> setVMRootForFlush a b \<lbrace>\<lambda>_. invs'\<rbrace>"
apply (simp add: setVMRootForFlush_def)
apply (wp storePDE_Invalid_invs mapM_wp' crunch_wps | simp add: crunch_simps)+
apply (simp add: getThreadVSpaceRoot_def)
apply (wp storePDE_Invalid_invs mapM_wp' crunch_wps | simp add: crunch_simps)+
done
lemma dmo_invalidateLocalTLB_VAASID_invs'[wp]:
"\<lbrace>invs'\<rbrace> doMachineOp (invalidateLocalTLB_VAASID x) \<lbrace>\<lambda>_. invs'\<rbrace>"
apply (wp dmo_invs' no_irq_invalidateLocalTLB_VAASID no_irq)
apply clarsimp
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' p = underlying_memory m p"
in use_valid)
apply (clarsimp simp: invalidateLocalTLB_VAASID_def machine_op_lift_def
machine_rest_lift_def split_def | wp)+
done
lemma dmo_cVA_PoU_invs'[wp]:
"\<lbrace>invs'\<rbrace> doMachineOp (cleanByVA_PoU w p) \<lbrace>\<lambda>_. invs'\<rbrace>"
apply (wp dmo_invs' no_irq_cleanByVA_PoU no_irq)
apply clarsimp
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' pa = underlying_memory m pa"
in use_valid)
apply (clarsimp simp: cleanByVA_PoU_def machine_op_lift_def
machine_rest_lift_def split_def | wp)+
done
lemma dmo_ccr_PoU_invs'[wp]:
"\<lbrace>invs'\<rbrace> doMachineOp (cleanCacheRange_PoU s e p) \<lbrace>\<lambda>r. invs'\<rbrace>"
apply (wp dmo_invs' no_irq_cleanCacheRange_PoU no_irq)
apply clarsimp
apply (drule_tac Q="\<lambda>_ m'. underlying_memory m' pa = underlying_memory m pa"
in use_valid)
apply (clarsimp simp: cleanCacheRange_PoU_def machine_op_lift_def
machine_rest_lift_def split_def | wp)+
done
(* FIXME: Move *)
lemma dmo_invalidateLocalTLB_ASID_invs'[wp]:
"\<lbrace>invs'\<rbrace> doMachineOp (invalidateLocalTLB_ASID a) \<lbrace>\<lambda>_. invs'\<rbrace>"
apply (wp dmo_invs' no_irq_invalidateLocalTLB_ASID no_irq)
apply clarsimp
apply (drule_tac P4="\<lambda>m'. underlying_memory m' p = underlying_memory m p"
in use_valid[where P=P and Q="\<lambda>_. P" for P])
apply (simp add: invalidateLocalTLB_ASID_def machine_op_lift_def
machine_rest_lift_def split_def | wp)+
done
lemma dmo_cleanCaches_PoU_invs'[wp]:
"\<lbrace>invs'\<rbrace> doMachineOp cleanCaches_PoU \<lbrace>\<lambda>_. invs'\<rbrace>"
apply (wp dmo_invs' no_irq_cleanCaches_PoU no_irq)
apply clarsimp
apply (drule_tac P4="\<lambda>m'. underlying_memory m' p = underlying_memory m p"
in use_valid[where P=P and Q="\<lambda>_. P" for P])
apply (simp add: cleanCaches_PoU_def machine_op_lift_def
machine_rest_lift_def split_def | wp)+
done
crunch invs'[wp]: unmapPageTable "invs'"
(ignore: storePDE doMachineOp
wp: dmo_invalidateLocalTLB_VAASID_invs' dmo_setCurrentPD_invs'
storePDE_Invalid_invs mapM_wp' no_irq_setCurrentPD
crunch_wps
simp: crunch_simps)
lemma perform_pti_invs [wp]:
"\<lbrace>invs' and valid_pti' pti\<rbrace> performPageTableInvocation pti \<lbrace>\<lambda>_. invs'\<rbrace>"
apply (clarsimp simp: performPageTableInvocation_def getSlotCap_def
split: page_table_invocation.splits)
apply (intro conjI allI impI)
apply (rule hoare_pre)
apply (wp arch_update_updateCap_invs getCTE_wp
hoare_vcg_ex_lift no_irq_cleanCacheRange_PoU mapM_x_wp'
| wpc | simp add: o_def
| (simp only: imp_conv_disj, rule hoare_vcg_disj_lift))+
apply (clarsimp simp: valid_pti'_def cte_wp_at_ctes_of
is_arch_update'_def isCap_simps valid_cap'_def
capAligned_def)
apply (rule hoare_pre)
apply (wp arch_update_updateCap_invs valid_pde_lift'
no_irq_cleanByVA_PoU
| simp)+
apply (clarsimp simp: cte_wp_at_ctes_of valid_pti'_def)
done
crunch invs'[wp]: setVMRootForFlush "invs'"
lemma addPTEOffset_Invalid[simp]:
"addPTEOffset InvalidPTE x = InvalidPTE"
by (simp add: addPTEOffset_def)
lemma in_set_zip_singleton[simp]:
"(x, y) \<in> set (zip xs [z]) = ((\<exists>xs'. xs = x#xs') \<and> y = z)"
by (cases xs) auto
lemma valid_pte'_offset:
"\<lbrakk> valid_pte' pte s; x \<le> 15; pte = LargePagePTE p a b c; vmsz_aligned' p ARMLargePage \<rbrakk>
\<Longrightarrow> valid_pte' (addPTEOffset pte x) s"
using is_aligned_mult_triv2[of x 12, simplified] is_aligned_pptrBaseOffset [of ARMLargePage]
apply (clarsimp simp: addPTEOffset_def valid_mapping'_def addPAddr_def fromPAddr_def is_aligned_add)
apply (clarsimp simp: ptrFromPAddr_def vmsz_aligned'_def)
apply (drule aligned_offset_non_zero[rotated -1, where n=16 and y="x * 0x1000"])
apply (erule is_aligned_add, simp)
apply simp
apply (rule word_less_power_trans2[where k=12 and m=16, simplified])
apply unat_arith
apply simp
apply (simp add: add_ac)
done
lemma mapM_x_storePTE_invs:
"\<lbrace>invs' and valid_pte' pte and
K (pte_vmsz_aligned' pte \<and> length slots = (case pte of LargePagePTE _ _ _ _ \<Rightarrow> 16 | _ \<Rightarrow> 1))\<rbrace>
mapM_x (\<lambda>(slot, i). storePTE slot (addPTEOffset pte i))
(zip slots [(0::32 word).e.of_nat (length slots - Suc 0)])
\<lbrace>\<lambda>_. invs'\<rbrace>"
apply (rule hoare_post_imp)
prefer 2
apply (rule mapM_x_wp')
apply (wpsimp wp: valid_pte_lift')
apply (clarsimp split: pte.splits)
apply (rule valid_pte'_offset; simp?)
apply (drule in_set_zip2, simp)
apply simp
done
lemma valid_pde'_offset:
"\<lbrakk> valid_pde' pde s; x \<le> 15; pde = SuperSectionPDE p a b c; vmsz_aligned' p ARMSuperSection \<rbrakk>
\<Longrightarrow> valid_pde' (addPDEOffset pde x) s"
using is_aligned_mult_triv2[of x 21, simplified] is_aligned_pptrBaseOffset [of ARMSuperSection]
apply (clarsimp simp: addPDEOffset_def valid_mapping'_def addPAddr_def fromPAddr_def is_aligned_add)
apply (clarsimp simp: ptrFromPAddr_def vmsz_aligned'_def)
apply (drule aligned_offset_non_zero[rotated -1, where n=25 and y="x * 0x200000"])
apply (erule is_aligned_add, simp)
apply simp
apply (rule word_less_power_trans2[where k=21 and m=25, simplified])
apply unat_arith
apply simp
apply (simp add: add_ac)
done
lemma addPDEOffset_InvalidPDE[simp]:
"(addPDEOffset pde x = InvalidPDE) = (pde = InvalidPDE)"
by (cases pde; simp add: addPDEOffset_def)
lemma mapM_x_storePDE_invs:
"\<lbrace>invs' and valid_pde' pde and K (\<forall>p \<in> set slots. valid_pde_mapping' (p && mask pdBits) pde) and
K (pde_vmsz_aligned' pde \<and> length slots = (case pde of SuperSectionPDE _ _ _ _ \<Rightarrow> 16 | _ \<Rightarrow> 1))\<rbrace>
mapM_x (\<lambda>(slot, i). storePDE slot (addPDEOffset pde i))
(zip slots [(0::32 word).e.of_nat (length slots - Suc 0)])
\<lbrace>\<lambda>_. invs'\<rbrace>"
apply (rule hoare_gen_asm)
apply (rule hoare_post_imp)
prefer 2
apply (rule mapM_x_wp')
apply (wpsimp wp: valid_pde_lift')
apply (rule conjI)
apply (clarsimp split: pde.splits)
apply (rule valid_pde'_offset; simp?)
apply (drule in_set_zip2, simp)
apply (clarsimp simp: valid_pde_mapping'_def)
apply (drule in_set_zip1, simp)
apply simp
done
lemma mapM_storePTE_invs:
"\<lbrace>invs' and valid_pte' pte\<rbrace> mapM (swp storePTE pte) ps \<lbrace>\<lambda>_. invs'\<rbrace>"
apply (rule hoare_post_imp)
prefer 2
apply (rule mapM_wp')
apply simp
apply (wp valid_pte_lift')
apply simp+
done
lemma mapM_storePDE_invs:
"\<lbrace>invs' and valid_pde' pde
and K (\<forall>p \<in> set ps. valid_pde_mapping' (p && mask pdBits) pde)\<rbrace>
mapM (swp storePDE pde) ps \<lbrace>\<lambda>xa. invs'\<rbrace>"
apply (rule hoare_post_imp)
prefer 2
apply (rule mapM_wp')
apply simp
apply (wp valid_pde_lift')
apply simp+
done
crunch cte_wp_at': unmapPage "\<lambda>s. P (cte_wp_at' P' p s)"
(wp: crunch_wps simp: crunch_simps)
lemmas unmapPage_typ_ats [wp] = typ_at_lifts [OF unmapPage_typ_at']
crunch inv: lookupPTSlot P
(wp: crunch_wps simp: crunch_simps)
lemma flushPage_invs' [wp]:
"\<lbrace>invs'\<rbrace> flushPage sz pd asid vptr \<lbrace>\<lambda>_. invs'\<rbrace>"
apply (simp add: flushPage_def)
apply (wp dmo_invalidateLocalTLB_VAASID_invs' hoare_drop_imps setVMRootForFlush_invs'
no_irq_invalidateLocalTLB_VAASID
|simp)+
done
lemma unmapPage_invs' [wp]:
"\<lbrace>invs'\<rbrace> unmapPage sz asid vptr pptr \<lbrace>\<lambda>_. invs'\<rbrace>"
unfolding unmapPage_def
by (wpsimp wp: lookupPTSlot_inv mapM_storePTE_invs mapM_storePDE_invs
hoare_vcg_const_imp_lift)
crunch (no_irq) no_irq[wp]: doFlush
(simp: Let_def)
crunches pteCheckIfMapped, pdeCheckIfMapped
for invs'[wp]: "invs'"
and valid_pte'[wp]: "valid_pte' pte"
and valid_pde'[wp]: "valid_pde' pde"
lemma perform_pt_invs [wp]:
notes no_irq[wp]
shows
"\<lbrace>invs' and valid_page_inv' pt\<rbrace> performPageInvocation pt \<lbrace>\<lambda>_. invs'\<rbrace>"
apply (simp add: performPageInvocation_def)
apply (cases pt)
apply clarsimp
apply ((wp dmo_invs' hoare_vcg_all_lift setVMRootForFlush_invs' | simp add: tcb_at_invs')+)[2]
apply (rule hoare_pre_imp[of _ \<top>], assumption)
apply (clarsimp simp: valid_def
disj_commute[of "pointerInUserData p s" for p s])
apply (thin_tac "x : fst (setVMRootForFlush a b s)" for x a b)
apply (erule use_valid)
apply (clarsimp simp: doFlush_def Let_def split: flush_type.splits)
apply (clarsimp simp: mapM_mapM_x split: sum.split | intro conjI impI
| wp mapM_x_storePTE_invs mapM_x_storePDE_invs)
apply (clarsimp simp: valid_page_inv'_def valid_slots'_def
valid_pde_slots'_def mapM_mapM_x
split: sum.split option.splits
| intro conjI impI
| wp mapM_storePTE_invs mapM_storePDE_invs
mapM_x_storePTE_invs mapM_x_storePDE_invs
hoare_vcg_all_lift hoare_vcg_const_imp_lift
arch_update_updateCap_invs unmapPage_cte_wp_at' getSlotCap_wp
| wpc
| drule valid_slots_duplicated'_length_Inl valid_slots_duplicated'_length_Inr)+
apply (clarsimp simp: cte_wp_at_ctes_of)
apply (case_tac cte)
apply clarsimp
apply (drule ctes_of_valid_cap', fastforce)
apply (clarsimp simp: valid_cap'_def cte_wp_at_ctes_of valid_page_inv'_def
capAligned_def is_arch_update'_def isCap_simps)
apply clarsimp
apply (wp arch_update_updateCap_invs unmapPage_cte_wp_at' getSlotCap_wp|wpc)+
apply (rename_tac acap word a b)
apply (rule_tac Q="\<lambda>_. invs' and cte_wp_at' (\<lambda>cte. \<exists>d r R sz m. cteCap cte =
ArchObjectCap (PageCap d r R sz m)) word"
in hoare_strengthen_post)
apply (wp unmapPage_cte_wp_at')
apply (clarsimp simp: cte_wp_at_ctes_of)
apply (case_tac cte)
apply clarsimp
apply (frule ctes_of_valid_cap')
apply (auto simp: valid_page_inv'_def valid_slots'_def
cte_wp_at_ctes_of valid_pde_slots'_def)[1]
apply (simp add: is_arch_update'_def isCap_simps)
apply (simp add: valid_cap'_def capAligned_def)
apply (clarsimp simp: cte_wp_at_ctes_of)
apply (simp add: is_arch_update'_def isCap_simps)
apply (case_tac cte)
apply clarsimp+
done
lemma ucast_ucast_le_low_bits [simp]:
"ucast (ucast x :: 10 word) \<le> (2 ^ asid_low_bits - 1 :: word32)"
apply (rule word_less_sub_1)
apply (rule order_less_le_trans)
apply (rule ucast_less)
apply simp
apply (simp add: asid_low_bits_def)
done
lemma perform_aci_invs [wp]:
"\<lbrace>invs' and valid_apinv' api\<rbrace> performASIDPoolInvocation api \<lbrace>\<lambda>_. invs'\<rbrace>"
apply (clarsimp simp: performASIDPoolInvocation_def split: asidpool_invocation.splits)
apply (wp arch_update_updateCap_invs getASID_wp getSlotCap_wp)
apply (clarsimp simp: valid_apinv'_def cte_wp_at_ctes_of)
apply (case_tac cte)
apply clarsimp
apply (drule ctes_of_valid_cap', fastforce)
apply (clarsimp simp: isPDCap_def valid_cap'_def capAligned_def is_arch_update'_def isCap_simps)
apply (drule ko_at_valid_objs', fastforce, simp add: projectKOs)
apply (clarsimp simp: valid_obj'_def ran_def mask_asid_low_bits_ucast_ucast
split: if_split_asm)
apply (case_tac ko, clarsimp simp: inv_def)
apply (clarsimp simp: page_directory_at'_def, drule_tac x=0 in spec)
apply auto
done
lemma capMaster_isPDCap:
"capMasterCap cap' = capMasterCap cap \<Longrightarrow> isPDCap cap' = isPDCap cap"
by (simp add: capMasterCap_def isPDCap_def split: capability.splits arch_capability.splits)
lemma isPDCap_PD :
"isPDCap (ArchObjectCap (PageDirectoryCap r m))"
by (simp add: isPDCap_def)
end
end