238 lines
8.5 KiB
Plaintext
238 lines
8.5 KiB
Plaintext
(*
|
|
* Copyright 2014, General Dynamics C4 Systems
|
|
*
|
|
* This software may be distributed and modified according to the terms of
|
|
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
|
|
* See "LICENSE_GPLv2.txt" for details.
|
|
*
|
|
* @TAG(GD_GPL)
|
|
*)
|
|
|
|
(*
|
|
CSpace invariants
|
|
*)
|
|
|
|
theory ArchCSpaceInv_AI
|
|
imports "../CSpaceInv_AI"
|
|
begin
|
|
|
|
context Arch begin global_naming ARM
|
|
|
|
definition
|
|
safe_ioport_insert :: "cap \<Rightarrow> cap \<Rightarrow> 'a::state_ext state \<Rightarrow> bool"
|
|
where
|
|
"safe_ioport_insert newcap oldcap s \<equiv> True"
|
|
|
|
declare safe_ioport_insert_def[simp]
|
|
|
|
lemma safe_ioport_insert_triv:
|
|
"\<not>is_arch_cap newcap \<Longrightarrow> safe_ioport_insert newcap oldcap s"
|
|
by (clarsimp simp: safe_ioport_insert_def)
|
|
|
|
lemma set_cap_ioports':
|
|
"\<lbrace>\<lambda>s. valid_ioports s
|
|
\<and> cte_wp_at (\<lambda>cap'. safe_ioport_insert cap cap' s) ptr s\<rbrace>
|
|
set_cap cap ptr
|
|
\<lbrace>\<lambda>rv. valid_ioports\<rbrace>"
|
|
by wpsimp
|
|
|
|
lemma replace_cap_invs:
|
|
"\<lbrace>\<lambda>s. invs s \<and> cte_wp_at (replaceable s p cap) p s
|
|
\<and> cap \<noteq> cap.NullCap
|
|
\<and> ex_cte_cap_wp_to (appropriate_cte_cap cap) p s
|
|
\<and> s \<turnstile> cap\<rbrace>
|
|
set_cap cap p
|
|
\<lbrace>\<lambda>rv s. invs s\<rbrace>"
|
|
apply (simp add: invs_def valid_state_def valid_mdb_def2)
|
|
apply (rule hoare_pre)
|
|
apply (wp replace_cap_valid_pspace
|
|
set_cap_caps_of_state2 set_cap_idle
|
|
replace_cap_ifunsafe valid_irq_node_typ
|
|
set_cap_typ_at set_cap_irq_handlers
|
|
set_cap_valid_arch_caps
|
|
set_cap_cap_refs_respects_device_region_replaceable)
|
|
apply (clarsimp simp: valid_pspace_def cte_wp_at_caps_of_state replaceable_def)
|
|
apply (rule conjI)
|
|
apply (fastforce simp: tcb_cap_valid_def
|
|
dest!: cte_wp_tcb_cap_valid [OF caps_of_state_cteD])
|
|
apply (rule conjI)
|
|
apply (erule_tac P="\<lambda>cps. mdb_cte_at cps (cdt s)" in rsubst)
|
|
apply (rule ext)
|
|
apply (safe del: disjE)[1]
|
|
apply (simp add: gen_obj_refs_empty final_NullCap)+
|
|
apply (rule conjI)
|
|
apply (simp add: untyped_mdb_def is_cap_simps)
|
|
apply (erule disjE)
|
|
apply (clarsimp, rule conjI, clarsimp+)[1]
|
|
apply (erule allEI, erule allEI)
|
|
apply (drule_tac x="fst p" in spec, drule_tac x="snd p" in spec)
|
|
apply (clarsimp simp: gen_obj_refs_subset)
|
|
apply (drule(1) disjoint_subset, simp)
|
|
apply (rule conjI)
|
|
apply (erule descendants_inc_minor)
|
|
apply simp
|
|
apply (elim disjE)
|
|
apply clarsimp
|
|
apply clarsimp
|
|
apply (rule conjI)
|
|
apply (erule disjE)
|
|
apply (simp add: fun_upd_def[symmetric] fun_upd_idem)
|
|
apply (simp add: untyped_inc_def not_is_untyped_no_range)
|
|
apply (rule conjI)
|
|
apply (erule disjE)
|
|
apply (simp add: fun_upd_def[symmetric] fun_upd_idem)
|
|
apply (simp add: ut_revocable_def)
|
|
apply (rule conjI)
|
|
apply (erule disjE)
|
|
apply (clarsimp simp: irq_revocable_def)
|
|
apply clarsimp
|
|
apply (clarsimp simp: irq_revocable_def)
|
|
apply (rule conjI)
|
|
apply (erule disjE)
|
|
apply (simp add: fun_upd_def[symmetric] fun_upd_idem)
|
|
apply (simp add: reply_master_revocable_def)
|
|
apply (rule conjI)
|
|
apply (erule disjE)
|
|
apply (simp add: fun_upd_def[symmetric] fun_upd_idem)
|
|
apply (clarsimp simp add: reply_mdb_def)
|
|
apply (thin_tac "\<forall>a b. (a, b) \<in> cte_refs cp nd \<and> Q a b\<longrightarrow> R a b" for cp nd Q R)
|
|
apply (thin_tac "is_pt_cap cap \<longrightarrow> P" for cap P)+
|
|
apply (thin_tac "is_pd_cap cap \<longrightarrow> P" for cap P)+
|
|
apply (rule conjI)
|
|
apply (unfold reply_caps_mdb_def)[1]
|
|
apply (erule allEI, erule allEI)
|
|
apply (fastforce split: if_split_asm simp: is_cap_simps)
|
|
apply (unfold reply_masters_mdb_def)[1]
|
|
apply (erule allEI, erule allEI)
|
|
apply (fastforce split: if_split_asm simp: is_cap_simps)
|
|
apply (rule conjI)
|
|
apply (erule disjE)
|
|
apply (clarsimp)
|
|
apply (drule caps_of_state_cteD)
|
|
apply (erule(1) valid_reply_capsD [OF has_reply_cap_cte_wpD])
|
|
apply (simp add: is_cap_simps)
|
|
apply (frule(1) valid_global_refsD2)
|
|
apply (frule(1) cap_refs_in_kernel_windowD)
|
|
apply (rule conjI)
|
|
apply (erule disjE)
|
|
apply (clarsimp simp: valid_reply_masters_def cte_wp_at_caps_of_state)
|
|
apply (cases p, fastforce)
|
|
apply (simp add: is_cap_simps)
|
|
apply (elim disjE)
|
|
apply simp
|
|
apply (clarsimp simp: valid_table_capsD[OF caps_of_state_cteD]
|
|
valid_arch_caps_def unique_table_refs_no_cap_asidE)
|
|
apply simp
|
|
apply (rule Ball_emptyI, simp add: gen_obj_refs_subset)
|
|
done
|
|
|
|
definition
|
|
"is_simple_cap_arch cap \<equiv> \<not>is_pt_cap cap \<and> \<not> is_pd_cap cap"
|
|
|
|
declare is_simple_cap_arch_def[simp]
|
|
|
|
lemma is_simple_cap_arch:
|
|
"\<not>is_arch_cap cap \<Longrightarrow> is_simple_cap_arch cap"
|
|
by (simp add: is_cap_simps)
|
|
|
|
definition
|
|
"is_derived_arch cap cap' \<equiv>
|
|
((is_pt_cap cap \<or> is_pd_cap cap) \<longrightarrow>
|
|
cap_asid cap = cap_asid cap' \<and> cap_asid cap \<noteq> None) \<and>
|
|
(vs_cap_ref cap = vs_cap_ref cap' \<or> is_pg_cap cap')"
|
|
|
|
lemma is_derived_arch_non_arch:
|
|
"\<not>is_arch_cap cap \<Longrightarrow> \<not> is_arch_cap cap' \<Longrightarrow>
|
|
is_derived_arch cap cap'"
|
|
unfolding is_derived_arch_def is_pg_cap_def is_pt_cap_def is_pd_cap_def
|
|
vs_cap_ref_def is_arch_cap_def
|
|
by (auto split: cap.splits)
|
|
|
|
lemma
|
|
cap_master_cap_arch_simps:
|
|
"cap_master_arch_cap ((arch_cap.PageCap dev ref rghts sz mapdata)) =
|
|
(arch_cap.PageCap dev ref UNIV sz None)"
|
|
"cap_master_arch_cap ( (arch_cap.ASIDPoolCap pool asid)) =
|
|
(arch_cap.ASIDPoolCap pool 0)"
|
|
"cap_master_arch_cap ( (arch_cap.PageTableCap ptr x)) =
|
|
(arch_cap.PageTableCap ptr None)"
|
|
"cap_master_arch_cap ( (arch_cap.PageDirectoryCap ptr y)) =
|
|
(arch_cap.PageDirectoryCap ptr None)"
|
|
"cap_master_arch_cap ( arch_cap.ASIDControlCap) =
|
|
arch_cap.ASIDControlCap"
|
|
by (simp add: cap_master_arch_cap_def)+
|
|
|
|
lemmas cap_master_cap_def = cap_master_cap_def[simplified cap_master_arch_cap_def]
|
|
|
|
lemma same_master_cap_same_types:
|
|
"cap_master_cap cap = cap_master_cap cap' \<Longrightarrow>
|
|
(is_pt_cap cap = is_pt_cap cap') \<and> (is_pd_cap cap = is_pd_cap cap')"
|
|
by (clarsimp simp: cap_master_cap_def is_cap_simps
|
|
split: cap.splits arch_cap.splits)
|
|
|
|
lemma is_derived_cap_arch_asid_issues:
|
|
"is_derived_arch cap cap' \<Longrightarrow>
|
|
cap_master_cap cap = cap_master_cap cap'
|
|
\<Longrightarrow> ((is_pt_cap cap \<or> is_pd_cap cap) \<longrightarrow> cap_asid cap \<noteq> None)
|
|
\<and> (is_pg_cap cap \<or> (vs_cap_ref cap = vs_cap_ref cap'))"
|
|
apply (simp add: is_derived_arch_def)
|
|
by (auto simp: cap_master_cap_def is_cap_simps
|
|
cap_asid_def
|
|
split: cap.splits arch_cap.splits option.splits)
|
|
|
|
lemma is_derived_cap_arch_asid:
|
|
"is_derived_arch cap cap' \<Longrightarrow> cap_master_cap cap = cap_master_cap cap' \<Longrightarrow>
|
|
is_pt_cap cap' \<or> is_pd_cap cap' \<Longrightarrow> cap_asid cap = cap_asid cap'"
|
|
unfolding is_derived_arch_def
|
|
apply (cases cap; cases cap'; simp)
|
|
by (auto simp: is_cap_simps cap_master_cap_def split: arch_cap.splits)
|
|
|
|
definition
|
|
safe_parent_for_arch :: "cap \<Rightarrow> cap \<Rightarrow> bool"
|
|
where
|
|
"safe_parent_for_arch cap parent \<equiv> False"
|
|
|
|
declare safe_parent_for_arch_def[simp]
|
|
|
|
lemma safe_parent_for_arch_not_arch:
|
|
"\<not>is_arch_cap cap \<Longrightarrow> \<not>safe_parent_for_arch cap p"
|
|
by (clarsimp simp: safe_parent_for_arch_def is_cap_simps)
|
|
|
|
lemma safe_parent_cap_range_arch:
|
|
"\<And>cap pcap. safe_parent_for_arch cap pcap \<Longrightarrow> cap_range cap \<subseteq> cap_range pcap"
|
|
by (clarsimp simp: safe_parent_for_arch_def cap_range_def)
|
|
|
|
definition
|
|
"cap_asid_base_arch cap \<equiv> case cap of
|
|
ASIDPoolCap _ asid \<Rightarrow> Some asid
|
|
| _ \<Rightarrow> None"
|
|
|
|
declare cap_asid_base_arch_def[abs_def, simp]
|
|
|
|
definition cap_asid_base :: "cap \<Rightarrow> asid option" where
|
|
"cap_asid_base cap \<equiv> arch_cap_fun_lift cap_asid_base_arch None cap"
|
|
|
|
lemmas cap_asid_base_simps [simp] =
|
|
cap_asid_base_def [simplified, split_simps cap.split arch_cap.split]
|
|
|
|
definition
|
|
"cap_vptr_arch acap \<equiv> case acap of
|
|
(PageCap _ _ _ _ (Some (_, vptr))) \<Rightarrow> Some vptr
|
|
| (PageTableCap _ (Some (_, vptr))) \<Rightarrow> Some vptr
|
|
| _ \<Rightarrow> None"
|
|
|
|
definition
|
|
"cap_vptr cap \<equiv> arch_cap_fun_lift cap_vptr_arch None cap"
|
|
|
|
declare cap_vptr_arch_def[abs_def, simp]
|
|
|
|
lemmas cap_vptr_simps [simp] =
|
|
cap_vptr_def [simplified, split_simps cap.split arch_cap.split option.split prod.split]
|
|
|
|
end
|
|
context begin interpretation Arch .
|
|
requalify_facts replace_cap_invs
|
|
end
|
|
|
|
end
|