(* * 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) *) (* * The layout of the capability space and other parts of the system-initialiser. *) theory RootTask_SI imports WellFormed_SI begin (****************************************************************** * Definition of the CSpace of the root task. * * This requires a default cap to all of the objects created, * * and a copy of caps to all of the CNodes (for installing caps). * ******************************************************************) consts si_cnode_id :: cdl_object_id si_asidpool_id :: cdl_object_id si_asidpool_base :: nat definition si_cnode_size :: cdl_size_bits where "si_cnode_size = 12" (* If we axioimise this size, we need it to be smaller than the word size. * We need this to prove that: - word_bits - si_cnode_size + si_cnode_size = word_bits. - offset (of_nat slot) si_cnode_size = slot *) lemma si_cnode_size_less_than_word_size [simp]: "si_cnode_size < word_bits" by (clarsimp simp: si_cnode_size_def word_bits_def) lemma si_cnode_size_less_than_eq_word_size [simp]: "si_cnode_size \ word_bits" by (rule less_imp_le_nat, simp) lemma si_cnode_size_greater_than_1 [simp]: "1 < si_cnode_size" by (clarsimp simp: si_cnode_size_def) lemma si_cnode_size_greater_than_2 [simp]: "2 < si_cnode_size" by (clarsimp simp: si_cnode_size_def) lemma unat_less_2_si_cnode_size: "unat (cptr::32 word) < 2 ^ si_cnode_size \ cptr < 2 ^ si_cnode_size" by (metis si_cnode_size_less_than_word_size unat_power_lower32 word_less_nat_alt) lemma unat_less_2_si_cnode_size': "(cptr::32 word) < 2 ^ si_cnode_size \ unat cptr < 2 ^ si_cnode_size" by (metis unat_less_helper word_unat_power) (* This is stored in the root TCB. *) definition si_cspace_cap :: cdl_cap where "si_cspace_cap = CNodeCap si_cnode_id 0 (word_bits - si_cnode_size) si_cnode_size" (* This is the cap the root TCB has to its own root cnode (stored in its root CNode). *) definition si_cnode_cap :: cdl_cap where "si_cnode_cap = CNodeCap si_cnode_id 0 (word_bits - si_cnode_size) si_cnode_size" definition root_tcb :: cdl_object where "root_tcb = update_slots [tcb_cspace_slot \ si_cspace_cap, tcb_vspace_slot \ undefined, tcb_replycap_slot \ undefined, tcb_caller_slot \ undefined, tcb_ipcbuffer_slot \ undefined, tcb_pending_op_slot \ undefined] (Tcb (default_tcb minBound))" definition empty_asid :: cdl_asid_pool where "empty_asid = \cdl_asid_pool_caps = empty_cap_map asid_low_bits\" definition si_asid :: "sep_state \ bool" where "si_asid \ (si_cnode_id, unat seL4_CapInitThreadASIDPool) \c AsidPoolCap si_asidpool_id si_asidpool_base \* si_asidpool_id \f AsidPool empty_asid \* (\* offset\{offset. offset < 2 ^ asid_low_bits}. (si_asidpool_id, offset) \c -)" abbreviation "si_tcb_id \ root_tcb_id" definition si_objects :: "sep_state \ bool" where "si_objects \ si_tcb_id \f root_tcb \* si_cnode_id \f CNode (empty_cnode si_cnode_size) \* (si_tcb_id, tcb_cspace_slot) \c si_cspace_cap \* (si_tcb_id, tcb_pending_op_slot) \c RunningCap \* (si_cnode_id, unat seL4_CapInitThreadCNode) \c si_cnode_cap \* (si_cnode_id, unat seL4_CapIRQControl) \c IrqControlCap \* si_asid" definition si_objects_extra_caps' :: "cdl_object_id set \ cdl_cptr list \ cdl_cptr list \ sep_state \ bool" where "si_objects_extra_caps' obj_ids free_cptrs untyped_cptrs \ \s. \untyped_caps all_available_ids. ((\* (cptr, cap) \ set (zip untyped_cptrs untyped_caps). (si_cnode_id, unat cptr) \c cap) \* (\* cptr \ set (drop (card obj_ids) free_cptrs). (si_cnode_id, unat cptr) \c NullCap) \* (\* obj_id\all_available_ids. obj_id \o Untyped)) s" definition si_objects_extra_caps :: "cdl_object_id set \ cdl_cptr list \ cdl_cptr list \ cdl_state \ sep_state \ bool" where "si_objects_extra_caps obj_ids free_cptrs untyped_cptrs spec \ \s. \untyped_caps all_available_ids. ((\* (cptr, cap) \ set (zip untyped_cptrs untyped_caps). (si_cnode_id, unat cptr) \c cap) \* (\* cptr \ set (drop (card obj_ids + card {obj_id \ obj_ids. cnode_or_tcb_at obj_id spec}) free_cptrs). (si_cnode_id, unat cptr) \c NullCap) \* (\* obj_id\all_available_ids. obj_id \o Untyped)) s" lemma distinct_take_drop_append: "distinct xs \ set (take b (drop a xs)) \ set (drop (a + b) xs) = {}" by (metis distinct_append distinct_drop take_drop_append) lemma si_objects_extra_caps'_si_objects_extra_caps: "distinct free_slots \ si_objects_extra_caps' obj_ids free_slots untyped_cptrs = (si_objects_extra_caps obj_ids free_slots untyped_cptrs spec \* (\* cptr \ set (take (card {obj_id \ obj_ids. cnode_or_tcb_at obj_id spec}) (drop (card obj_ids) free_slots)). (si_cnode_id, unat cptr) \c NullCap))" apply (rule ext) apply (clarsimp simp: si_objects_extra_caps'_def si_objects_extra_caps_def sep_conj_exists) apply (rule ex_eqI)+ apply (subst take_drop_append [where a="card obj_ids" and b="card {obj_id \ obj_ids. cnode_or_tcb_at obj_id spec}"]) apply clarsimp apply (subst sep.prod.union_disjoint, (simp add: distinct_take_drop_append)+)+ apply (clarsimp simp: sep_conj_ac) done definition si_irq_nodes :: "cdl_state \ sep_state \ bool" where "si_irq_nodes spec \ (\s. \k_irq_table. (\* irq\used_irqs spec. irq \irq k_irq_table irq \* k_irq_table irq \o IRQNode empty_irq_node) s)" (*************************************** * Lemmas about the root task objects. * ***************************************) lemma is_cnode_cap_si_cspace_cap [simp]: "is_cnode_cap si_cspace_cap" by (clarsimp simp: si_cspace_cap_def) lemma is_cnode_cap_si_cnode_cap [simp]: "is_cnode_cap si_cnode_cap" by (clarsimp simp: si_cnode_cap_def) lemma is_tcb_root_tcb [simp]: "is_tcb root_tcb" by (clarsimp simp: root_tcb_def) lemma cap_guard_size_si_cnode_cap_plus_si_cnode_size [simp]: "cap_guard_size si_cnode_cap + si_cnode_size = word_bits" by (clarsimp simp: si_cnode_cap_def) lemma cap_object_si_cspace_cap [simp]: "cap_object si_cspace_cap = si_cnode_id" by (clarsimp simp: cap_object_def cap_has_object_def si_cspace_cap_def) lemma cap_object_si_cnode_cap [simp]: "cap_object si_cnode_cap = si_cnode_id" by (clarsimp simp: cap_object_def cap_has_object_def si_cnode_cap_def) lemma offset_slot_si_cnode_size: "slot < 2^si_cnode_size \ offset (of_nat slot) si_cnode_size = slot" by (clarsimp simp: offset_slot) lemma offset_slot_si_cnode_size': "slot < 2^si_cnode_size \ offset slot si_cnode_size = unat slot" by (clarsimp simp: offset_slot') lemma guard_equal_si_cspace_cap: "src_index < 2 ^ si_cnode_size \ guard_equal si_cspace_cap src_index 32" apply (clarsimp simp: si_cspace_cap_def guard_equal_def Let_unfold) apply (subst and_mask_eq_iff_shiftr_0 [THEN iffD1]) apply (clarsimp simp: word_bits_def) apply (erule less_mask_eq) apply (clarsimp simp: mask_def) done lemma guard_equal_si_cspace_cap': "src_index < 2 ^ si_cnode_size \ guard_equal si_cspace_cap src_index word_bits" by (drule guard_equal_si_cspace_cap, simp add: word_bits_def) lemma guard_equal_si_cnode_cap: "src_index < 2 ^ si_cnode_size \ guard_equal si_cnode_cap src_index 32" apply (clarsimp simp: si_cnode_cap_def guard_equal_def Let_unfold) apply (subst and_mask_eq_iff_shiftr_0 [THEN iffD1]) apply (clarsimp simp: word_bits_def) apply (erule less_mask_eq) apply (clarsimp simp: mask_def) done lemma seL4_CapInitThreadASIDPool_si_cnode_size [simp]: "seL4_CapInitThreadASIDPool < 2 ^ si_cnode_size" by (clarsimp simp: seL4_CapInitThreadASIDPool_def si_cnode_size_def) lemma guard_equal_si_cspace_cap_seL4_CapInitThreadASIDPool [simp]: "guard_equal si_cspace_cap seL4_CapInitThreadASIDPool word_bits" by (rule guard_equal_si_cspace_cap', simp) lemma si_cspace_cap_guard_equal: "guard_equal si_cnode_cap src_index 32 \ src_index < 2 ^ si_cnode_size" apply (clarsimp simp: si_cnode_cap_def guard_equal_def Let_unfold si_cnode_size_def) apply (subst (asm) shiftr_mask_eq') apply (simp add: word_bits_size word_bits_def) apply (subst (asm) le_mask_iff [symmetric]) apply (clarsimp simp: mask_def) apply (insert word32_less_sub_le [where x=src_index and n=12]) apply (clarsimp simp: word_bits_def) done lemma one_lvl_lookup_si_cspace_cap [simp]: "one_lvl_lookup si_cspace_cap word_bits si_cnode_size" by (clarsimp simp: one_lvl_lookup_def si_cspace_cap_def) lemmas one_lvl_lookup_si_cspace_cap' [simp] = one_lvl_lookup_si_cspace_cap [simplified word_bits_def, simplified] lemma one_lvl_lookup_si_cnode_cap [simp]: "one_lvl_lookup si_cnode_cap word_bits si_cnode_size" by (clarsimp simp: one_lvl_lookup_def si_cnode_cap_def) lemmas one_lvl_lookup_si_cnode_cap' [simp] = one_lvl_lookup_si_cnode_cap [simplified word_bits_def, simplified] lemma obj_tcb_root_tcb [simp]: "Tcb (obj_tcb root_tcb) = root_tcb" by (clarsimp simp: obj_tcb_def root_tcb_def update_slots_def) (*************************** * Lemmas about word size. * ***************************) lemma seL4_CapInitThreadCNode_less_than_si_cnode_size [simp]: "seL4_CapInitThreadCNode < 2 ^ si_cnode_size" apply (insert si_cnode_size_greater_than_1) apply (insert power_strict_increasing [where n=1 and a="(2::nat)" and N=si_cnode_size, simplified]) apply (clarsimp) apply (drule of_nat_less_pow_32) apply (clarsimp simp: seL4_CapInitThreadCNode_def)+ done lemma offset_seL4_CapInitThreadCNode [simp]: "offset seL4_CapInitThreadCNode si_cnode_size = unat seL4_CapInitThreadCNode" by (rule offset_slot', simp) lemma seL4_CapIRQControl_less_than_si_cnode_size [simp]: "seL4_CapIRQControl < 2 ^ si_cnode_size" apply (simp add: seL4_CapIRQControl_def) apply (insert si_cnode_size_greater_than_2) apply (insert power_strict_increasing [where n=2 and a="(2::nat)" and N=si_cnode_size, simplified]) apply (drule of_nat_less_pow_32, simp_all) done lemma offset_seL4_CapIRQControl [simp]: "offset seL4_CapIRQControl si_cnode_size = unat seL4_CapIRQControl" by (rule offset_slot', simp) (* There is a cap in the root cnode that points to the obj_id specified. * This cap should be the default cap to that object. * * This predicate can be used for spec objects, or the duplicated cnode caps. *) definition si_cap_at :: "(cdl_object_id \ cdl_object_id option) \ (cdl_object_id \ cdl_cptr option) \ cdl_state \ bool \ cdl_object_id \ sep_pred" where "si_cap_at t si_caps spec dev obj_id \ \s. \cap_ptr slot obj kobj_id. ((si_cnode_id, slot) \c default_cap (object_type obj) {kobj_id} (object_size_bits obj) dev) s \ si_caps obj_id = Some cap_ptr \ unat cap_ptr = slot \ cap_ptr < 2 ^ si_cnode_size \ cdl_objects spec obj_id = Some obj \ t obj_id = Some kobj_id" definition si_irq_cap_at :: "(cdl_irq \ cdl_cptr option) \ cdl_state \ cdl_irq \ sep_pred" where "si_irq_cap_at si_irq_caps spec irq \ \s. \cap_ptr slot. ((si_cnode_id, slot) \c IrqHandlerCap irq) s \ si_irq_caps irq = Some cap_ptr \ unat cap_ptr = slot \ cap_ptr < 2 ^ si_cnode_size" definition si_caps_at :: "(cdl_object_id \ cdl_object_id option) \ (cdl_object_id \ cdl_cptr option) \ cdl_state \ bool \ cdl_object_id set \ sep_pred" where "si_caps_at t si_caps spec dev obj_ids \ \* obj_id \ obj_ids. (si_cap_at t si_caps spec) dev obj_id" definition si_irq_caps_at :: "(cdl_irq \ cdl_cptr option) \ cdl_state \ cdl_irq set \ sep_pred" where "si_irq_caps_at si_irq_caps spec irqs \ \* irq \ irqs. si_irq_cap_at si_irq_caps spec irq" definition si_obj_cap_at' :: " (cdl_object_id \ cdl_object_id option) \ (cdl_object_id \ cdl_cptr option) \ cdl_state \ bool \ cdl_object_id \ cdl_cnode_index \ sep_pred" where "si_obj_cap_at' t si_caps spec dev obj_id slot \ \s. \ spec_cap. si_cap_at t si_caps spec dev (cap_object spec_cap) s \ opt_cap (obj_id, slot) spec = Some spec_cap" definition si_obj_cap_at where "si_obj_cap_at t si_caps spec dev obj_id slot \ if original_cap_at (obj_id, slot) spec \ cap_at cap_has_object (obj_id, slot) spec then si_obj_cap_at' t si_caps spec dev obj_id slot else \" definition si_obj_caps_at :: "(cdl_object_id \ cdl_object_id option) \ (cdl_object_id \ cdl_cptr option) \ cdl_state \ bool \ cdl_object_id \ sep_pred" where "si_obj_caps_at t si_caps spec dev obj_id \ \* slot \ dom (slots_of obj_id spec). si_obj_cap_at t si_caps spec dev obj_id slot" definition si_objs_caps_at :: "(cdl_object_id \ cdl_object_id option) \ (cdl_object_id \ cdl_cptr option) \ cdl_state \ bool \ cdl_object_id set \ sep_pred" where "si_objs_caps_at t si_caps spec dev obj_ids \ \* obj_id \ obj_ids. (si_obj_caps_at t si_caps spec) dev obj_id" definition si_spec_irq_cap_at' :: "(cdl_irq \ cdl_cptr option) \ cdl_state \ cdl_object_id \ cdl_cnode_index \ sep_pred" where "si_spec_irq_cap_at' si_irq_caps spec obj_id slot \ \s. \ spec_cap. si_irq_cap_at si_irq_caps spec (cap_irq spec_cap) s \ opt_cap (obj_id, slot) spec = Some spec_cap" definition si_spec_irq_cap_at where "si_spec_irq_cap_at si_irq_caps spec obj_id slot \ if irqhandler_cap_at (obj_id, slot) spec then si_spec_irq_cap_at' si_irq_caps spec obj_id slot else \" definition si_spec_irq_caps_at :: "(cdl_irq \ cdl_cptr option) \ cdl_state \ cdl_object_id \ sep_pred" where "si_spec_irq_caps_at si_irq_caps spec obj_id \ \* slot \ dom (slots_of obj_id spec). si_spec_irq_cap_at si_irq_caps spec obj_id slot" definition si_spec_irqs_caps_at :: "(cdl_irq \ cdl_cptr option) \ cdl_state \ cdl_object_id set \ sep_pred" where "si_spec_irqs_caps_at si_irq_caps spec obj_ids \ \* obj_id \ obj_ids. si_spec_irq_caps_at si_irq_caps spec obj_id" definition "si_null_cap_at t si_irq_caps spec obj_id \ \s. \cap_ptr slot obj kobj_id. ((si_cnode_id, slot) \c NullCap) s \ si_irq_caps obj_id = Some cap_ptr \ unat cap_ptr = slot \ cap_ptr < 2 ^ si_cnode_size \ cdl_objects spec obj_id = Some obj \ t obj_id = Some kobj_id" definition "si_null_irq_cap_at si_irq_caps spec irq \ \s. \cap_ptr slot. ((si_cnode_id, slot) \c NullCap) s \ si_irq_caps irq = Some cap_ptr \ unat cap_ptr = slot \ cap_ptr < 2 ^ si_cnode_size" definition si_spec_obj_null_cap_at' :: " (cdl_object_id \ cdl_object_id option) \ (cdl_object_id \ cdl_cptr option) \ cdl_state \ cdl_object_id \ cdl_cnode_index \ sep_pred" where "si_spec_obj_null_cap_at' t si_irq_caps spec obj_id slot \ \s. \ spec_cap. si_null_cap_at t si_irq_caps spec (cap_object spec_cap) s \ opt_cap (obj_id, slot) spec = Some spec_cap" definition si_spec_obj_null_cap_at where "si_spec_obj_null_cap_at t si_irq_caps spec obj_id slot \ if original_cap_at (obj_id, slot) spec \ cap_at cap_has_object (obj_id, slot) spec then si_spec_obj_null_cap_at' t si_irq_caps spec obj_id slot else \" definition si_spec_obj_null_caps_at :: "(cdl_object_id \ cdl_object_id option) \ (cdl_object_id \ cdl_cptr option) \ cdl_state \ cdl_object_id \ sep_pred" where "si_spec_obj_null_caps_at t si_irq_caps spec obj_id \ \* slot \ dom (slots_of obj_id spec). si_spec_obj_null_cap_at t si_irq_caps spec obj_id slot" definition si_spec_objs_null_caps_at :: "(cdl_object_id \ cdl_object_id option) \ (cdl_object_id \ cdl_cptr option) \ cdl_state \ cdl_object_id set \ sep_pred" where "si_spec_objs_null_caps_at t si_irq_caps spec obj_ids \ \* obj_id \ obj_ids. si_spec_obj_null_caps_at t si_irq_caps spec obj_id" definition si_spec_irq_null_cap_at' :: "(cdl_irq \ cdl_cptr option) \ cdl_state \ cdl_object_id \ cdl_cnode_index \ sep_pred" where "si_spec_irq_null_cap_at' si_irq_caps spec obj_id slot \ \s. \ spec_cap. si_null_irq_cap_at si_irq_caps spec (cap_irq spec_cap) s \ opt_cap (obj_id, slot) spec = Some spec_cap \ \is_untyped_cap spec_cap" definition si_spec_irq_null_cap_at where "si_spec_irq_null_cap_at si_irq_caps spec obj_id slot \ if irqhandler_cap_at (obj_id, slot) spec then si_spec_irq_null_cap_at' si_irq_caps spec obj_id slot else \" definition si_spec_irq_null_caps_at :: "(cdl_irq \ cdl_cptr option) \ cdl_state \ cdl_object_id \ sep_pred" where "si_spec_irq_null_caps_at si_irq_caps spec obj_id \ \* slot \ dom (slots_of obj_id spec). si_spec_irq_null_cap_at si_irq_caps spec obj_id slot" definition si_spec_irqs_null_caps_at :: "(cdl_irq \ cdl_cptr option) \ cdl_state \ cdl_object_id set \ sep_pred" where "si_spec_irqs_null_caps_at si_irq_caps spec obj_ids \ \* obj_id \ obj_ids. si_spec_irq_null_caps_at si_irq_caps spec obj_id" definition si_null_caps_at :: "(cdl_object_id \ cdl_object_id option) \ (cdl_object_id \ cdl_cptr option) \ cdl_state \ cdl_object_id set \ sep_pred" where "si_null_caps_at t si_caps spec obj_ids \ \* obj_id \ obj_ids. si_null_cap_at t si_caps spec obj_id" lemma si_cap_at_less_si_cnode_size: "\\si_cap_at t opt_sel4_cap spec dev obj_id \* R\ s; Some cap_ptr = opt_sel4_cap obj_id\ \ cap_ptr < 2 ^ si_cnode_size" by (clarsimp simp: si_cap_at_def sep_conj_exists) lemma si_irq_cap_at_less_si_cnode_size: "\\si_irq_cap_at opt_sel4_cap spec obj_id \* R\ s; Some cap_ptr = opt_sel4_cap obj_id\ \ cap_ptr < 2 ^ si_cnode_size" by (clarsimp simp: si_irq_cap_at_def sep_conj_exists) lemma si_cap_at_has_k_obj_id: "\\si_cap_at t opt_sel4_cap spec dev obj_id \* R\ s\ \ \cap_object_id. t obj_id = Some cap_object_id" by (clarsimp simp: si_cap_at_def sep_conj_exists) (****************************************************** * Using just si_cap_at when you have si_caps_at. * ******************************************************) lemma valid_si_caps_at_si_cap_at: "\finite obj_ids; obj_id \ obj_ids; (\R. \\si_cap_at t orig_caps spec dev obj_id \* P \* R\\ f \\_.\si_cap_at t orig_caps spec dev obj_id \* Q \* R\\)\ \ \\si_caps_at t orig_caps spec dev obj_ids \* P \* R\\ f \\_.\si_caps_at t orig_caps spec dev obj_ids \* Q \* R\\" apply (clarsimp simp: si_caps_at_def) apply (drule sep_set_conj_map_singleton_wp [where f=f and I="si_cap_at t orig_caps spec dev" and P=P and Q=Q and R=R, rotated]) apply (clarsimp simp: sep_conj_ac)+ done (********************************************************** * The pre and post conditions of the system initialiser. * **********************************************************) (* That the boot info is valid, and that there are enough free slots to initialise a system. *) definition valid_boot_info where "valid_boot_info bootinfo spec \ \s. \untyped_caps fstart fend ustart uend. ((\*(cptr, cap) \ set (zip [ustart .e. uend - 1] untyped_caps). (si_cnode_id, unat cptr) \c cap) \* (\* cptr \ set [fstart .e. fend - 1]. (si_cnode_id, unat cptr) \c NullCap) \* (\* obj_id\(\cap\set untyped_caps. cap_free_ids cap). obj_id \o Untyped) \* si_objects \* si_irq_nodes spec) s \ card (dom (cdl_objects spec)) + card {obj_id. cnode_or_tcb_at obj_id spec} \ unat fend - unat fstart \ length untyped_caps = unat uend - unat ustart \ distinct_sets (map cap_free_ids untyped_caps) \ list_all is_full_untyped_cap untyped_caps \ list_all well_formed_untyped_cap untyped_caps \ list_all (\c. \ is_device_cap c) untyped_caps \ bi_untypes bootinfo = (ustart, uend) \ bi_free_slots bootinfo = (fstart, fend) \ ustart < 2 ^ si_cnode_size \ (uend - 1) < 2 ^ si_cnode_size \ fstart < 2 ^ si_cnode_size \ (fend - 1) < 2 ^ si_cnode_size \ uend \ 0 \ fend \ 0" definition si_final_objects :: "cdl_state \ (cdl_object_id \ cdl_object_id option) \ sep_pred" where "si_final_objects spec t \ \s. \dup_caps (untyped_cptrs::32 word list) (free_cptrs::32 word list) untyped_caps all_available_ids. ((\* cptr \ set (take (card (dom (cdl_objects spec))) free_cptrs). (si_cnode_id, unat cptr) \c NullCap) \* (\* cptr \ set (drop (card (dom (cdl_objects spec)) + card ({obj_id. cnode_or_tcb_at obj_id spec})) free_cptrs). (si_cnode_id, unat cptr) \c NullCap) \* (\* (cptr, untyped_cap) \ set (zip untyped_cptrs untyped_caps). (si_cnode_id, unat cptr) \c untyped_cap) \* (\* obj_id \ all_available_ids. obj_id \o Untyped) \* (\* obj_id \ {obj_id. cnode_or_tcb_at obj_id spec}. (si_cap_at t dup_caps spec False obj_id)) \* si_objects) s" (******************************************************** * Conversion of si_objs_caps_at to si_caps_at * ********************************************************) lemma orig_cap_rewrite: "Set.filter (\cap_ref. original_cap_at cap_ref spec \ cap_at cap_has_object cap_ref spec) (SIGMA obj_id:{obj_id. cnode_at obj_id spec}. dom (slots_of obj_id spec)) = {cap_ref. original_cap_at cap_ref spec \ object_cap_ref cap_ref spec}" by (auto simp: object_cap_ref_def opt_cap_def object_at_def cap_at_def real_object_at_def split: option.splits) lemma slots_tcb: "\well_formed spec; opt_cap (obj_id, slot) spec = Some cap; cdl_objects spec obj_id = Some obj; obj = Tcb tcb\ \ slot = 0 \ slot = 1 \ slot = 2 \ slot = 3 \ slot = 4 \ slot = 5 \ slot = 6" apply (frule (1) well_formed_object_slots) apply (drule (1) well_formed_well_formed_tcb) apply (clarsimp simp: well_formed_tcb_def opt_cap_def slots_of_def opt_object_def) apply (drule (1) dom_eqD) apply (clarsimp simp: object_default_state_def2 dom_object_slots_default_tcb tcb_pending_op_slot_def tcb_boundntfn_slot_def) done lemma object_at_dom_cdl_objects: "object_at P obj_id s \ obj_id \ dom (cdl_objects s)" by (clarsimp simp: object_at_def) lemma foo: "\well_formed spec; irq_node_at obj_id spec\ \ obj_id \ irq_nodes spec" by (metis irq_nodes_def mem_Collect_eq) lemma well_formed_irqhandler_cap_in_cnode: "\well_formed spec; opt_cap (obj_id, slot) spec = Some cap; is_irqhandler_cap cap; cdl_objects spec obj_id = Some obj\ \ is_cnode obj" apply (case_tac obj) apply (fastforce simp: opt_cap_def slots_of_def object_slots_def opt_object_def is_cnode_def object_at_def is_asidpool_def)+ apply (frule (3) slots_tcb) apply (drule (1) well_formed_well_formed_tcb) apply (clarsimp simp: well_formed_tcb_def opt_cap_def slots_of_def opt_object_def) apply (erule allE [where x=slot]) apply (simp add: tcb_slot_defs cap_type_def split: cdl_cap.splits) apply (fastforce simp: opt_cap_def slots_of_def object_slots_def opt_object_def is_cnode_def object_at_def is_asidpool_def) apply (frule_tac obj_id=obj_id in well_formed_asidpool_at, simp add: object_at_def) apply (frule (1) well_formed_pt, simp add: object_at_def, simp+) apply (frule (1) well_formed_pd, simp add: object_at_def, simp+) apply (clarsimp simp: is_fake_pt_cap_def split: cdl_cap.splits) apply (fastforce simp: opt_cap_def slots_of_def object_slots_def opt_object_def is_cnode_def object_at_def is_asidpool_def)+ apply (frule (1) well_formed_well_formed_irq_node) apply (fastforce simp: well_formed_irq_node_def opt_cap_def slots_of_def opt_object_def object_at_def irq_nodes_def is_irq_node_def) done lemma well_formed_irqhandler_cap_in_cnode_at: "\well_formed spec; opt_cap (obj_id, slot) spec = Some cap; is_irqhandler_cap cap\ \ cnode_at obj_id spec" apply (frule opt_cap_cdl_objects, clarsimp) apply (drule (3) well_formed_irqhandler_cap_in_cnode) apply (clarsimp simp: object_at_def) done lemma irqhandler_cap_rewrite: "well_formed spec \ Set.filter (\irq. irqhandler_cap_at irq spec) (SIGMA obj_id:{obj_id. cnode_at obj_id spec}. dom (slots_of obj_id spec)) = {cap_ref. irqhandler_cap_at cap_ref spec}" apply (clarsimp simp: object_cap_ref_def object_at_def cap_at_def split: option.splits) apply rule apply clarsimp apply clarsimp apply (frule opt_cap_dom_cdl_objects) apply (frule opt_cap_dom_slots_of, clarsimp) apply (frule (3) well_formed_irqhandler_cap_in_cnode) apply (frule (1) well_formed_well_formed_irq_node) apply (clarsimp simp: well_formed_irq_node_def object_at_def opt_cap_def slots_of_def opt_object_def dom_def) done lemma well_formed_object_cap_real: "well_formed spec \ object_cap_ref cap_ref spec = (cap_at_to_real_object cap_ref spec \ cnode_at (fst cap_ref) spec)" apply (clarsimp simp: cap_at_def cap_at_to_real_object_def object_cap_ref_def) apply (rule iffI) apply clarsimp apply (drule (1) well_formed_well_formed_cap_to_real_object', simp) apply (clarsimp simp: well_formed_cap_to_real_object_def real_object_at_def) apply (clarsimp simp: real_object_at_def opt_cap_dom_cdl_objects) done (* This lemma converts between the two represenatations of the fact that the * root task has orig caps to each of the objects. * * This can be specified either: * - on the objects themselves. * - on the cap slots of CNodes that have a orig cap in them. * * This relies on the bijection between orig capabilities and objects in the spec. *) lemma si_caps_at_conversion: "\well_formed spec; real_ids = {obj_id. real_object_at obj_id spec}; cnode_ids = {obj_id. cnode_at obj_id spec}\ \ si_objs_caps_at t si_caps spec dev cnode_ids = si_caps_at t si_caps spec dev real_ids" apply (clarsimp simp: si_objs_caps_at_def si_obj_caps_at_def [abs_def] si_obj_cap_at_def [abs_def] si_caps_at_def) apply (subst sep.prod.Sigma, clarsimp+) apply (clarsimp simp: split_def) apply (subst sep_map_set_conj_restrict_predicate) apply (rule finite_SigmaI, clarsimp+) apply (subst orig_cap_rewrite) apply (frule well_formed_bij) apply (clarsimp simp: bij_betw_def) apply (rule sep_map_set_conj_reindex_cong [where f="\cap_ref. cap_ref_object cap_ref spec", symmetric]) apply (subst well_formed_object_cap_real, simp+) apply (simp add: real_objects_def real_object_at_def) apply (subst well_formed_object_cap_real, simp+) apply (clarsimp simp: cap_ref_object_def object_cap_ref_def si_obj_cap_at'_def) done lemma si_null_caps_at_conversion: "\well_formed spec; real_ids = {obj_id. real_object_at obj_id spec}; cnode_ids = {obj_id. cnode_at obj_id spec}\ \ si_spec_objs_null_caps_at t si_caps spec cnode_ids = si_null_caps_at t si_caps spec real_ids" apply (clarsimp simp: si_spec_objs_null_caps_at_def si_spec_obj_null_caps_at_def [abs_def] si_spec_obj_null_cap_at_def [abs_def] si_null_caps_at_def) apply (subst sep.prod.Sigma, clarsimp+) apply (clarsimp simp: split_def) apply (subst sep_map_set_conj_restrict_predicate) apply (rule finite_SigmaI, clarsimp+) apply (subst orig_cap_rewrite) apply (frule well_formed_bij) apply (clarsimp simp: bij_betw_def) apply (rule sep_map_set_conj_reindex_cong [where f="\cap_ref. cap_ref_object cap_ref spec" and h="(si_null_cap_at t si_caps spec)" and B="{obj_id. real_object_at obj_id spec}", symmetric]) apply (subst well_formed_object_cap_real, simp+) apply (simp add: real_objects_def real_object_at_def) apply (subst well_formed_object_cap_real, simp+) apply (clarsimp simp: cap_ref_object_def object_cap_ref_def si_spec_obj_null_cap_at'_def) done lemma si_null_caps_at_reindex: "\distinct (obj_ids::32 word list); distinct (free_cptrs); orig_caps = map_of (zip obj_ids free_cptrs); length obj_ids \ length free_cptrs\ \ (\* obj_id\set obj_ids. (\s. \cap_ptr. ((si_cnode_id, unat cap_ptr) \c NullCap) s \ orig_caps obj_id = Some cap_ptr)) = (\* cptr\set (take (length obj_ids) free_cptrs). (si_cnode_id, unat cptr) \c NullCap)" apply (rule sep_map_set_conj_reindex_cong [symmetric, where f="\obj_id. the (orig_caps obj_id)" and h="\cptr. (si_cnode_id, unat cptr) \c NullCap" and B="set (take (length obj_ids) free_cptrs)"]) apply clarsimp apply (erule (2) map_of_zip_inj') apply clarsimp apply (subst zip_take_length[symmetric]) apply (subst map_of_zip_range) apply (clarsimp simp: min_def) apply assumption apply simp apply clarsimp apply (rule ext) apply rule apply clarsimp apply (rule_tac x="the (map_of (zip obj_ids free_cptrs) a)" in exI) apply clarsimp apply (frule_tac x=a in map_of_zip_is_Some', clarsimp) done lemma si_null_caps_at_simplified_helper: "\(si_null_caps_at t orig_caps spec obj_ids) s\ \ (\* obj_id \ obj_ids. (\s. \cap_ptr. ((si_cnode_id, unat cap_ptr) \c NullCap) s \ orig_caps obj_id = Some cap_ptr)) s" apply (clarsimp simp: si_null_caps_at_def si_null_cap_at_def [abs_def]) apply (erule sep_map_set_conj_impl) apply blast apply clarsimp done lemma si_null_caps_at_simplified: "\(si_spec_objs_null_caps_at t si_caps spec cnode_ids) s; well_formed spec; cnode_ids = {obj_id. cnode_at obj_id spec}; real_ids = {obj_id. real_object_at obj_id spec}; real_ids = set obj_ids; distinct obj_ids; distinct free_cptrs; si_caps = map_of (zip obj_ids free_cptrs); length obj_ids \ length free_cptrs\ \ (\* cptr \ set (take (length obj_ids) free_cptrs). ((si_cnode_id, unat cptr) \c NullCap)) s" apply (subst (asm) si_null_caps_at_conversion, assumption+) apply (drule si_null_caps_at_simplified_helper) apply (subst si_null_caps_at_reindex [symmetric], simp+) done lemma map_of_zip_range': "\length xs = length ys; distinct xs; set xs = X\ \ (\x. (the (map_of (zip xs ys) x))) ` X = set ys" by (metis map_of_zip_range) lemma si_irq_caps_at_conversion: "\well_formed spec; cnode_ids = {obj_id. cnode_at obj_id spec}; irqs = used_irqs spec\ \ si_spec_irqs_caps_at irq_caps spec cnode_ids = si_irq_caps_at irq_caps spec irqs" apply (clarsimp simp: si_spec_irqs_caps_at_def si_irq_caps_at_def si_spec_irq_caps_at_def [abs_def] si_spec_irq_cap_at_def [abs_def]) apply (subst sep.prod.Sigma, clarsimp+) apply (clarsimp simp: split_def) apply (subst sep_map_set_conj_restrict_predicate) apply (rule finite_SigmaI, clarsimp+) apply (subst irqhandler_cap_rewrite, assumption) apply (frule well_formed_irqhandler_bij) apply (clarsimp simp: bij_betw_def) apply (rule sep_map_set_conj_reindex_cong [where f="\cap_ref. cap_ref_irq cap_ref spec", symmetric], simp+) apply (clarsimp simp: si_spec_irq_cap_at'_def cap_ref_irq_def cap_at_def) done definition si_null_irq_caps_at :: "(cdl_irq \ cdl_cptr option) \ cdl_state \ cdl_irq set \ sep_pred" where "si_null_irq_caps_at si_irq_caps spec irqs \ \* irq \ irqs. si_null_irq_cap_at si_irq_caps spec irq" lemma si_null_irq_caps_at_simplified_helper: "\(si_null_irq_caps_at si_irq_caps spec irqs) s\ \ (\* irq \ irqs. (\s. \cap_ptr. ((si_cnode_id, unat cap_ptr) \c NullCap) s \ si_irq_caps irq = Some cap_ptr)) s" apply (clarsimp simp: si_null_irq_caps_at_def si_null_irq_cap_at_def) apply (erule sep_map_set_conj_impl) apply blast apply clarsimp done lemma map_of_zip_inj2: "\distinct xs; distinct ys; length xs \ length ys; set xs = X\ \ inj_on (\x. the (map_of (zip xs ys) x)) X" by (metis map_of_zip_inj') lemma opt_cap_has_slots: "\opt_cap (obj_id, slot) spec = Some cap\ \ object_at has_slots obj_id spec" by (auto simp: object_at_def has_slots_def opt_cap_def slots_of_def opt_object_def object_slots_def split: option.splits cdl_object.splits) lemma well_formed_non_ntfn_in_real_object: "\well_formed spec; opt_cap (obj_id, slot) spec = Some cap; \is_ntfn_cap cap; cap \ NullCap\ \ real_object_at obj_id spec" apply (frule opt_cap_cdl_objects, clarsimp) apply (frule (1) well_formed_well_formed_irq_node) apply (clarsimp simp: well_formed_irq_node_def real_object_at_def opt_cap_def slots_of_def opt_object_def opt_cap_dom_cdl_objects) done lemma irqhandler_cap_at_simp: "well_formed spec \ {(obj_id, slot). cnode_at obj_id spec \ irqhandler_cap_at (obj_id, slot) spec} = {(obj_id, slot). irqhandler_cap_at (obj_id, slot) spec}" apply (safe) apply (clarsimp simp: cap_at_def) apply (frule (2) well_formed_irqhandler_cap_in_cnode_at) apply (frule (1) well_formed_non_ntfn_in_real_object, simp+) done lemma orig_cap_rewrite_v2: "(SIGMA obj_id:{obj_id. cnode_at obj_id spec}. dom (slots_of obj_id spec)) = {(obj_id, slot). cnode_at obj_id spec \ slots_of obj_id spec slot \ None}" by auto lemma rewrite_irqhandler_cap_at: "well_formed spec \ Set.filter (\cap_ref. irqhandler_cap_at cap_ref spec) (SIGMA obj_id:{obj_id. cnode_at obj_id spec}. dom (slots_of obj_id spec)) = {(obj_id, slot). irqhandler_cap_at (obj_id, slot) spec}" apply (subst irqhandler_cap_at_simp [symmetric]) by (auto simp: opt_cap_def cap_at_def) lemma well_formed_used_irqs_rewrite: "well_formed spec \ (\cap_ref. cap_ref_irq cap_ref spec) ` {(obj_id, slot). irqhandler_cap_at (obj_id, slot) spec} = used_irqs spec" apply (drule well_formed_irqhandler_bij) apply (auto simp: bij_betw_def) done lemma si_irq_null_caps_at_simplified: "\(si_spec_irqs_null_caps_at irq_caps spec {obj_id. cnode_at obj_id spec}) s; well_formed spec; distinct irqs; distinct free_cptrs; set irqs = used_irqs spec; irq_caps = map_of (zip irqs free_cptrs); length irqs \ length free_cptrs\ \ (\* cptr \ set (take (length irqs) free_cptrs). ((si_cnode_id, unat cptr) \c NullCap)) s" apply (clarsimp simp: si_spec_irqs_null_caps_at_def si_spec_irq_null_caps_at_def si_spec_irq_null_cap_at_def si_spec_irqs_caps_at_def) apply (subst (asm) sep.prod.Sigma, clarsimp+) apply (clarsimp simp: split_def) apply (subst (asm) sep_map_set_conj_restrict_predicate, rule finite_SigmaI, clarsimp+) apply (subst (asm) rewrite_irqhandler_cap_at, simp) apply (subst (asm) sep_map_set_conj_reindex_cong [where f = "\cap_ref. cap_ref_irq cap_ref spec" and h = "si_null_irq_cap_at (map_of (zip irqs free_cptrs)) spec", symmetric]) apply (drule well_formed_irqhandler_bij) apply (clarsimp simp: bij_betw_def cond_case_prod_eta) apply simp apply (clarsimp simp: si_spec_irq_null_cap_at'_def cap_at_def cap_ref_irq_def) apply clarsimp apply (drule si_null_irq_caps_at_simplified_helper [simplified si_null_irq_caps_at_def]) apply (subst (asm) sep_map_set_conj_reindex_cong [symmetric, where f = "\irq. the ( map_of (zip irqs free_cptrs) irq)" and h = "\cptr. (si_cnode_id, unat cptr) \c NullCap" and B = "set (take (length irqs) free_cptrs)"]) apply (subst well_formed_used_irqs_rewrite, assumption) apply (metis map_of_zip_inj') apply (subst well_formed_used_irqs_rewrite, assumption) apply (subst zip_take_length[symmetric], subst map_of_zip_range', simp+) apply (rule ext) apply rule apply clarsimp apply (rule_tac x="the (map_of (zip irqs free_cptrs) a)" in exI) apply clarsimp apply (frule_tac x1="(cap_irq (the (opt_cap (aa, b) spec)))" in map_of_zip_is_Some'[THEN iffD1], clarsimp) apply (fastforce simp: cap_at_def used_irqs_def all_caps_def) apply (clarsimp simp: cap_ref_irq_def) apply simp done end