(* * 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) *) (* Retype refinement *) theory Retype_AI imports VSpace_AI begin abbreviation "up_aligned_area ptr sz \ {ptr..(ptr && ~~ mask sz) + (2 ^ sz - 1)}" abbreviation "down_aligned_area ptr sz \ {(ptr && ~~ mask sz) + (2 ^ sz - 1) .. ptr}" context begin interpretation Arch . requalify_facts global_refs_kheap requalify_consts clearMemory clearMemoryVM end declare global_refs_kheap[simp] locale Retype_AI_clearMemoryVM = assumes clearMemoryVM_return [simp]: "\ a b. clearMemoryVM a b = return ()" context Retype_AI_clearMemoryVM begin lemmas clearMemoryVM_return_raw = clearMemoryVM_return[abs_def] end lemma upto_enum_inc_1: "a < 2^word_bits - 1 \ [(0::machine_word).e.1 + a] = [0.e.a] @ [(1+a)]" apply (simp add:upto_enum_word) apply (subgoal_tac "unat (1 +a) = 1 + unat a") apply simp apply (subst unat_plus_simple[THEN iffD1]) apply (rule word_plus_mono_right2[where b = "2^word_bits - 2"]) apply (simp add:word_bits_def minus_one_norm)+ apply unat_arith apply simp done lemma unat_of_nat_minus_1: "\n < 2^len_of TYPE('a);n\ 0\ \ (unat (((of_nat n):: 'a :: len word) - 1)) = n - 1" apply (subst unat_minus_one) apply (rule of_nat_neq_0) apply simp apply (simp add:of_nat_neq_0 word_bits_def) apply (simp add:unat_of_nat word_bits_def) done lemma range_to_bl': "\ is_aligned (ptr :: 'a :: len word) bits; bits < len_of TYPE('a) \ \ {ptr .. ptr + (2 ^ bits) - 1} = {x. take (len_of TYPE('a) - bits) (to_bl x) = take (len_of TYPE('a) - bits) (to_bl ptr)}" apply (rule set_eqI, rule iffI) apply clarsimp apply (subgoal_tac "\y. x = ptr + y \ y < 2 ^ bits") apply clarsimp apply (subst is_aligned_add_conv) apply assumption apply simp apply simp apply (rule_tac x="x - ptr" in exI) apply (simp add: add_diff_eq[symmetric]) apply (simp only: word_less_sub_le[symmetric]) apply (rule word_diff_ls') apply (simp add: field_simps) apply assumption apply simp apply (subgoal_tac "\y. y < 2 ^ bits \ to_bl (ptr + y) = to_bl x") apply clarsimp apply (rule conjI) apply (erule(1) is_aligned_no_wrap') apply (simp only: add_diff_eq[symmetric]) apply (rule word_plus_mono_right) apply simp apply (erule is_aligned_no_wrap') apply simp apply (rule_tac x="of_bl (drop (len_of TYPE('a) - bits) (to_bl x))" in exI) apply (rule context_conjI) apply (rule order_less_le_trans [OF of_bl_length]) apply simp apply simp apply (subst is_aligned_add_conv) apply assumption apply simp apply (drule sym) apply (simp add: word_rep_drop) done lemma range_to_bl: "is_aligned (ptr :: 'a :: len word) bits \ {ptr..ptr + 2 ^ bits - 1} = {x. take (len_of TYPE('a) - bits) (to_bl x) = take (len_of TYPE('a) - bits) (to_bl ptr)}" apply (erule is_aligned_get_word_bits) apply (erule(1) range_to_bl') apply (rule set_eqI) apply (simp add: power_overflow) done lemma aligned_ranges_subset_or_disjoint: "\ is_aligned (p :: 'a :: len word) n; is_aligned (p' :: 'a :: len word) n' \ \ {p .. p + 2 ^ n - 1} \ {p' .. p' + 2 ^ n' - 1} = {} \ {p .. p + 2 ^ n - 1} \ {p' .. p' + 2 ^ n' - 1} \ {p .. p + 2 ^ n - 1} \ {p' .. p' + 2 ^ n' - 1}" apply (simp add: range_to_bl) apply (rule disjCI2) apply (erule nonemptyE) apply simp apply (subgoal_tac "(\n''. len_of TYPE('a) - n = (len_of TYPE('a) - n') + n'') \ (\n''. len_of TYPE('a) - n' = (len_of TYPE('a) - n) + n'')") apply (elim conjE disjE exE) apply (rule disjI1) apply (clarsimp simp: take_add) apply (rule disjI2) apply (clarsimp simp: take_add) apply arith done lemma aligned_range_offset_subset: assumes al: "is_aligned (ptr :: 'a :: len word) sz" and al': "is_aligned x sz'" and szv: "sz' \ sz" and xsz: "x < 2 ^ sz" shows "{ptr + x .. (ptr + x) + 2 ^ sz' - 1} \ {ptr .. ptr + 2 ^ sz - 1}" using al proof (rule is_aligned_get_word_bits) assume p0: "ptr = 0" and szv': "len_of TYPE ('a) \ sz" hence "(2 :: 'a word) ^ sz = 0" by simp thus ?thesis using p0 apply - apply (erule ssubst) apply simp done next assume szv': "sz < len_of TYPE('a)" hence blah: "2 ^ (sz - sz') < (2 :: nat) ^ len_of TYPE('a)" using szv apply - apply (rule power_strict_increasing, simp+) done show ?thesis using szv szv' apply (intro range_subsetI) apply (rule is_aligned_no_wrap' [OF al xsz]) apply (simp only: add_diff_eq[symmetric]) apply (subst add.assoc, rule word_plus_mono_right) apply (subst iffD1 [OF le_m1_iff_lt]) apply (simp add: p2_gt_0 word_bits_conv) apply (rule is_aligned_add_less_t2n[OF al' _ szv xsz]) apply simp apply (simp add: field_simps szv al is_aligned_no_overflow) done qed lemma aligned_diff: "\is_aligned (dest :: 'a :: len word) bits; is_aligned (ptr :: 'a :: len word) sz; bits \ sz; sz < len_of TYPE('a); dest < ptr\ \ (2^ bits - 1) + dest < ptr" apply (frule_tac p' = ptr in aligned_ranges_subset_or_disjoint) apply assumption apply (elim disjE) apply clarsimp apply (drule_tac ptr = dest in is_aligned_no_overflow) apply simp apply (drule is_aligned_no_overflow) apply clarsimp apply (erule impE) apply (erule order_trans[OF less_imp_le]) apply (clarsimp simp:field_simps) apply (clarsimp simp:not_less field_simps not_le) apply clarsimp apply (drule_tac ptr = dest in is_aligned_no_overflow) apply simp apply fastforce apply clarsimp apply (frule is_aligned_no_overflow) apply (erule impE) apply (frule(1) is_aligned_no_overflow) apply (rule ccontr) apply (clarsimp simp:not_less p_assoc_help) apply (subst (asm) add.commute[where b = "(2^ sz - 1)"]) apply (subst (asm) add.commute[where b = "(2^ bits - 1)"])+ apply (drule word_sub_mono2) apply (rule word_le_minus_mono_left) apply (erule(1) two_power_increasing) apply (simp add:word_1_le_power) apply (simp add:field_simps is_aligned_no_overflow)+ done lemma default_object_tcbE: "\ default_object ty dev us = TCB tcb; ty \ Untyped; \ tcb = default_tcb; ty = Structures_A.TCBObject \ \ R \ \ R" unfolding default_object_def by (cases ty, auto) locale Retype_AI_slot_bits = assumes slot_bits_def2: "slot_bits = cte_level_bits" and arch_kobj_size_cong: "\a a1 c c1. \a = a1; c=c1\ \ arch_kobj_size (default_arch_object a b c) = arch_kobj_size (default_arch_object a1 b1 c1)" lemma (in Retype_AI_slot_bits) obj_bits_cong: "\a = a1; c=c1\ \ obj_bits (default_object a b c) = obj_bits (default_object a1 b1 c1)" by (simp add: default_object_def arch_kobj_size_cong split: if_splits apiobject_type.splits) lemma (in Retype_AI_slot_bits) obj_bits_api_default_object: "\ ty \ Untyped\ \ obj_bits_api ty us = obj_bits (default_object ty dev us)" unfolding obj_bits_api_def default_object_def by (cases ty) (simp_all add: slot_bits_def2 arch_kobj_size_cong wf_empty_bits) lemma obj_bits_api_default_CapTableObject: "obj_bits (default_object Structures_A.apiobject_type.CapTableObject dev us) = cte_level_bits + us" by (simp add: default_object_def wf_empty_bits) lemma empty_cnode_dom: "x \ dom (empty_cnode n) \ length x = n" unfolding dom_def empty_cnode_def by (simp split: if_split_asm) context Retype_AI_slot_bits begin lemma obj_bits_api_def2: "obj_bits_api type obj_size_bits = (case type of Structures_A.Untyped \ obj_size_bits | _ \ obj_bits (default_object type False obj_size_bits))" by (simp add: obj_bits_api_def default_object_def wf_empty_bits dom_empty_cnode ex_with_length slot_bits_def2 split: apiobject_type.split) lemma obj_bits_api_def3: "obj_bits_api type obj_size_bits = (if type = Structures_A.Untyped then obj_size_bits else obj_bits (default_object type False obj_size_bits))" by (simp add: obj_bits_api_def default_object_def wf_empty_bits dom_empty_cnode ex_with_length slot_bits_def2 split: apiobject_type.split) lemma obj_bits_api_def4: "obj_bits_api type obj_size_bits = (if type = Structures_A.Untyped then obj_size_bits else obj_bits (default_object type True obj_size_bits))" by (simp add: obj_bits_api_def default_object_def arch_kobj_size_cong wf_empty_bits dom_empty_cnode ex_with_length slot_bits_def2 split: apiobject_type.split) lemma obj_bits_dev_irr: "ty \ Untyped \ obj_bits (default_object ty dev us) = obj_bits_api ty us" by (simp add: obj_bits_api_def3 cong: obj_bits_cong) lemma default_obj_range: "ty \ Untyped \ obj_range p (default_object ty dev us) = {p..p + 2 ^ (obj_bits_api ty us) - 1}" by (simp add: obj_range_def obj_bits_dev_irr) end definition "retype_addrs \ \(ptr' :: obj_ref) ty n us. map (\p. ptr_add ptr' (p * 2 ^ obj_bits_api ty us)) [0..< n]" lemma retype_addrs_base [simp]: "0 < n \ x \ set (retype_addrs x ty n us)" unfolding retype_addrs_def apply (simp add: ptr_add_def) apply (rule image_eqI [where x = 0]) apply simp apply (simp add: power_sub[symmetric]) done lemma retype_addrs_aligned: assumes xin: "x \ set (retype_addrs ptr ty n us)" and al: "is_aligned ptr (obj_bits_api ty us)" and nv: "sz < word_bits" and oav: "obj_bits_api ty us \ sz" shows "is_aligned x (obj_bits_api ty us)" using xin unfolding retype_addrs_def ptr_add_def apply (clarsimp simp: word_unat_power [symmetric]) apply (subst mult.commute, subst shiftl_t2n [symmetric]) apply (rule aligned_add_aligned[OF al is_aligned_shift]) apply (insert assms) apply simp+ done lemma (in pspace_update_eq) pspace_no_overlap_update [simp]: "pspace_no_overlap S (f s) = pspace_no_overlap S s" by (simp add: pspace_no_overlap_def pspace) (* FIXME: move *) lemma multi_lessD: "\(a::nat)*b < c;0 \ a < c \ b < c" by (cases a, simp_all,cases b,simp_all) lemma unat_le_helper: "(x :: 'a :: len word) \ of_nat n \ unat x \ n" by (rule word_unat_less_le) lemma word_of_nat_plus: "of_nat (a + b) = of_nat a + (of_nat b :: ('a :: len) word)" by (rule of_nat_add) lemma word_of_nat_minus: "b<= a ==> of_nat (a - b) = of_nat a - (of_nat b :: ('a :: len) word)" by (rule of_nat_diff) lemma unat_shiftl_absorb: "\x \ 2^p ; p + k < len_of TYPE('a)\ \ unat (x :: 'a :: len word) * 2^k = unat (x * 2^k)" apply (simp add:unat_word_ariths) apply (subst mod_less) apply (rule le_less_trans[OF mult_le_mono1]) apply (erule iffD1[OF word_le_nat_alt]) apply (clarsimp simp: power_add[symmetric])+ done lemma word_up_bound: "(ptr::('a::len) word) \ 2^(len_of TYPE('a)) - 1 " by auto lemma word_plus_mono_right_split: "\unat ((x :: 'a :: len word) && mask sz) + unat z < 2 ^ sz ; sz < len_of TYPE('a)\ \x \ x + z" (is "\?bound;?len\ \?rhs \ ?lhs") apply (subgoal_tac "(x && ~~ mask sz) + (x && mask sz) \ (x && ~~ mask sz) + ((x && mask sz) + z)") apply (simp add:word_plus_and_or_coroll2 field_simps) apply (rule word_plus_mono_right) apply (simp add:no_olen_add ) apply (rule less_le_trans) apply (simp add:uint_nat) apply (subst of_nat_add[symmetric]) apply (drule iffD2[OF of_nat_less_iff]) apply simp apply (rule less_imp_le) apply (rule less_le_trans[where y = "2^len_of TYPE('a)"] ) apply simp apply (simp add:word_bits_def) apply (rule word_plus_mono_right2) apply (rule is_aligned_no_overflow') apply (rule is_aligned_neg_mask[OF le_refl]) apply (rule le_m1_iff_lt[THEN iffD1,THEN iffD2]) apply (simp add:p2_gt_0 word_bits_def) apply (rule iffD2[OF word_less_nat_alt]) apply (auto simp:unat_plus_if_size word_size word_bits_def not_less) done lemmas machine_word_plus_mono_right_split = word_plus_mono_right_split[where 'a=machine_word_len, folded word_bits_def] (* range_cover locale: proves properties when a small range is inside in a large range *) locale range_cover = fixes ptr :: "'a :: len word" and sz sbit n assumes aligned: "is_aligned ptr sbit" and sz:"sz< len_of TYPE('a)" "sbit \ sz" "n + unat (ptr && mask sz >> sbit) \ 2 ^ (sz - sbit)" context range_cover begin lemma range_cover_compare_bound: "n * 2 ^ sbit + unat (ptr && mask sz) \ 2 ^ sz" proof - have mask_before_neg_mask: "(ptr && mask sz) && ~~ mask sbit = ptr && mask sz" using aligned sz by (simp add:mask_twice is_aligned_mask mask_out_sub_mask min_def) show ?thesis using aligned sz apply (drule_tac i = "a +b" for a b in Nat.mult_le_mono[where k = "2^sbit",OF _ le_refl]) apply (subst (asm) add_mult_distrib) apply (clarsimp simp: power_add[symmetric]) apply (subst (asm) unat_shiftl_absorb[where p = "sz - sbit"]) apply (rule less_imp_le) apply (rule shiftr_less_t2n) apply (rule less_le_trans) apply (rule and_mask_less') apply (simp add:word_bits_def) apply (rule two_power_increasing) apply simp apply (simp add:word_bits_def field_simps) apply simp apply (subst (asm) mult.commute[where b = "2^sbit"], subst (asm) shiftl_t2n[symmetric]) apply (subst (asm) and_not_mask[symmetric]) apply (simp add:mask_before_neg_mask) done qed lemma range_cover_compare: assumes pointer:"p < n" shows "unat (ptr && mask sz) + unat (((of_nat p) :: 'a :: len word) * 2 ^ sbit) < 2 ^ sz" proof - have mask_before_neg_mask: "(ptr && mask sz) && ~~ mask sbit = ptr && mask sz" using aligned sz by (simp add:mask_twice is_aligned_mask mask_out_sub_mask min_def) have absolute_compare:"n * 2 ^ sbit + unat (ptr && mask sz) \ 2 ^ sz" by (rule range_cover_compare_bound) have no_overflow_n:"n * 2^sbit < 2^len_of TYPE('a)" using aligned sz apply (clarsimp dest!:add_leD1) apply (rule le_less_trans) apply (drule Nat.mult_le_mono[where i = n and k = "2^sbit",OF _ le_refl]) apply (clarsimp simp: power_add[symmetric]) apply (assumption) apply clarsimp done have no_overflow_p:"p * 2^sbit < 2^len_of TYPE('a)" apply (rule le_less_trans[OF _ no_overflow_n]) apply (simp add:pointer less_imp_le) done show ?thesis apply (rule less_le_trans[OF _ absolute_compare]) apply (subst add.commute) apply clarsimp apply (case_tac "p = 0") apply (insert pointer) apply (clarsimp simp: range_cover_def pointer) apply (simp add:unat_word_ariths) apply (rule le_less_trans[OF mod_less_eq_dividend]) apply (rule less_le_trans[OF mult_less_mono1[where j = n]]) apply (cut_tac no_overflow_p) apply (drule multi_lessD[OF no_overflow_p],simp) apply (clarsimp simp:unat_of_nat word_bits_def) using sz apply (simp add:unat_gt_0 range_cover_def) apply (rule mult_le_mono2) apply (rule unat_le_helper) apply simp done qed lemma no_overflow_n:"n * 2^sbit < 2^len_of TYPE('a)" using aligned sz apply (clarsimp dest!:add_leD1) apply (rule le_less_trans) apply (drule Nat.mult_le_mono[where i = n and k = "2^sbit",OF _ le_refl]) apply (clarsimp simp: power_add[symmetric]) apply (assumption) apply clarsimp done lemma range_cover_n_le: "n \ 2 ^ (len_of TYPE('a) - sbit)" "n \ 2 ^ (sz - sbit)" using aligned sz by (auto elim: le_trans[OF add_leD1]) lemma range_cover_n_less: shows weak: "n < 2 ^ len_of TYPE('a)" and string: "n < 2 ^ (len_of TYPE('a) - sbit)" proof - show str: "n < 2 ^ (len_of TYPE('a) - sbit)" using aligned sz by (auto intro: le_less_trans range_cover_n_le(2)) show "n<2^len_of TYPE('a)" using str by (rule less_le_trans) simp qed lemma range_cover_le_n_less: "p \ n \ p < 2^ len_of TYPE('a)" "p \ n \ p < 2^ (len_of TYPE('a) - sbit)" apply (erule le_less_trans[OF _ range_cover_n_less(1)]) apply (erule le_less_trans[OF _ range_cover_n_less(2)]) done lemma unat_of_nat_n :"unat ((of_nat n):: 'a :: len word) = n" using range_cover_n_less apply (simp add:unat_of_nat) done lemma unat_of_nat_n_shift: "gbits \ sbit \ unat (((of_nat n):: 'a :: len word) << gbits) = (n * 2^ gbits)" apply (simp add:shiftl_t2n field_simps) apply (subst mult.commute) apply (subst unat_mult_power_lem) apply (case_tac "gbits = sbit") apply (rule le_less_trans[OF range_cover_n_le(2)]) apply clarsimp apply (rule diff_less_mono) apply (rule sz) apply (rule sz) apply (rule le_less_trans[OF range_cover_n_le(1)]) apply clarsimp apply (rule diff_less_mono2) apply simp using sz apply simp apply simp done lemma unat_of_nat_shift: "\gbits \ sbit;p\ n\ \ (unat (((of_nat p):: 'a :: len word) * 2 ^ gbits)) = (p * 2^ gbits)" apply (subst mult.commute[where a = "of_nat p"]) apply (subst mult.commute[where a = "p "]) apply (subst unat_mult_power_lem) apply (case_tac "gbits = sbit") apply simp apply (erule le_less_trans[OF _ range_cover_le_n_less(2) ]) apply simp apply (erule le_less_trans) apply (rule less_le_trans[OF range_cover_n_less(2)]) apply clarsimp apply (erule diff_le_mono2) apply (simp add:range_cover_def)+ done lemma range_cover_base_le: "(ptr && mask sz) \ (ptr && mask sz) + (of_nat n << sbit)" apply (clarsimp simp:no_olen_add_nat shiftl_t2n unat_of_nat_shift field_simps) apply (subst add.commute) apply (rule le_less_trans[OF range_cover_compare_bound]) apply (rule less_le_trans[OF power_strict_increasing]) using sz apply simp+ done end lemma range_cover_subset: fixes ptr :: "'a :: len word" assumes cover: "range_cover ptr sz sbit n" assumes pointer: "p 0" shows "{ptr + of_nat p * 2^sbit .. ptr + of_nat p * 2 ^ sbit + 2 ^ sbit - 1} \ {ptr .. ptr + of_nat n * 2 ^ sbit - 1}" apply clarsimp apply (intro conjI) apply (rule word_plus_mono_right_split[OF range_cover.range_cover_compare[OF cover pointer]]) using cover apply (simp add:range_cover_def) proof - note n_less = range_cover.range_cover_n_less[OF cover] have unat_of_nat_m1: "unat (of_nat n - (1 :: 'a :: len word)) < n" using not_0 n_less by (simp add:unat_of_nat_minus_1) have decomp:"of_nat n * 2 ^ sbit = of_nat (n - 1) * 2 ^ sbit + (2 :: 'a :: len word) ^ sbit" apply (simp add:distrib_right[where b = "1::'a word",simplified,symmetric]) using not_0 n_less apply (simp add:unat_of_nat_minus_1) done show "ptr + of_nat p * 2 ^ sbit + 2 ^ sbit - 1 \ ptr + of_nat n * 2 ^ sbit - 1" apply (subst decomp) apply (simp add:add.assoc[symmetric]) apply (simp add:p_assoc_help) apply (rule order_trans[OF word_plus_mono_left word_plus_mono_right]) apply (rule word_plus_mono_right) apply (rule word_mult_le_mono1[OF word_of_nat_le]) apply (insert n_less not_0 pointer) apply (simp add:unat_of_nat_minus_1) apply (rule p2_gt_0[THEN iffD2]) using cover apply (simp add:word_bits_def range_cover_def) using cover apply (simp only: word_bits_def[symmetric] unat_power_lower range_cover_def) apply (clarsimp simp: unat_of_nat_minus_1 ) apply (rule nat_less_power_trans2[OF range_cover.range_cover_le_n_less(2),OF cover]) apply (simp add:unat_of_nat_m1 less_imp_le) using cover apply (simp add:range_cover_def) apply (rule word_plus_mono_right_split[where sz = sz]) using range_cover.range_cover_compare[OF cover,where p = "unat (of_nat n - (1 :: 'a :: len word))"] apply (clarsimp simp:unat_of_nat_m1) using cover apply (simp add:range_cover_def) apply (rule olen_add_eqv[THEN iffD2]) apply (subst add.commute[where a = "2^sbit - 1"]) apply (subst p_assoc_help[symmetric]) apply (rule is_aligned_no_overflow) apply (insert cover) apply (clarsimp simp:range_cover_def) apply (erule aligned_add_aligned[OF _ is_aligned_mult_triv2]) apply (simp add:range_cover_def)+ done qed lemma range_cover_rel: assumes cover: "range_cover ptr sz sbit n" assumes le:"sbit' \ sbit" assumes num_r: "m = 2 ^ (sbit - sbit') * n" shows "range_cover ptr sz sbit' m" using cover apply (clarsimp simp:num_r range_cover_def) apply (intro conjI) apply (erule is_aligned_weaken[OF _ le]) apply (erule le_trans[OF le]) apply (drule is_aligned_weaken[OF _ le])+ apply (drule mult_le_mono2[where j = "2^(sz-sbit)" and k = "2^(sbit-sbit')"]) apply (subst (asm) power_add[symmetric]) apply (clarsimp simp:field_simps le) apply (erule le_trans[rotated]) apply clarsimp apply (rule unat_le_helper) apply clarsimp apply (insert le) apply (fold shiftl_t2n) apply (simp add: shiftr_shiftl1) apply (rule eq_refl[OF is_aligned_neg_mask_eq[symmetric]]) apply (rule is_aligned_shiftr[OF is_aligned_weaken]) apply (rule aligned_already_mask[where n = "sbit"]) apply (insert cover) apply (simp add:range_cover_def) apply simp done lemma unat_plus_gt: "unat ((a::('a::len word)) + b) \ (unat a + unat b)" by (clarsimp simp:unat_plus_if_size) lemma retype_addrs_subset_ptr_bits: assumes cover: "range_cover ptr sz (obj_bits_api ty us) n" shows "set (retype_addrs ptr ty n us) \ {ptr .. (ptr &&~~ mask sz) + (2 ^ sz - 1)}" apply (clarsimp simp:retype_addrs_def ptr_add_def) apply (intro conjI) apply (rule word_plus_mono_right_split) apply (erule range_cover.range_cover_compare[OF cover]) using cover apply (simp add:range_cover_def) apply (subst word_plus_and_or_coroll2[symmetric,where w = "mask sz"]) apply (subst add.commute) apply (subst add.assoc) apply (rule word_plus_mono_right) apply (insert cover) apply (drule(1) range_cover.range_cover_compare) apply (rule iffD1[OF le_m1_iff_lt,THEN iffD2]) using cover apply (simp add: p2_gt_0 range_cover_def word_bits_def) apply (rule iffD2[OF word_less_nat_alt]) apply (rule le_less_trans[OF unat_plus_gt]) using cover apply (clarsimp simp:unat_power_lower range_cover_def) apply (insert cover) apply (rule is_aligned_no_wrap'[OF is_aligned_neg_mask,OF le_refl ]) apply (simp add:range_cover_def)+ done lemma pspace_no_overlapE: "\ pspace_no_overlap S s; kheap s x = Some ko; {x..x + (2 ^ obj_bits ko - 1)} \ S = {} \ R\ \ R" unfolding pspace_no_overlap_def by auto lemma base_member_set: fixes x :: "'a :: len word" assumes al: "is_aligned x sz" and szv: "sz < len_of TYPE('a)" shows "x \ {x .. x + (2 ^ sz - 1)}" proof (simp, rule is_aligned_no_wrap') show "(2 :: 'a :: len word) ^ sz - 1 < 2 ^ sz" using szv by (simp add: word_less_nat_alt word_neq_0_conv unat_minus_one) qed fact+ abbreviation(input) "pspace_no_overlap_range_cover ptr bits \ pspace_no_overlap {ptr .. (ptr && ~~ mask bits) + (2 ^ bits - 1)}" lemma pspace_no_overlap_into_Int_none: assumes ps: "pspace_no_overlap_range_cover ptr sz s" and vp: "valid_pspace s" and cover: "range_cover ptr sz (obj_bits_api ty us) n" shows "set (retype_addrs ptr ty n us) \ dom (kheap s) = {}" proof - { fix x ko assume ps': "kheap s x = Some ko" have "x \ {ptr .. (ptr && ~~ mask sz) + (2 ^ sz - 1)}" proof (rule orthD1) show "x \ {x .. x + (2 ^ obj_bits ko - 1)}" proof (rule base_member_set) from vp show "is_aligned x (obj_bits ko)" using ps' by (auto elim!: valid_pspaceE pspace_alignedE) show "obj_bits ko < len_of TYPE(machine_word_len)" by (rule valid_pspace_obj_sizes [OF _ ranI, unfolded word_bits_def]) fact+ qed show "{x..x + (2 ^ obj_bits ko - 1)} \ {ptr..(ptr && ~~ mask sz) + (2 ^ sz - 1)} = {}" using ps by (rule pspace_no_overlapE) fact+ qed hence "x \ set (retype_addrs ptr ty n us)" using assms subsetD[OF retype_addrs_subset_ptr_bits[OF cover]] by auto } thus ?thesis by auto qed lemma pspace_no_overlapD1: "\ pspace_no_overlap_range_cover ptr sz s; kheap s x = Some ko; range_cover ptr sz (obj_bits_api ty us) n; valid_pspace s\ \ x \ set (retype_addrs ptr ty n us)" apply (drule(2) pspace_no_overlap_into_Int_none) apply (simp add:range_cover_def) apply (erule orthD2) apply (erule domI) done lemma pspace_no_overlapD2: "\ pspace_no_overlap_range_cover ptr sz s; x \ set (retype_addrs ptr ty n us); range_cover ptr sz (obj_bits_api ty us) n; valid_pspace s \ \ x \ dom (kheap s)" apply (drule(2) pspace_no_overlap_into_Int_none) apply (simp add:range_cover_def) apply (erule(1) orthD1) done lemma pspace_no_overlapC: "\ pspace_no_overlap_range_cover ptr sz s; x \ set (retype_addrs ptr ty n us); kheap s x = Some ko; range_cover ptr sz (obj_bits_api ty us) n;valid_pspace s \ \ P" by (auto dest: pspace_no_overlapD1) lemma null_filterE: "\ null_filter cps x = Some cap; \ cps x = Some cap; cap \ cap.NullCap \ \ R \ \ R" by (simp add: null_filter_def split: if_split_asm) lemma across_null_filter_eq: assumes eq: "null_filter xs = null_filter ys" shows "\ xs x = Some v; ys x = Some v \ R; \ v = cap.NullCap; ys x = None \ \ R \ \ R" apply (cases "null_filter xs x") apply (subgoal_tac "null_filter ys x = None") apply (simp add: null_filter_def split: if_split_asm) apply (simp add: eq) apply (subgoal_tac "null_filter ys x = Some a") apply (simp add: null_filter_def split: if_split_asm) apply (simp add: eq) done lemma mdb_cte_at_no_descendants: "\ mdb_cte_at f m; \ f x \ \ descendants_of x m = {}" apply (clarsimp simp add: descendants_of_def) apply (erule tranclE2) apply (simp add: cdt_parent_of_def) apply (drule(1) mdb_cte_atD) apply simp apply (simp add: cdt_parent_of_def) apply (drule(1) mdb_cte_atD) apply simp done lemma caps_of_state_foldr: assumes tyun: "ty \ Untyped" fixes s sz ptr us addrs dev defines "s' \ (s\kheap := foldr (\p ps. ps(p \ default_object ty dev us)) addrs (kheap s)\)" shows "caps_of_state s' = (\(oref,cref). if oref \ set addrs then (case ty of Structures_A.CapTableObject \ empty_cnode us | Structures_A.TCBObject \ option_map (\x. cap.NullCap) \ tcb_cap_cases | _ \ empty) cref else caps_of_state s (oref,cref))" apply (rule ext)+ apply (case_tac x) apply (rename_tac oref cref) apply (simp add: caps_of_state_cte_wp_at split del: if_split) apply (case_tac "\cap. cte_wp_at (op = cap) (oref, cref) s'") apply clarsimp apply (simp add: s'_def cte_wp_at_cases) apply (erule disjE) apply (clarsimp simp add: foldr_upd_app_if default_object_def caps_of_state_cte_wp_at cte_wp_at_cases tyun empty_cnode_def split: if_split_asm Structures_A.apiobject_type.splits) apply (clarsimp simp add: foldr_upd_app_if default_object_def caps_of_state_cte_wp_at cte_wp_at_cases tyun empty_cnode_def default_tcb_def split: if_split_asm Structures_A.apiobject_type.splits) apply (clarsimp simp: tcb_cap_cases_def split: if_split_asm) apply simp apply (simp add: cte_wp_at_cases s'_def foldr_upd_app_if) apply (rule conjI) apply (clarsimp simp: default_object_def wf_empty_bits split: Structures_A.apiobject_type.split_asm) apply (fastforce simp: tcb_cap_cases_def split: if_split_asm) apply clarsimp apply (simp add: caps_of_state_cte_wp_at) apply (simp add: cte_wp_at_cases) done lemma null_filter_caps_of_state_foldr: fixes s sz ptr us addrs dev assumes tyun: "ty \ Untyped" and nondom: "\x \ set addrs. x \ dom (kheap s)" defines "s' \ (s\kheap := foldr (\p ps. ps(p \ default_object ty dev us)) addrs (kheap s)\)" shows "null_filter (caps_of_state s') = null_filter (caps_of_state s)" unfolding s'_def apply (subst caps_of_state_foldr[OF tyun]) apply (rule ext) apply (clarsimp simp add: null_filter_def split_def empty_cnode_def split: Structures_A.apiobject_type.splits) apply (subgoal_tac "a \ set addrs \ caps_of_state s (a, b) \ Some cap.NullCap \ None = caps_of_state s (a, b)", simp) apply clarsimp apply (subgoal_tac "tcb_cap_cases b = None", simp) apply (rule ccontr, clarsimp) apply clarsimp apply (rule sym, rule ccontr, clarsimp) apply (drule bspec[OF nondom]) apply (drule caps_of_state_cteD) apply (erule cte_wp_atE, fastforce+) done lemma retype_addrs_fold: " map (\p. ptr_add ptr' (p * 2 ^ obj_bits_api ty us)) [0..< n ] = retype_addrs ptr' ty n us" by (simp add: retype_addrs_def power_sub) lemma mult_div_rearrange: "(b::nat) \ a \ (2::nat) ^ a * (p div 2 ^ b) = 2 ^ (a - b) * (2 ^ b * (p div 2 ^ b))" by (auto simp:field_simps power_add[symmetric]) lemma shiftr_mask_cmp: "\c \ n; n \ len_of TYPE('a)\ \ ((a::('a::len) word) \ mask n) = ((a >> c) \ mask (n - c))" apply (rule iffI) apply (drule le_shiftr[where n = c]) apply (simp add:mask_2pm1[symmetric] shiftr_mask2)+ apply (simp add:le_mask_iff shiftr_shiftr) done locale Retype_AI_no_gs_types = fixes no_gs_types :: "apiobject_type set" assumes no_gs_types_simps [simp]: "Untyped \ no_gs_types" "TCBObject \ no_gs_types" "EndpointObject \ no_gs_types" "NotificationObject \ no_gs_types" lemma measure_unat': "p \ 0 \ unat (p - 1) \ unat p - 1" apply (insert measure_unat[where p = p]) apply simp done (* FIXME: move *) lemma range_cover_not_zero: "\n \ 0; range_cover (ptr :: 'a :: len word) sz bits n\ \ ((of_nat n) :: 'a :: len word) \ 0" apply (rule of_nat_neq_0) apply simp apply (drule range_cover.range_cover_n_less) apply simp done lemma range_cover_not_zero_shift: "\n \ 0; range_cover (ptr :: 'a :: len word) sz bits n; gbits \ bits\ \ ((of_nat n) :: 'a :: len word) << gbits \ 0" apply (rule word_shift_nonzero[where m = "sz-gbits"]) prefer 2 apply (clarsimp simp:range_cover_def) apply (clarsimp simp:word_le_nat_alt) apply (subst unat_power_lower) apply (rule less_le_trans[OF diff_less_Suc]) apply (simp add:range_cover_def) apply (simp add:range_cover.unat_of_nat_n) apply (erule le_trans[OF range_cover.range_cover_n_le(2)]) apply (rule power_increasing) apply simp+ using range_cover_not_zero apply auto done lemma mult_plus_1: "(a::nat) + b * a = a * (b + 1)" by simp lemma range_cover_cell_subset: "\range_cover ptr sz us n;x < of_nat n\ \ {ptr + x * 2 ^ us..ptr + x * 2 ^ us + 2 ^ us - 1} \ {ptr..(ptr && ~~ mask sz) + 2 ^ sz - 1}" proof - assume cover:"range_cover ptr sz us n" and cmp:"x> us)) = ptr && mask sz" apply (subst shiftl_t2n[symmetric]) apply (subst and_not_mask[symmetric]) apply (rule is_aligned_neg_mask_eq) using cover apply (simp add:is_aligned_mask mask_twice range_cover_def min_def) done show ?thesis using cover cmp apply clarsimp apply (intro conjI) apply (rule word_plus_mono_right_split) apply (drule range_cover.range_cover_compare[where p = "unat x"]) apply (erule unat_less_helper) apply (simp add: range_cover.unat_of_nat_shift[where gbits = us]) apply (simp add:range_cover_def) apply (subst word_plus_and_or_coroll2[symmetric,where w = "mask sz"]) apply (subst add.commute) apply (simp add:p_assoc_help) apply (subst add.assoc)+ apply (rule word_plus_mono_right) apply (cut_tac nasty_split_lt[where x="((ptr && mask sz) >> us) + x" and n=us and m=sz]) apply (simp add: sh field_simps) apply (clarsimp simp:range_cover_def word_less_nat_alt) apply (rule le_less_trans[OF unat_plus_gt]) apply (erule less_le_trans[rotated]) apply (clarsimp simp:range_cover.unat_of_nat_n[OF cover]) apply (simp add:range_cover_def p_assoc_help[symmetric])+ apply (rule is_aligned_no_overflow[OF is_aligned_neg_mask ,OF le_refl]) done qed lemma is_aligned_ptr_add_helper: "\ is_aligned ptr d; d < word_bits; c \ d; c \ a + b; a + b < word_bits \ \ is_aligned (ptr_add ptr (x * 2 ^ a * 2 ^ b)) c" apply (simp add: ptr_add_def) apply (erule aligned_add_aligned) apply (rule is_aligned_weaken) apply (simp add: field_simps power_add[symmetric]) apply (rule is_aligned_mult_triv2) apply assumption+ done lemma range_cover_no_0: "\ ptr \ 0; range_cover (ptr :: 'a :: len word) sz sbit n;p < n\ \ ptr + of_nat p * 2 ^ sbit \ 0" apply (subst word_plus_and_or_coroll2[symmetric,where w = "mask sz"]) apply (case_tac "(ptr && ~~ mask sz) \ 0") apply (subst add.commute) apply (subst add.assoc) apply (rule aligned_offset_non_zero) apply (rule is_aligned_neg_mask[OF le_refl]) apply (simp add:word_less_nat_alt) apply (rule le_less_trans[OF unat_plus_gt]) apply (rule less_le_trans[OF range_cover.range_cover_compare]) apply simp apply ((simp add:range_cover_def)+)[3] apply (subgoal_tac "(ptr && mask sz) \ 0") apply (rule unat_gt_0[THEN iffD1]) apply (simp add:not_less) apply (subst iffD1[OF unat_add_lem]) apply (rule less_le_trans[OF range_cover.range_cover_compare]) apply simp+ apply (simp add:range_cover_def word_bits_def) apply simp apply (rule disjI1) apply unat_arith apply (rule ccontr) apply (subst (asm) word_plus_and_or_coroll2[symmetric,where w = "mask sz" and t = ptr]) apply (clarsimp simp:not_less) done lemma range_cover_mem: "\x < n; range_cover ptr sz us n\ \ ptr + (of_nat x) * 2 ^ us \ {ptr..(ptr && ~~ mask sz) + 2 ^ sz - 1}" apply (clarsimp) apply (intro conjI) apply (rule word_plus_mono_right_split[where sz = sz]) apply (erule range_cover.range_cover_compare) apply ((simp add:range_cover_def)+)[2] apply (subst p_assoc_help) apply (subst word_plus_and_or_coroll2[symmetric,where w = "mask sz"]) apply (subst add.commute) apply (subst add.assoc) apply (rule word_plus_mono_right) apply (simp add:word_le_nat_alt) apply (rule le_trans[OF unat_plus_gt]) apply (subst unat_minus_one[OF power_not_zero]) apply (simp add:range_cover_def) apply (frule(1) range_cover.range_cover_compare) apply (clarsimp simp:range_cover_def le_m1_iff_lt power_not_zero nat_le_Suc_less_imp) apply (rule is_aligned_no_wrap'[OF is_aligned_neg_mask,OF le_refl ]) apply (simp add:range_cover_def) done lemma range_cover_mem': "\x < of_nat n; range_cover ptr sz us n\ \ ptr + x * 2 ^ us \ {ptr..(ptr && ~~ mask sz) + 2 ^ sz - 1}" apply (drule range_cover_mem[where x = "unat x",rotated]) apply (erule unat_less_helper) apply auto done lemma range_cover_subset_not_empty: "\x < of_nat n; range_cover ptr sz us n\ \ {ptr + x * 2 ^ us..ptr + x * 2 ^ us + 2 ^ us - 1} \ {}" apply (clarsimp simp:p_assoc_help) apply (rule is_aligned_no_overflow') apply (rule is_aligned_add_multI) apply (fastforce simp:range_cover_def)+ done crunch global_refs[wp]: retype_region "\s. P (global_refs s)" (simp: crunch_simps) locale Retype_AI_retype_region_ret = fixes state_ext_t :: "'state_ext :: state_ext itself" assumes retype_region_ret_folded: "\ y n bits ty dev. \\\ retype_region y n bits ty dev \\r (s :: 'state_ext state). r = retype_addrs y ty n bits\" context Retype_AI_retype_region_ret begin lemmas retype_region_ret = retype_region_ret_folded[unfolded retype_addrs_def] lemma retype_region_global_refs_disjoint: "\(\s::'state_ext state. {ptr .. (ptr && ~~ mask sz) + 2 ^ sz - 1} \ global_refs s = {}) and K (range_cover ptr sz (obj_bits_api apiobject_type obits) n)\ retype_region ptr n obits apiobject_type dev \\r s. global_refs s \ set r = {}\" apply (rule hoare_gen_asm) apply (rule hoare_lift_Pf3[where f=global_refs]) apply (rule hoare_assume_pre) apply (clarsimp simp: Int_commute) apply (rule hoare_chain) apply(rule retype_region_ret) apply simp apply (erule disjoint_subset2[rotated]) apply (rule subsetI, simp only: mask_in_range[symmetric]) apply (clarsimp simp: ptr_add_def) apply (intro conjI) apply (rule machine_word_plus_mono_right_split[where sz = sz]) apply (erule(1) range_cover.range_cover_compare) apply (simp add:range_cover_def word_bits_def) apply (subst p_assoc_help) apply (subst word_plus_and_or_coroll2[symmetric,where w = "mask sz"]) apply (subst add.commute) apply (subst add.assoc) apply (rule word_plus_mono_right) apply (simp add:word_le_nat_alt) apply (rule le_trans[OF unat_plus_gt]) apply (subst unat_minus_one[OF power_not_zero]) apply (simp add:range_cover_def) apply (frule(1) range_cover.range_cover_compare) apply (clarsimp simp:range_cover_def le_m1_iff_lt power_not_zero nat_le_Suc_less_imp) apply (rule is_aligned_no_wrap'[OF is_aligned_neg_mask,OF le_refl ]) apply (simp add:range_cover_def) apply (simp add:range_cover_def) apply wp done end crunch valid_pspace: do_machine_op "valid_pspace" lemma do_machine_op_return_foo: "do_machine_op (do x\a;return () od) = (do (do_machine_op a); return () od)" apply (clarsimp simp:do_machine_op_def bind_def gets_def get_def return_def select_f_def split_def simpler_modify_def) apply (rule ext)+ apply (clarsimp simp:image_def) apply (rule set_eqI) apply clarsimp done abbreviation(input) "all_invs_but_equal_kernel_mappings_restricted S \ (\s. equal_kernel_mappings (s \ kheap := restrict_map (kheap s) (- S) \)) and valid_pspace and valid_mdb and valid_idle and only_idle and if_unsafe_then_cap and valid_reply_caps and valid_reply_masters and valid_global_refs and valid_arch_state and valid_irq_node and valid_irq_handlers and valid_vspace_objs and valid_irq_states and valid_global_objs and valid_arch_caps and valid_kernel_mappings and valid_asid_map and valid_global_vspace_mappings and pspace_in_kernel_window and cap_refs_in_kernel_window and pspace_respects_device_region and cap_refs_respects_device_region and cur_tcb and valid_ioc and valid_machine_state and valid_ioports" lemma all_invs_but_equal_kernel_mappings_restricted_eq: "all_invs_but_equal_kernel_mappings_restricted {} = invs" by (rule ext, simp add: invs_def valid_state_def conj_comms restrict_map_def) locale Retype_AI_dmo_eq_kernel_restricted = fixes state_ext_t :: "'state_ext::state_ext itself" and machine_op_t :: "'machine_op_t itself" assumes dmo_eq_kernel_restricted[wp]: "\ f m. \\s::'state_ext state. equal_kernel_mappings (kheap_update (f (kheap s)) s)\ do_machine_op m :: ('state_ext state, 'machine_op_t) nondet_monad \\rv s. equal_kernel_mappings (kheap_update (f (kheap s)) s)\" crunch only_idle[wp]: do_machine_op "only_idle" crunch valid_global_refs[wp]: do_machine_op "valid_global_refs" crunch global_mappings[wp]: do_machine_op "valid_global_vspace_mappings" crunch valid_kernel_mappings[wp]: do_machine_op "valid_kernel_mappings" crunch cap_refs_in_kernel_window[wp]: do_machine_op "cap_refs_in_kernel_window" locale Retype_AI_post_retype_invs = fixes state_ext_t :: "'state_ext::state_ext itself" and post_retype_invs_check :: "apiobject_type \ bool" and post_retype_invs :: "apiobject_type \ machine_word list \ 'state_ext state \ bool" assumes post_retype_invs_def': "post_retype_invs tp refs \ if post_retype_invs_check tp then all_invs_but_equal_kernel_mappings_restricted (set refs) else invs" lemma (in Retype_AI_retype_region_ret) retype_region_aligned_for_init[wp]: "\\s::'state_ext state. range_cover ptr sz (obj_bits_api new_type obj_sz) n\ retype_region ptr n obj_sz new_type dev \\rv s. \ref \ set rv. is_aligned ref (obj_bits_api new_type obj_sz)\" apply (rule hoare_assume_pre) apply (rule hoare_chain, rule retype_region_ret) apply simp apply (clarsimp simp: ptr_add_def dest!: less_two_pow_divD) apply (rule aligned_add_aligned) apply (fastforce simp:range_cover_def) apply (subst mult.commute, subst shiftl_t2n[symmetric], rule is_aligned_shiftl) apply simp apply (simp add:range_cover_def)+ done lemma honestly_16_10: "is_aligned (p :: word32) 10 \ p + 16 \ {p .. p + 1023}" apply simp apply (intro conjI is_aligned_no_wrap' word_plus_mono_right, (assumption | simp add: word_bits_def)+) done definition caps_no_overlap :: "machine_word \ nat \ 'z::state_ext state \ bool" where "caps_no_overlap ptr sz s \ \cap \ ran (caps_of_state s). untyped_range cap \ {ptr .. (ptr && ~~ mask sz) + 2 ^ sz - 1} \ {} \ {ptr .. (ptr && ~~ mask sz) + 2 ^ sz - 1} \ untyped_range cap" definition caps_overlap_reserved :: "machine_word set \ ('z::state_ext) state \ bool" where "caps_overlap_reserved S (s :: ('z::state_ext) state) \ \cap \ ran (caps_of_state s). (is_untyped_cap cap \ usable_untyped_range cap \ S = {})" lemma of_nat_2: "((of_nat (2::nat))::word32) = 2" by simp lemma subset_le_imp_less: "\ A \ B \ \ A \ B" by auto lemma non_disjoing_subset: "\A \ B; A \ C \ {}\ \ B \ C \ {}" by blast lemma pspace_no_overlap_same_type: "\pspace_no_overlap S s; ko_at k p s; a_type ko = a_type k\ \ pspace_no_overlap S (kheap_update (\_. (kheap s(p \ ko))) s)" unfolding pspace_no_overlap_def by (clarsimp simp: obj_at_def obj_bits_T) lemma set_object_no_overlap: "\pspace_no_overlap S and obj_at (\k. a_type ko = a_type k) p\ set_object p ko \\r. pspace_no_overlap S\" unfolding set_object_def apply simp apply wp apply (clarsimp simp del: fun_upd_apply) apply (drule obj_at_ko_atD, erule exE) apply (rule pspace_no_overlap_same_type) apply auto done lemma set_cap_no_overlap: "\pspace_no_overlap S\ set_cap cap cte \\r. pspace_no_overlap S\" unfolding set_cap_def by (wpsimp wp: set_object_no_overlap get_object_wp simp: split_beta obj_at_def a_type_def wf_cs_upd [unfolded fun_upd_def]) definition if_unsafe_then_cap2 :: "(cslot_ptr \ cap) \ (irq \ obj_ref) \ bool" where "if_unsafe_then_cap2 f x \ \cref. (f cref \ None \ (the (f cref)) \ cap.NullCap) \ (\cref'. f cref' \ None \ cref \ cte_refs (the (f cref')) x \ appropriate_cte_cap (the (f cref)) (the (f cref')))" lemma null_filter_same: "cps p \ Some cap.NullCap \ null_filter cps p = cps p" by (simp add: null_filter_def) lemma cte_wp_at_not_Null: "cte_wp_at (\cp. cp \ cap.NullCap) p s \ caps_of_state s p \ Some cap.NullCap" by (clarsimp simp: cte_wp_at_caps_of_state) lemma unsafe_rep2: "if_unsafe_then_cap = (\s. if_unsafe_then_cap2 (null_filter (caps_of_state s)) (interrupt_irq_node s))" apply (simp only: if_unsafe_then_cap2_def o_def) apply (subst P_null_filter_caps_of_cte_wp_at, simp)+ apply (simp add: null_filter_same [where cps="caps_of_state s" for s, OF cte_wp_at_not_Null]) apply (fastforce simp: if_unsafe_then_cap2_def cte_wp_at_caps_of_state if_unsafe_then_cap_def ex_cte_cap_wp_to_def intro!: ext) done lemma descendants_inc_null_filter: "\mdb_cte_at (swp (cte_wp_at (op \ cap.NullCap)) s) (cdt s)\ \ descendants_inc (cdt s) (null_filter (caps_of_state s)) = descendants_inc (cdt s) (caps_of_state s)" apply (simp add:descendants_inc_def descendants_of_def del:split_paired_All) apply (intro iffI allI impI) apply (drule spec)+ apply (erule(1) impE) apply (frule tranclD) apply (drule tranclD2) apply (simp add:cdt_parent_rel_def is_cdt_parent_def del:split_paired_All) apply (elim conjE exE) apply (drule(1) mdb_cte_atD)+ apply (simp add:swp_def cte_wp_at_caps_of_state null_filter_def del:split_paired_All) apply (elim conjE exE) apply simp apply (drule spec)+ apply (erule(1) impE) apply (frule tranclD) apply (drule tranclD2) apply (simp add:cdt_parent_rel_def is_cdt_parent_def del:split_paired_All) apply (elim conjE exE) apply (drule(1) mdb_cte_atD)+ apply (simp add:swp_def cte_wp_at_caps_of_state null_filter_def del:split_paired_All) apply (elim conjE exE) apply simp done definition valid_mdb2 :: "[cslot_ptr \ cap, cslot_ptr \ cslot_ptr, cslot_ptr \ bool] \ bool" where "valid_mdb2 cps m r \ (\p p'. m p' = Some p \ {cps p, cps p'} \ {None, Some cap.NullCap} = {}) \ (\p p' c c'. cps p = Some c \ is_untyped_cap c \ cps p' = Some c' \ obj_refs c' \ untyped_range c \ {} \ p' \ descendants_of p m) \ descendants_inc m cps \ (\p. \ m \ p \ p) \ untyped_inc m cps \ ut_revocable r cps \ irq_revocable r cps \ reply_master_revocable r cps \ reply_mdb m cps \ valid_arch_mdb r cps" lemma conj_cong2: "\P = P'; P \ Q = Q'\ \ (P \ Q) = (P' \ Q')" by auto lemma valid_mdb_rep2: "valid_mdb = (\s. valid_mdb2 (null_filter (caps_of_state s)) (cdt s) (is_original_cap s))" apply (simp add: valid_mdb_def valid_mdb2_def untyped_mdb_def no_mloop_def untyped_inc_def) apply (rule ext) apply (rule conj_cong2) apply (simp add: mdb_cte_at_def) apply (rule arg_cong[where f=All, OF ext])+ apply ((clarsimp simp: cte_wp_at_caps_of_state null_filter_def | rule conjI iffI | drule iffD1 [OF not_None_eq, OF not_sym])+)[1] apply (rule conj_cong) apply (rule arg_cong[where f=All, OF ext])+ apply (clarsimp simp: null_filter_def) apply (rule conj_cong) apply (simp add:descendants_inc_null_filter) apply (rule arg_cong2 [where f="op \"]) apply (rule refl) apply (rule arg_cong2 [where f="op \"]) prefer 2 apply (rule arg_cong2 [where f="op \"]) apply (simp add: ut_revocable_def null_filter_def del: split_paired_All) apply (auto simp: is_cap_simps)[1] apply (rule arg_cong2 [where f="op \"]) apply (simp add: irq_revocable_def null_filter_def del: split_paired_All) apply auto[1] apply (rule arg_cong2 [where f="op \"]) apply (simp add: reply_master_revocable_def null_filter_def del: split_paired_All) apply (auto simp: is_cap_simps)[1] apply (simp add: reply_mdb_def null_filter_def) apply (rule arg_cong2 [where f="op \"]) apply (simp add: reply_caps_mdb_def del: split_paired_Ex split_paired_All) apply (fastforce intro!: iffI elim!: allEI exEI simp del: split_paired_Ex split_paired_All) apply (rule arg_cong2 [where f="op \"]) apply (fastforce simp: reply_masters_mdb_def intro!: iffI elim!: allEI simp del: split_paired_All split: if_split_asm) apply (fastforce simp: valid_arch_mdb_null_filter[simplified null_filter_def]) apply (rule arg_cong[where f=All, OF ext])+ apply ((clarsimp simp: cte_wp_at_caps_of_state null_filter_def | rule conjI iffI | drule iffD1 [OF not_None_eq, OF not_sym])+)[1] done lemma valid_mdb_rep3: "valid_mdb = (\s. \m r. cdt s = m \ is_original_cap s = r \ valid_mdb2 (null_filter (caps_of_state s)) m r)" by (simp add: valid_mdb_rep2) lemma retype_region_mdb[wp]: "\\s. P (cdt s)\ retype_region ptr n us ty dev \\rv s. P (cdt s)\" apply (simp add: retype_region_def split del: if_split cong: if_cong) apply (wp|clarsimp)+ done lemma retype_region_revokable[wp]: "\\s. P (is_original_cap s)\ retype_region ptr n us ty dev \\rv s. P (is_original_cap s)\" apply (simp add: retype_region_def split del: if_split cong: if_cong) apply (wp|clarsimp)+ done lemma pspace_no_overlap_obj_not_in_range: "\ pspace_no_overlap S s; obj_at P ptr' s; pspace_aligned s; valid_objs s \ \ ptr' \ S" apply (clarsimp simp add: pspace_no_overlap_def obj_at_def) apply (elim allE, drule(1) mp) apply (simp add: field_simps) apply (drule_tac x=ptr' in eqset_imp_iff) apply (erule pspace_alignedE, erule domI) apply (drule valid_obj_sizes, erule ranI) apply (clarsimp simp: add_diff_eq[symmetric]) apply (simp add: is_aligned_no_wrap') done lemma obj_at_kheap_trans_state[simp]:"obj_at P ptr (kheap_update f (trans_state f' s)) = obj_at P ptr (kheap_update f s)" apply (simp only: trans_state_update[symmetric] more_update.obj_at_update) done lemma retype_region_obj_at: assumes tyunt: "ty \ Structures_A.apiobject_type.Untyped" shows "\\\ retype_region ptr n us ty dev \\r s. \x \ set (retype_addrs ptr ty n us). obj_at (\ko. ko = default_object ty dev us) x s\" using tyunt unfolding retype_region_def apply (simp only: return_bind bind_return foldr_upd_app_if fun_app_def K_bind_def) apply wp apply (simp only: obj_at_kheap_trans_state) apply wp apply (simp only: simp_thms if_True) apply (rule ballI) apply (subst retype_addrs_fold) apply simp apply (unfold obj_at_def) apply clarsimp done lemma retype_region_obj_at_other: assumes ptrv: "ptr \ set (retype_addrs ptr' ty n us)" shows "\obj_at P ptr\ retype_region ptr' n us ty dev \\r. obj_at P ptr\" using ptrv unfolding retype_region_def retype_addrs_def apply (simp only: foldr_upd_app_if fun_app_def K_bind_def) apply (wpsimp simp: obj_at_def) done lemma retype_region_obj_at_other2: "\\s. ptr \ set (retype_addrs ptr' ty n us) \ obj_at P ptr s\ retype_region ptr' n us ty dev \\rv. obj_at P ptr\" by (rule hoare_assume_pre) (wpsimp wp: retype_region_obj_at_other) lemma retype_region_obj_at_other3: "\\s. pspace_no_overlap_range_cover ptr sz s \ obj_at P p s \ range_cover ptr sz (obj_bits_api ty us) n \ valid_objs s \ pspace_aligned s\ retype_region ptr n us ty dev \\rv. obj_at P p\" apply (rule hoare_pre) apply (rule retype_region_obj_at_other2) apply clarsimp apply (drule subsetD [rotated, OF _ retype_addrs_subset_ptr_bits]) apply simp apply (drule(3) pspace_no_overlap_obj_not_in_range) apply (simp add: field_simps) done lemma retype_region_st_tcb_at: "\\(s::'state_ext::state_ext state). pspace_no_overlap_range_cover ptr' sz s \ pred_tcb_at proj P t s \ range_cover ptr' sz (obj_bits_api ty us) n \ valid_objs s \ pspace_aligned s\ retype_region ptr' n us ty dev \\rv. pred_tcb_at proj P t\" by (simp add: retype_region_obj_at_other3 pred_tcb_at_def) lemma retype_region_cur_tcb[wp]: "\pspace_no_overlap_range_cover ptr sz and cur_tcb and K (range_cover ptr sz (obj_bits_api ty us) n) and K (is_aligned ptr sz \ sz < word_bits) and valid_objs and pspace_aligned\ retype_region ptr n us ty dev \\rv. cur_tcb\" apply (rule hoare_post_imp [where Q="\rv s. \tp. tcb_at tp s \ cur_thread s = tp"]) apply (simp add: cur_tcb_def) apply (wpsimp wp: hoare_vcg_ex_lift retype_region_obj_at_other3 simp: retype_region_def) apply (auto simp: cur_tcb_def cong: if_cong) done lemma retype_addrs_mem_sz_0_is_ptr: assumes "x \ set (retype_addrs ptr ty n us)" and "n = 0" shows "x = ptr" using assms unfolding retype_addrs_def by (clarsimp simp: ptr_add_def) locale Retype_AI_obj_bits_api_neq_0 = assumes obj_bits_api_neq_0: "\ty us. ty \ Untyped \ 0 < obj_bits_api ty us" lemma retype_addrs_range_subset: "\ p \ set (retype_addrs ptr ty n us); range_cover ptr sz (obj_bits_api ty us) n \ \ {p .. p + 2 ^ obj_bits_api ty us - 1} \ {ptr..(ptr && ~~ mask sz) + 2^sz - 1}" apply (clarsimp simp: retype_addrs_def ptr_add_def simp del: atLeastatMost_subset_iff atLeastAtMost_iff) apply (frule_tac x = "of_nat pa" in range_cover_cell_subset) apply (erule of_nat_mono_maybe[rotated]) apply (drule range_cover.range_cover_n_less) apply (simp add:word_bits_def) apply fastforce done context Retype_AI_slot_bits begin lemma retype_addrs_obj_range_subset: "\ p \ set (retype_addrs ptr ty n us); range_cover ptr sz (obj_bits (default_object ty dev us)) n; ty \ Untyped \ \ obj_range p (default_object ty dev us) \ {ptr..(ptr && ~~ mask sz) + (2^sz - 1)}" by(simp add: obj_range_def obj_bits_api_default_object[symmetric] retype_addrs_range_subset p_assoc_help[symmetric] del: atLeastatMost_subset_iff) lemma retype_addrs_obj_range_subset_strong: "\ p \ set (retype_addrs ptr ty n us); range_cover ptr sz (obj_bits_api ty us) n; ty \ Untyped \ \ obj_range p (default_object ty dev us) \ {ptr..ptr + of_nat n * 2 ^ obj_bits_api ty us - 1}" unfolding obj_range_def apply (frule retype_addrs_obj_range_subset) apply (simp add:obj_bits_dev_irr) apply (simp add:obj_range_def)+ apply (intro conjI impI) apply (erule(1) impE) apply clarsimp apply (case_tac "n = 0") apply (clarsimp simp:retype_addrs_def) proof - assume cover:"range_cover ptr sz (obj_bits_api ty us) n" and mem_p:"p \ set (retype_addrs ptr ty n us)" and not_0:"n\ 0" and tyunt:"ty\ Untyped" note n_less = range_cover.range_cover_n_less[OF cover] have unat_of_nat_m1: "unat (of_nat n - (1::machine_word)) < n" using not_0 n_less by (simp add:unat_of_nat_minus_1) have decomp:"of_nat n * 2 ^ obj_bits_api ty us = of_nat (n - 1) * 2 ^ (obj_bits (default_object ty dev us)) + (2 :: machine_word) ^ obj_bits (default_object ty dev us)" apply (simp add:distrib_right[where b = "1::'a::len word",simplified,symmetric]) using not_0 n_less apply (simp add: unat_of_nat_minus_1 obj_bits_api_def3 tyunt cong: obj_bits_cong) done show "p + 2 ^ obj_bits (default_object ty dev us) - 1 \ ptr + of_nat n * 2 ^ obj_bits_api ty us - 1" apply (subst decomp) apply (simp add:add.assoc[symmetric]) apply (simp add:p_assoc_help) apply (rule order_trans[OF word_plus_mono_left word_plus_mono_right]) using mem_p not_0 apply (clarsimp simp: retype_addrs_def ptr_add_def shiftl_t2n tyunt obj_bits_dev_irr) apply (rule word_plus_mono_right) apply (rule word_mult_le_mono1[OF word_of_nat_le]) using n_less not_0 apply (simp add:unat_of_nat_minus_1) apply (rule p2_gt_0[THEN iffD2]) using cover apply (simp add: word_bits_def range_cover_def obj_bits_dev_irr tyunt) apply (simp only: word_bits_def[symmetric]) using not_0 n_less apply (clarsimp simp: unat_of_nat_minus_1 obj_bits_dev_irr tyunt) apply (subst unat_power_lower) using cover apply (simp add:range_cover_def) apply (rule nat_less_power_trans2[OF range_cover.range_cover_le_n_less(2),OF cover, folded word_bits_def]) apply (simp add:unat_of_nat_m1 less_imp_le) using cover apply (simp add:range_cover_def word_bits_def) apply (rule machine_word_plus_mono_right_split[where sz = sz]) using range_cover.range_cover_compare[OF cover,where p = "unat (of_nat n - (1::machine_word))"] apply (clarsimp simp:unat_of_nat_m1) using cover apply (simp add:range_cover_def word_bits_def) apply (rule olen_add_eqv[THEN iffD2]) apply (subst add.commute[where a = "2^(obj_bits (default_object ty dev us)) - 1"]) apply (subst p_assoc_help[symmetric]) apply (rule is_aligned_no_overflow) apply (insert cover) apply (clarsimp simp:range_cover_def) apply (erule aligned_add_aligned[OF _ is_aligned_mult_triv2]) apply (simp add: obj_bits_dev_irr range_cover_def tyunt)+ done qed lemma retype_addrs_mem_subset_ptr_bits: assumes cover:"range_cover ptr sz (obj_bits_api ty us) n" and tynunt: "ty \ Untyped" and xv: "x \ set (retype_addrs ptr ty n us)" shows "{x .. x + (2 ^ obj_bits_api ty us - 1)} \ {ptr .. (ptr && ~~ mask sz) + (2 ^ sz - 1)}" apply (insert cover) using retype_addrs_obj_range_subset [OF xv _ tynunt] by (simp add: obj_bits_dev_irr tynunt obj_range_def field_simps) lemma pspace_no_overlap_retype_addrs_empty: assumes nptr: "pspace_no_overlap_range_cover ptr sz s" and xv: "x \ set (retype_addrs ptr ty n us)" and yv: "y \ set (retype_addrs ptr ty n us)" and kov: "kheap s y = Some ko" and tyv: "ty \ Structures_A.apiobject_type.Untyped" and cover: "range_cover ptr sz (obj_bits_api ty us) n" and oab: "obj_bits_api ty us \ sz" shows "{x..x + (2 ^ obj_bits (default_object ty dev us) - 1)} \ {y..y + (2 ^ obj_bits ko - 1)} = {}" proof - have "{x..x + (2 ^ obj_bits (default_object ty dev us) - 1)} \ {ptr..(ptr && ~~ mask sz) + (2 ^ sz - 1)}" by (subst obj_bits_api_default_object [OF tyv, symmetric], rule retype_addrs_mem_subset_ptr_bits) fact+ moreover have "{ptr..(ptr && ~~ mask sz) + (2 ^ sz - 1)} \ {y..y + (2 ^ obj_bits ko - 1)} = {}" by (subst Int_commute, rule pspace_no_overlapE) fact+ ultimately show ?thesis by auto qed end lemma valid_obj_default_object: assumes tyunt: "ty \ Untyped" and tyct: "ty = CapTableObject \ us < word_bits - cte_level_bits \ 0 < us" and arch: "valid_arch_tcb default_arch_tcb s" shows "valid_obj ptr (default_object ty dev us) s" unfolding valid_obj_def default_object_def apply (cases ty) apply (simp add: tyunt) apply (simp add: valid_tcb_def default_tcb_def valid_tcb_state_def tcb_cap_cases_def valid_ipc_buffer_cap_def word_bits_def arch) apply (simp add: valid_ep_def default_ep_def) apply (simp add: valid_ntfn_def default_notification_def default_ntfn_def valid_bound_tcb_def) apply (frule tyct) apply (clarsimp simp: valid_cs_def empty_cnode_def well_formed_cnode_n_def) apply safe apply (erule ranE) apply (simp split: if_split_asm) apply (simp add: valid_cs_size_def well_formed_cnode_n_def) apply safe apply (simp split: if_split_asm) apply (clarsimp split: if_split_asm) apply (clarsimp simp add: wellformed_arch_default) done lemma valid_vspace_obj_default: assumes tyunt: "ty \ Structures_A.apiobject_type.Untyped" shows "ArchObj ao = default_object ty dev us \ valid_vspace_obj ao s'" apply (cases ty, simp_all add: default_object_def tyunt) apply (simp add: valid_vspace_obj_default') done lemma usable_range_subseteq: "\cap_aligned cap;is_untyped_cap cap\ \ usable_untyped_range cap \ untyped_range cap" apply (clarsimp simp:is_cap_simps cap_aligned_def split:if_splits) apply (erule order_trans[OF is_aligned_no_wrap']) apply (erule of_nat_power) apply (simp add:word_bits_def)+ done lemma usable_range_emptyD: "\cap_aligned cap;is_untyped_cap cap ;usable_untyped_range cap = {}\ \ 2 ^ cap_bits cap \ free_index_of cap" apply (clarsimp simp:is_cap_simps not_le free_index_of_def cap_aligned_def split:if_splits) apply (drule(1) of_nat_power [where 'a=machine_word_len, folded word_bits_def]) apply (drule word_plus_mono_right[OF _ is_aligned_no_overflow[unfolded p_assoc_help],rotated]) apply simp apply (simp add:p_assoc_help) done locale Retype_AI_valid_untyped_helper = fixes state_ext_t :: "'state_ext::state_ext itself" assumes valid_untyped_helper: "\s c q ty ptr sz us n dev. \ (s :: 'state_ext state) \ c; cte_wp_at (op = c) q s; ty \ Untyped; range_cover ptr sz (obj_bits_api ty us) n; is_untyped_cap c \ usable_untyped_range c \ {ptr..ptr + of_nat (n * 2 ^ (obj_bits_api ty us)) - 1} = {}; pspace_no_overlap_range_cover ptr sz s; caps_no_overlap ptr sz s; valid_pspace s \ \ valid_cap c (s\kheap := \x. if x \ set (retype_addrs ptr ty n us) then Some (default_object ty dev us) else kheap s x\)" lemma cap_refs_respects_device_region_cap_range: "\cte_wp_at (\c. {ptr..(ptr && ~~ mask sz) + (2 ^ sz - 1)} \ cap_range c \ cap_is_device c = dev) slot s; cap_refs_respects_device_region s\ \ up_aligned_area ptr sz \ (if dev then device_region s else - device_region s)" unfolding cap_refs_respects_device_region_def apply (drule spec[where x = slot]) apply (clarsimp simp: cte_wp_at_caps_of_state cap_range_respects_device_region_def) apply fastforce done locale retype_region_proofs = fixes s :: "'state_ext :: state_ext state" and ty us ptr sz n ps s' dev assumes vp: "valid_pspace s" and vm: "valid_mdb s" and res: "caps_overlap_reserved {ptr..ptr + of_nat (n * 2 ^ (obj_bits_api ty us)) - 1} s" and tyunt: "ty \ Structures_A.apiobject_type.Untyped" and tyct: "ty = CapTableObject \ us < word_bits - cte_level_bits \ 0 < us" and orth: "pspace_no_overlap_range_cover ptr sz s" and mem : "caps_no_overlap ptr sz s" and cover: "range_cover ptr sz (obj_bits_api ty us) n" and dev: "\slot. cte_wp_at (\c. {ptr..(ptr && ~~ mask sz) + (2 ^ sz - 1)} \ cap_range c \ cap_is_device c = dev) slot s" defines "ps \ (\x. if x \ set (retype_addrs ptr ty n us) then Some (default_object ty dev us) else kheap s x)" and "s' \ kheap_update (\y. ps) s" locale retype_region_proofs_gen = retype_region_proofs s ty us ptr sz n ps s' dev + Retype_AI_slot_bits + Retype_AI_valid_untyped_helper "TYPE('state_ext)" for s :: "'state_ext :: state_ext state" and ty us ptr sz n ps s' dev + assumes hyp_refs_eq: "state_hyp_refs_of s' = state_hyp_refs_of s" assumes valid_arch_tcb_default[simp]: "\s :: 'state_ext :: state_ext state. valid_arch_tcb default_arch_tcb s" assumes wellformed_default_obj: "\ ptra \ set (retype_addrs ptr ty n us); kheap s ptra = Some (ArchObj x5); arch_valid_obj x5 s\ \ arch_valid_obj x5 s'" context retype_region_proofs begin lemma obj_at_pres: "\P x. obj_at P x s \ obj_at P x s'" by (clarsimp simp: obj_at_def s'_def ps_def dest: domI) (rule pspace_no_overlapC [OF orth _ _ cover vp]) lemma orthr: "\x obj. kheap s x = Some obj \ x \ set (retype_addrs ptr ty n us)" apply (rule ccontr) apply (frule pspace_no_overlapC[OF orth _ _ _ vp,rotated]) apply (rule cover) apply auto done lemma cte_at_pres: "\p. cte_at p s \ cte_at p s'" unfolding cte_at_cases s'_def ps_def apply (erule disjE) apply (clarsimp simp: well_formed_cnode_n_def orthr)+ done lemma pred_tcb_at_pres: "\P t. pred_tcb_at proj P t s \ pred_tcb_at proj P t s'" unfolding pred_tcb_at_def by (erule obj_at_pres) end context retype_region_proofs_gen begin lemma psp_dist: shows "pspace_distinct s'" proof - have distinct:"pspace_distinct s" apply (rule valid_pspaceE) apply (rule vp) apply simp done moreover { fix x y assume xne: "x \ y" and xv: "x \ set (retype_addrs ptr ty n us)" and yv: "y \ set (retype_addrs ptr ty n us)" have "is_aligned x (obj_bits_api ty us)" apply (rule retype_addrs_aligned) apply fact+ apply (insert cover) apply (auto simp: range_cover_def word_bits_def) done moreover have "is_aligned y (obj_bits_api ty us)" apply (rule retype_addrs_aligned) apply fact+ apply (insert cover) apply (auto simp: range_cover_def word_bits_def) done ultimately have "{x..x + (2 ^ obj_bits (default_object ty dev us) - 1)} \ {y..y + (2 ^ obj_bits (default_object ty dev us) - 1)} = {}" using xne tyunt cover apply - apply (rule aligned_neq_into_no_overlap) apply (simp_all add: range_cover_def word_bits_def obj_bits_dev_irr) done } note inter = this moreover { fix x y ko' assume xne: "x \ y" and xv: "x \ set (retype_addrs ptr ty n us)" and yv: "y \ set (retype_addrs ptr ty n us)" and "kheap s y = Some ko'" have "{x..x + (2 ^ obj_bits (default_object ty dev us) - 1)} \ {y..y + (2 ^ obj_bits ko' - 1)} = {}" apply (rule pspace_no_overlap_retype_addrs_empty [OF orth]) apply fact+ apply (insert cover tyunt) apply (simp add: range_cover_def word_bits_def)+ done }note inter' = this show ?thesis unfolding pspace_distinct_def s'_def ps_def apply (clarsimp split: if_split_asm option.splits simp del: Int_atLeastAtMost) apply (intro conjI impI allI) apply (erule(2) inter) apply clarify apply (erule(3) inter') apply clarify apply (subst Int_commute) apply (erule(3) inter'[OF neq_commute[THEN iffD1]]) apply clarify apply (insert vp[unfolded valid_pspace_def pspace_distinct_def]) apply clarify apply (drule_tac x = x in spec) apply (drule_tac x = y in spec) apply (erule allE impE)+ apply fastforce apply simp done qed lemma psp_al: shows "pspace_aligned s'" unfolding pspace_aligned_def s'_def ps_def proof (clarsimp split: if_split_asm) fix x assume "x \ set (retype_addrs ptr ty n us)" thus "is_aligned x (obj_bits (default_object ty dev us))" apply - apply (drule retype_addrs_aligned) apply (insert cover tyunt) apply (fastforce simp:range_cover_def word_bits_def)+ apply (simp add: obj_bits_dev_irr split: Structures_A.apiobject_type.splits) done next fix x y assume "x \ set (retype_addrs ptr ty n us)" and px: "kheap s x = Some y" have "pspace_aligned s" by (rule valid_pspaceE[OF vp],simp) thus "is_aligned x (obj_bits y)" proof show "x \ dom (kheap s)" by (rule domI) fact+ next assume "is_aligned x (obj_bits (the (kheap s x)))" thus "is_aligned x (obj_bits y)" using px by simp qed qed end lemma le_subset: "\(a::('g::len) word) \ c\ \ {c..b} \ {a..b}" by clarsimp context retype_region_proofs_gen begin lemma valid_cap_pres: "\ s \ c; cte_wp_at (op = c) (oref,cref) s \ \ s' \ c" using cover mem orth apply (simp add:s'_def ps_def) apply (rule valid_untyped_helper[ OF _ _ tyunt cover _ _ _ vp ]) apply simp+ apply (simp add:cte_wp_at_caps_of_state) apply (drule res[unfolded caps_overlap_reserved_def,THEN bspec,OF ranI]) apply simp apply simp+ done lemma valid_objs: "valid_objs s'" apply (clarsimp simp:valid_objs_def) apply (rule valid_pspaceE[OF vp]) apply (clarsimp simp:valid_objs_def s'_def ps_def split:if_splits) apply (simp add:valid_obj_default_object[OF tyunt tyct]) apply (simp (no_asm) add:valid_obj_def) apply (drule bspec) apply (erule domI) apply (clarsimp simp:valid_obj_def split:Structures_A.kernel_object.splits) apply (clarsimp simp: valid_cs_def) apply (drule (1) bspec) apply (clarsimp simp: ran_def) apply (erule valid_cap_pres[unfolded s'_def ps_def]) apply (clarsimp simp add: cte_wp_at_cases valid_cs_size_def s'_def ps_def) apply fastforce apply (clarsimp simp: valid_tcb_def) apply (rule conjI) apply (rule ballI, drule(1) bspec, clarsimp elim!: ranE) apply (erule valid_cap_pres[unfolded s'_def ps_def]) apply (rule cte_wp_at_tcbI, fastforce+)[1] apply (fastforce simp: valid_tcb_state_def valid_bound_ntfn_def elim!: obj_at_pres[unfolded s'_def ps_def] valid_arch_tcb_typ_at split: Structures_A.thread_state.splits option.splits) apply (fastforce simp: valid_ep_def elim!: obj_at_pres[unfolded s'_def ps_def] split: Structures_A.endpoint.splits) apply (fastforce simp: valid_ntfn_def valid_bound_tcb_def elim!: obj_at_pres[unfolded s'_def ps_def] split: Structures_A.ntfn.splits option.splits) apply (clarsimp simp: wellformed_default_obj[unfolded s'_def ps_def]) done end context retype_region_proofs begin lemma refs_eq: "state_refs_of s' = state_refs_of s" unfolding s'_def ps_def apply (clarsimp intro!: ext simp: state_refs_of_def simp: orthr split: option.splits) apply (cases ty, simp_all add: tyunt default_object_def default_tcb_def default_ep_def default_notification_def default_ntfn_def) done lemma cte_retype: "\P p. \ P cap.NullCap \ cte_wp_at P p s' = cte_wp_at P p s" unfolding s'_def ps_def apply (safe elim!: cte_wp_atE) apply (clarsimp split: if_split_asm Structures_A.apiobject_type.split_asm simp: default_object_def tyunt default_tcb_def empty_cnode_def cte_wp_at_cases dest!: orthr | simp add: tcb_cap_cases_def)+ done lemma iflive_s: "if_live_then_nonz_cap s" by (rule valid_pspaceE [OF vp]) lemma default_object_not_live: "\ live (default_object ty dev us)" apply (cases ty, simp_all add: tyunt default_object_def default_tcb_not_live default_arch_object_not_live) apply (simp add: live_def default_ep_def default_notification_def default_ntfn_def)+ done lemma iflive: "if_live_then_nonz_cap s'" using iflive_s unfolding if_live_then_nonz_cap_def s'_def ps_def apply - apply (clarsimp elim!: obj_atE simp: default_object_not_live split: if_split_asm) apply (frule(1) if_live_then_nonz_capD2[OF iflive_s]) apply (simp add: ex_nonz_cap_to_def cte_retype[unfolded s'_def ps_def]) done lemma final_retype: "is_final_cap' cap s' = is_final_cap' cap s" by (simp add: is_final_cap'_def2 cte_retype) lemma not_final_NullCap: "\s. \ is_final_cap' cap.NullCap s" by (simp add: is_final_cap'_def) lemma zombies_s: "zombies_final s" by (rule valid_pspaceE[OF vp]) lemma zombies: "zombies_final s'" unfolding zombies_final_def by (clarsimp simp: final_retype is_zombie_def cte_retype not_final_NullCap elim!: zombies_finalD [OF _ zombies_s]) end lemma (in retype_region_proofs_gen) valid_pspace: "valid_pspace s'" using vp by (simp add: valid_pspace_def valid_objs psp_al psp_dist iflive zombies refs_eq hyp_refs_eq) (* I have the feeling I'm making this unnecessarily hard, but I can't put my finger on where. *) lemma F: "\x c s. (caps_of_state s x = Some c) = (cte_wp_at (op = c) x s)" apply (simp add: caps_of_state_cte_wp_at) apply (fastforce simp: cte_wp_at_def) done lemma F2: "\x c s. (null_filter (caps_of_state s) x = Some c) = (cte_wp_at (\cap. cap \ cap.NullCap \ cap = c) x s)" apply (simp add: null_filter_def F) apply (fastforce simp: cte_wp_at_def) done lemma F3: "\x s. (None = null_filter (caps_of_state s) x) = (\c. \ cte_wp_at (\cap. cap \ cap.NullCap \ cap = c) x s)" apply safe apply (simp add: F2[symmetric]) apply (rule sym, rule ccontr, clarsimp simp: F2) done lemma (in retype_region_proofs) null_filter: "null_filter (caps_of_state s') = null_filter (caps_of_state s)" apply (rule ext) apply (case_tac "null_filter (caps_of_state s) x") apply (simp add: eq_commute) apply (simp add: F3 cte_retype) apply simp apply (simp add: F2 cte_retype) done context retype_region_proofs begin lemma idle_s': "idle_thread s' = idle_thread s" by (simp add: s'_def ps_def) lemma valid_idle: "valid_idle s \ valid_idle s'" by (clarsimp simp add: valid_idle_def idle_s' refs_eq pred_tcb_at_pres) lemma arch_state [simp]: "arch_state s' = arch_state s" by (simp add: s'_def) lemma irq_node [simp]: "interrupt_irq_node s' = interrupt_irq_node s" by (simp add: s'_def) lemma caps_retype: assumes nonnull: "cap \ cap.NullCap" and newcap: "caps_of_state s' p = Some cap" shows "caps_of_state s p = Some cap" proof - from newcap have "cte_wp_at (op = cap) p s'" by (simp add: cte_wp_at_caps_of_state) hence "cte_wp_at (op = cap) p s" by (rule_tac subst [OF cte_retype], rule_tac nonnull, assumption) thus ?thesis by (simp add: cte_wp_at_caps_of_state) qed lemma unique_reply_caps: "unique_reply_caps (caps_of_state s) \ unique_reply_caps (caps_of_state s')" using caps_retype by (fastforce simp add: is_cap_simps unique_reply_caps_def simp del: split_paired_All elim!: allEI) lemma valid_reply_caps: "valid_reply_caps s \ valid_reply_caps s'" by (clarsimp simp: valid_reply_caps_def unique_reply_caps has_reply_cap_def pred_tcb_at_pres cte_retype) lemma valid_reply_masters: "valid_reply_masters s \ valid_reply_masters s'" by (clarsimp simp: valid_reply_masters_def cte_retype is_cap_simps obj_at_pres) end lemma ran_null_filter: "ran (null_filter m) = (ran m - {cap.NullCap})" apply (simp add: null_filter_def ran_def cong: conj_cong) apply force done lemma valid_irq_handlers_def2: "valid_irq_handlers = (\s. \cap \ ran (null_filter (caps_of_state s)). \irq \ cap_irqs cap. interrupt_states s irq = irq_state.IRQSignal)" apply (rule ext) apply (simp add: valid_irq_handlers_def irq_issued_def ran_null_filter) apply auto done lemma p_in_obj_range: "\ kheap s p = Some ko; pspace_aligned s; valid_objs s \ \ p \ obj_range p ko" apply (simp add: pspace_aligned_def) apply (drule bspec, erule domI) apply (drule valid_obj_sizes, erule ranI) apply (simp add: obj_range_def add_diff_eq[symmetric]) apply (erule is_aligned_no_wrap') apply (erule word_power_less_1[where 'a=machine_word_len, folded word_bits_def]) done lemma p_in_obj_range_internal: "\ kheap s (p && ~~ mask (obj_bits ko))= Some ko; pspace_aligned s; valid_objs s \ \ p \ obj_range (p && ~~ mask (obj_bits ko)) ko" apply (drule p_in_obj_range,simp+) apply (simp add: obj_range_def word_and_le2 word_neg_and_le p_assoc_help) done context retype_region_proofs begin lemma interrupt_states: "interrupt_states s' = interrupt_states s" by (simp add: s'_def) lemma valid_irq_handlers: "valid_irq_handlers s \ valid_irq_handlers s'" by (simp add: valid_irq_handlers_def2 null_filter interrupt_states) lemma mdb_and_revokable: "cdt s' = cdt s" "is_original_cap s' = is_original_cap s" by (simp add: s'_def)+ lemma cur_tcb: "cur_tcb s \ cur_tcb s'" apply (simp add: cur_tcb_def, rule obj_at_pres) apply (simp add: s'_def) done lemma only_idle: "only_idle s \ only_idle s'" apply (clarsimp simp: only_idle_def) apply (clarsimp simp: s'_def pred_tcb_at_def obj_at_def ps_def split: if_split_asm) apply (simp add: default_object_def tyunt split: Structures_A.apiobject_type.splits) apply (simp add: default_tcb_def) done lemma valid_irq_states: "valid_irq_states s \ valid_irq_states s'" apply(simp add: s'_def valid_irq_states_def) done lemma cap_refs_in_kernel_window: "cap_refs_in_kernel_window s \ cap_refs_in_kernel_window s'" apply (simp add: cap_refs_in_kernel_window_def valid_refs_def) apply (simp add: cte_retype cap_range_def) done lemma valid_ioc: "valid_ioc s \ valid_ioc s'" using cte_retype by (simp add: valid_ioc_def s'_def) end locale retype_region_proofs_invs = retype_region_proofs_gen s ty us ptr sz n ps s' dev + Retype_AI_post_retype_invs "TYPE('state_ext)" post_retype_invs_check post_retype_invs for s :: "'state_ext :: state_ext state" and ty us ptr sz n ps s' dev post_retype_invs_check and post_retype_invs :: "apiobject_type \ machine_word list \ 'state_ext state \ bool" + fixes region_in_kernel_window :: "machine_word set \ 'state_ext state \ bool" assumes valid_global_refs: "valid_global_refs s \ valid_global_refs s'" assumes valid_arch_state: "valid_arch_state s \ valid_arch_state s'" assumes valid_vspace_objs': "valid_vspace_objs s \ valid_vspace_objs s'" assumes valid_cap: "(s::'state_ext state) \ cap \ untyped_range cap \ {ptr .. (ptr && ~~ mask sz) + 2 ^ sz - 1} = {} \ s' \ cap" assumes post_retype_invs: "\ invs (s :: 'state_ext state); region_in_kernel_window {ptr .. (ptr && ~~ mask sz) + 2 ^ sz - 1} s \ \ post_retype_invs ty (retype_addrs ptr ty n us) s'" context Retype_AI_slot_bits begin lemma use_retype_region_proofs': assumes x: "\s. \ retype_region_proofs s ty us ptr sz n dev; P s \ \ Q (retype_addrs ptr ty n us) (s\kheap := \x. if x \ set (retype_addrs ptr ty n us) then Some (default_object ty dev us) else kheap s x\)" assumes y: "\x s f. Q x (trans_state f s) = Q x s" shows "\ ty = CapTableObject \ 0 < us; \s. P s \ Q (retype_addrs ptr ty n us) s \ \ \\s. valid_pspace s \ valid_mdb s \ range_cover ptr sz (obj_bits_api ty us) n \ caps_overlap_reserved {ptr..ptr + of_nat n * 2 ^ obj_bits_api ty us - 1} s \ caps_no_overlap ptr sz s \ pspace_no_overlap_range_cover ptr sz s \ (\slot. cte_wp_at (\c. {ptr..(ptr && ~~ mask sz) + (2 ^ sz - 1)} \ cap_range c \ cap_is_device c = dev) slot s) \ P s\ retype_region ptr n us ty dev \Q\" apply (simp add: retype_region_def split del: if_split) apply (rule hoare_pre, (wp|simp add:y trans_state_update[symmetric] del: trans_state_update)+) apply (clarsimp simp: retype_addrs_fold foldr_upd_app_if fun_upd_def[symmetric]) apply safe apply (rule x) apply (rule retype_region_proofs.intro, simp_all)[1] apply (fastforce simp add: range_cover_def obj_bits_api_def slot_bits_def2 word_bits_def)+ done end locale Retype_AI = Retype_AI_clearMemoryVM + Retype_AI_slot_bits + Retype_AI_retype_region_ret state_ext_t + Retype_AI_post_retype_invs state_ext_t post_retype_invs_check post_retype_invs + Retype_AI_obj_bits_api_neq_0 + Retype_AI_no_gs_types no_gs_types + Retype_AI_dmo_eq_kernel_restricted state_ext_t machine_op_t for state_ext_t :: "'state_ext::state_ext itself" and post_retype_invs_check and post_retype_invs :: "apiobject_type \ machine_word list \ 'state_ext state \ bool" and no_gs_types and machine_op_t :: "'machine_op_t itself" + fixes state_ext'_t :: "'state_ext'::state_ext itself" fixes region_in_kernel_window :: "machine_word set \ 'state_ext state \ bool" assumes invs_post_retype_invs: "\(s::'state_ext state) ty refs. invs s \ post_retype_invs ty refs s" assumes equal_kernel_mappings_trans_state[simp]: "\(f::'state_ext \ 'state_ext') (s::'state_ext state). equal_kernel_mappings (trans_state f s) = equal_kernel_mappings s" assumes retype_region_proofs_assms: "\s ty us ptr sz n dev. retype_region_proofs (s::'state_ext state) ty us ptr sz n dev \ retype_region_proofs_invs s ty us ptr sz n dev post_retype_invs_check post_retype_invs region_in_kernel_window" context Retype_AI begin lemmas use_retype_region_proofs = use_retype_region_proofs'[where Q="\_. Q" and P=Q, simplified] for Q lemma retype_region_proofs_assms': assumes "retype_region_proofs (s::'state_ext state) ty us ptr sz n dev" shows "retype_region_proofs_gen s ty us ptr sz n dev" using assms retype_region_proofs_assms by (auto simp: retype_region_proofs_invs_def) lemmas retype_region_valid_pspace = use_retype_region_proofs [where Q=valid_pspace, OF retype_region_proofs_gen.valid_pspace[OF retype_region_proofs_assms'], simplified] lemmas retype_region_caps_of = use_retype_region_proofs [where Q="\s. P (null_filter (caps_of_state s))", OF ssubst [where P=P, OF retype_region_proofs.null_filter], simplified] for P lemma retype_region_valid_cap: "\ty = Structures_A.apiobject_type.CapTableObject \ 0 < us\ \ \(\s::'state_ext state. valid_pspace s \ caps_overlap_reserved {ptr..ptr + of_nat n * 2 ^ obj_bits_api ty us - 1} s \ valid_mdb s \ range_cover ptr sz (obj_bits_api ty us) n \ caps_no_overlap ptr sz s \ pspace_no_overlap_range_cover ptr sz s \ (\slot. cte_wp_at (\c. {ptr..(ptr && ~~ mask sz) + (2 ^ sz - 1)} \ cap_range c \ cap_is_device c = dev) slot s) \ s \ cap) and K (untyped_range cap \ {ptr..(ptr &&~~ mask sz) + 2 ^ sz - 1} = {})\ retype_region ptr n us ty dev \\r s. s \ cap\" apply (rule hoare_gen_asm) apply (rule hoare_pre) apply (rule use_retype_region_proofs) apply (erule retype_region_proofs_invs.valid_cap[OF retype_region_proofs_assms]) apply simp+ done lemmas retype_region_aligned = use_retype_region_proofs [where Q=pspace_aligned, OF retype_region_proofs_gen.psp_al[OF retype_region_proofs_assms'], simplified] lemmas retype_region_valid_idle = use_retype_region_proofs [where Q=valid_idle, OF retype_region_proofs.valid_idle, simplified] lemmas retype_region_valid_arch = use_retype_region_proofs [where Q=valid_arch_state, OF retype_region_proofs_invs.valid_arch_state[OF retype_region_proofs_assms], simplified] lemmas retype_region_valid_globals = use_retype_region_proofs [where Q=valid_global_refs, OF retype_region_proofs_invs.valid_global_refs[OF retype_region_proofs_assms], simplified] lemmas retype_region_valid_reply_caps = use_retype_region_proofs [where Q=valid_reply_caps, OF retype_region_proofs.valid_reply_caps, simplified] lemmas retype_region_valid_reply_masters = use_retype_region_proofs [where Q=valid_reply_masters, OF retype_region_proofs.valid_reply_masters, simplified] lemmas retype_region_arch_objs = use_retype_region_proofs [where Q=valid_vspace_objs, OF retype_region_proofs_invs.valid_vspace_objs'[OF retype_region_proofs_assms], simplified] crunch irq_node[wp]: retype_region "\s. P (interrupt_irq_node s)" (simp: crunch_simps) crunch interrupt_states[wp]: retype_region "\s. P (interrupt_states s)" (simp: crunch_simps) lemma invs_trans_state[simp]: "invs (trans_state f s) = invs s" apply (simp add: invs_def valid_state_def) done lemma post_retype_invs_trans_state[simp]: "post_retype_invs ty refs (trans_state f s) = post_retype_invs ty refs s" apply (simp add: post_retype_invs_def') apply (simp add: trans_state_update[symmetric] del: trans_state_update) done lemma retype_region_post_retype_invs: "\(invs::'state_ext state \ bool) and caps_no_overlap ptr sz and pspace_no_overlap_range_cover ptr sz and caps_overlap_reserved {ptr..ptr + of_nat n * 2 ^ obj_bits_api ty us - 1} and region_in_kernel_window {ptr .. (ptr && ~~ mask sz) + 2 ^ sz - 1} and (\s. \slot. cte_wp_at (\c. {ptr..(ptr && ~~ mask sz) + (2 ^ sz - 1)} \ cap_range c \ cap_is_device c = dev) slot s) and K (ty = Structures_A.CapTableObject \ 0 < us) and K (range_cover ptr sz (obj_bits_api ty us) n) \ retype_region ptr n us ty dev\\rv. post_retype_invs ty rv\" apply (rule hoare_gen_asm)+ apply (rule hoare_pre, rule use_retype_region_proofs'[where sz = sz and P="invs and region_in_kernel_window {ptr .. (ptr &&~~ mask sz) + 2 ^ sz - 1}"]) apply (rule retype_region_proofs_invs.post_retype_invs [OF retype_region_proofs_assms], simp+) apply (simp add: invs_post_retype_invs) apply (clarsimp simp:invs_def valid_state_def) done lemma subset_not_le_trans: "\\ A \ B; C \ B\ \ \ A \ C" by auto lemma cte_wp_at_trans_state[simp]: "cte_wp_at P ptr (kheap_update f (trans_state f' s)) = cte_wp_at P ptr (kheap_update f s)" by (simp add: trans_state_update[symmetric] del: trans_state_update) lemma retype_region_cte_at_other: assumes cover: "range_cover ptr' sz (obj_bits_api ty us) n" shows "\\s. pspace_no_overlap_range_cover ptr' sz s \ cte_wp_at P ptr s \ valid_pspace s\ retype_region ptr' n us ty dev \\r. cte_wp_at P ptr\" unfolding retype_region_def apply (simp only: foldr_upd_app_if fun_app_def K_bind_def) apply wp apply (simp only: cte_wp_at_trans_state) apply wp+ apply (subst retype_addrs_fold) apply clarsimp apply (clarsimp simp: cte_wp_at_cases del: disjCI) apply (erule disjEI) apply (auto dest!: pspace_no_overlapD1[OF _ _ cover]) done lemma retype_cte_wp_at: "\\s. cte_wp_at P ptr s \ pspace_no_overlap_range_cover ptr' sz s \ valid_pspace s \ range_cover ptr' sz (obj_bits_api ty us) n\ retype_region ptr' n us ty dev \\r. cte_wp_at P ptr\" apply (rule hoare_assume_pre) apply (rule hoare_pre) apply (rule retype_region_cte_at_other) apply fastforce apply simp done lemma pspace_no_overlap_typ_at_def: "pspace_no_overlap S = (\s. \T x. typ_at T x s \ {x..x + (2 ^ obj_bits_type T - 1)} \ S = {})" apply (simp add: pspace_no_overlap_def obj_at_def) apply (rule ext) apply (auto simp: obj_bits_T) done lemma pspace_no_overlap_typ_at_lift: assumes f: "\P T p. \\s. P (typ_at T p s)\ f \\rv s. P (typ_at T p s)\" shows "\pspace_no_overlap S\ f \\rv. pspace_no_overlap S\" apply (clarsimp simp: pspace_no_overlap_typ_at_def) apply (wp hoare_vcg_all_lift f) done lemma swp_clearMemoryVM [simp]: "swp clearMemoryVM x = (\_. return ())" by (rule ext,simp) (* FIXME: move *) lemma bind_assoc_reverse: "(do x \ A; _ \ B x; C x od) = (do x \ do x \ A; _ \ B x; return x od; C x od)" by (simp only: bind_assoc return_bind) (* FIXME: move *) lemmas do_machine_op_bind = submonad_bind [OF submonad_do_machine_op submonad_do_machine_op submonad_do_machine_op] (* FIXME: move *) lemmas do_machine_op_return = submonad_do_machine_op.return lemma ioc_more_swap[simp]: " s'\exst := sa', is_original_cap := sa\ = s'\is_original_cap := sa, exst := sa'\" apply simp done lemma is_final_cap'_more_update[simp]: "is_final_cap' cap (trans_state f s) = is_final_cap' cap s" by (simp add: is_final_cap'_def) lemma no_cap_to_obj_with_diff_ref_more_update[simp]: "no_cap_to_obj_with_diff_ref cap sl (trans_state f s) = no_cap_to_obj_with_diff_ref cap sl s" by (simp add: no_cap_to_obj_with_diff_ref_def) end (* FIXME: irq_state stuff moved from CNodeInv_AI, not clear it makes sense here. *) lemma cte_wp_at_irq_state_independent[intro!, simp]: "is_final_cap' x (s\machine_state := machine_state s\irq_state := f (irq_state (machine_state s))\\) = is_final_cap' x s" by (simp add: is_final_cap'_def) lemma zombies_final_irq_state_independent[intro!, simp]: "zombies_final (s\machine_state := machine_state s\irq_state := f (irq_state (machine_state s))\\) = zombies_final s" by (simp add: zombies_final_def) lemma ex_cte_cap_wp_to_irq_state_independent[intro!, simp]: "ex_cte_cap_wp_to x y (s\machine_state := machine_state s\irq_state := f (irq_state (machine_state s))\\) = ex_cte_cap_wp_to x y s" by (simp add: ex_cte_cap_wp_to_def) end