(* * 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) *) (* * Well formed constraints of what capDL specifications the system-initialiser can initialise. * * There are two types of constraints: * - fundamental ones (such as that specs must be finite), * and other seL4 limitations (such as that page tables can't be shared). * - limitations of the initialiser. * * The latter are commented with LIMITATION. *) theory WellFormed_SI imports "../proof/capDL-api/Kernel_DP" "../proof/sep-capDL/Separation_SD" "../lib/SimpStrategy" begin lemma cap_has_object_NullCap [simp]: "\cap_has_object NullCap" by (clarsimp simp: cap_has_object_def) lemma cap_has_object_not_NullCap: "cap_has_object cap \ cap \ NullCap" by clarsimp lemma is_irqhandler_cap_not_NullCap: "is_irqhandler_cap cap \ cap \ NullCap" by clarsimp lemma cap_has_object_not_irqhandler_cap: "cap_has_object cap \ \ is_irqhandler_cap cap" by (clarsimp simp: cap_has_object_def cap_type_def split: cdl_cap.splits) lemmas cap_has_object_not_irqhandler_cap_simp[simp] = cap_has_object_not_irqhandler_cap[OF ByAssum] lemmas cap_has_object_not_NullCap_simp[simp] = cap_has_object_not_NullCap[OF ByAssum] lemmas is_irqhandler_cap_not_NullCap_simp[simp] = is_irqhandler_cap_not_NullCap[OF ByAssum] definition cap_ref_object :: "cdl_cap_ref \ cdl_state \ cdl_object_id" where "cap_ref_object cap_ref s \ cap_object (the (opt_cap cap_ref s))" definition cap_ref_irq :: "cdl_cap_ref \ cdl_state \ cdl_irq" where "cap_ref_irq cap_ref s \ cap_irq (the (opt_cap cap_ref s))" definition real_cap_ref :: "cdl_cap_ref \ cdl_state \ bool" where "real_cap_ref cap_ref s \ \cap. opt_cap cap_ref s = Some cap \ cap \ NullCap \ cnode_at (fst cap_ref) s" definition object_cap_ref :: "cdl_cap_ref \ cdl_state \ bool" where "object_cap_ref cap_ref s \ \cap. opt_cap cap_ref s = Some cap \ cap_has_object cap \ cnode_at (fst cap_ref) s" (* MOVE ME *) definition "guard_bits = (18::nat)" lemma guard_less_guard_bits: "\guard_size < guard_bits; (g::word32) < 2 ^ guard_size\ \ g < 2 ^ guard_bits" apply (erule less_le_trans) apply (rule two_power_increasing, simp) apply (clarsimp simp: guard_bits_def) done lemma guard_size_shiftl_non_zero: "\guard_size < guard_bits; guard_size \ 0\ \ ((of_nat guard_size)::word32) << 3 \ 0" apply (rule word_shift_nonzero [where m=guard_bits]) apply clarsimp apply (rule order_less_imp_le) apply (rule guard_less_guard_bits, assumption) apply (insert n_less_equal_power_2 [where n=guard_size]) apply clarsimp apply (rule of_nat_n_less_equal_power_2) apply (clarsimp simp: guard_bits_def) apply (clarsimp simp: guard_bits_def) apply (clarsimp simp: of_nat_0) apply (drule of_nat_0) apply (erule less_le_trans) apply (clarsimp simp: guard_bits_def word_bits_def) apply clarsimp done (* End of MOVE ME *) definition well_formed_cap :: "cdl_cap \ bool" where "well_formed_cap cap \ (case cap of EndpointCap _ b _ \ b < 2 ^ badge_bits | NotificationCap _ b r \ (b < 2 ^ badge_bits) \ (r \ {AllowRead, AllowWrite}) | CNodeCap _ g gs sz \ (gs < guard_bits) \ (g < 2 ^ gs) \ (sz + gs \ 32) | TcbCap _ \ True | FrameCap _ r _ _ ad \ r \ {vm_read_write, vm_read_only} \ ad = None | PageTableCap _ _ ad \ ad = None | PageDirectoryCap _ _ ad \ ad = None | IrqHandlerCap _ \ True (* LIMITATION: The following should probably eventually be true. *) | IrqControlCap \ False | UntypedCap _ _ \ False | AsidControlCap \ False | AsidPoolCap _ _ \ False | _ \ False)" (* LIMITATION: The specification cannot contain ASID numbers. *) definition vm_cap_has_asid :: "cdl_cap \ bool" where "vm_cap_has_asid cap \ (case cap of FrameCap _ _ _ _ ad \ ad \ None | PageTableCap _ _ ad \ ad \ None | PageDirectoryCap _ _ ad \ ad \ None | _ \ False)" definition is_real_vm_cap :: "cdl_cap \ bool" where "is_real_vm_cap cap \ (case cap of FrameCap _ _ _ Real _ \ True | PageTableCap _ Real _ \ True | PageDirectoryCap _ Real _ \ True | _ \ False)" definition is_fake_vm_cap :: "cdl_cap \ bool" where "is_fake_vm_cap cap \ (case cap of FrameCap _ _ _ Fake _ \ True | PageTableCap _ Fake _ \ True | PageDirectoryCap _ Fake _ \ True | _ \ False)" (* Original caps must have default rights, * and original endpoint + notification caps must not be badged. *) definition is_copyable_cap :: "cdl_cap \ bool" where "is_copyable_cap cap \ \ is_irqhandler_cap cap" definition well_formed_orig_cap :: "cdl_cap \ bool" where "well_formed_orig_cap cap \ (cap_has_type cap \ cap_rights (default_cap (the (cap_type cap)) undefined undefined) = cap_rights cap) \ (ep_related_cap cap \ cap_badge cap = 0)" definition well_formed_cdt :: "cdl_state \ cdl_cap_ref \ cdl_cap \ bool" where "well_formed_cdt spec cap_ref cap \ cnode_at (fst cap_ref) spec \ cap_has_object cap \ (\orig_obj_id orig_slot orig_cap. cnode_at orig_obj_id spec \ (\obj. opt_object (cap_object cap) spec = Some obj) \ original_cap_at (orig_obj_id, orig_slot) spec \ opt_cap (orig_obj_id, orig_slot) spec = Some orig_cap \ cap_has_object orig_cap \ cap_object orig_cap = cap_object cap)" (* MOVEME *) lemma well_formed_cdt_irqhandler_cap: "is_irqhandler_cap cap \ well_formed_cdt spec cap_ref cap" by (clarsimp simp: well_formed_cdt_def split: cdl_cap.splits) (* The only thing that points to IRQ objects is the IRQ table (not a cap). *) definition well_formed_cap_to_real_object :: "cdl_state \ cdl_cap \ bool" where "well_formed_cap_to_real_object spec cap \ cap_has_object cap \ real_object_at (cap_object cap) spec" definition well_formed_cap_types_match :: "cdl_state \ cdl_cap \ bool" where "well_formed_cap_types_match spec cap \ (cap_has_object cap \ (\cap_obj. cdl_objects spec (cap_object cap) = Some cap_obj \ cap_type cap = Some (object_type cap_obj))) \ (is_irqhandler_cap cap \ (\cap_obj. cdl_objects spec (cdl_irq_node spec (cap_irq cap)) = Some cap_obj \ cap_type cap = Some (object_type cap_obj)))" definition well_formed_caps :: "cdl_state \ cdl_object_id \ cdl_object \ bool" where "well_formed_caps spec obj_id obj \ \slot cap. object_slots obj slot = Some cap \ cap \ NullCap \ (well_formed_cap cap \ (original_cap_at (obj_id, slot) spec \ well_formed_orig_cap cap) \ (\original_cap_at (obj_id, slot) spec \ is_copyable_cap cap) \ well_formed_cdt spec (obj_id, slot) cap \ well_formed_cap_to_real_object spec cap \ well_formed_cap_types_match spec cap \ ((is_cnode obj \ is_tcb obj) \ (\ is_fake_vm_cap cap)))" definition well_formed_cap_to_object :: "cdl_state \ cdl_object_id \ cdl_object \ bool" where "well_formed_cap_to_object spec obj_id obj \ (\cnode_id slot cap. opt_cap (cnode_id, slot) spec = Some cap \ original_cap_at (cnode_id, slot) spec \ cnode_at cnode_id spec \ (real_object_at obj_id spec \ cap_object cap = obj_id \ cap_has_object cap) \ (\real_object_at obj_id spec \ is_irqhandler_cap cap \ cdl_irq_node spec (cap_irq cap) = obj_id)) \ (\slot cap. (opt_cap slot spec = Some cap \ is_cnode_cap cap \ cap_object cap = obj_id) \ object_size_bits obj = cnode_cap_size cap)" (* For every IRQ object that has a cap in it, * there should be an IRQ handler cap to that object. * There can be more IRQ handler caps than this, * but every object must have a cap to it. *) definition well_formed_irqhandler_caps :: "cdl_state \ bool" where "well_formed_irqhandler_caps spec \ (\irq. irq \ bound_irqs spec \ (\cnode_id slot cap. opt_cap (cnode_id, slot) spec = Some cap \ is_irqhandler_cap cap \ cap_irq cap = irq))" definition well_formed_orig_caps_unique :: "cdl_state \ bool" where "well_formed_orig_caps_unique spec \ \obj_id obj_id' slot slot' cap cap'. cnode_at obj_id spec \ cnode_at obj_id' spec \ cap_has_object cap \ cap_has_object cap' \ opt_cap (obj_id, slot) spec = Some cap \ opt_cap (obj_id', slot') spec = Some cap' \ cap \ NullCap \ original_cap_at (obj_id, slot) spec \ cap' \ NullCap \ original_cap_at (obj_id', slot') spec \ cap_object cap = cap_object cap' \ (obj_id = obj_id' \ slot = slot')" definition well_formed_irqhandler_caps_unique :: "cdl_state \ bool" where "well_formed_irqhandler_caps_unique spec \ \obj_id obj_id' slot slot' cap cap'. opt_cap (obj_id, slot) spec = Some cap \ opt_cap (obj_id', slot') spec = Some cap' \ is_irqhandler_cap cap \ is_irqhandler_cap cap' \ cap_irq cap = cap_irq cap' \ (obj_id = obj_id' \ slot = slot')" definition well_formed_tcb :: "cdl_state \ cdl_object_id \ cdl_object \ bool" where "well_formed_tcb spec obj_id obj \ is_tcb obj \ \ tcb_has_fault obj \ tcb_domain obj = minBound \ (\slot cap. object_slots obj slot = Some cap \ ((slot = tcb_cspace_slot \ is_cnode_cap cap \ cap_guard_size cap \ 0 \ cap_object cap \ irq_nodes spec) \ (slot = tcb_vspace_slot \ is_pd_cap cap) \ (slot = tcb_ipcbuffer_slot \ is_frame_cap cap \ is_default_cap cap) \ (slot = tcb_replycap_slot \ cap = NullCap \ cap = MasterReplyCap obj_id) \ (slot = tcb_caller_slot \ cap = NullCap) \ (slot = tcb_pending_op_slot \ cap = NullCap \ cap = RestartCap) \ (slot = tcb_boundntfn_slot \ cap = NullCap) )) \ ((object_slots obj tcb_replycap_slot = Some (MasterReplyCap obj_id)) = (object_slots obj tcb_pending_op_slot = Some RestartCap))" definition well_formed_fake_pt_caps_unique :: "cdl_state \ bool" where "well_formed_fake_pt_caps_unique spec \ \obj_id obj_id' slot slot' cap cap'. pd_at obj_id spec \ pd_at obj_id' spec \ opt_cap (obj_id, slot) spec = Some cap \ opt_cap (obj_id', slot') spec = Some cap' \ cap \ NullCap \ is_fake_pt_cap cap \ cap' \ NullCap \ is_fake_pt_cap cap' \ cap_object cap = cap_object cap' \ (obj_id = obj_id' \ slot = slot')" definition well_formed_cap_to_non_empty_pt :: "cdl_state \ cdl_object_id \ cdl_object \ bool" where "well_formed_cap_to_non_empty_pt spec obj_id obj \ pt_at obj_id spec \ object_default_state obj \ obj \ (\pd_id slot cap. opt_cap (pd_id, slot) spec = Some cap \ pd_at pd_id spec \ cap_object cap = obj_id \ cap_has_object cap)" definition well_formed_vspace :: "cdl_state \ cdl_object_id \ cdl_object \ bool" where "well_formed_vspace spec obj_id obj \ well_formed_cap_to_non_empty_pt spec obj_id obj \ (\slot cap. (is_pt obj \ object_slots obj slot = Some cap \ cap \ NullCap \ (\sz. cap_type cap = Some (FrameType sz) \ (sz = 12 \ sz = 16) \ is_fake_vm_cap cap) ) \ (is_pd obj \ object_slots obj slot = Some cap \ cap \ NullCap \ (is_fake_pt_cap cap \ (\sz. cap_type cap = Some (FrameType sz) \ (sz = 20 \ sz = 24) \ is_fake_vm_cap cap) )))" (* LIMITATION: The caps in a IRQ Node must have full permissions and be unbadged. *) definition well_formed_irq_node :: "cdl_state \ cdl_object_id \ cdl_object \ bool" where "well_formed_irq_node spec obj_id obj \ \slot cap. obj_id \ irq_nodes spec \ dom (object_slots obj) = {0} \ (object_slots obj slot = Some cap \ (cap \ NullCap \ (is_ntfn_cap cap \ is_default_cap cap)))" definition well_formed_irq_table :: "cdl_state \ bool" where "well_formed_irq_table spec \ inj (cdl_irq_node spec) \ irq_nodes spec = {obj_id. \irq. cdl_irq_node spec irq = obj_id \ obj_id \ dom (cdl_objects spec)}" definition well_formed :: "cdl_state \ bool" where "well_formed spec \ well_formed_orig_caps_unique spec \ well_formed_irqhandler_caps_unique spec \ well_formed_fake_pt_caps_unique spec \ well_formed_irqhandler_caps spec \ well_formed_irq_table spec \ (\obj_id. case cdl_objects spec obj_id of Some obj \ well_formed_caps spec obj_id obj \ well_formed_cap_to_object spec obj_id obj \ well_formed_tcb spec obj_id obj \ well_formed_vspace spec obj_id obj \ well_formed_irq_node spec obj_id obj \ object_size_bits obj < word_bits \ object_size_bits (object_default_state obj) = object_size_bits obj \ dom (object_slots (object_default_state obj)) = dom (object_slots obj) \ (cnode_at obj_id spec \ 0 < object_size_bits obj) | None \ True)" lemma dom_cap_map [simp]: "dom (\n. if n \ N then Some a else None) = {0::nat .. N}" by (rule, clarsimp simp: dom_def)+ lemma dom_cap_map' [simp]: "dom (\n. if n < N then Some a else None) = {0::nat ..< N}" by (rule, clarsimp simp: dom_def)+ (******************************* * Rules about well_formed_cap. * *******************************) lemma well_formed_cap_cap_has_object_eq: "\well_formed_cap cap; cap_has_object cap; cap_type cap = cap_type cap'\ \ cap_has_object cap'" by (clarsimp simp: well_formed_cap_def cap_type_def cap_has_object_def split: cdl_cap.splits)+ lemma well_formed_cap_update_cap_objects [simp]: "is_untyped_cap cap \ well_formed_cap (update_cap_objects x cap) = well_formed_cap cap" apply (clarsimp simp: update_cap_object_def update_cap_objects_def well_formed_cap_def) apply (cases cap, simp_all) done lemma well_formed_cap_update_cap_object [simp]: "well_formed_cap (update_cap_object x cap) = well_formed_cap cap" apply (clarsimp simp: update_cap_object_def well_formed_cap_def) apply (cases cap, simp_all add:is_default_cap_def cap_type_def cap_badge_def default_cap_def) done lemma cap_rights_inter_default_cap_rights: "\well_formed_cap cap; cap_type cap = Some type\ \ cap_rights (default_cap type ids sz) \ cap_rights cap = cap_rights cap" by (fastforce simp: well_formed_cap_def default_cap_def cap_type_def cap_rights_def validate_vm_rights_def vm_read_write_def vm_kernel_only_def vm_read_only_def split: cdl_cap.splits cdl_object_type.splits) lemma well_formed_cap_derived_cap [simp]: "\well_formed_cap cap; \ vm_cap_has_asid cap\ \ derived_cap cap = cap" by (clarsimp simp: well_formed_cap_def vm_cap_has_asid_def derived_cap_def not_Some_eq_tuple split: cdl_cap.splits) (********************************* * Rules about well_formed spec. * *********************************) lemma dom_if_0 [simp]: "dom (\a. if a = 0 then Some b else None) = {0}" by (auto split: split_if_asm) lemma well_formed_finite [elim!]: "well_formed spec \ finite (dom (slots_of obj_id spec))" apply (clarsimp simp: well_formed_def) apply (erule_tac x=obj_id in allE) apply (clarsimp simp: opt_object_def slots_of_def split: option.splits) apply (rename_tac obj) apply (drule_tac t="dom (object_slots obj)" in sym) (* Makes rewriting work. *) apply (clarsimp simp: object_default_state_def2 object_slots_def default_tcb_def tcb_pending_op_slot_def empty_cnode_def empty_irq_node_def empty_cap_map_def split: cdl_object.splits) done lemma well_formed_finite_object_slots: "\well_formed spec; cdl_objects spec obj_id = Some obj\ \ finite (dom (object_slots obj))" apply (drule well_formed_finite [where obj_id=obj_id]) apply (clarsimp simp: slots_of_def opt_object_def) done lemma well_formed_distinct_slots_of_list [elim!]: "well_formed spec \ distinct (slots_of_list spec obj_id)" apply (drule_tac obj_id=obj_id in well_formed_finite) apply (clarsimp simp: slots_of_list_def) done lemma well_formed_object_size_bits: "\well_formed spec; cdl_objects spec obj_id = Some obj\ \ object_size_bits (object_default_state obj) = object_size_bits obj" apply (clarsimp simp: well_formed_def) apply (erule_tac x=obj_id in allE) apply (clarsimp) done lemma well_formed_well_formed_caps: "\well_formed spec; cdl_objects spec obj_id = Some obj\ \ well_formed_caps spec obj_id obj" by (clarsimp simp: well_formed_def split: option.splits) lemma well_formed_well_formed_cap: "\well_formed spec; cdl_objects spec obj_id = Some obj; object_slots obj slot = Some cap; cap \ NullCap\ \ well_formed_cap cap" apply (clarsimp simp: well_formed_def) apply (erule_tac x=obj_id in allE) apply (clarsimp simp: well_formed_caps_def) done lemma well_formed_well_formed_cap': "\well_formed spec; opt_cap (obj_id, slot) spec = Some cap; cap \ NullCap\ \ well_formed_cap cap" apply (frule opt_cap_dom_cdl_objects) apply clarsimp apply (frule (1) object_slots_opt_cap, simp) apply (erule (3) well_formed_well_formed_cap) done lemma well_formed_well_formed_cap_to_object: "\well_formed spec; cdl_objects spec obj_id = Some obj\ \ well_formed_cap_to_object spec obj_id obj" by (clarsimp simp: well_formed_def split: option.splits) lemma well_formed_well_formed_cap_to_real_object: "\well_formed spec; cdl_objects spec obj_id = Some obj; object_slots obj slot = Some cap; cap \ NullCap\ \ well_formed_cap_to_real_object spec cap" apply (clarsimp simp: well_formed_def) apply (erule_tac x=obj_id in allE) apply (clarsimp simp: well_formed_caps_def) done lemma well_formed_well_formed_cap_to_real_object': "\well_formed spec; opt_cap cap_ref spec = Some cap; cap \ NullCap\ \ well_formed_cap_to_real_object spec cap" apply (frule opt_cap_dom_cdl_objects) apply (clarsimp split: prod.splits) apply (frule (1) object_slots_opt_capD) apply (erule (3) well_formed_well_formed_cap_to_real_object) done lemma well_formed_well_formed_cap_types_match: "\well_formed spec; cdl_objects spec obj_id = Some obj; object_slots obj slot = Some cap; cap \ NullCap\ \ well_formed_cap_types_match spec cap" apply (clarsimp simp: well_formed_def) apply (erule_tac x=obj_id in allE) apply (clarsimp simp: well_formed_caps_def) done lemma well_formed_well_formed_cap_types_match': "\well_formed spec; opt_cap cap_ref spec = Some cap; cap \ NullCap\ \ well_formed_cap_types_match spec cap" apply (frule opt_cap_dom_cdl_objects) apply (clarsimp) apply (frule (1) object_slots_opt_capD) apply (erule (3) well_formed_well_formed_cap_types_match) done lemma well_formed_cap_object_is_real: "\well_formed spec; opt_cap slot spec = Some cap; cap_has_object cap\ \ real_object_at (cap_object cap) spec" apply (drule (1) well_formed_well_formed_cap_to_real_object', simp) apply (clarsimp simp: well_formed_cap_to_real_object_def) done lemma well_formed_types_match: "\well_formed spec; opt_cap (obj_id, slot) spec = Some cap; cdl_objects spec (cap_object cap) = Some cap_obj; cap_has_object cap\ \ Some (object_type cap_obj) = cap_type cap" apply (frule cap_has_object_not_NullCap) apply (clarsimp simp: well_formed_def) apply (erule_tac x=obj_id in allE) apply (clarsimp simp: opt_cap_def opt_object_def slots_of_def) apply (clarsimp split: option.splits) apply (rename_tac obj) apply (clarsimp simp: well_formed_caps_def well_formed_cap_types_match_def) apply (erule_tac x=slot in allE) apply (clarsimp) done lemma well_formed_object_slots: "\well_formed spec; cdl_objects spec obj_id = Some obj\ \ dom (object_slots obj) = dom (object_slots (object_default_state obj))" apply (clarsimp simp: well_formed_def) apply (erule allE [where x=obj_id]) apply simp done lemma well_formed_slot_object_size_bits: "\well_formed spec; opt_cap (obj_id, slot) spec = Some cap; cdl_objects spec obj_id = Some obj; cnode_at obj_id spec\ \ slot < 2 ^ object_size_bits obj" apply (frule opt_cap_cdl_objects) apply (clarsimp simp: well_formed_def object_at_def is_cnode_def) apply (erule_tac x=obj_id in allE) apply clarsimp apply (clarsimp simp: opt_cap_def opt_object_def) apply (subgoal_tac "slot \ dom (object_slots (object_default_state obj))") apply (thin_tac "dom P = dom Q" for P Q) apply (clarsimp simp: well_formed_caps_def) apply (erule_tac x=slot in allE) apply (clarsimp simp: object_default_state_def2 object_type_def has_slots_def default_tcb_def object_size_bits_def object_slots_def empty_cnode_def empty_cap_map_def pt_size_def pd_size_def split: cdl_object.splits split_if_asm) apply (clarsimp simp: object_slots_slots_of) done lemma well_formed_cnode_object_size_bits: "\well_formed spec; cnode_at obj_id spec; cdl_objects spec obj_id = Some obj\ \ 0 < object_size_bits obj" apply (clarsimp simp: well_formed_def) apply (erule_tac x=obj_id in allE) apply (clarsimp simp: is_cnode_def object_at_def) done lemma well_formed_cnode_object_size_bits_eq: "\well_formed spec; opt_cap slot spec = Some cap; cdl_objects spec (cap_object cap) = Some obj; is_cnode_cap cap\ \ object_size_bits obj = cnode_cap_size cap" apply (frule (1) well_formed_cap_object_is_real) apply (clarsimp simp: cap_has_object_def cap_type_def split: cdl_cap.splits) apply (clarsimp simp: well_formed_def split_def split:option.splits) apply (erule_tac x="cap_object cap" in allE) apply (case_tac slot) apply (clarsimp simp: is_cnode_def opt_object_def well_formed_cap_to_object_def) done lemma slots_of_set [simp]: "well_formed spec \ set (slots_of_list spec obj) = dom (slots_of obj spec)" by (clarsimp simp: slots_of_list_def well_formed_finite) lemma well_formed_well_formed_tcb: "\well_formed spec; cdl_objects spec obj_id = Some obj\ \ well_formed_tcb spec obj_id obj" apply (clarsimp simp: well_formed_def) apply (erule_tac x=obj_id in allE) apply clarsimp done lemma well_formed_well_formed_vspace: "\well_formed spec; cdl_objects spec obj_id = Some obj\ \ well_formed_vspace spec obj_id obj" apply (clarsimp simp: well_formed_def) apply (erule_tac x=obj_id in allE) apply clarsimp done lemma well_formed_well_formed_irq_node: "\well_formed spec; cdl_objects spec obj_id = Some obj\ \ well_formed_irq_node spec obj_id obj" apply (clarsimp simp: well_formed_def) apply (erule_tac x=obj_id in allE) apply clarsimp done lemma well_formed_well_formed_irqhandler_caps: "well_formed spec \ well_formed_irqhandler_caps spec" by (clarsimp simp: well_formed_def) lemma well_formed_well_formed_irq_table: "well_formed spec \ well_formed_irq_table spec" by (clarsimp simp: well_formed_def) lemma well_formed_inj_cdl_irq_node: "well_formed spec \ inj (cdl_irq_node spec)" by (clarsimp simp: well_formed_def well_formed_irq_table_def) lemma well_formed_vm_cap_has_asid: "\well_formed spec; cdl_objects spec obj_id = Some obj; object_slots obj slot = Some cap\ \ \vm_cap_has_asid cap" apply (case_tac "cap = NullCap") apply (clarsimp simp: vm_cap_has_asid_def) apply (drule (3) well_formed_well_formed_cap) apply (clarsimp simp: well_formed_cap_def vm_cap_has_asid_def split: cdl_cap.splits) done lemma is_fake_vm_cap_cap_type: "is_fake_vm_cap cap \ (\sz. cap_type cap = Some (FrameType sz)) \ (cap_type cap = Some PageTableType) \ (cap_type cap = Some PageDirectoryType)" by (clarsimp simp: is_fake_vm_cap_def cap_type_def split: cdl_cap.splits) lemma well_formed_irq_node_in_irq_nodes: "\well_formed spec; cdl_objects spec obj_id = Some obj; is_irq_node obj\ \ obj_id \ irq_nodes spec" find_theorems irq_nodes oops term real_object_at lemma well_formed_irq_node_cap_is_ntfn_cap: "\well_formed spec; cdl_objects spec obj_id = Some obj; is_irq_node obj; object_slots obj slot = Some cap; cap \ NullCap\ \ is_ntfn_cap cap" apply (frule (3) well_formed_well_formed_cap_types_match) apply (clarsimp simp: well_formed_cap_types_match_def) oops lemma well_formed_is_fake_vm_cap: "\well_formed spec; cdl_objects spec obj_id = Some obj; is_cnode obj \ is_tcb obj \ is_irq_node obj; object_slots obj slot = Some cap\ \ \is_fake_vm_cap cap" apply (case_tac "is_irq_node obj") apply (frule (1) well_formed_well_formed_irq_node) apply (clarsimp simp: well_formed_irq_node_def object_at_def irq_nodes_def) apply (drule is_fake_vm_cap_cap_type) apply (cases "cap = NullCap", simp_all) apply (clarsimp simp: well_formed_def) apply (erule_tac x=obj_id in allE) apply (clarsimp simp: well_formed_caps_def) apply (erule_tac x=slot in allE) apply (clarsimp simp: domI is_fake_vm_cap_def) done lemma vm_cap_has_asid_update_cap_object [simp]: "vm_cap_has_asid (update_cap_object obj_id cap) = vm_cap_has_asid cap" by (clarsimp simp: cap_has_object_def update_cap_object_def vm_cap_has_asid_def split: cdl_cap.splits) lemma well_formed_object_size_bits_word_bits [simp]: "\well_formed spec; cdl_objects spec obj_id = Some spec_obj\ \ object_size_bits spec_obj < word_bits" apply (clarsimp simp: well_formed_def) apply (erule_tac x=obj_id in allE) apply clarsimp done lemma well_formed_is_untyped_cap: "\well_formed spec; cnode_at obj_id spec; opt_cap (obj_id, slot) spec = Some cap\ \ \ is_untyped_cap cap" apply (frule opt_cap_cdl_objects) apply (clarsimp simp: well_formed_def) apply (erule_tac x=obj_id in allE) apply (clarsimp simp: opt_cap_def well_formed_caps_def) apply (erule_tac x=slot in allE) apply (clarsimp simp: slots_of_def opt_object_def well_formed_cap_def cap_type_def split: cdl_cap.splits) done lemma well_formed_cap_has_object: "\well_formed spec; opt_cap (obj_id, slot) spec = Some spec_cap; spec_cap \ NullCap; \ is_untyped_cap spec_cap; \ is_irqhandler_cap spec_cap\ \ cap_has_object spec_cap" apply (clarsimp simp: opt_cap_def opt_object_def slots_of_def) apply (clarsimp simp: well_formed_def) apply (clarsimp split: option.splits) apply (rename_tac obj) apply (erule_tac x=obj_id in allE) apply (erule_tac x=obj in allE) apply (clarsimp simp: well_formed_caps_def) apply (erule_tac x=slot in allE) apply (clarsimp simp: domI) apply (clarsimp simp: cap_has_object_def well_formed_cap_def split: cdl_cap.splits) done lemma well_formed_cap_object: "\well_formed spec; opt_cap (obj_id, slot) spec = Some spec_cap; cap_has_object spec_cap\ \ \obj. cdl_objects spec (cap_object spec_cap) = Some obj" apply (frule (1) well_formed_well_formed_cap', clarsimp) apply (frule (1) well_formed_cap_has_object) apply clarsimp apply (clarsimp simp: well_formed_cap_def cap_type_def split: cdl_cap.splits) apply simp apply (clarsimp simp: opt_cap_def slots_of_def opt_object_def split: option.splits) apply (frule (1) well_formed_well_formed_caps) apply (clarsimp simp: well_formed_caps_def well_formed_cap_types_match_def) apply (erule allE [where x=slot]) apply (erule allE [where x=spec_cap]) apply clarsimp done lemma well_formed_cap_object_in_dom: "\well_formed spec; opt_cap (obj_id, slot) spec = Some spec_cap; cap_has_object spec_cap\ \ cap_object spec_cap \ dom (cdl_objects spec)" by (drule (2) well_formed_cap_object, clarsimp) lemma well_formed_all_caps_cap_object: "\well_formed spec; cap \ all_caps spec; cap_has_object cap\ \\obj. cdl_objects spec (cap_object cap) = Some obj" apply (clarsimp simp: all_caps_def) apply (erule (2) well_formed_cap_object) done lemma well_formed_all_caps_cap_irq: "\well_formed spec; cap \ all_caps spec; is_irqhandler_cap cap\ \\obj. cdl_objects spec (cdl_irq_node spec (cap_irq cap)) = Some obj" apply (clarsimp simp: all_caps_def) apply (frule (1) well_formed_well_formed_cap_types_match', simp) apply (clarsimp simp: well_formed_cap_types_match_def) done lemma well_formed_update_cap_rights_idem: "\well_formed_cap cap; rights = cap_rights cap\ \ update_cap_rights rights cap = cap" by (auto simp: update_cap_rights_def cap_rights_def well_formed_cap_def validate_vm_rights_def vm_kernel_only_def vm_read_write_def vm_read_only_def split: cdl_cap.splits) lemma default_ep_cap[simp]: "is_default_cap (EndpointCap a 0 UNIV)" by (simp add:is_default_cap_def default_cap_def cap_type_def) lemma default_ntfn_cap[simp]: "is_default_cap (NotificationCap a 0 {AllowRead, AllowWrite})" by (simp add:is_default_cap_def default_cap_def cap_type_def) lemma default_cap_well_formed_cap: "\well_formed_cap cap; cap_type cap = Some type; cnode_cap_size cap = sz\ \ well_formed_cap (default_cap type obj_ids sz)" by (auto simp: well_formed_cap_def default_cap_def cap_type_def word_gt_a_gt_0 vm_read_write_def cnode_cap_size_def split: cdl_cap.splits) lemma default_cap_well_formed_cap2: "\is_default_cap cap; cap_type cap = Some type; sz \ 32; \ is_untyped_cap cap; \ is_asidpool_cap cap\ \ well_formed_cap (default_cap type obj_ids sz)" apply (clarsimp simp: is_default_cap_def) apply (clarsimp simp: default_cap_def well_formed_cap_def word_gt_a_gt_0 badge_bits_def guard_bits_def vm_read_write_def cnode_cap_size_def split: cdl_object_type.splits cdl_cap.splits) done lemma well_formed_well_formed_orig_cap: "\well_formed spec; opt_cap (obj_id, slot) spec = Some cap; cap \ NullCap; original_cap_at (obj_id, slot) spec\ \ well_formed_orig_cap cap" apply (frule opt_cap_dom_cdl_objects) apply (clarsimp simp: dom_def, rename_tac obj) apply (frule (1) object_slots_opt_cap, simp) apply (clarsimp simp: well_formed_def well_formed_caps_def) apply (erule allE [where x=obj_id]) apply (clarsimp simp: well_formed_caps_def) done lemma well_formed_orig_ep_cap_is_default_helper: "\well_formed_orig_cap cap; ep_related_cap cap; cap_has_type cap\ \ is_default_cap cap" by (clarsimp simp: well_formed_orig_cap_def is_default_cap_def cap_rights_def ep_related_cap_def default_cap_def cap_type_def split: cdl_cap.splits) lemma well_formed_orig_ep_cap_is_default: "\well_formed spec; original_cap_at (obj_id, slot) spec; opt_cap (obj_id, slot) spec = Some cap; ep_related_cap cap; cap \ NullCap\ \ is_default_cap cap" apply (case_tac "\obj_id. cap = ReplyCap obj_id") apply (frule (1) well_formed_well_formed_cap', simp) apply (clarsimp simp: well_formed_cap_def) apply (frule (3) well_formed_well_formed_orig_cap) apply (erule (1) well_formed_orig_ep_cap_is_default_helper) apply (fastforce simp: ep_related_cap_def split: cdl_cap.splits) done lemma cap_rights_default_cap_eq: "cap_rights (default_cap type obj_ids sz) = cap_rights (default_cap type obj_ids' sz')" apply (clarsimp simp: cap_rights_def default_cap_def) apply (case_tac type, simp_all) done lemma well_formed_orig_caps: "\well_formed spec; original_cap_at (obj_id, slot) spec; slots_of obj_id spec slot = Some cap; cap \ NullCap; cap_type cap = Some type\ \ cap_rights (default_cap type obj_ids sz) = cap_rights cap" apply (frule well_formed_well_formed_orig_cap, simp add: opt_cap_def, assumption+) apply (clarsimp simp: well_formed_orig_cap_def) apply (subst (asm) cap_rights_default_cap_eq, fast) done lemma well_formed_cdt: "\well_formed spec; opt_cap (obj_id, slot) spec = Some cap; cap_has_object cap; cnode_at obj_id spec\ \ \orig_obj_id orig_slot orig_cap. cnode_at orig_obj_id spec \ original_cap_at (orig_obj_id, orig_slot) spec \ opt_cap (orig_obj_id, orig_slot) spec = Some orig_cap \ cap_has_object orig_cap \ cap_object orig_cap = cap_object cap" apply (clarsimp simp: well_formed_def) apply (erule_tac x=obj_id in allE) apply (clarsimp simp: split: option.splits) apply (clarsimp simp: object_at_def) apply (clarsimp simp: well_formed_caps_def) apply (erule_tac x=slot in allE) apply (clarsimp simp: well_formed_cdt_def object_slots_opt_cap) by blast lemma well_formed_cap_to_real_object: "\well_formed spec; real_object_at obj_id spec\ \ \cnode_id slot cap. opt_cap (cnode_id, slot) spec = Some cap \ original_cap_at (cnode_id, slot) spec \ cnode_at cnode_id spec \ cap_object cap = obj_id \ cap_has_object cap" apply (clarsimp simp: well_formed_def) apply (erule_tac x=obj_id in allE) apply (clarsimp simp: well_formed_cap_to_object_def real_object_at_def split: option.splits) done lemma well_formed_cap_to_irq_object: "\well_formed spec; cdl_objects spec obj_id = Some obj; obj_id \ irq_nodes spec\ \ \cnode_id slot cap. opt_cap (cnode_id, slot) spec = Some cap \ original_cap_at (cnode_id, slot) spec \ cnode_at cnode_id spec \ is_irqhandler_cap cap \ cdl_irq_node spec (cap_irq cap) = obj_id" apply (frule (1) well_formed_well_formed_cap_to_object) apply (clarsimp simp: well_formed_cap_to_object_def real_object_at_def split: option.splits) done lemma well_formed_cap_to_non_empty_pt: "\well_formed spec; pt_at obj_id spec; object_at (\obj. object_default_state obj \ obj) obj_id spec\ \ \pd_id slot cap. opt_cap (pd_id, slot) spec = Some cap \ pd_at pd_id spec \ cap_object cap = obj_id \ cap_has_object cap" apply (clarsimp simp: well_formed_def) apply (erule_tac x=obj_id in allE) apply (clarsimp simp: object_at_def) apply (clarsimp simp: well_formed_vspace_def well_formed_cap_to_non_empty_pt_def object_at_def) done lemma dom_object_slots_default_tcb: "dom (object_slots (Tcb (default_tcb domain))) = {0..tcb_boundntfn_slot}" by (clarsimp simp: object_slots_def default_tcb_def) lemma well_formed_tcb_has_fault: "\well_formed spec; cdl_objects spec obj_id = Some (Tcb tcb)\ \ \ cdl_tcb_has_fault tcb" apply (drule (1) well_formed_well_formed_tcb) apply (clarsimp simp: well_formed_tcb_def tcb_has_fault_def) done lemma well_formed_tcb_domain: "\well_formed spec; cdl_objects spec obj_id = Some (Tcb tcb)\ \ cdl_tcb_domain tcb = minBound" apply (drule (1) well_formed_well_formed_tcb) apply (clarsimp simp: well_formed_tcb_def tcb_domain_def) done lemma well_formed_object_domain: "\well_formed spec; cdl_objects spec obj_id = Some obj\ \ object_domain obj = minBound" apply (case_tac "\tcb. obj = Tcb tcb") apply clarsimp apply (drule (1) well_formed_tcb_domain) apply (clarsimp simp: object_domain_def) apply (clarsimp simp: object_domain_def minBound_word split: cdl_object.splits) done lemma well_formed_tcb_object_slots: "\well_formed spec; cdl_objects spec obj_id = Some tcb; is_tcb tcb\ \ dom (object_slots tcb) = {0..tcb_boundntfn_slot}" apply (frule (1) well_formed_object_slots) apply (clarsimp simp: object_default_state_def2 is_tcb_def split: cdl_object.splits) apply (rule dom_object_slots_default_tcb) done lemma well_formed_tcb_cspace_cap: "\well_formed spec; tcb_at obj_id spec\ \ \cspace_cap. opt_cap (obj_id, tcb_cspace_slot) spec = Some cspace_cap \ is_cnode_cap cspace_cap \ cap_guard_size cspace_cap \ 0 \ real_object_at (cap_object cspace_cap) spec" apply (clarsimp simp: object_at_def) apply (frule (1) well_formed_well_formed_caps) apply (frule (1) well_formed_well_formed_tcb) apply (frule (2) well_formed_tcb_object_slots) apply (clarsimp simp: well_formed_caps_def) apply (clarsimp simp: well_formed_tcb_def) apply (erule_tac x=tcb_cspace_slot in allE)+ apply (clarsimp simp: is_tcb_def object_default_state_def2 split: cdl_object.splits) apply (rename_tac cdl_tcb) apply (clarsimp simp: opt_cap_def slots_of_def opt_object_def split: option.splits) apply (subgoal_tac "\cspace_cap. object_slots (Tcb cdl_tcb) tcb_cspace_slot = Some cspace_cap") apply (clarsimp simp: dom_def well_formed_tcb_def real_object_at_def) apply (erule well_formed_cap_object [where obj_id=obj_id and slot=tcb_cspace_slot]) apply (simp add: opt_cap_def slots_of_def opt_object_def) apply (clarsimp simp: cap_has_object_def cap_type_def split: cdl_cap.splits) apply (auto simp: dom_def tcb_pending_op_slot_def tcb_cspace_slot_def) done lemma cap_data_cap_guard_size_0: "\well_formed_cap cap; is_cnode_cap cap; cap_data cap = 0\ \ cap_guard_size cap = 0" apply (clarsimp simp: cap_type_def cap_data_def guard_as_rawdata_def well_formed_cap_def split: cdl_cap.splits) apply (subst (asm) is_aligned_add_or [where n=8]) apply (rule is_aligned_shift) apply (rule shiftl_less_t2n) apply (rule word_of_nat_less) apply (clarsimp simp: guard_bits_def) apply clarsimp apply (clarsimp simp: word_or_zero) apply (rule ccontr) apply (drule (1) guard_size_shiftl_non_zero) apply simp done lemma well_formed_tcb_cspace_cap_cap_data: "\well_formed spec; tcb_at obj_id spec; cdl_objects spec obj_id = Some (Tcb tcb); opt_cap (obj_id, tcb_cspace_slot) spec = Some spec_cspace_cap\ \ cap_data spec_cspace_cap \ 0" apply (frule (1) well_formed_tcb_cspace_cap, clarsimp) apply (frule (1) well_formed_well_formed_cap', clarsimp) apply (drule (2) cap_data_cap_guard_size_0, simp) done lemma well_formed_tcb_opt_cap: "\well_formed spec; tcb_at obj_id spec; slot \ {0..tcb_boundntfn_slot}\ \ \cap. opt_cap (obj_id, slot) spec = Some cap" apply (clarsimp simp: object_at_def) apply (drule (1) well_formed_object_slots) apply (fastforce simp: object_default_state_def2 is_tcb_def opt_cap_def slots_of_def opt_object_def object_slots_def default_tcb_def dom_def tcb_pending_op_slot_def split: cdl_object.splits split_if_asm) done lemma well_formed_tcb_vspace_cap: "\well_formed spec; tcb_at obj_id spec\ \ \vspace_cap. opt_cap (obj_id, tcb_vspace_slot) spec = Some vspace_cap \ is_pd_cap vspace_cap" apply (frule (1) well_formed_tcb_opt_cap [where slot=tcb_vspace_slot], simp add: tcb_slot_defs) apply (clarsimp simp: object_at_def) apply (frule (1) well_formed_well_formed_tcb) apply (auto simp: well_formed_tcb_def opt_cap_def slots_of_def opt_object_def ) done lemma well_formed_tcb_ipcbuffer_cap: "\well_formed spec; tcb_at obj_id spec\ \ \tcb_ipcbuffer_cap. opt_cap (obj_id, tcb_ipcbuffer_slot) spec = Some tcb_ipcbuffer_cap \ is_default_cap tcb_ipcbuffer_cap \ is_frame_cap tcb_ipcbuffer_cap" apply (frule (1) well_formed_tcb_opt_cap [where slot=tcb_ipcbuffer_slot], simp add: tcb_slot_defs) apply (clarsimp simp: object_at_def) apply (frule (1) well_formed_well_formed_tcb) apply (auto simp: well_formed_tcb_def opt_cap_def slots_of_def opt_object_def) done lemma well_formed_tcb_caller_cap: "\well_formed spec; tcb_at obj_id spec\ \ opt_cap (obj_id, tcb_caller_slot) spec = Some NullCap" apply (frule (1) well_formed_tcb_opt_cap [where slot=tcb_caller_slot], simp add: tcb_slot_defs) apply (clarsimp simp: object_at_def) apply (frule (1) well_formed_well_formed_tcb) apply (auto simp: well_formed_tcb_def opt_cap_def slots_of_def opt_object_def) done lemma well_formed_tcb_replycap_cap: "\well_formed spec; tcb_at obj_id spec\ \ opt_cap (obj_id, tcb_replycap_slot) spec = Some NullCap \ opt_cap (obj_id, tcb_replycap_slot) spec = Some (MasterReplyCap obj_id)" apply (frule (1) well_formed_tcb_opt_cap [where slot=tcb_replycap_slot], simp add: tcb_slot_defs) apply (clarsimp simp: object_at_def) apply (frule (1) well_formed_well_formed_tcb) apply (auto simp: well_formed_tcb_def opt_cap_def slots_of_def opt_object_def) done lemma well_formed_tcb_pending_op_cap: "\well_formed spec; tcb_at obj_id spec\ \ opt_cap (obj_id, tcb_pending_op_slot) spec = Some NullCap \ opt_cap (obj_id, tcb_pending_op_slot) spec = Some RestartCap" apply (frule (1) well_formed_tcb_opt_cap [where slot=tcb_pending_op_slot], simp add: tcb_slot_defs) apply (clarsimp simp: object_at_def) apply (frule (1) well_formed_well_formed_tcb) apply (auto simp: well_formed_tcb_def opt_cap_def slots_of_def opt_object_def) done lemma well_formed_tcb_pending_op_replycap: "\well_formed spec; tcb_at obj_id spec\ \ (opt_cap (obj_id, tcb_replycap_slot) spec = Some (MasterReplyCap obj_id)) = (opt_cap (obj_id, tcb_pending_op_slot) spec = Some RestartCap)" apply (clarsimp simp: object_at_def) apply (drule (1) well_formed_well_formed_tcb) apply (clarsimp simp: well_formed_tcb_def opt_cap_def slots_of_def opt_object_def) done lemma well_formed_tcb_boundntfn_cap: "\well_formed spec; tcb_at obj_id spec\ \ opt_cap (obj_id, tcb_boundntfn_slot) spec = Some NullCap" apply (frule (1) well_formed_tcb_opt_cap [where slot=tcb_boundntfn_slot], simp add: tcb_slot_defs) apply (elim exE) apply (clarsimp simp: object_at_def) apply (drule (1) well_formed_well_formed_tcb) by (auto simp: well_formed_tcb_def opt_cap_def slots_of_def opt_object_def) lemma well_formed_orig_caps_unique: "\well_formed spec; original_cap_at (obj_id, slot) spec; original_cap_at (obj_id', slot') spec; cnode_at obj_id spec; cnode_at obj_id' spec; cap_has_object cap; cap_has_object cap'; opt_cap (obj_id, slot) spec = Some cap; opt_cap (obj_id', slot') spec = Some cap'; cap_object cap = cap_object cap'\ \ obj_id = obj_id' \ slot = slot'" by (clarsimp simp: well_formed_def well_formed_orig_caps_unique_def) lemma well_formed_orig_caps_unique': "\well_formed spec; original_cap_at (obj_id, slot) spec; original_cap_at (obj_id', slot') spec; real_cap_ref (obj_id, slot) spec; real_cap_ref (obj_id', slot') spec; opt_cap (obj_id, slot) spec = Some cap; opt_cap (obj_id', slot') spec = Some cap'; cap_has_object cap; cap_has_object cap'; cap_object cap = cap_object cap'\ \ obj_id = obj_id' \ slot = slot'" by (clarsimp simp: well_formed_def well_formed_orig_caps_unique_def real_cap_ref_def) lemma well_formed_irqhandler_caps_unique: "\well_formed s; is_irqhandler_cap cap; is_irqhandler_cap cap'; opt_cap (obj_id, slot) s = Some cap; opt_cap (obj_id', slot') s = Some cap'; cap_irq cap = cap_irq cap'\ \ obj_id = obj_id' \ slot = slot'" by (clarsimp simp: well_formed_def well_formed_irqhandler_caps_unique_def) lemma object_cap_ref_cap_irq: "\object_cap_ref (obj_id, slot) spec; opt_cap (obj_id, slot) spec = Some cap\ \ cap_irq cap = undefined" by (auto simp: object_cap_ref_def cap_has_object_def cap_irq_def split: cdl_cap.splits) lemma object_cap_ref_real_cap_ref: "object_cap_ref (obj_id, slot) spec \ real_cap_ref (obj_id, slot) spec" by (clarsimp simp: object_cap_ref_def real_cap_ref_def) lemma well_formed_orig_caps_unique_object_cap: "\well_formed spec; original_cap_at (obj_id, slot) spec; original_cap_at (obj_id', slot') spec; object_cap_ref (obj_id, slot) spec; object_cap_ref (obj_id', slot') spec; opt_cap (obj_id, slot) spec = Some cap; opt_cap (obj_id', slot') spec = Some cap'; cap_has_object cap; cap_has_object cap'; cap_object cap = cap_object cap'\ \ obj_id = obj_id' \ slot = slot'" apply (frule object_cap_ref_real_cap_ref, drule (1) object_cap_ref_cap_irq)+ apply (erule (8) well_formed_orig_caps_unique', simp) done lemma well_formed_child_cap_not_copyable: "\well_formed spec; \ original_cap_at (obj_id, slot) spec; opt_cap (obj_id, slot) spec = Some cap; cap \ NullCap\ \ is_copyable_cap cap" apply (clarsimp simp: well_formed_def) apply (erule_tac x=obj_id in allE) apply (clarsimp simp: opt_cap_def opt_object_def slots_of_def) apply (clarsimp split: option.splits) apply (rename_tac obj) apply (clarsimp simp: well_formed_caps_def) done lemma well_formed_child_cap_not_copyable': "\well_formed spec; opt_cap (obj_id, slot) spec = Some cap; cap \ NullCap\ \ \original_cap_at (obj_id, slot) spec \ is_copyable_cap cap" by (rule impI, erule (3) well_formed_child_cap_not_copyable) lemma well_formed_pd: "\well_formed spec; opt_cap (obj_id, slot) spec = Some cap; pd_at obj_id spec; cap \ NullCap\ \ is_frame_cap cap \ is_fake_pt_cap cap" apply (clarsimp simp: object_at_def) apply (frule (1) well_formed_well_formed_vspace) apply (clarsimp simp: well_formed_vspace_def) apply (erule allE [where x=slot]) apply (erule allE [where x=cap]) apply (clarsimp simp: opt_cap_def slots_of_def opt_object_def split: option.splits) done lemma well_formed_pt: "\well_formed spec; opt_cap (obj_id, slot) spec = Some cap; pt_at obj_id spec; cap \ NullCap\ \ is_frame_cap cap" apply (clarsimp simp: object_at_def) apply (frule (1) well_formed_well_formed_vspace) apply (clarsimp simp: well_formed_vspace_def) apply (erule allE [where x=slot]) apply (erule allE [where x=cap]) apply (clarsimp simp: opt_cap_def slots_of_def opt_object_def split: option.splits) done lemma well_formed_pt_cap_is_fake_pt_cap: "\well_formed spec; opt_cap (obj_id, slot) spec = Some cap; pd_at obj_id spec; is_pt_cap cap\ \ is_fake_pt_cap cap" by (frule (2) well_formed_pd, clarsimp+) (**************************************** * Rules about IRQ caps and IRQ CNodes. * ****************************************) lemma well_formed_irq_nodes_object_type: "\well_formed spec; obj_id \ irq_nodes spec; cdl_objects spec obj_id = Some object\ \ object_type object = IRQNodeType" apply (frule (1) well_formed_well_formed_irq_node) apply (frule (2) well_formed_cap_to_irq_object) apply (clarsimp simp: opt_cap_def slots_of_def opt_object_def split: option.splits) apply (frule (2) well_formed_well_formed_cap_types_match, simp) apply (clarsimp simp: well_formed_cap_types_match_def) done lemma well_formed_object_at_irq_node_irq_node_at: "\well_formed spec; object_at P obj_id spec; obj_id \ irq_nodes spec\ \ irq_node_at obj_id spec" apply (clarsimp simp: object_at_def) apply (frule (2) well_formed_irq_nodes_object_type) apply (simp add: object_type_is_object) done lemma real_object_not_irq_node: "well_formed spec \ (real_object_at obj_id spec \ cnode_at obj_id spec) = cnode_at obj_id spec" "well_formed spec \ (real_object_at obj_id spec \ tcb_at obj_id spec) = tcb_at obj_id spec" "well_formed spec \ (real_object_at obj_id spec \ table_at obj_id spec) = table_at obj_id spec" "well_formed spec \ (real_object_at obj_id spec \ capless_at obj_id spec) = capless_at obj_id spec" apply (insert well_formed_object_at_irq_node_irq_node_at [where spec=spec and obj_id=obj_id]) apply (fastforce simp: real_object_at_def object_at_def object_type_is_object)+ done lemma object_at_real_object_at: "\well_formed spec; cnode_at obj_id spec\ \ real_object_at obj_id spec" "\well_formed spec; tcb_at obj_id spec\ \ real_object_at obj_id spec" "\well_formed spec; ep_at obj_id spec\ \ real_object_at obj_id spec" "\well_formed spec; ntfn_at obj_id spec\ \ real_object_at obj_id spec" "\well_formed spec; table_at obj_id spec\ \ real_object_at obj_id spec" "\well_formed spec; pd_at obj_id spec\ \ real_object_at obj_id spec" "\well_formed spec; pt_at obj_id spec\ \ real_object_at obj_id spec" "\well_formed spec; frame_at obj_id spec\ \ real_object_at obj_id spec" apply (insert well_formed_object_at_irq_node_irq_node_at [where spec=spec and obj_id=obj_id]) apply (fastforce simp: real_object_at_def object_at_def object_type_is_object)+ done lemma well_formed_irq_node_slot_0: "\well_formed spec; irq_id \ irq_nodes spec; opt_cap (irq_id, slot) spec = Some cap\ \ slot = 0" apply (frule opt_cap_cdl_objects, clarsimp) apply (frule (1) well_formed_well_formed_irq_node) apply (frule (1) object_slots_opt_cap, simp) apply (simp add: well_formed_irq_node_def dom_def, blast) done lemma well_formed_irq_nodes_cdl_irq_node: "cdl_irq_node spec irq \ irq_nodes spec \ irq_node_at (cdl_irq_node spec irq) spec" by (simp add: irq_nodes_def) lemma well_formed_cdl_irq_node_irq_nodes: "\well_formed spec; cdl_objects spec (cdl_irq_node spec irq) = Some irq_node\ \ cdl_irq_node spec irq \ irq_nodes spec" apply (drule well_formed_well_formed_irq_table) apply (clarsimp simp: well_formed_irq_table_def) apply (fastforce simp: object_at_def) done lemma well_formed_irq_is_irq_node: "\well_formed spec; cdl_objects spec (cdl_irq_node spec irq) = Some irq_node\ \ is_irq_node irq_node" apply (frule (1) well_formed_cdl_irq_node_irq_nodes) apply (clarsimp simp: irq_nodes_def object_at_def) done lemma well_formed_object_slots_irq_node: "\well_formed spec; cdl_objects spec (cdl_irq_node spec irq) = Some irq_node\ \ dom (object_slots irq_node) = {0}" apply (frule (1) well_formed_cdl_irq_node_irq_nodes) apply (frule (1) well_formed_well_formed_irq_node) apply (clarsimp simp: well_formed_irq_node_def) done lemma well_formed_irq_ntfn_cap: "\well_formed spec; irq \ bound_irqs spec; opt_cap (cdl_irq_node spec irq, 0) spec = Some ntfn_cap\ \ ntfn_cap = NotificationCap (cap_object ntfn_cap) 0 {AllowRead, AllowWrite}" apply (frule opt_cap_cdl_objects, clarsimp) apply (frule (1) well_formed_object_slots_irq_node [where irq=irq]) apply (frule (1) well_formed_well_formed_irq_node) apply (frule (1) well_formed_cdl_irq_node_irq_nodes) apply (clarsimp simp: well_formed_irq_node_def) apply (erule allE [where x=0]) apply (erule allE [where x=ntfn_cap]) apply (fastforce simp: bound_irqs_def opt_cap_def slots_of_def opt_object_def is_default_cap_def default_cap_def cap_object_def cap_has_object_def split: cdl_cap.splits) done lemma well_formed_bound_irqs_are_used_irqs: "well_formed spec \ bound_irqs spec \ used_irqs spec" apply (frule well_formed_well_formed_irqhandler_caps) apply (fastforce simp: well_formed_irqhandler_caps_def used_irqs_def bound_irqs_def all_caps_def) done lemma well_formed_slots_of_used_irq_node: "\well_formed spec; irq \ used_irqs spec\ \ dom (slots_of (cdl_irq_node spec irq) spec) = {0}" apply (clarsimp simp: used_irqs_def slots_of_def opt_object_def split: option.splits) apply (frule (2) well_formed_all_caps_cap_irq, clarsimp) apply (erule (1) well_formed_object_slots_irq_node) done lemma well_formed_slot_0_of_used_irq_node: "\well_formed spec; irq \ used_irqs spec\ \ \ntfn_cap. slots_of (cdl_irq_node spec irq) spec 0 = Some ntfn_cap" apply (frule (1) well_formed_slots_of_used_irq_node) apply (clarsimp simp: dom_eq_singleton_conv) done lemma well_formed_object_slots_default_irq_node: "\well_formed spec; cdl_objects spec (cdl_irq_node spec irq) = Some irq_node\ \ dom (object_slots (object_default_state irq_node)) = {0}" by (metis well_formed_object_slots well_formed_object_slots_irq_node) lemma object_slots_empty_cnode: "object_slots (CNode (empty_cnode sz)) = empty_cap_map sz" by (clarsimp simp: object_slots_def empty_cnode_def) lemma dom_empty_cap_map_singleton: "dom (empty_cap_map (sz)) = {0} \ sz = 0" apply (clarsimp simp: empty_cap_map_def) apply (subst (asm) atLeastLessThan_singleton [symmetric]) apply (drule atLeastLessThan_inj(2), simp+) done lemma well_formed_size_irq_node: "\well_formed spec; cdl_objects spec (cdl_irq_node spec irq) = Some irq_node\ \ object_size_bits irq_node = 0" apply (frule (1) well_formed_irq_is_irq_node) apply (frule (1) well_formed_object_slots) apply (drule (1) well_formed_object_slots_default_irq_node) apply (clarsimp simp: object_default_state_def2 is_cnode_def object_slots_empty_cnode object_size_bits_def dom_empty_cap_map_singleton is_irq_node_def split: cdl_object.splits) done lemma well_formed_used_irqs_have_irq_node: "\well_formed spec; irq \ used_irqs spec\ \ \irq_node. cdl_objects spec (cdl_irq_node spec irq) = Some irq_node" apply (clarsimp simp: used_irqs_def) apply (erule (2) well_formed_all_caps_cap_irq) done lemma well_formed_bound_irqs_have_irq_node: "\well_formed spec; irq \ bound_irqs spec\ \ \irq_node. cdl_objects spec (cdl_irq_node spec irq) = Some irq_node" apply (frule well_formed_well_formed_irqhandler_caps) apply (clarsimp simp: well_formed_irqhandler_caps_def used_irqs_def bound_irqs_def all_caps_def) done lemma well_formed_irq_node_is_bound: "\well_formed spec; cdl_objects spec (cdl_irq_node spec irq) = Some irq_node; object_slots irq_node 0 \ Some NullCap\ \ irq \ bound_irqs spec" apply (frule well_formed_well_formed_irqhandler_caps) apply (frule (1) well_formed_object_slots_default_irq_node) apply (frule (1) well_formed_object_slots) apply (clarsimp simp: well_formed_irqhandler_caps_def bound_irqs_def dom_eq_singleton_conv slots_of_def opt_object_def) done lemma well_formed_cap_object_cdl_irq_node: "\well_formed spec; irq \ bound_irqs spec\ \ \obj. is_ntfn obj \ cdl_objects spec (cap_object (the (opt_cap (cdl_irq_node spec irq, 0) spec))) = Some obj" apply (frule well_formed_bound_irqs_are_used_irqs) apply (frule (1) well_formed_bound_irqs_have_irq_node, clarsimp) apply (frule well_formed_slot_0_of_used_irq_node [where irq=irq], fast) apply (clarsimp simp: opt_cap_def) apply (rename_tac cap) apply (frule (1) well_formed_irq_ntfn_cap, simp add: opt_cap_def) apply (frule well_formed_cap_object, simp add: opt_cap_def) apply (metis cap_has_object_simps(12)) apply clarsimp apply (frule well_formed_types_match [where obj_id = "cdl_irq_node spec irq" and slot = 0]) apply (simp add: opt_cap_def) apply simp apply (metis cap_has_object_simps(12)) apply (clarsimp simp: object_type_is_object cap_type_def split: cdl_cap.splits) done (* There are no untyped objects (as there are no untyped caps). *) lemma well_formed_object_untyped: "\well_formed spec; cdl_objects spec obj_id = Some object\ \ object_type object \ UntypedType" apply (case_tac "real_object_at obj_id spec") apply (frule (1) well_formed_cap_to_real_object) apply clarsimp apply (frule (1) well_formed_types_match, simp add: cap_has_object_def) apply (clarsimp simp: cap_has_object_def) apply (clarsimp simp: cap_type_def cap_has_object_def split: cdl_cap.splits) apply (frule (2) well_formed_is_untyped_cap) apply (clarsimp simp: cap_type_def) apply (clarsimp simp: real_object_at_def dom_def) apply (drule (2) well_formed_irq_nodes_object_type) apply simp done lemma well_formed_asidpool_at: "well_formed spec \ \ asidpool_at obj_id spec" apply (clarsimp simp: object_at_def object_type_is_object) apply (frule well_formed_cap_to_real_object [where obj_id=obj_id]) apply (clarsimp simp: real_object_at_def dom_def) apply (drule (2) well_formed_irq_nodes_object_type, simp) apply clarsimp apply (frule (2) well_formed_types_match [symmetric], clarsimp+) apply (frule (1) well_formed_well_formed_cap', clarsimp) apply (clarsimp simp: well_formed_cap_def cap_type_def split: cdl_cap.splits) done lemma well_formed_no_asidpools: "well_formed spec \ [obj \ obj_ids. asidpool_at obj spec] = []" by (clarsimp simp: filter_empty_conv well_formed_asidpool_at) lemma well_formed_fake_pt_cap_in_pd: "\well_formed spec; slots_of obj_id spec slot = Some cap; is_fake_pt_cap cap\ \ pd_at obj_id spec" apply (clarsimp simp: slots_of_def opt_object_def split: option.splits) apply (rename_tac obj) apply (frule well_formed_asidpool_at [where obj_id=obj_id]) apply (frule (1) well_formed_well_formed_vspace) apply (case_tac "is_cnode obj \ is_tcb obj \ is_irq_node obj") apply (frule (3) well_formed_is_fake_vm_cap) apply (clarsimp simp: is_fake_vm_cap_def is_fake_pt_cap_def split: cdl_cap.splits) apply clarsimp apply (clarsimp simp: object_at_def object_type_is_object) apply (case_tac obj, simp_all add: object_slots_def object_at_def object_type_is_object object_type_def) apply (clarsimp simp: well_formed_vspace_def) apply (erule allE [where x=slot]) apply (erule allE [where x=cap]) apply (clarsimp simp: is_fake_pt_cap_is_pt_cap object_slots_def) done lemma cap_has_object_cap_irq [simp]: "cap_has_object cap \ cap_irq cap = undefined" by (auto simp: cap_has_object_def cap_irq_def split: cdl_cap.splits) definition cap_at_to_real_object :: "cdl_cap_ref \ cdl_state \ bool" where "cap_at_to_real_object cap_ref s = cap_at (\cap. cap_has_object cap \ cap_object cap \ irq_nodes s) cap_ref s" (* FIXME: Why doesn't every cap pointing to an object not point to an IRQ Node? *) (* There is a bijection between objects and orig caps. *) lemma well_formed_bij: "well_formed s \ bij_betw (\cap_ref. cap_ref_object cap_ref s) {cap_ref. original_cap_at cap_ref s \ cap_at_to_real_object cap_ref s \ cnode_at (fst cap_ref) s} ((real_objects s))" apply (clarsimp simp: bij_betw_def) apply (rule conjI) apply (clarsimp simp: inj_on_def real_cap_ref_def cap_ref_object_def object_cap_ref_def cap_at_to_real_object_def cap_at_def) apply (erule_tac cap=cap and cap'=capa in well_formed_orig_caps_unique, (assumption|fastforce)+) apply (clarsimp simp: image_def) apply rule apply (clarsimp simp: real_cap_ref_def cap_ref_object_def object_cap_ref_def cap_at_to_real_object_def cap_at_def real_objects_def real_object_at_def) apply (erule (1) well_formed_cap_object, clarsimp) apply clarsimp apply (clarsimp simp: real_cap_ref_def cap_ref_object_def real_objects_def real_object_at_def) apply (frule_tac well_formed_cap_to_real_object, fastforce simp: real_object_at_def) apply (fastforce simp: cap_at_to_real_object_def cap_at_def) done lemma well_formed_irqhandler_bij: "well_formed s \ bij_betw (\cap_ref. cap_ref_irq cap_ref s) {cap_ref. irqhandler_cap_at cap_ref s} (used_irqs s)" apply (clarsimp simp: bij_betw_def) apply (rule conjI) apply (clarsimp simp: inj_on_def real_cap_ref_def cap_ref_object_def object_cap_ref_def cap_at_to_real_object_def cap_at_def) apply (erule_tac cap=cap and cap'=capa in well_formed_irqhandler_caps_unique, (assumption|clarsimp simp: cap_ref_irq_def)+) apply (fastforce simp: image_def used_irqs_def cap_ref_irq_def cap_at_def all_caps_def) done lemma fake_cap_rewrite: "well_formed spec \ Set.filter (\cap_ref. fake_pt_cap_at cap_ref spec) (SIGMA obj_id:{obj_id. pd_at obj_id spec}. dom (slots_of obj_id spec)) = {cap_ref. fake_pt_cap_at cap_ref spec}" apply (clarsimp simp: Set.filter_def cap_at_def opt_cap_def split: option.splits) apply (rule) apply clarsimp apply clarsimp apply (frule (2) well_formed_fake_pt_cap_in_pd) apply (fastforce) done lemma well_formed_fake_pt_caps_unique: "\well_formed spec; pd_at obj_id spec; pd_at obj_id' spec; opt_cap (obj_id, slot) spec = Some cap; opt_cap (obj_id', slot') spec = Some cap'; is_fake_pt_cap cap; is_fake_pt_cap cap'; cap_object cap = cap_object cap'\ \ obj_id = obj_id' \ slot = slot'" by (fastforce simp: well_formed_def well_formed_fake_pt_caps_unique_def) lemma well_formed_fake_pt_caps_unique': "\well_formed spec; pd_at obj_id spec; pd_at obj_id' spec; fake_pt_cap_at (obj_id, slot) spec; fake_pt_cap_at (obj_id', slot') spec; cap_ref_object (obj_id, slot) spec = cap_ref_object (obj_id', slot') spec\ \ obj_id = obj_id' \ slot = slot'" by (erule well_formed_fake_pt_caps_unique [where cap="the (opt_cap (obj_id, slot) spec)" and cap'="the (opt_cap (obj_id', slot') spec)"], (clarsimp simp: cap_ref_object_def cap_at_def)+) (* There is a bijection between pts and pts in pds. *) lemma well_formed_pt_cap_bij: "well_formed spec \ bij_betw (\cap_ref. cap_ref_object cap_ref spec) {(obj_id, slot). pd_at obj_id spec \ fake_pt_cap_at (obj_id, slot) spec} {obj_id. \cap. cap \ all_caps spec \ obj_id = cap_object cap \ is_fake_pt_cap cap}" apply (clarsimp simp: bij_betw_def) apply (rule conjI) apply (clarsimp simp: inj_on_def) apply (erule (5) well_formed_fake_pt_caps_unique') apply (rule) apply (clarsimp simp: cap_at_def) apply (rule_tac x=cap in exI) apply (rule conjI, clarsimp) apply (clarsimp simp: cap_ref_object_def cap_at_def) apply (clarsimp simp: image_def all_caps_def) apply (rename_tac obj_id slot) apply (rule_tac x=obj_id in exI) apply (rule conjI) apply (clarsimp simp: opt_cap_def) apply (erule (2) well_formed_fake_pt_cap_in_pd) apply (rule_tac x=slot in exI) apply (clarsimp simp: cap_ref_object_def cap_at_def) done lemma well_formed_objects_real_or_irq: "well_formed spec \ {obj_id. real_object_at obj_id spec} \ (cdl_irq_node spec ` used_irqs spec) = dom (cdl_objects spec)" apply (frule well_formed_well_formed_irqhandler_caps) apply (frule well_formed_inj_cdl_irq_node) apply (rule) apply clarsimp apply (rule conjI) apply (clarsimp simp: real_object_at_def object_at_def) apply (clarsimp simp: used_irqs_def all_caps_def opt_cap_def slots_of_def opt_object_def split: option.splits) apply (frule (2) well_formed_well_formed_cap_types_match, simp) apply (clarsimp simp: well_formed_cap_types_match_def) apply (clarsimp simp: real_object_at_def) apply (rule conjI) apply clarsimp apply clarsimp apply (frule (1) well_formed_cap_to_irq_object, simp add: irq_nodes_def) apply (fastforce simp: used_irqs_def all_caps_def dest!: injD) done lemma well_formed_objects_only_real_or_irq: "well_formed spec \ {obj_id. real_object_at obj_id spec} \ (cdl_irq_node spec ` used_irqs spec) = {}" apply (subst disjoint_iff_not_equal, clarsimp) apply (frule (1) well_formed_used_irqs_have_irq_node, clarsimp) apply (frule (1) well_formed_cdl_irq_node_irq_nodes) apply (auto simp: real_object_at_def) done lemma well_formed_objects_card: "\well_formed spec \ \ card (used_irqs spec) + card {x. real_object_at x spec} = card (dom (cdl_objects spec))" apply (frule well_formed_inj_cdl_irq_node) apply (frule well_formed_objects_real_or_irq) apply (frule well_formed_objects_only_real_or_irq) apply (subgoal_tac " card (used_irqs spec) = card (used_irq_nodes spec)", simp) apply (subst card_Un_Int, simp+) apply (metis Int_commute Nat.add_0_right Un_commute card_empty used_irq_nodes_def) by (metis card_image inj_inj_on used_irq_nodes_def) (**************************************** * Packing data into a well_formed cap. * ****************************************) lemma update_cap_rights_and_data: "\t (cap_object spec_cap) = Some client_object_id; \ is_untyped_cap spec_cap; well_formed_cap spec_cap; \ vm_cap_has_asid spec_cap; \ is_fake_vm_cap spec_cap; \ is_irqhandler_cap spec_cap; cap_type spec_cap = Some type\ \ update_cap_data_det (cap_data spec_cap) (update_cap_rights (cap_rights spec_cap) (default_cap type {client_object_id} (cnode_cap_size spec_cap))) = update_cap_object client_object_id spec_cap" apply (case_tac "\is_cnode_cap spec_cap") apply (case_tac spec_cap, simp_all add: cap_type_def, (fastforce simp: cap_data_def cap_rights_def default_cap_def update_cap_rights_def badge_update_def update_cap_badge_def update_cap_object_def update_cap_data_det_def well_formed_cap_def Word.less_mask_eq is_fake_vm_cap_def validate_vm_rights_def vm_read_write_def vm_read_only_def split: cdl_frame_cap_type.splits)+) apply (case_tac spec_cap, simp_all add: cap_type_def) apply (rename_tac word1 word2 nat1 nat2) apply (clarsimp simp: update_cap_data_det_def update_cap_rights_def default_cap_def well_formed_cap_def update_cap_object_def cap_rights_def cap_data_def cnode_cap_size_def) apply (case_tac "guard_as_rawdata (CNodeCap word1 word2 nat1 nat2) = 0") apply (clarsimp simp: guard_update_def guard_as_rawdata_def) apply (cut_tac p="word2 << 8" and d="of_nat nat1 << 3" and n=8 in is_aligned_add_or) apply (simp add: is_aligned_shiftl) apply (rule shiftl_less_t2n) apply (clarsimp simp: guard_bits_def word_of_nat_less) apply simp apply (clarsimp simp: word_or_zero) apply (drule word_shift_zero, erule less_imp_le) apply (clarsimp simp: guard_bits_def) apply (drule_tac m=8 in word_shift_zero, rule less_imp_le) apply (clarsimp simp: guard_bits_def word_of_nat_less) apply simp apply (clarsimp simp: of_nat_0 guard_bits_def word_bits_def) apply (clarsimp simp: badge_update_def cap_rights_def cap_data_def guard_update_def guard_as_rawdata_def) apply (cut_tac p="word2 << 8" and d="of_nat nat1 << 3" and n=8 in is_aligned_add_or) apply (simp add: is_aligned_shiftl) apply (rule shiftl_less_t2n) apply (clarsimp simp: guard_bits_def word_of_nat_less) apply simp apply (simp add: word_ao_dist shiftr_over_or_dist shiftl_shiftr1 word_size shiftl_mask_is_0 word_bw_assocs mask_and_mask guard_as_rawdata_def guard_update_def) apply (subst le_mask_iff[THEN iffD1]) apply (rule plus_one_helper) apply (unfold mask_plus_1) apply (rule shiftl_less_t2n) apply (clarsimp simp: guard_bits_def word_of_nat_less) apply simp apply (subst less_mask_eq) apply (subst less_mask_eq) apply (clarsimp simp: guard_bits_def word_of_nat_less) apply (subst unat_of_nat32) apply (clarsimp simp: guard_bits_def word_bits_def) apply (clarsimp simp: min_def guard_bits_def) apply simp apply (subst less_mask_eq) apply (clarsimp simp: guard_bits_def word_of_nat_less) apply (clarsimp simp: guard_bits_def word_of_nat_less word_bits_def unat_of_nat32) done lemma update_cap_data: "\t (cap_object spec_cap) = Some client_object_id; cap_type spec_cap = Some type; cap_data spec_cap = data; well_formed_cap spec_cap; \ is_untyped_cap spec_cap; \ vm_cap_has_asid spec_cap; \ is_fake_vm_cap spec_cap; \ is_irqhandler_cap spec_cap; cap_rights (default_cap type {obj_id} sz) = cap_rights spec_cap\ \ update_cap_data_det data (default_cap type {client_object_id} (cnode_cap_size spec_cap)) = update_cap_object client_object_id spec_cap" apply (frule (6) update_cap_rights_and_data) apply clarsimp apply (subgoal_tac "update_cap_rights (cap_rights spec_cap) (default_cap type {client_object_id} (cnode_cap_size spec_cap)) = default_cap type {client_object_id} (cnode_cap_size spec_cap)") apply clarsimp apply (subst well_formed_update_cap_rights_idem) apply (erule (1) default_cap_well_formed_cap, simp) apply (subst cap_rights_default_cap_eq, fast) apply simp done end