(* * Copyright 2014, General Dynamics C4 Systems * * This software may be distributed and modified according to the terms of * the GNU General Public License version 2. Note that NO WARRANTY is provided. * See "LICENSE_GPLv2.txt" for details. * * @TAG(GD_GPL) *) theory DetSchedAux_AI imports DetSchedInvs_AI begin context begin interpretation Arch . requalify_facts invoke_untyped_st_tcb_at end crunch_ignore (del: cap_swap_ext cap_move_ext cap_insert_ext empty_slot_ext create_cap_ext tcb_sched_action reschedule_required set_thread_state_ext switch_if_required_to attempt_switch_to timer_tick set_priority retype_region_ext) crunch_ignore (add: do_extended_op) crunch ekheap[wp]: update_cdt_list "\s. P (ekheap s)" crunch rqueues[wp]: update_cdt_list "\s. P (ready_queues s)" crunch schedact[wp]: update_cdt_list "\s. P (scheduler_action s)" crunch cur_domain[wp]: update_cdt_list "\s. P (cur_domain s)" crunch ekheap[wp]: create_cap, cap_insert "\s :: det_ext state. P (ekheap s)" (wp: crunch_wps) crunch rqueues[wp]: create_cap, cap_insert "\s :: det_ext state. P (ready_queues s)" (wp: crunch_wps) crunch schedact[wp]: create_cap, cap_insert "\s :: det_ext state. P (scheduler_action s)" (wp: crunch_wps) crunch cur_domain[wp]: create_cap, cap_insert "\s :: det_ext state. P (cur_domain s)" (wp: crunch_wps) lemma create_cap_ct[wp]: "\\s. P (cur_thread s)\ create_cap a b c d e \\r s. P (cur_thread s)\" apply (simp add: create_cap_def) apply (rule hoare_pre) apply (wp dxo_wp_weak | wpc | simp)+ done crunch valid_etcbs[wp]: create_cap,cap_insert,set_cap valid_etcbs (wp: valid_etcbs_lift set_cap_typ_at) lemma valid_etcb_fold_update: "valid_etcbs_2 ekh kh \ type \ apiobject_type.Untyped \ valid_etcbs_2 (foldr (\p ekh. ekh(p := default_ext type cdom)) ptrs ekh) (foldr (\p kh. kh(p \ default_object type dev o_bits)) ptrs kh)" apply (induct ptrs) apply simp apply (case_tac type) apply (clarsimp simp add: valid_etcbs_def st_tcb_at_kh_def obj_at_kh_def obj_at_def is_etcb_at_def default_object_def default_ext_def)+ done lemma retype_etcb_at_helper: "\etcb_at' P t ekh; valid_etcbs_2 ekh kh; d \ apiobject_type.Untyped; foldr (\p kh. kh(p \ default_object d dev c)) ptrs kh t = Some (TCB tcb); tcb_state tcb \ Inactive\ \ etcb_at' P t ((foldr (\p ekh. ekh(p := default_ext d cdom)) ptrs) ekh)" apply (induct ptrs) apply simp apply (case_tac d) apply (clarsimp split: split_if_asm simp: default_tcb_def default_object_def default_ext_def etcb_at'_def)+ done lemma retype_region_etcb_at:"\(\s. etcb_at P t s) and valid_etcbs\ retype_region a b c d dev \\r s. st_tcb_at (Not o inactive) t s \ etcb_at P t s\ " apply (simp add: retype_region_def) apply (simp add: retype_region_ext_def bind_assoc) apply wp apply (clarsimp simp add: pred_tcb_at_def obj_at_def simp del: fun_upd_apply) apply (blast intro: retype_etcb_at_helper) done lemma retype_region_valid_etcbs[wp]:"\valid_etcbs\ retype_region a b c d dev \\_. valid_etcbs\" apply (simp add: retype_region_def) apply (simp add: retype_region_ext_def bind_assoc) apply wp apply (clarsimp simp del: fun_upd_apply) apply (blast intro: valid_etcb_fold_update) done lemma typ_at_pred_tcb_at_lift: assumes typ_lift: "\P T p. \\s. P (typ_at T p s)\ f \\r s. P (typ_at T p s)\" assumes pred_lift: "\P. \pred_tcb_at proj P t\ f \\_. pred_tcb_at proj P t\" shows "\\s. \ pred_tcb_at proj P t s\ f \\r s. \ pred_tcb_at proj P t s\" apply (simp add: valid_def obj_at_def pred_tcb_at_def) apply clarsimp apply (case_tac "kheap s t") apply (cut_tac P="\x. \ x" and p=t and T="ATCB" in typ_lift) apply (simp add: valid_def obj_at_def) apply force apply (cut_tac P="\x. x" and p=t and T="a_type aa" in typ_lift) apply (cut_tac P="\t. \ P t" in pred_lift) apply (simp add: valid_def obj_at_def pred_tcb_at_def) apply (drule_tac x=s in spec) apply simp apply (drule_tac x="(a,b)" in bspec) apply simp apply simp apply (subgoal_tac "a_type aa = ATCB") apply (erule a_type_ATCBE) apply simp apply force apply simp done lemma create_cap_no_pred_tcb_at: "\\s. \ pred_tcb_at proj P t s\ create_cap apiobject_type nat' prod' dev x \\r s. \ pred_tcb_at proj P t s\" apply (rule typ_at_pred_tcb_at_lift) apply wp done lemma cap_insert_no_pred_tcb_at: "\\s. \ pred_tcb_at proj P t s\ cap_insert cap src dest \\r s. \ pred_tcb_at proj P t s\" apply (rule typ_at_pred_tcb_at_lift) apply wp done locale DetSchedAux_AI = fixes state_ext_t :: "'state_ext::state_ext itself" assumes invoke_untyped_ct[wp]: "\P i. \\s::'state_ext state. P (cur_thread s)\ invoke_untyped i \\_ s. P (cur_thread s)\" assumes invoke_untyped_idle_thread[wp]: "\P i. \\s::'state_ext state. P (idle_thread s)\ invoke_untyped i \\_ s. P (idle_thread s)\" locale DetSchedAux_AI_det_ext = DetSchedAux_AI "TYPE(det_ext)" + assumes delete_objects_etcb_at[wp]: "\P t a b. \\s::det_ext state. etcb_at P t s\ delete_objects a b \\r s. etcb_at P t s\" assumes invoke_untyped_etcb_at: "\P t ui. \(\s :: det_ext state. etcb_at P t s) and valid_etcbs\ invoke_untyped ui \\r s. st_tcb_at (Not o inactive) t s \ etcb_at P t s\ " assumes init_arch_objects_valid_etcbs[wp]: "\t r n sz refs. \valid_etcbs\ init_arch_objects t r n sz refs \\_. valid_etcbs\" assumes init_arch_objects_valid_blocked[wp]: "\t r n sz refs. \valid_blocked\ init_arch_objects t r n sz refs \\_. valid_blocked\" assumes invoke_untyped_cur_domain[wp]: "\P i. \\s. P (cur_domain s)\ invoke_untyped i \\_ s. P (cur_domain s)\" assumes invoke_untyped_ready_queues[wp]: "\P i. \\s. P (ready_queues s)\ invoke_untyped i \\_ s. P (ready_queues s)\" assumes invoke_untyped_scheduler_action[wp]: "\P i. \\s. P (scheduler_action s)\ invoke_untyped i \\_ s. P (scheduler_action s)\" lemma delete_objects_valid_etcbs[wp]: "\valid_etcbs\ delete_objects a b \\_. valid_etcbs\" apply (simp add: delete_objects_def) apply wp apply (simp add: detype_def detype_ext_def wrap_ext_det_ext_ext_def) apply (rule hoare_pre) apply (simp add: do_machine_op_def) apply (wp|wpc)+ apply (simp add: valid_etcbs_def st_tcb_at_kh_def obj_at_kh_def obj_at_def is_etcb_at_def) done lemmas mapM_x_defsym = mapM_x_def[symmetric] context DetSchedAux_AI_det_ext begin crunch valid_etcbs[wp]: invoke_untyped "valid_etcbs" (wp: preemption_point_inv' mapME_x_inv_wp crunch_wps whenE_inv simp: mapM_x_defsym crunch_simps unless_def) end crunch valid_blocked[wp]: create_cap,cap_insert,set_cap valid_blocked (wp: valid_blocked_lift set_cap_typ_at) lemma valid_blocked_fold_update: "valid_blocked_2 queues kh sa ct \ type \ apiobject_type.Untyped \ valid_blocked_2 queues (foldr (\p kh. kh(p \ default_object type dev o_bits)) ptrs kh) sa ct" apply (induct ptrs) apply simp apply (case_tac type) apply simp apply (clarsimp, clarsimp simp: valid_blocked_def st_tcb_at_kh_def obj_at_kh_def obj_at_def default_object_def default_tcb_def)+ done lemma retype_region_valid_blocked[wp]: "\valid_blocked\ retype_region a b c d dev \\_. valid_blocked\" apply (simp add: retype_region_def) apply (simp add: retype_region_ext_def bind_assoc) apply wp apply (clarsimp simp del: fun_upd_apply) apply (blast intro: valid_blocked_fold_update) done lemma delete_objects_valid_blocked[wp]: "\valid_blocked\ delete_objects a b \\_. valid_blocked\" apply (simp add: delete_objects_def) apply wp apply (simp add: detype_def detype_ext_def wrap_ext_det_ext_ext_def) apply (rule hoare_pre) apply (simp add: do_machine_op_def) apply (wp|wpc)+ apply (simp add: valid_blocked_def st_tcb_at_kh_def obj_at_kh_def obj_at_def is_etcb_at_def) done context DetSchedAux_AI_det_ext begin crunch valid_blocked[wp]: invoke_untyped "valid_blocked" (wp: preemption_point_inv' mapME_x_inv_wp crunch_wps whenE_inv simp: mapM_x_defsym crunch_simps unless_def) end (*Leverages the fact that retype only clears out inactive tcbs under the invariants*) lemma valid_sched_tcb_state_preservation: assumes st_tcb: "\P t. \I and ct_active and st_tcb_at (P and Not o inactive and Not o idle) t\ f \\_.st_tcb_at P t\" assumes stuff: "\P t. \(\s. etcb_at P t s) and valid_etcbs\ f \\r s. st_tcb_at (Not o inactive) t s \ etcb_at P t s\" assumes cur_thread: "\P. \\s. P (cur_thread s)\ f \\r s. P (cur_thread s)\" assumes idle_thread: "\P. \\s. P (idle_thread s)\ f \\r s. P (idle_thread s)\" assumes valid_etcb: "\valid_etcbs\ f \\_. valid_etcbs\" assumes valid_blocked: "\valid_blocked\ f \\_. valid_blocked\" assumes valid_idle: "\I\ f \\_. valid_idle\" assumes valid_others: "\P. \\s. P (scheduler_action s) (ready_queues s) (cur_domain s)\ f \\r s. P (scheduler_action s) (ready_queues s) (cur_domain s)\" shows "\I and ct_active and valid_sched and valid_idle\ f \\_. valid_sched\" apply (clarsimp simp add: valid_sched_def valid_def) apply (frule(1) use_valid[OF _ valid_etcb]) apply (frule(1) use_valid[OF _ valid_blocked]) apply simp apply (frule_tac P1="\sa rq cdom. rq = ready_queues s \ sa = scheduler_action s \ cdom = cur_domain s" in use_valid[OF _ valid_others]) apply simp apply (rule conjI) apply (clarsimp simp add: valid_queues_def) apply (drule_tac x=d in spec) apply (drule_tac x=p in spec) apply clarsimp apply (drule_tac x=t in bspec) apply simp apply clarsimp apply (subgoal_tac "st_tcb_at runnable t b") apply simp apply (rule conjI) apply (fastforce simp: valid_etcbs_def pred_tcb_at_def obj_at_def) apply (frule_tac P1="(\t. tcb_priority t = p \ tcb_domain t = d)" and t1=t in use_valid[OF _ stuff]) apply simp apply (simp add: pred_tcb_at_def obj_at_def) apply force apply (rule_tac use_valid[OF _ st_tcb],assumption) apply simp apply (erule pred_tcb_weakenE) apply simp apply (case_tac "itcb_state tcb") apply simp+ apply (frule_tac P1="\ct. ct = (cur_thread s)" in use_valid[OF _ cur_thread]) apply simp apply (rule conjI) apply simp apply simp apply (clarsimp simp add: valid_sched_action_def is_activatable_def weak_valid_sched_action_def) apply (rule conjI) apply clarsimp apply (frule_tac P1="active" and t1="cur_thread s" in use_valid[OF _ st_tcb]) apply (simp add: ct_in_state_def) apply (erule pred_tcb_weakenE) apply simp apply (case_tac "itcb_state tcb") apply simp+ apply (erule pred_tcb_weakenE) apply (case_tac "itcb_state tcb") apply simp+ apply (rule conjI) apply clarsimp apply (rule_tac use_valid[OF _ st_tcb],assumption) apply simp apply (erule pred_tcb_weakenE) apply simp apply (case_tac "itcb_state tcb", simp+) apply (rule conjI) apply (clarsimp simp: switch_in_cur_domain_def in_cur_domain_def) apply (rule use_valid[OF _ stuff, rule_format], assumption) apply simp apply (rule use_valid[OF _ st_tcb], assumption) apply simp apply (erule st_tcb_weakenE) apply (case_tac st, simp+) apply (clarsimp simp: ct_in_cur_domain_2_def in_cur_domain_2_def) apply (frule_tac P1="\idle. idle = (idle_thread s)" in use_valid[OF _ idle_thread], simp) apply (rule conjI) apply (rule impI) apply (simp, erule disjE, simp) apply (frule_tac P1="(\t. tcb_domain t = cur_domain s)" and t1="cur_thread s" in use_valid[OF _ stuff]) apply (clarsimp simp: etcb_at_def split: option.splits) apply clarsimp apply (erule notE, rule use_valid[OF _ st_tcb],assumption) apply (simp add: ct_in_state_def) apply (erule st_tcb_weakenE) apply simp apply (case_tac st, simp+) apply(frule (1) use_valid[OF _ valid_idle]) apply(simp add: valid_idle_etcb_def) apply(frule use_valid[OF _ stuff[where t=idle_thread_ptr]]) apply simp apply(erule mp) apply(fastforce simp: valid_idle_def pred_tcb_at_def obj_at_def) done lemma valid_idle_etcb_lift: assumes "\P t. \\s. etcb_at P t s\ f \\r s. etcb_at P t s\" shows "\valid_idle_etcb\ f \\r. valid_idle_etcb\" apply(simp add: valid_idle_etcb_def) apply(wp assms) done context DetSchedAux_AI_det_ext begin lemma invoke_untyped_valid_sched: "\invs and valid_untyped_inv ui and ct_active and valid_sched and valid_idle \ invoke_untyped ui \ \_ . valid_sched \" apply (rule hoare_pre) apply (rule_tac I="invs and valid_untyped_inv ui and ct_active" in valid_sched_tcb_state_preservation) apply (wp invoke_untyped_st_tcb_at) apply simp apply (wp invoke_untyped_etcb_at) apply (rule hoare_post_impErr, rule hoare_pre, rule invoke_untyp_invs, simp_all add: invs_valid_idle)[1] apply (rule_tac f="\s. P (scheduler_action s)" in hoare_lift_Pf) apply (rule_tac f="\s. x (ready_queues s)" in hoare_lift_Pf) apply wp apply simp done end lemmas hoare_imp_lift_something = hoare_convert_imp crunch valid_queues[wp]: create_cap,cap_insert valid_queues (wp: valid_queues_lift) crunch valid_sched_action[wp]: create_cap,cap_insert valid_sched_action (wp: valid_sched_action_lift) crunch valid_sched[wp]: create_cap,cap_insert valid_sched (wp: valid_sched_lift) end