(* * Copyright 2014, NICTA * * This software may be distributed and modified according to the terms of * the GNU General Public License version 2. Note that NO WARRANTY is provided. * See "LICENSE_GPLv2.txt" for details. * * @TAG(NICTA_GPL) *) theory DuplicateCaps_SI imports "../proof/capDL-api/CNode_DP" ObjectInitialised_SI RootTask_SI SysInit_SI begin lemma sep_map_zip_fst: "\distinct xs; length xs \ length ys\ \ (\* (x, y) \ set (zip xs ys). f x) = (\* x \ set xs. f x)" apply (subst sep_list_conj_sep_map_set_conj [symmetric], simp add: distinct_zipI1)+ apply (subst map_zip_fst', assumption) apply simp done lemma sep_map_zip_snd_take: "\distinct xs; distinct ys\ \ (\* (x, y) \ set (zip xs ys). f y) = (\* x \ set (take (length xs) ys). f x)" apply (subst sep_list_conj_sep_map_set_conj [symmetric], simp add: distinct_zipI1)+ apply (subst map_zip_snd_take) apply simp done lemma sep_map_c_unat [simp]: "(\slot. (obj_id, slot) \c NullCap) \ unat = (\cptr. (obj_id, unat cptr) \c NullCap)" by fastforce lemma wfdc_obj_not_untyped: "well_formed_cap (default_cap t oid sz) \ t \ UntypedType" by (clarsimp simp:default_cap_def well_formed_cap_def) lemma derived_cap_default: "derived_cap (default_cap ty oid sz) = (default_cap ty oid sz)" by (case_tac ty, simp_all add:derived_cap_def default_cap_def) lemma real_cnode_or_tcb_at_wfc: "\real_cnode_or_tcb_at obj_id spec; cdl_objects spec obj_id = Some obj; sz \ 32\ \ well_formed_cap (default_cap (object_type obj) oid sz)" apply (elim disjE) apply (simp add: real_object_at_def real_cnode_at_def object_at_def is_tcb_def default_cap_def well_formed_cap_def is_cnode_def object_type_def guard_bits_def split: cdl_object.splits)+ done lemma seL4_CNode_Copy_sep_helper: "\(free_cptr::32 word) < 2 ^ si_cnode_size; (cap_ptr::32 word) < 2 ^ si_cnode_size; well_formed_cap (default_cap (object_type obj) {kobj_id} (object_size_bits obj))\ \ \\s. \si_tcb_id \f root_tcb \* (si_tcb_id, tcb_cspace_slot) \c si_cspace_cap \* (si_tcb_id, tcb_pending_op_slot) \c RunningCap \* si_cnode_id \f CNode (empty_cnode si_cnode_size) \* (si_cnode_id, unat seL4_CapInitThreadCNode) \c si_cnode_cap \* (si_cnode_id, unat cap_ptr) \c default_cap (object_type obj) {kobj_id} (object_size_bits obj) \* (si_cnode_id, unat free_cptr) \c NullCap \* R\ s\ seL4_CNode_Copy seL4_CapInitThreadCNode free_cptr 32 seL4_CapInitThreadCNode cap_ptr 32 UNIV \\rv.\si_tcb_id \f root_tcb \* (si_tcb_id, tcb_cspace_slot) \c si_cspace_cap \* (si_tcb_id, tcb_pending_op_slot) \c RunningCap \* si_cnode_id \f CNode (empty_cnode si_cnode_size) \* (si_cnode_id, unat seL4_CapInitThreadCNode) \c si_cnode_cap \* (si_cnode_id, unat cap_ptr) \c default_cap (object_type obj) {kobj_id} (object_size_bits obj) \* (si_cnode_id, unat free_cptr) \c default_cap (object_type obj) {kobj_id} (object_size_bits obj) \* R\\" apply (rule hoare_chain) apply (rule_tac src_index=cap_ptr and cnode_cap=si_cspace_cap and cnode_cap'=si_cnode_cap and root_size=si_cnode_size and src_cap="default_cap (object_type obj) {kobj_id} (object_size_bits obj)" and R=R in seL4_CNode_Copy_sep, (simp add: wfdc_obj_not_untyped offset_slot offset_slot'|clarsimp)+) apply (rule conjI) apply sep_solve apply (clarsimp simp: guard_equal_si_cspace_cap guard_equal_si_cnode_cap word_bits_def) apply (simp add: well_formed_update_cap_rights_idem derived_cap_default) apply sep_solve done lemma duplicate_cap_sep_helper: "\well_formed spec; distinct obj_ids; list_all (\n. n < 2 ^ si_cnode_size) (map unat free_cptrs); (obj_id, free_cptr) \ set (zip [obj\obj_ids. real_cnode_or_tcb_at obj spec] free_cptrs); set obj_ids = dom (cdl_objects spec)\ \ \\(si_cnode_id, unat free_cptr) \c NullCap \* si_cap_at t orig_caps spec obj_id \* si_objects \* R\\ duplicate_cap spec orig_caps (obj_id, free_cptr) \\_ s. \si_cap_at t (map_of (zip [obj\obj_ids. real_cnode_or_tcb_at obj spec] free_cptrs)) spec obj_id \* si_cap_at t orig_caps spec obj_id \* si_objects \* R\ s\" apply (rule hoare_assume_pre) apply (clarsimp simp: duplicate_cap_def si_cap_at_def sep_conj_exists) apply (rule_tac x=free_cptr in hoare_exI) apply (frule map_of_zip_tuple_in, simp, simp) apply (frule in_set_zip1) apply (frule in_set_zip2) apply (subgoal_tac "\kobj_id. t obj_id = Some kobj_id \ orig_caps obj_id = Some cap_ptr \ cap_ptr < 2 ^ si_cnode_size") apply (clarsimp simp: si_objects_def Ball_set_list_all[symmetric]) apply (wp hoare_drop_imps) apply (rule hoare_chain) apply (rule_tac free_cptr=free_cptr and cap_ptr=cap_ptr and R="(si_cnode_id, unat seL4_CapIRQControl) \c IrqControlCap \* si_asid \* R" in seL4_CNode_Copy_sep_helper) apply (rule unat_less_2_si_cnode_size, simp) apply simp apply (erule(1) real_cnode_or_tcb_at_wfc) apply (frule (1) well_formed_object_size_bits_word_bits, simp add: word_bits_def) apply sep_solve apply sep_solve apply (rule unat_less_2_si_cnode_size, simp) apply clarsimp done lemma well_formed_tcb_at_real_object_at: "\well_formed spec; tcb_at obj_id spec\ \ real_object_at obj_id spec" apply (clarsimp simp: real_object_at_def) apply (rule conjI) apply (clarsimp simp: object_at_def) apply clarsimp apply (frule (2) well_formed_object_at_irq_cnode_cnode_at) apply (clarsimp simp: object_at_def object_type_is_object) done lemma duplicate_cap_sep: "\\(si_cnode_id, unat free_cptr) \c NullCap \* si_caps_at t orig_caps spec {obj_id. real_object_at obj_id spec} \* si_objects \* R\ and K ( well_formed spec \ distinct obj_ids \ list_all (\n. n < 2 ^ si_cnode_size) (map unat free_cptrs) \ (obj_id, free_cptr) \ set (zip [obj\obj_ids. real_cnode_or_tcb_at obj spec] free_cptrs) \ set obj_ids = dom (cdl_objects spec))\ duplicate_cap spec orig_caps (obj_id, free_cptr) \\_. \si_cap_at t (map_of (zip [obj\obj_ids. real_cnode_or_tcb_at obj spec] free_cptrs)) spec obj_id \* si_caps_at t orig_caps spec {obj_id. real_object_at obj_id spec} \* si_objects \* R\\" apply (rule hoare_gen_asm) apply clarsimp apply (frule well_formed_finite [where obj_id=obj_id]) apply (clarsimp simp: si_caps_at_def) apply (rule hoare_chain [where P="\((si_cnode_id, unat free_cptr) \c NullCap \* si_objects) \* (\* obj_id \ {obj_id. real_object_at obj_id spec}. si_cap_at t orig_caps spec obj_id) \* R\" and Q="\rv.\(si_cap_at t (map_of (zip [obj\obj_ids. real_cnode_or_tcb_at obj spec] free_cptrs)) spec obj_id \* si_objects) \* (\* obj_id \ {obj_id. real_object_at obj_id spec}. si_cap_at t orig_caps spec obj_id) \* R\"]) apply (rule sep_set_conj_map_singleton_wp [where x=obj_id]) apply simp apply (drule in_set_zip1) apply (fastforce simp: real_cnode_at_def2 well_formed_tcb_at_real_object_at) apply (rule hoare_chain) apply (rule_tac t=t and R=R in duplicate_cap_sep_helper, assumption+) apply sep_solve apply sep_solve apply sep_solve apply simp apply sep_solve done lemma duplicate_caps_sep_helper: "\\si_caps_at t orig_caps spec {obj_id. real_object_at obj_id spec} \* (\* (obj_id, free_cptr) \ set (zip [obj\obj_ids. real_cnode_or_tcb_at obj spec] free_cptrs). (si_cnode_id, unat free_cptr) \c NullCap) \* si_objects \* R\ and K( well_formed spec \ distinct obj_ids \ list_all (\n. n < 2 ^ si_cnode_size) (map unat free_cptrs) \ set obj_ids = dom (cdl_objects spec) \ length [obj\obj_ids . real_cnode_or_tcb_at obj spec] \ length free_cptrs)\ duplicate_caps spec orig_caps obj_ids free_cptrs \\dup_caps. \si_caps_at t dup_caps spec {obj_id. real_cnode_or_tcb_at obj_id spec} \* si_caps_at t orig_caps spec {obj_id. real_object_at obj_id spec} \* si_objects \* R\\" apply (rule hoare_gen_asm) apply (clarsimp simp: duplicate_caps_def si_caps_at_def) apply (wp) apply (rule hoare_chain) apply (rule mapM_x_set_sep [where f="duplicate_cap spec orig_caps" and xs="zip [obj\obj_ids . real_cnode_or_tcb_at obj spec] free_cptrs" and P="\(obj_id,free_cptr). (si_cnode_id, unat free_cptr) \c NullCap" and Q="\(obj_id,free_cptr). (si_cap_at t (map_of (zip [obj\obj_ids. real_cnode_or_tcb_at obj spec] free_cptrs)) spec obj_id)" and I="si_caps_at t orig_caps spec {obj_id. real_object_at obj_id spec} \* si_objects" and R=R]) apply (rule distinct_zipI1, simp) apply (clarsimp simp: sep_conj_assoc) apply (rename_tac obj_id free_cptr) apply (wp sep_wp: duplicate_cap_sep [where obj_ids=obj_ids and free_cptrs=free_cptrs and t=t]) apply clarsimp apply sep_solve apply (clarsimp simp: sep_conj_assoc si_caps_at_def) apply sep_solve apply (subst (asm) sep_map_zip_fst, simp+) apply (clarsimp simp: sep_conj_assoc si_caps_at_def) done (* FIXME, move higher *) lemma distinct_card': "\distinct xs; set xs = A\ \ card (A) = length xs" by (clarsimp simp: distinct_card) (* FIXME, move higher *) lemma distinct_length_filter': "distinct xs \ length [x\xs. P x] = card {x \ set xs. P x}" by (metis distinct_length_filter set_conj_Int_simp inf_commute) lemma duplicate_caps_sep_no_rv: "\\si_caps_at t orig_caps spec {obj_id. real_object_at obj_id spec} \* si_objects \* si_objects_extra_caps' (set obj_ids) free_cptrs untyped_cptrs \* R\ and K(well_formed spec \ distinct obj_ids \ distinct free_cptrs \ set obj_ids = dom (cdl_objects spec) \ list_all (\n. n < 2 ^ si_cnode_size) (map unat free_cptrs) \ length obj_ids + card {obj_id. real_cnode_or_tcb_at obj_id spec} \ length free_cptrs \ free_cptrs' = drop (length obj_ids) free_cptrs)\ duplicate_caps spec orig_caps obj_ids free_cptrs' \\dup_caps s. \si_caps_at t dup_caps spec {obj_id. real_cnode_or_tcb_at obj_id spec} \* si_caps_at t orig_caps spec {obj_id. real_object_at obj_id spec} \* si_objects \* si_objects_extra_caps (set obj_ids) free_cptrs untyped_cptrs spec \* R\ s\" apply (rule hoare_gen_asm) apply (rule hoare_chain) apply (rule duplicate_caps_sep_helper[where t=t and free_cptrs=free_cptrs' and R="\s. \untyped_caps all_available_ids. ((\* (cptr, y) \ set (zip untyped_cptrs untyped_caps). (si_cnode_id, unat cptr) \c y) \* (\* obj_id\all_available_ids. obj_id \o Untyped) \* (\* map (\free_cptr. (si_cnode_id, unat free_cptr) \c NullCap) (drop (card {obj_id. real_cnode_or_tcb_at obj_id spec}) (drop (length obj_ids) free_cptrs))) \* R) s"], simp+) apply (clarsimp simp: Ball_set_list_all[symmetric] dest!: in_set_dropD) apply (rule conjI) apply (clarsimp simp: si_objects_extra_caps'_def sep_conj_exists sep_conj_assoc) apply (rule_tac x=untyped_caps in exI) apply (rule_tac x=all_available_ids in exI) apply (subst sep_map_zip_snd_take, simp+) apply (subst (asm) drop_take_drop[symmetric, where a="card (dom (cdl_objects spec))" and b="length [obj\obj_ids. real_cnode_or_tcb_at obj spec]"]) apply (subst take_drop) apply clarsimp apply (clarsimp simp: distinct_card' distinct_length_filter') apply (subst sep_list_conj_sep_map_set_conj, simp) apply (subst (asm) sep.setprod.union_disjoint, simp+) apply (simp add: drop_take) apply (subst add.commute) apply (erule distinct_take_drop_append) apply sep_solve apply (subst (asm) distinct_card [symmetric], simp+)+ apply (subst distinct_card [symmetric], simp+)+ apply (fastforce dest!: in_set_dropD) apply (clarsimp simp: si_objects_extra_caps_def sep_conj_exists sep_conj_assoc) apply (rule_tac x=untyped_caps in exI) apply (rule_tac x=all_available_ids in exI) apply (subst add.commute) apply (subst (asm) distinct_card [symmetric], simp)+ apply (clarsimp simp: distinct_card' distinct_length_filter') apply (subst (asm) sep_list_conj_sep_map_set_conj, simp) apply sep_solve done lemma duplicate_caps_rv: "\\si_caps_at t orig_caps spec {obj_id. real_object_at obj_id spec} \* si_objects \* si_objects_extra_caps' (set obj_ids) free_cptrs untyped_cptrs \* R\\ duplicate_caps spec orig_caps obj_ids free_cptrs' \\dup_caps _. dup_caps = map_of (zip [obj\obj_ids. real_cnode_or_tcb_at obj spec] free_cptrs')\" apply (clarsimp simp: duplicate_caps_def) apply (wp, clarsimp) done lemma duplicate_caps_sep: "\\(si_caps_at t orig_caps spec {obj_id. real_object_at obj_id spec} \* si_objects \* si_objects_extra_caps' (dom (cdl_objects spec)) free_cptrs_orig untyped_cptrs \* R) and K (well_formed spec \ distinct obj_ids \ set obj_ids = dom (cdl_objects spec) \ list_all (\n. n < 2 ^ si_cnode_size) free_cptrs_orig \ free_cptrs = drop (length obj_ids) free_cptrs_orig \ distinct free_cptrs_orig \ length obj_ids + card {obj_id. real_cnode_or_tcb_at obj_id spec} \ length free_cptrs_orig)\\ duplicate_caps spec orig_caps obj_ids free_cptrs \\dup_caps. \(si_caps_at t dup_caps spec {obj_id. real_cnode_or_tcb_at obj_id spec} \* si_caps_at t orig_caps spec {obj_id. real_object_at obj_id spec} \* si_objects \* si_objects_extra_caps (dom (cdl_objects spec)) free_cptrs_orig untyped_cptrs spec \* R) and K (dup_caps = map_of (zip [obj\obj_ids. real_cnode_or_tcb_at obj spec] free_cptrs))\ \" apply clarsimp apply (rule hoare_gen_asm_conj) apply (rule hoare_conjI, elim conjE) apply (rule hoare_chain[OF duplicate_caps_sep_no_rv], simp+) apply (simp add: list_all_iff unat_less_2_si_cnode_size' | rule conjI)+ apply (wp duplicate_caps_rv, simp) done end