(* * Copyright 2014, NICTA * * This software may be distributed and modified according to the terms of * the GNU General Public License version 2. Note that NO WARRANTY is provided. * See "LICENSE_GPLv2.txt" for details. * * @TAG(NICTA_GPL) *) theory InitTCB_SI imports "../proof/capDL-api/KHeap_DP" "../proof/capDL-api/TCB_DP" ObjectInitialised_SI RootTask_SI SysInit_SI begin lemma cap_has_type_cap_has_object [simp]: "\cap_has_type cap; \ is_irqhandler_cap cap\ \ cap_has_object cap" by (clarsimp simp: cap_type_def cap_has_object_def split: cdl_cap.splits) lemma tcb_empty_decomp: "is_tcb obj \ (obj_id \o object_default_state obj) = (obj_id \f Tcb (default_tcb (object_domain obj)) \* (obj_id, tcb_cspace_slot) \c NullCap \* (obj_id, tcb_vspace_slot) \c NullCap \* (obj_id, tcb_ipcbuffer_slot) \c NullCap \* (obj_id, tcb_replycap_slot) \c NullCap \* (obj_id, tcb_caller_slot) \c NullCap \* (obj_id, tcb_pending_op_slot) \c NullCap \* (obj_id, tcb_boundntfn_slot) \c NullCap \* obj_id \E Tcb (default_tcb (object_domain obj)))" apply (rule ext, rename_tac s) apply (clarsimp simp: is_tcb_def object_default_state_def2) apply (case_tac obj, simp_all) apply (subst sep_map_o_decomp) apply (subst sep_map_S_decomp_list [where slots = "[0 .e. tcb_boundntfn_slot]"]) apply (force simp: default_tcb_def object_slots_def) apply clarsimp apply (clarsimp simp: sep_list_conj_def default_tcb_slots object_domain_def tcb_slot_defs) apply (subst sep_map_s_sep_map_c_eq, simp add: default_tcb_def object_slots_def tcb_boundntfn_slot_def, clarsimp simp: sep_conj_ac)+ done lemma tcb_decomp': "\well_formed spec; cdl_objects spec obj_id = Some obj; is_tcb obj; opt_cap (obj_id, tcb_cspace_slot) spec = Some cspace_cap; opt_cap (obj_id, tcb_vspace_slot) spec = Some vspace_cap; opt_cap (obj_id, tcb_ipcbuffer_slot) spec = Some buffer_frame_cap; opt_cap (obj_id, tcb_replycap_slot) spec = Some reply_cap; opt_cap (obj_id, tcb_pending_op_slot) spec = Some pending_cap; opt_cap (obj_id, tcb_boundntfn_slot) spec = Some bound_cap\ \ (k_obj_id \o spec2s t obj) = (k_obj_id \f obj \* (k_obj_id, tcb_cspace_slot) \c cap_transform t cspace_cap \* (k_obj_id, tcb_vspace_slot) \c cap_transform t vspace_cap \* (k_obj_id, tcb_ipcbuffer_slot) \c cap_transform t buffer_frame_cap \* (k_obj_id, tcb_replycap_slot) \c cap_transform t reply_cap \* (k_obj_id, tcb_caller_slot) \c NullCap \* (k_obj_id, tcb_pending_op_slot) \c cap_transform t pending_cap \* (k_obj_id, tcb_boundntfn_slot) \c cap_transform t bound_cap \* k_obj_id \E Tcb (default_tcb minBound))" apply (frule (1) well_formed_object_slots) apply (frule (1) well_formed_object_domain) apply (frule well_formed_tcb_caller_cap [where obj_id=obj_id], simp add: object_at_def) apply (clarsimp simp: is_tcb_def object_domain_def object_default_state_def2) apply (case_tac obj, simp_all) apply (subst sep_map_o_decomp) apply (subst sep_map_S_decomp_list [where slots = "[0 .e. tcb_boundntfn_slot]"]) apply (drule (1) well_formed_object_slots, simp add: foo) apply (force simp: object_default_state_def2 default_tcb_def object_slots_def split: cdl_object.splits) apply clarsimp apply (clarsimp simp: sep_list_conj_def default_tcb_slots tcb_slot_defs) apply (drule_tac obj'="Tcb (default_tcb minBound)" and p = k_obj_id in sep_map_E_eq [rotated], simp add: object_type_def) apply (subst sep_map_s_sep_map_c_eq, rule object_slots_spec2s', fastforce simp: opt_cap_def slots_of_def object_slots_def opt_object_def)+ apply (clarsimp simp: sep_conj_ac) done lemma tcb_half_decomp': "\well_formed spec; cdl_objects spec obj_id = Some obj; is_tcb obj; opt_cap (obj_id, tcb_cspace_slot) spec = Some cspace_cap; opt_cap (obj_id, tcb_vspace_slot) spec = Some vspace_cap; opt_cap (obj_id, tcb_ipcbuffer_slot) spec = Some buffer_frame_cap\ \ (k_obj_id \o spec2s t (tcb_half spec obj)) = (k_obj_id \f obj \* (k_obj_id, tcb_cspace_slot) \c cap_transform t cspace_cap \* (k_obj_id, tcb_vspace_slot) \c cap_transform t vspace_cap \* (k_obj_id, tcb_ipcbuffer_slot) \c cap_transform t buffer_frame_cap \* (k_obj_id, tcb_replycap_slot) \c NullCap \* (k_obj_id, tcb_caller_slot) \c NullCap \* (k_obj_id, tcb_pending_op_slot) \c NullCap \* (k_obj_id, tcb_boundntfn_slot) \c NullCap \* k_obj_id \E Tcb (default_tcb minBound))" apply (frule (1) well_formed_object_slots) apply (frule (1) well_formed_object_domain) apply (frule well_formed_tcb_replycap_cap [where obj_id=obj_id], simp add: object_at_def) apply (frule well_formed_tcb_caller_cap [where obj_id=obj_id], simp add: object_at_def) apply (frule well_formed_tcb_pending_op_cap [where obj_id=obj_id], simp add: object_at_def) apply (frule well_formed_tcb_boundntfn_cap [where obj_id=obj_id], simp add: object_at_def) apply (clarsimp simp: is_tcb_def object_domain_def object_default_state_def2) apply (case_tac obj, simp_all) apply (subst sep_map_o_decomp) apply (subst sep_map_S_decomp_list [where slots = "[0 .e. tcb_boundntfn_slot]"]) apply (drule (1) well_formed_object_slots, simp add: foo) apply (force simp: object_default_state_def2 default_tcb_def object_slots_def split: cdl_object.splits) apply clarsimp apply (clarsimp simp: sep_list_conj_def default_tcb_slots tcb_slot_defs) apply (drule_tac obj'="Tcb (default_tcb minBound)" and p = k_obj_id in sep_map_E_eq [rotated], simp add: object_type_def) apply (subst sep_map_s_sep_map_c_eq, rule object_slots_spec2s', simp add: object_slots_tcb_half tcb_slot_defs, fastforce simp: opt_cap_def slots_of_def object_slots_def opt_object_def)+ apply (clarsimp simp: sep_conj_ac) done lemma tcb_decomp [simplified]: "\well_formed spec; cdl_objects spec obj_id = Some obj; is_tcb obj\ \ (k_obj_id \o spec2s t obj) = (k_obj_id \f obj \* (k_obj_id, tcb_cspace_slot) \c cap_transform t (the $ opt_cap (obj_id, tcb_cspace_slot) spec) \* (k_obj_id, tcb_vspace_slot) \c cap_transform t (the $ opt_cap (obj_id, tcb_vspace_slot) spec) \* (k_obj_id, tcb_ipcbuffer_slot) \c cap_transform t (the $ opt_cap (obj_id, tcb_ipcbuffer_slot) spec) \* (k_obj_id, tcb_replycap_slot) \c cap_transform t (the $ opt_cap (obj_id, tcb_replycap_slot) spec) \* (k_obj_id, tcb_caller_slot) \c NullCap \* (k_obj_id, tcb_pending_op_slot) \c cap_transform t (the $ opt_cap (obj_id, tcb_pending_op_slot) spec) \* (k_obj_id, tcb_boundntfn_slot) \c cap_transform t (the $ opt_cap (obj_id, tcb_boundntfn_slot) spec) \* k_obj_id \E Tcb (default_tcb minBound))" apply (simp add: is_tcb_obj_type) apply (frule (1) object_type_object_at) apply (frule (1) well_formed_tcb_cspace_cap) apply (frule (1) well_formed_tcb_vspace_cap) apply (frule (1) well_formed_tcb_ipcbuffer_cap) apply (frule (1) well_formed_tcb_replycap_cap) apply (frule (1) well_formed_tcb_caller_cap) apply (frule (1) well_formed_tcb_pending_op_cap) apply (frule (1) well_formed_tcb_boundntfn_cap) apply clarsimp apply (subst tcb_decomp' [where cspace_cap = "the $ opt_cap (obj_id, tcb_cspace_slot) spec" and vspace_cap = "the $ opt_cap (obj_id, tcb_vspace_slot) spec" and buffer_frame_cap = "the $ opt_cap (obj_id, tcb_ipcbuffer_slot) spec" and reply_cap = "the $ opt_cap (obj_id, tcb_replycap_slot) spec" and pending_cap = "the $ opt_cap (obj_id, tcb_pending_op_slot) spec" and bound_cap = "the $ opt_cap (obj_id, tcb_boundntfn_slot) spec"], (fastforce simp: is_tcb_obj_type)+) done lemma tcb_half_decomp [simplified]: "\well_formed spec; cdl_objects spec obj_id = Some obj; is_tcb obj\ \ (k_obj_id \o spec2s t (tcb_half spec obj)) = (k_obj_id \f obj \* (k_obj_id, tcb_cspace_slot) \c cap_transform t (the $ opt_cap (obj_id, tcb_cspace_slot) spec) \* (k_obj_id, tcb_vspace_slot) \c cap_transform t (the $ opt_cap (obj_id, tcb_vspace_slot) spec) \* (k_obj_id, tcb_ipcbuffer_slot) \c cap_transform t (the $ opt_cap (obj_id, tcb_ipcbuffer_slot) spec) \* (k_obj_id, tcb_replycap_slot) \c NullCap \* (k_obj_id, tcb_caller_slot) \c NullCap \* (k_obj_id, tcb_pending_op_slot) \c NullCap \* (k_obj_id, tcb_boundntfn_slot) \c NullCap \* k_obj_id \E Tcb (default_tcb minBound))" apply (simp add: is_tcb_obj_type) apply (frule (1) object_type_object_at) apply (frule (1) well_formed_tcb_cspace_cap) apply (frule (1) well_formed_tcb_vspace_cap) apply (frule (1) well_formed_tcb_ipcbuffer_cap) apply (frule (1) well_formed_tcb_replycap_cap) apply (frule (1) well_formed_tcb_caller_cap) apply (frule (1) well_formed_tcb_pending_op_cap) apply clarsimp apply (subst tcb_half_decomp' [where cspace_cap = "the $ opt_cap (obj_id, tcb_cspace_slot) spec" and vspace_cap = "the $ opt_cap (obj_id, tcb_vspace_slot) spec" and buffer_frame_cap = "the $ opt_cap (obj_id, tcb_ipcbuffer_slot) spec"], (fastforce simp: is_tcb_obj_type)+) done lemma default_cap_size_0: "type \ CNodeType \ default_cap type obj_id sz dev = default_cap type obj_id 0 dev" by (clarsimp simp: default_cap_def split: cdl_object_type.splits) lemma tcb_configure_pre: "\well_formed spec; tcb_at obj_id spec; opt_cap (obj_id, tcb_cspace_slot) spec = Some cspace_cap; opt_cap (obj_id, tcb_vspace_slot) spec = Some vspace_cap; opt_cap (obj_id, tcb_ipcbuffer_slot) spec = Some buffer_frame_cap; cap_object cspace_cap = cspace_id; cap_object vspace_cap = vspace_id; cap_object buffer_frame_cap = buffer_frame_id; cdl_objects spec cspace_id = Some spec_cnode; object_size_bits spec_cnode = cnode_size; cap_type buffer_frame_cap = Some buffer_frame_type; orig_caps obj_id = Some tcb_index; orig_caps cspace_id = Some cspace_index; orig_caps vspace_id = Some vspace_index; orig_caps buffer_frame_id = Some buffer_frame_index; t obj_id = Some k_obj_id; t cspace_id = Some cspace_kobj_id; t vspace_id = Some vspace_kobj_id; t buffer_frame_id = Some buffer_frame_kobj_id; tcb_slot = offset tcb_index si_cnode_size; cspace_slot = offset cspace_index si_cnode_size; vspace_slot = offset vspace_index si_cnode_size; buffer_frame_slot = offset buffer_frame_index si_cnode_size; tcb_cap = default_cap TcbType {k_obj_id} 0 False; k_cspace_cap = default_cap CNodeType {cspace_kobj_id} cnode_size False; k_vspace_cap = default_cap PageDirectoryType {vspace_kobj_id} 0 False; k_buffer_frame_cap = default_cap buffer_frame_type {buffer_frame_kobj_id} 0 False; \object_empty spec t obj_id \* si_cap_at t orig_caps spec False obj_id \* si_cap_at t orig_caps spec False cspace_id \* si_cap_at t orig_caps spec False vspace_id \* si_cap_at t orig_caps spec False buffer_frame_id \* si_objects \* R\ s\ \ \si_tcb_id \f root_tcb \* (si_tcb_id, tcb_pending_op_slot) \c RunningCap \* (* Root CNode. *) si_cnode_id \f CNode (empty_cnode si_cnode_size) \* (* Cap to the root CNode. *) (si_tcb_id, tcb_cspace_slot) \c si_cspace_cap \* (* Cap that the root task has to it's own CNode. *) (si_cnode_id, unat seL4_CapInitThreadCNode) \c si_cnode_cap \* (* IRQ control cap *) (si_cnode_id, unat seL4_CapIRQControl) \c IrqControlCap \* (* ASID caps. *) si_asid \* (* Client TCB. *) k_obj_id \f Tcb (default_tcb minBound) \* (* Cap to the client TCB. *) (si_cnode_id, tcb_slot) \c tcb_cap \* (* Caps to install in the TCB *) (si_cnode_id, cspace_slot) \c k_cspace_cap \* (si_cnode_id, vspace_slot) \c k_vspace_cap \* (si_cnode_id, buffer_frame_slot) \c k_buffer_frame_cap \* (* Caps slots in the TCB. *) (k_obj_id, tcb_cspace_slot) \c NullCap \* (k_obj_id, tcb_vspace_slot) \c NullCap \* (k_obj_id, tcb_ipcbuffer_slot) \c NullCap \* (k_obj_id, tcb_replycap_slot) \c NullCap \* (k_obj_id, tcb_caller_slot) \c NullCap \* (k_obj_id, tcb_pending_op_slot) \c NullCap \* (k_obj_id, tcb_boundntfn_slot) \c NullCap \* k_obj_id \E Tcb (default_tcb minBound) \* R\ s" apply clarsimp apply (frule (1) well_formed_tcb_cspace_cap) apply (frule (1) well_formed_tcb_vspace_cap) apply (frule (1) well_formed_tcb_ipcbuffer_cap) apply (clarsimp simp: object_empty_def object_initialised_general_def) apply (clarsimp simp: si_objects_def) apply (clarsimp simp: sep_conj_exists sep_conj_assoc) apply (clarsimp simp: si_cap_at_def sep_conj_assoc sep_conj_exists) apply (clarsimp simp: object_at_def) apply (subst (asm) tcb_empty_decomp, assumption) apply (subst offset_slot', assumption)+ apply (frule (1) well_formed_object_domain [where obj_id=obj_id]) apply (frule (2) well_formed_types_match [where cap=cspace_cap], clarsimp) apply (frule (2) well_formed_types_match [where cap=vspace_cap], clarsimp) apply (frule (2) well_formed_types_match [where cap=buffer_frame_cap], clarsimp simp: cap_type_def) apply (clarsimp simp: object_type_is_object) apply (subst (asm) (2) default_cap_size_0 [where type=TcbType], simp) apply (subst (asm) (2) default_cap_size_0 [where type=PageDirectoryType], simp) apply (cut_tac type="FrameType sz" and sz="(object_size_bits obja)" and dev=False and obj_id="{buffer_frame_kobj_id}" in default_cap_size_0, simp+) apply sep_solve done (* Replace well_formed_cnode_object_size_bits_eq with this one. *) lemma well_formed_cnode_object_size_bits_eq2: "\well_formed spec; cdl_objects spec obj_id = Some spec_obj; cdl_objects spec (cap_object cap) = Some obj; cap_type cap = Some CNodeType; object_slots spec_obj slot = Some cap\ \ object_size_bits obj = cnode_cap_size cap" apply (erule well_formed_cnode_object_size_bits_eq [where slot="(obj_id,slot)"]) apply (clarsimp simp: opt_cap_def slots_of_def opt_object_def split: option.splits) apply (clarsimp simp: opt_object_def split: option.splits) apply assumption done lemma default_cap_update_cap_object_non_cnode: "\cap_type cap = Some type; is_default_cap cap; cnode_cap_size cap \ 32; type \ UntypedType; type \ AsidPoolType; type \ CNodeType; type \ IRQNodeType; dev = (is_device_cap cap)\ \ default_cap type {obj_id} sz dev = update_cap_object obj_id cap" apply (frule (5) default_cap_update_cap_object [where obj_id=obj_id]) apply (subst default_cap_size_0, simp+) done lemma sep_map_f_eq_tcb_fault_endpoint: "\\ cdl_tcb_has_fault tcb; cdl_tcb_domain tcb = minBound\ \ obj_id \f Tcb (update_tcb_fault_endpoint (cdl_tcb_fault_endpoint tcb) (default_tcb minBound)) = obj_id \f Tcb tcb" apply (rule sep_map_f_eq_tcb) apply (clarsimp simp: update_tcb_fault_endpoint_def) apply (clarsimp simp: update_tcb_fault_endpoint_def default_tcb_def) apply (clarsimp simp: update_tcb_fault_endpoint_def default_tcb_def) done lemma cnode_not_device[simp]: "is_cnode_cap spec_cspace_cap \ \ is_device_cap spec_cspace_cap" by (auto simp: is_device_cap_def split: cdl_cap.splits) lemma well_formed_nondevice_cap_in_tcb: "\well_formed spec;cdl_objects spec obj_id = Some (Tcb spec_tcb)\ \ \ cap_at (\c. is_device_cap c) (obj_id, slot) spec" by (simp add: well_formed_def) lemma tcb_configure_post: "\well_formed spec; tcb_at obj_id spec; cdl_objects spec obj_id = Some (Tcb spec_tcb); opt_cap (obj_id, tcb_cspace_slot) spec = Some spec_cspace_cap; opt_cap (obj_id, tcb_vspace_slot) spec = Some spec_vspace_cap; opt_cap (obj_id, tcb_ipcbuffer_slot) spec = Some spec_buffer_frame_cap; cap_object spec_cspace_cap = cspace_id; cap_object spec_vspace_cap = vspace_id; cap_object spec_buffer_frame_cap = buffer_frame_id; cdl_objects spec cspace_id = Some spec_cnode; object_size_bits spec_cnode = cnode_size; cap_type spec_buffer_frame_cap = Some buffer_frame_type; cap_data spec_cspace_cap = cspace_cap_data; cap_data spec_vspace_cap = vspace_cap_data; cspace_cap = default_cap CNodeType {cspace_kobj_id} cnode_size False; vspace_cap = default_cap PageDirectoryType {vspace_kobj_id} 0 False; buffer_frame_cap = default_cap buffer_frame_type {buffer_frame_kobj_id} 0 False; orig_caps obj_id = Some tcb_index; orig_caps cspace_id = Some cspace_index; orig_caps vspace_id = Some vspace_index; orig_caps buffer_frame_id = Some buffer_frame_index; t obj_id = Some k_obj_id; t cspace_id = Some cspace_kobj_id; t vspace_id = Some vspace_kobj_id; t buffer_frame_id = Some buffer_frame_kobj_id; cdl_tcb_fault_endpoint new_tcb = cdl_tcb_fault_endpoint spec_tcb; cdl_tcb_has_fault new_tcb = cdl_tcb_has_fault spec_tcb; tcb_index < 2 ^ si_cnode_size; cspace_index < 2 ^ si_cnode_size; vspace_index < 2 ^ si_cnode_size; buffer_frame_index < 2 ^ si_cnode_size; \si_tcb_id \f root_tcb \* (si_tcb_id, tcb_pending_op_slot) \c RunningCap \* (si_tcb_id, tcb_cspace_slot) \c si_cspace_cap \* si_cnode_id \f CNode (empty_cnode si_cnode_size) \* (si_cnode_id, unat seL4_CapInitThreadCNode) \c si_cnode_cap \* (si_cnode_id, offset tcb_index si_cnode_size) \c default_cap TcbType {k_obj_id} 0 False \* (si_cnode_id, offset cspace_index si_cnode_size) \c default_cap CNodeType {cspace_kobj_id} cnode_size False \* (si_cnode_id, offset vspace_index si_cnode_size) \c default_cap PageDirectoryType {vspace_kobj_id} 0 False \* (si_cnode_id, offset buffer_frame_index si_cnode_size) \c buffer_frame_cap \* (si_cnode_id, unat seL4_CapIRQControl) \c IrqControlCap \* si_asid \* k_obj_id \f Tcb (update_tcb_fault_endpoint (cdl_tcb_fault_endpoint spec_tcb) (default_tcb minBound)) \* (k_obj_id, tcb_cspace_slot) \c update_cap_data_det cspace_cap_data (default_cap CNodeType {cspace_kobj_id} cnode_size False) \* (k_obj_id, tcb_vspace_slot) \c default_cap PageDirectoryType {vspace_kobj_id} 0 False \* (k_obj_id, tcb_ipcbuffer_slot) \c buffer_frame_cap \* (k_obj_id, tcb_replycap_slot) \c NullCap \* (k_obj_id, tcb_caller_slot) \c NullCap \* (k_obj_id, tcb_pending_op_slot) \c NullCap \* (k_obj_id, tcb_boundntfn_slot) \c NullCap \* k_obj_id \E Tcb (default_tcb minBound) \* R\ s\ \ \tcb_half_initialised spec t obj_id \* si_cap_at t orig_caps spec False obj_id \* si_cap_at t orig_caps spec False cspace_id \* si_cap_at t orig_caps spec False vspace_id \* si_cap_at t orig_caps spec False buffer_frame_id \* si_objects \* R\ s" apply (frule (1) well_formed_tcb_cspace_cap) apply (frule (1) well_formed_tcb_vspace_cap) apply (frule (1) well_formed_tcb_ipcbuffer_cap) apply (frule (1) well_formed_tcb_replycap_cap) apply (frule (1) well_formed_tcb_caller_cap) apply (frule (1) well_formed_tcb_pending_op_cap) apply (frule (1) well_formed_tcb_boundntfn_cap) apply (frule (1) well_formed_tcb_has_fault) apply (frule (1) well_formed_tcb_domain) apply (frule (1) well_formed_cap_object [where slot=tcb_cspace_slot], clarsimp) apply (frule (1) well_formed_cap_object [where slot=tcb_vspace_slot], clarsimp) apply (frule (1) well_formed_cap_object [where slot=tcb_ipcbuffer_slot], clarsimp simp: cap_type_def) apply (frule (1) well_formed_nondevice_cap_in_tcb[where slot = tcb_ipcbuffer_slot]) apply clarsimp apply (frule (1) well_formed_types_match [where slot=tcb_cspace_slot], fastforce+) apply (frule (1) well_formed_types_match [where slot=tcb_vspace_slot], fastforce+) apply (frule (1) well_formed_types_match [where slot=tcb_ipcbuffer_slot], (fastforce simp: cap_type_def)+) apply (clarsimp simp: tcb_half_initialised_def object_initialised_general_def) apply (clarsimp simp: si_objects_def) apply (clarsimp simp: sep_conj_exists sep_conj_assoc) apply (clarsimp simp: si_cap_at_def sep_conj_assoc sep_conj_exists) apply (clarsimp simp: object_at_def) apply (subst tcb_half_decomp' [where obj_id=obj_id and k_obj_id=k_obj_id], (assumption|simp)+) apply (subst (asm) sep_map_f_eq_tcb_fault_endpoint, assumption+) apply (clarsimp simp: opt_cap_def slots_of_def opt_object_def) apply (frule (2) well_formed_well_formed_cap [where cap=spec_cspace_cap], simp add: cap_type_null) apply (frule (2) well_formed_well_formed_cap [where cap=spec_vspace_cap], simp add: cap_type_null) apply (frule (2) well_formed_vm_cap_has_asid [where cap=spec_cspace_cap]) apply (frule (2) well_formed_vm_cap_has_asid [where cap=spec_vspace_cap]) apply (frule (1) well_formed_is_fake_vm_cap [where cap=spec_vspace_cap], simp+) apply (frule (4) well_formed_cnode_object_size_bits_eq2, simp) apply (subst (asm) update_cap_data [where spec_cap = spec_cspace_cap], (assumption|simp|fastforce dest: is_fake_vm_cap_cap_type)+) apply (subst cap_transform_update_cap_object [where obj_id="cap_object spec_cspace_cap"], (assumption|simp)+) apply (subst cap_transform_update_cap_object [where obj_id="cap_object spec_vspace_cap"], (assumption|simp)+) apply (clarsimp simp: cap_at_def opt_cap_def slots_of_def opt_object_def) apply (subst cap_transform_update_cap_object [where obj_id="cap_object spec_buffer_frame_cap"], (assumption|simp)+) apply (subst (asm) default_cap_update_cap_object_non_cnode, assumption, assumption, simp+) apply (subst (asm) default_cap_update_cap_object_non_cnode, assumption, assumption, simp+) apply (subst default_cap_update_cap_object_non_cnode, assumption, assumption, simp+) apply (subst default_cap_update_cap_object_pd [where dev =False,THEN sym], assumption, assumption, simp+) apply (cut_tac type = "FrameType sz" and obj_id = buffer_frame_kobj_id and sz = 0 in default_cap_update_cap_object_non_cnode, (assumption|simp|fastforce)+) apply (subst (asm) offset_slot', assumption)+ apply (clarsimp simp: sep_conj_assoc) apply (clarsimp simp: object_type_simps) apply (subst default_cap_size_0 [where type=TcbType], simp) apply (cut_tac type=PageDirectoryType and sz="(object_size_bits obj)" and dev = False and obj_id="{vspace_kobj_id}" in default_cap_size_0, simp+) apply (cut_tac type="FrameType sz" and sz="(object_size_bits obja)" and obj_id="{buffer_frame_kobj_id}" in default_cap_size_0, simp+) by sep_solve lemma tcb_cap_has_object [elim]: "is_tcb_cap tcb_cap \ cap_has_object tcb_cap" by (clarsimp simp: cap_type_def cap_has_object_def split: cdl_cap.splits) lemma tcb_cap_not_ep_related_cap: "is_tcb_cap tcb_cap \ \ ep_related_cap tcb_cap" by (clarsimp simp: cap_type_def ep_related_cap_def split: cdl_cap.splits) lemma tcb_cap_not_is_memory_cap: "is_tcb_cap tcb_cap \ \ is_memory_cap tcb_cap" by (clarsimp simp: cap_type_def is_memory_cap_def split: cdl_cap.splits) lemma update_cap_data_det_cnode: "is_cnode_cap cap \ update_cap_data_det data cap = guard_update cap data" by (clarsimp simp: update_cap_data_det_def cap_type_def split: cdl_cap.splits) lemma cdl_update_cnode_cap_data_non_zero: "\is_cnode_cap cap; data \ 0\ \ cdl_update_cnode_cap_data cap data = guard_update cap data" by (clarsimp simp: cdl_update_cnode_cap_data_def guard_update_def cap_type_def split: cdl_cap.splits) lemma seL4_TCB_Configure_sep: "\(* Caps point to the right objects. *) cap_object cnode_cap = cnode_id; cap_object cnode_cap' = cnode_id; cap_object tcb_cap = tcb_id; (* Caps are of the right type. *) is_tcb_cap tcb_cap; is_cnode_cap cnode_cap; is_cnode_cap cspace_cap; is_pd_cap vspace_cap; is_frame_cap buffer_frame_cap; (* Cap slots match their cptrs. *) cnode_cap_slot = offset src_root root_size; tcb_cap_slot = offset tcb_root root_size; cspace_slot = offset cspace_root root_size; vspace_slot = offset vspace_root root_size; buffer_frame_slot = offset buffer_frame_root root_size; one_lvl_lookup cnode_cap word_bits root_size; guard_equal cnode_cap tcb_root word_bits; guard_equal cnode_cap cspace_root word_bits; guard_equal cnode_cap vspace_root word_bits; guard_equal cnode_cap buffer_frame_root word_bits; is_tcb root_tcb; buffer_addr \ 0; cspace_root_data \ 0; cspace_cap' = update_cap_data_det cspace_root_data cspace_cap; new_tcb_fields = update_tcb_fault_endpoint fault_ep tcb\ \ \\s. \ si_tcb_id \f root_tcb \* (si_tcb_id, tcb_pending_op_slot) \c RunningCap \* (* Root CNode. *) cnode_id \f CNode (empty_cnode root_size) \* (* Cap to the root CNode. *) (si_tcb_id, tcb_cspace_slot) \c cnode_cap \* (* Cap that the root task has to it's own CNode. *) (cnode_id, cnode_cap_slot) \c cnode_cap' \* (* IRQ control cap *) (si_cnode_id, unat seL4_CapIRQControl) \c IrqControlCap \* (* ASID caps. *) si_asid \* (* TCB's stuff *) tcb_id \f Tcb tcb \* (* Where to copy the cap from (in the client CNode). *) (cnode_id, tcb_cap_slot) \c tcb_cap \* (cnode_id, cspace_slot) \c cspace_cap \* (cnode_id, vspace_slot) \c vspace_cap \* (cnode_id, buffer_frame_slot) \c buffer_frame_cap \* (* Cap to the TCB. *) (tcb_id, tcb_cspace_slot) \c NullCap \* (tcb_id, tcb_vspace_slot) \c NullCap \* (tcb_id, tcb_ipcbuffer_slot) \c NullCap \* R\ s\ seL4_TCB_Configure tcb_root fault_ep priority cspace_root cspace_root_data vspace_root vspace_root_data buffer_addr buffer_frame_root \\_. \si_tcb_id \f root_tcb \* (si_tcb_id, tcb_pending_op_slot) \c RunningCap \* (* Root CNode. *) cnode_id \f CNode (empty_cnode root_size) \* (* Cap to the root CNode. *) (si_tcb_id, tcb_cspace_slot) \c cnode_cap \* (* Cap that the root task has to it's own CNode. *) (cnode_id, cnode_cap_slot) \c cnode_cap' \* (* IRQ control cap *) (si_cnode_id, unat seL4_CapIRQControl) \c IrqControlCap \* (* ASID caps. *) si_asid \* (* TCB's stuff *) tcb_id \f Tcb new_tcb_fields \* (* Where to copy the cap from (in the client CNode). *) (cnode_id, tcb_cap_slot) \c tcb_cap \* (cnode_id, cspace_slot) \c cspace_cap \* (cnode_id, vspace_slot) \c vspace_cap \* (cnode_id, buffer_frame_slot) \c buffer_frame_cap \* (* Cap to the TCB. *) (tcb_id, tcb_cspace_slot) \c cspace_cap' \* (tcb_id, tcb_vspace_slot) \c vspace_cap \* (tcb_id, tcb_ipcbuffer_slot) \c buffer_frame_cap \* R\\" apply (subst (asm) update_cap_data_det_cnode, assumption) apply (rule hoare_chain) apply (wp TCB_Configure_wp [where cnode_id=cnode_id and cnode_cap=cnode_cap and tcb_id=tcb_id and tcb_cap=tcb_cap and cspace_root=cspace_root and vspace_root=vspace_root and tcb_cap_slot=tcb_cap_slot and cspace_slot=cspace_slot and vspace_slot=vspace_slot and buffer_frame_slot=buffer_frame_slot and root_size=root_size and cspace_cap=cspace_cap and vspace_cap=vspace_cap and buffer_frame_cap=buffer_frame_cap and tcb = tcb and R="(si_cnode_id, unat seL4_CapIRQControl) \c IrqControlCap \* si_asid \* R"], (fastforce simp: tcb_cap_not_ep_related_cap tcb_cap_not_is_memory_cap cdl_update_cnode_cap_data_non_zero | intro conjI | sep_cancel)+) done lemma seL4_TCB_Configure_object_initialised_sep_helper: "\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; opt_cap (obj_id, tcb_vspace_slot) spec = Some spec_vspace_cap; opt_cap (obj_id, tcb_ipcbuffer_slot) spec = Some spec_buffer_frame_cap; cap_object spec_cspace_cap = cspace_id; cap_object spec_vspace_cap = vspace_id; cap_object spec_buffer_frame_cap = buffer_frame_id; cdl_objects spec cspace_id = Some spec_cnode; object_size_bits spec_cnode = cnode_size; cap_type spec_buffer_frame_cap = Some buffer_frame_type; orig_caps obj_id = Some tcb_index; orig_caps cspace_id = Some cspace_index; orig_caps vspace_id = Some vspace_index; orig_caps buffer_frame_id = Some buffer_frame_index; t obj_id = Some k_obj_id; t cspace_id = Some cspace_kobj_id; t vspace_id = Some vspace_kobj_id; t buffer_frame_id = Some buffer_frame_kobj_id; tcb_index < 2 ^ si_cnode_size; cspace_index < 2 ^ si_cnode_size; vspace_index < 2 ^ si_cnode_size; buffer_frame_index < 2 ^ si_cnode_size; (* Put this in later once we have priorities. priority = tcb_priority tcb; tcb_ipc_buffer_address tcb = buffer_addr; *) buffer_addr \ 0; cspace_root_data = cap_data spec_cspace_cap; fault_ep = cdl_tcb_fault_endpoint tcb\ \ \\object_empty spec t obj_id \* si_cap_at t orig_caps spec False obj_id \* si_cap_at t orig_caps spec False cspace_id \* si_cap_at t orig_caps spec False vspace_id \* si_cap_at t orig_caps spec False buffer_frame_id \* si_objects \* R\\ seL4_TCB_Configure tcb_index fault_ep priority cspace_index cspace_root_data vspace_index vspace_root_data buffer_addr buffer_frame_index \\_. \tcb_half_initialised spec t obj_id \* si_cap_at t orig_caps spec False obj_id \* si_cap_at t orig_caps spec False cspace_id \* si_cap_at t orig_caps spec False vspace_id \* si_cap_at t orig_caps spec False buffer_frame_id \* si_objects \* R\\" apply (frule (1) well_formed_tcb_vspace_cap, elim exE conjE) apply (frule (1) well_formed_tcb_ipcbuffer_cap, clarsimp) apply (frule (3) well_formed_tcb_cspace_cap_cap_data) apply (frule guard_equal_si_cspace_cap' [where src_index=tcb_index]) apply (frule guard_equal_si_cspace_cap' [where src_index=cspace_index]) apply (frule guard_equal_si_cspace_cap' [where src_index=vspace_index]) apply (frule guard_equal_si_cspace_cap' [where src_index=buffer_frame_index]) apply (rule hoare_chain) prefer 2 apply (rule_tac s=s and t=t and orig_caps=orig_caps in tcb_configure_pre, (assumption|rule refl|clarsimp)+)[1] apply (cut_tac tcb="default_tcb minBound" and cnode_cap = si_cspace_cap and cnode_cap' = si_cnode_cap and tcb_cap = "default_cap TcbType {k_obj_id} 0 False" and cspace_cap = "default_cap CNodeType {cspace_kobj_id} (object_size_bits spec_cnode) False" and vspace_cap = "default_cap PageDirectoryType {vspace_kobj_id} 0 False" and buffer_frame_cap = "default_cap (FrameType sz) {buffer_frame_kobj_id} 0 False" and cspace_root = cspace_index and vspace_root = vspace_index and buffer_frame_root = buffer_frame_index and src_root = seL4_CapInitThreadCNode and root_size = si_cnode_size and cspace_root_data = "cap_data spec_cspace_cap" and R="(k_obj_id, tcb_replycap_slot) \c NullCap \* (k_obj_id, tcb_caller_slot) \c NullCap \* (k_obj_id, tcb_pending_op_slot) \c NullCap \* (k_obj_id, tcb_boundntfn_slot) \c NullCap \* k_obj_id \E Tcb (default_tcb minBound) \* R" in seL4_TCB_Configure_sep, (assumption|simp|clarsimp)+)[1] apply (erule tcb_configure_post, (assumption|simp)+) apply (sep_solve) done lemma seL4_TCB_Configure_object_initialised_sep: "\\s. well_formed spec \ cdl_objects spec obj_id = Some (Tcb tcb) \ cdl_tcb_fault_endpoint tcb = fault_ep \ opt_cap (obj_id, tcb_cspace_slot) spec = Some spec_cspace_cap \ opt_cap (obj_id, tcb_vspace_slot) spec = Some spec_vspace_cap \ opt_cap (obj_id, tcb_ipcbuffer_slot) spec = Some spec_buffer_frame_cap \ cap_object spec_cspace_cap = cspace_id \ cap_object spec_vspace_cap = vspace_id \ cap_object spec_buffer_frame_cap = buffer_frame_id \ cdl_objects spec cspace_id = Some spec_cnode \ object_size_bits spec_cnode = cnode_size \ cap_type spec_buffer_frame_cap = Some buffer_frame_type \ fault_ep = cdl_tcb_fault_endpoint tcb \ cspace_root_data = cap_data spec_cspace_cap \ buffer_addr \ 0 \ orig_caps obj_id = Some tcb_index \ orig_caps cspace_id = Some cspace_index \ orig_caps vspace_id = Some vspace_index \ orig_caps buffer_frame_id = Some buffer_frame_index \ \object_empty spec t obj_id \* si_cap_at t orig_caps spec False obj_id \* si_cap_at t orig_caps spec False cspace_id \* si_cap_at t orig_caps spec False vspace_id \* si_cap_at t orig_caps spec False buffer_frame_id \* si_objects \* R\ s\ seL4_TCB_Configure tcb_index fault_ep priority cspace_index cspace_root_data vspace_index vspace_root_data buffer_addr buffer_frame_index \\_. \tcb_half_initialised spec t obj_id \* si_cap_at t orig_caps spec False obj_id \* si_cap_at t orig_caps spec False cspace_id \* si_cap_at t orig_caps spec False vspace_id \* si_cap_at t orig_caps spec False buffer_frame_id \* si_objects \* R\\" apply (rule hoare_assume_pre) apply (elim conjE) apply (rule hoare_weaken_pre) apply (rule_tac k_obj_id = "the (t obj_id)" and cspace_kobj_id = "the (t cspace_id)" and vspace_kobj_id = "the (t vspace_id)" and buffer_frame_kobj_id = "the (t buffer_frame_id)" in seL4_TCB_Configure_object_initialised_sep_helper, (assumption|fastforce simp: object_at_def si_cap_at_def sep_conj_exists)+) done lemma init_tcb_sep': "\well_formed spec; obj_id \ set tcbs; distinct tcbs; set tcbs = {obj_id. tcb_at obj_id spec}; opt_cap (obj_id, tcb_cspace_slot) spec = Some cspace_cap; opt_cap (obj_id, tcb_vspace_slot) spec = Some vspace_cap; opt_cap (obj_id, tcb_ipcbuffer_slot) spec = Some tcb_ipcbuffer_cap; cap_object cspace_cap = cspace_id; cap_object vspace_cap = vspace_id; cdl_objects spec cspace_id = Some spec_cnode; object_size_bits spec_cnode = cnode_size; cap_type tcb_ipcbuffer_cap = Some buffer_frame_type; cap_object tcb_ipcbuffer_cap = buffer_frame_id\ \ \\object_empty spec t obj_id \* si_cap_at t orig_caps spec False obj_id \* si_cap_at t orig_caps spec False cspace_id \* si_cap_at t orig_caps spec False vspace_id \* si_cap_at t orig_caps spec False buffer_frame_id \* si_objects \* R\\ init_tcb spec orig_caps obj_id \\_.\tcb_half_initialised spec t obj_id \* si_cap_at t orig_caps spec False obj_id \* si_cap_at t orig_caps spec False cspace_id \* si_cap_at t orig_caps spec False vspace_id \* si_cap_at t orig_caps spec False buffer_frame_id \* si_objects \* R\\" apply (clarsimp) apply (subgoal_tac "\tcb. cdl_objects spec obj_id = Some (Tcb tcb)", clarsimp) apply (frule well_formed_tcb_cspace_cap, fastforce) apply (frule well_formed_tcb_vspace_cap, fastforce) apply (frule well_formed_tcb_ipcbuffer_cap, fastforce) apply (clarsimp simp: init_tcb_def) apply (wp hoare_drop_imps seL4_TCB_Configure_object_initialised_sep [where spec_cspace_cap=cspace_cap and spec_vspace_cap=vspace_cap and spec_buffer_frame_cap=tcb_ipcbuffer_cap]) apply (fastforce simp: opt_thread_def opt_object_def cap_data_def tcb_ipc_buffer_address_non_zero si_cap_at_def sep_conj_exists) apply (clarsimp simp: object_at_def is_tcb_def) apply (clarsimp split: cdl_object.splits) done lemma init_tcb_sep: "\well_formed spec; obj_id \ set tcbs; distinct tcbs; set tcbs = {obj_id. tcb_at obj_id spec}\ \ \\object_empty spec t obj_id \* si_caps_at t orig_caps spec False {obj_id. real_object_at obj_id spec} \* si_objects \* R\\ init_tcb spec orig_caps obj_id \\_.\tcb_half_initialised spec t obj_id \* si_caps_at t orig_caps spec False {obj_id. real_object_at obj_id spec} \* si_objects \* R\\" apply (frule well_formed_tcb_cspace_cap, fastforce) apply (frule well_formed_tcb_vspace_cap, fastforce) apply (frule well_formed_tcb_ipcbuffer_cap, fastforce) apply (frule well_formed_tcb_replycap_cap, fastforce) apply (frule well_formed_tcb_caller_cap, fastforce) apply (frule well_formed_tcb_pending_op_cap, fastforce) apply (clarsimp simp: si_caps_at_def) apply (frule (1) well_formed_cap_object [where slot=tcb_cspace_slot], clarsimp) apply (frule (1) well_formed_cap_object [where slot=tcb_vspace_slot], clarsimp) apply (frule (1) well_formed_cap_object [where slot=tcb_ipcbuffer_slot], clarsimp simp: cap_type_def) apply clarsimp apply (frule object_at_real_object_at, simp) apply (rule_tac xs="{obj_id, cap_object cspace_cap, cap_object vspace_cap, cap_object tcb_ipcbuffer_cap}" in sep_set_conj_subset_wp') apply (frule (2) well_formed_types_match [where slot=tcb_vspace_slot], simp+) apply (frule (2) well_formed_types_match [where slot=tcb_ipcbuffer_slot], simp+) apply (rule conjI) apply (erule object_at_real_object_at, erule (1) object_type_object_at) apply (erule object_at_real_object_at, fastforce simp: object_at_def object_type_is_object) apply clarsimp apply clarsimp apply (wp sep_wp: init_tcb_sep' [where obj_id=obj_id and tcbs=tcbs and t=t], (assumption|fastforce simp: sep_conj_ac)+) (* We can break up the sep_map_set_conj if the object ids are distinct. *) apply (subgoal_tac "distinct [obj_id, cap_object cspace_cap, cap_object vspace_cap, cap_object tcb_ipcbuffer_cap]") apply (clarsimp simp: simp: sep_conj_assoc) apply (sep_safe+, sep_solve) (* The object_ids are all distinct because they point to different types of objects. *) apply (frule (2) well_formed_types_match [where slot=tcb_cspace_slot], clarsimp) apply (frule (2) well_formed_types_match [where slot=tcb_vspace_slot], clarsimp) apply (frule (2) well_formed_types_match [where slot=tcb_ipcbuffer_slot], clarsimp simp: cap_type_def) apply clarsimp apply (fastforce simp: object_type_def object_at_def is_tcb_def split: cdl_object.splits) done lemma init_tcbs_sep_helper: "\well_formed spec; distinct tcbs; set tcbs = {obj_id \ dom (cdl_objects spec). tcb_at obj_id spec}\ \ \\objects_empty spec t {obj_id. tcb_at obj_id spec} \* si_caps_at t orig_caps spec False {obj_id. real_object_at obj_id spec} \* si_objects \* R\\ mapM_x (init_tcb spec orig_caps) tcbs \\_.\tcbs_half_initialised spec t {obj_id. tcb_at obj_id spec} \* si_caps_at t orig_caps spec False {obj_id. real_object_at obj_id spec} \* si_objects \* R\\" apply (clarsimp simp: objects_empty_def tcbs_half_initialised_def) apply (rule hoare_name_pre_state) apply (rule hoare_chain) apply (rule_tac R=R in mapM_x_set_sep [where P="\obj_id. object_empty spec t obj_id" and Q="\obj_id. tcb_half_initialised spec t obj_id" and I="si_caps_at t orig_caps spec False {obj_id. real_object_at obj_id spec} \* si_objects" and xs="tcbs", simplified sep_conj_assoc], simp+) apply (wp init_tcb_sep [where t=t and tcbs=tcbs], (assumption|simp)+) done lemma is_tcb_default_cap: "is_tcb obj \ default_cap (object_type obj) {obj_id} sz dev = TcbCap obj_id" by (clarsimp simp: default_cap_def is_tcb_obj_type) lemma configure_tcb_sep: "\\tcb_half_initialised spec t obj_id \* si_cap_at t orig_caps spec False obj_id \* si_objects \* R\ and K(well_formed spec \ obj_id \ set tcbs \ distinct tcbs \ set tcbs = {obj_id. tcb_at obj_id spec})\ configure_tcb spec orig_caps obj_id \\_.\tcb_half_initialised spec t obj_id \* si_cap_at t orig_caps spec False obj_id \* si_objects \* R\\" apply (rule hoare_gen_asm) apply (clarsimp simp: configure_tcb_def object_initialised_def tcb_half_initialised_def object_initialised_general_def si_cap_at_def si_objects_def sep_conj_exists) apply (rule hoare_vcg_ex_lift | rule hoare_grab_asm | simp)+ apply (subst tcb_half_decomp, (simp add: object_at_def)+)+ apply (wp add: hoare_drop_imps sep_wp: seL4_TCB_WriteRegisters_wp [where root_tcb = root_tcb and cnode_cap = si_cspace_cap and root_size = si_cnode_size and tcb_cap = "TcbCap (the (t obj_id))" and tcb = "spec2s t (the (cdl_objects spec obj_id))"] | simp add: guard_equal_si_cspace_cap' cap_object_simps is_tcb_default_cap)+ apply (subst offset_slot_si_cnode_size', assumption)+ apply clarsimp apply sep_solve done lemma configure_tcbs_sep: "\\tcbs_half_initialised spec t {obj_id. tcb_at obj_id spec} \* si_caps_at t orig_caps spec False {obj_id. real_object_at obj_id spec} \* si_objects \* R\ and K(well_formed spec \ distinct tcbs \ set tcbs = {obj_id \ dom (cdl_objects spec). tcb_at obj_id spec})\ mapM_x (configure_tcb spec orig_caps) tcbs \\_.\tcbs_half_initialised spec t {obj_id. tcb_at obj_id spec} \* si_caps_at t orig_caps spec False {obj_id. real_object_at obj_id spec} \* si_objects \* R\\" apply (rule hoare_gen_asm) apply (clarsimp simp: objects_empty_def tcbs_half_initialised_def) apply (rule mapM_x_set_sep' [where P="\obj_id. tcb_half_initialised spec t obj_id" and Q="\obj_id. tcb_half_initialised spec t obj_id" and I="si_caps_at t orig_caps spec False {obj_id. real_object_at obj_id spec} \* si_objects" and xs="tcbs" and X="{obj_id. tcb_at obj_id spec}" and R=R, simplified sep_conj_assoc], assumption, simp) apply (clarsimp simp: si_caps_at_def, rename_tac obj_id) apply (rule hoare_chain) apply (rule_tac x = obj_id and xs = "{obj_id. real_object_at obj_id spec}" and P = "tcb_half_initialised spec t obj_id \* si_objects" and Q = "tcb_half_initialised spec t obj_id \* si_objects" and I = "si_cap_at t orig_caps spec False" and R=R in sep_set_conj_map_singleton_wp [simplified], simp_all add: object_at_real_object_at) apply (wp sep_wp: configure_tcb_sep [where t=t and tcbs=tcbs], (simp|sep_solve)+) done lemma init_tcbs_sep: "\\objects_empty spec t {obj_id. tcb_at obj_id spec} \* si_caps_at t orig_caps spec False {obj_id. real_object_at obj_id spec} \* si_objects \* R\ and K(well_formed spec \ set obj_ids = dom (cdl_objects spec) \ distinct obj_ids)\ init_tcbs spec orig_caps obj_ids \\_.\tcbs_half_initialised spec t {obj_id. tcb_at obj_id spec} \* si_caps_at t orig_caps spec False {obj_id. real_object_at obj_id spec} \* si_objects \* R\\" apply (rule hoare_gen_asm) apply (clarsimp simp: init_tcbs_def) apply (wp configure_tcbs_sep init_tcbs_sep_helper | simp)+ done end