1(* 2 * Copyright 2014, General Dynamics C4 Systems 3 * 4 * This software may be distributed and modified according to the terms of 5 * the GNU General Public License version 2. Note that NO WARRANTY is provided. 6 * See "LICENSE_GPLv2.txt" for details. 7 * 8 * @TAG(GD_GPL) 9 *) 10 11theory ArchInvariants_AI 12imports "../InvariantsPre_AI" 13begin 14 15\<comment> \<open>---------------------------------------------------------------------------\<close> 16section "Move this up" 17 18qualify ARM (in Arch) 19 20(* FIXME: move to spec level *) 21(* global data and code of the kernel, not covered by any cap *) 22axiomatization 23 kernel_data_refs :: "word32 set" 24 25end_qualify 26 27\<comment> \<open>---------------------------------------------------------------------------\<close> 28section "ARM-specific invariant definitions" 29 30qualify ARM_A (in Arch) 31(* ARM has no interest for iarch_tcb (introduced for ARM_HYP) , 32 and we consider no non-trivial predicates of iarch_tcb, 33 so an unspecified typedecl seems appropriate. 34 In contrast to using a unit type, this avoids 35 over-simplification of idle_tcb_at predicates, 36 which would make it hard to use facts that talk about idle_tcb_at. *) 37typedecl iarch_tcb 38end_qualify 39 40context Arch begin global_naming ARM 41 42definition 43 arch_tcb_to_iarch_tcb :: "arch_tcb \<Rightarrow> iarch_tcb" 44where 45 "arch_tcb_to_iarch_tcb arch_tcb \<equiv> undefined" 46 47lemma iarch_tcb_context_set[simp]: 48 "arch_tcb_to_iarch_tcb (arch_tcb_context_set p tcb) = arch_tcb_to_iarch_tcb tcb" 49 by (auto simp: arch_tcb_to_iarch_tcb_def arch_tcb_context_set_def) 50 51lemma iarch_tcb_set_registers[simp]: 52 "arch_tcb_to_iarch_tcb (arch_tcb_set_registers regs arch_tcb) 53 = arch_tcb_to_iarch_tcb arch_tcb" 54 by (simp add: arch_tcb_set_registers_def) 55 56(* These simplifications allows us to keep many arch-specific proofs unchanged. *) 57 58lemma arch_cap_fun_lift_expand[simp]: 59 "(arch_cap_fun_lift (\<lambda> ac. case ac of 60 ASIDPoolCap obj_ref asid \<Rightarrow> P_ASIDPoolCap obj_ref asid 61 | ASIDControlCap \<Rightarrow> P_ASIDControlCap 62 | PageCap dev obj_ref rights sz vr \<Rightarrow> P_PageCap dev obj_ref rights sz vr 63 | PageTableCap obj_ref vr \<Rightarrow> P_PageTableCap obj_ref vr 64 | PageDirectoryCap obj_ref asid \<Rightarrow> P_PageDirectoryCap obj_ref asid) 65 F) = (\<lambda>c. 66 (case c of 67 ArchObjectCap (ASIDPoolCap obj_ref asid) \<Rightarrow> P_ASIDPoolCap obj_ref asid 68 | ArchObjectCap (ASIDControlCap) \<Rightarrow> P_ASIDControlCap 69 | ArchObjectCap (PageCap dev obj_ref rights sz vr) \<Rightarrow> P_PageCap dev obj_ref rights sz vr 70 | ArchObjectCap (PageTableCap obj_ref vr) \<Rightarrow> P_PageTableCap obj_ref vr 71 | ArchObjectCap (PageDirectoryCap obj_ref asid) \<Rightarrow> P_PageDirectoryCap obj_ref asid 72 | _ \<Rightarrow> F))" 73 apply (rule ext) 74 by (simp add: arch_cap_fun_lift_def) 75 76lemma arch_obj_fun_lift_expand[simp]: 77 "(arch_obj_fun_lift (\<lambda> ako. case ako of 78 ASIDPool pool \<Rightarrow> P_ASIDPool pool 79 | PageTable pt \<Rightarrow> P_PageTable pt 80 | PageDirectory pd \<Rightarrow> P_PageDirectory pd 81 | DataPage dev s \<Rightarrow> P_DataPage dev s) 82 F) = (\<lambda>ko. 83 (case ko of 84 ArchObj (ASIDPool pool) \<Rightarrow> P_ASIDPool pool 85 | ArchObj (PageTable pt) \<Rightarrow> P_PageTable pt 86 | ArchObj (PageDirectory pd) \<Rightarrow> P_PageDirectory pd 87 | ArchObj (DataPage dev s) \<Rightarrow> P_DataPage dev s 88 | _ \<Rightarrow> F))" 89 apply (rule ext) 90 by (simp only: arch_obj_fun_lift_def) 91 92lemmas aa_type_simps = 93 aa_type_def[split_simps arch_kernel_obj.split] 94 95lemmas a_type_def = a_type_def[simplified aa_type_def] 96 97lemmas a_type_simps = a_type_def[split_simps kernel_object.split arch_kernel_obj.split] 98 99definition 100 "vmsz_aligned ref sz \<equiv> is_aligned ref (pageBitsForSize sz)" 101 102definition 103 "wellformed_mapdata sz \<equiv> 104 \<lambda>(asid, vref). 0 < asid \<and> asid \<le> 2^asid_bits - 1 105 \<and> vmsz_aligned vref sz \<and> vref < kernel_base" 106 107definition 108 wellformed_acap :: "arch_cap \<Rightarrow> bool" 109where 110 "wellformed_acap ac \<equiv> 111 case ac of 112 ASIDPoolCap r as 113 \<Rightarrow> is_aligned as asid_low_bits \<and> as \<le> 2^asid_bits - 1 114 | PageCap dev r rghts sz mapdata \<Rightarrow> rghts \<in> valid_vm_rights \<and> 115 case_option True (wellformed_mapdata sz) mapdata 116 | PageTableCap r (Some mapdata) \<Rightarrow> 117 wellformed_mapdata ARMSection mapdata 118 | PageDirectoryCap r (Some asid) \<Rightarrow> 119 0 < asid \<and> asid \<le> 2^asid_bits - 1 120 | _ \<Rightarrow> True" 121 122lemmas wellformed_acap_simps = 123 wellformed_mapdata_def wellformed_acap_def[split_simps arch_cap.split] 124 125definition 126 "in_device_frame p \<equiv> \<lambda>s. 127 \<exists>sz. typ_at (AArch (ADeviceData sz)) (p && ~~ mask (pageBitsForSize sz)) s" 128 129definition 130 "user_mem s \<equiv> \<lambda>p. 131 if (in_user_frame p s) 132 then Some (underlying_memory (machine_state s) p) 133 else None" 134 135definition 136 "device_mem s \<equiv> \<lambda>p. 137 if (in_device_frame p s) 138 then Some p 139 else None" 140 141abbreviation "device_region s \<equiv> dom (device_state (machine_state s))" 142 143lemma typ_at_pg_user: 144 "typ_at (AArch (AUserData sz)) buf s = ko_at (ArchObj (DataPage False sz)) buf s" 145 unfolding obj_at_def 146 by (auto simp: a_type_def split: Structures_A.kernel_object.split_asm arch_kernel_obj.split_asm if_split_asm) 147 148lemma typ_at_pg_device: 149 "typ_at (AArch (ADeviceData sz)) buf s = ko_at (ArchObj (DataPage True sz)) buf s" 150 unfolding obj_at_def 151 by (auto simp: a_type_def split: Structures_A.kernel_object.split_asm arch_kernel_obj.split_asm if_split_asm) 152 153lemmas typ_at_pg = typ_at_pg_user typ_at_pg_device 154 155(* this time with typ_at. might lead to confusion, but this is how 156 the rest should have been defined.. *) 157abbreviation 158 "asid_pool_at \<equiv> typ_at (AArch AASIDPool)" 159abbreviation 160 "page_table_at \<equiv> typ_at (AArch APageTable)" 161abbreviation 162 "page_directory_at \<equiv> typ_at (AArch APageDirectory)" 163 164definition 165 "pde_at p \<equiv> page_directory_at (p && ~~ mask pd_bits) 166 and K (is_aligned p 2)" 167definition 168 "pte_at p \<equiv> page_table_at (p && ~~ mask pt_bits) 169 and K (is_aligned p 2)" 170 171definition 172 valid_arch_cap_ref :: "arch_cap \<Rightarrow> 'z::state_ext state \<Rightarrow> bool" 173where 174 "valid_arch_cap_ref ac s \<equiv> (case ac of 175 ASIDPoolCap r as \<Rightarrow> typ_at (AArch AASIDPool) r s 176 | ASIDControlCap \<Rightarrow> True 177 | PageCap dev r rghts sz mapdata \<Rightarrow> if dev then (typ_at (AArch (ADeviceData sz)) r s) 178 else (typ_at (AArch (AUserData sz)) r s) 179 | PageTableCap r mapdata \<Rightarrow> typ_at (AArch APageTable) r s 180 | PageDirectoryCap r mapdata\<Rightarrow> typ_at (AArch APageDirectory) r s)" 181 182lemmas valid_arch_cap_ref_simps = 183 valid_arch_cap_ref_def[split_simps arch_cap.split] 184 185definition 186 valid_arch_cap :: "arch_cap \<Rightarrow> 'z::state_ext state \<Rightarrow> bool" 187where 188 "valid_arch_cap ac s \<equiv> (case ac of 189 ASIDPoolCap r as \<Rightarrow> 190 typ_at (AArch AASIDPool) r s \<and> is_aligned as asid_low_bits 191 \<and> as \<le> 2^asid_bits - 1 192 | ASIDControlCap \<Rightarrow> True 193 | PageCap dev r rghts sz mapdata \<Rightarrow> 194 (if dev then (typ_at (AArch (ADeviceData sz)) r s) 195 else (typ_at (AArch (AUserData sz)) r s)) \<and> 196 rghts \<in> valid_vm_rights \<and> 197 (case mapdata of None \<Rightarrow> True | Some (asid, ref) \<Rightarrow> 0 < asid \<and> asid \<le> 2^asid_bits - 1 198 \<and> vmsz_aligned ref sz \<and> ref < kernel_base) 199 | PageTableCap r mapdata \<Rightarrow> 200 typ_at (AArch APageTable) r s \<and> 201 (case mapdata of None \<Rightarrow> True 202 | Some (asid, vref) \<Rightarrow> 0 < asid \<and> asid \<le> 2 ^ asid_bits - 1 203 \<and> vref < kernel_base 204 \<and> is_aligned vref (pageBitsForSize ARMSection)) 205 | PageDirectoryCap r mapdata \<Rightarrow> 206 typ_at (AArch APageDirectory) r s \<and> 207 case_option True (\<lambda>asid. 0 < asid \<and> asid \<le> 2^asid_bits - 1) mapdata)" 208 209lemmas valid_arch_cap_simps = 210 valid_arch_cap_def[split_simps arch_cap.split] 211 212definition 213 "is_nondevice_page_cap_arch \<equiv> \<lambda>cap. case cap of 214 (PageCap False x xa xb xc) \<Rightarrow> True 215 | _ \<Rightarrow> False" 216 217definition 218 "is_nondevice_page_cap \<equiv> \<lambda>c. arch_cap_fun_lift is_nondevice_page_cap_arch False c" 219 220lemmas is_nondevice_page_cap_simps = is_nondevice_page_cap_def[split_simps arch_cap.split cap.split] 221 222primrec 223 acap_class :: "arch_cap \<Rightarrow> capclass" 224where 225 "acap_class (ASIDPoolCap x y) = PhysicalClass" 226| "acap_class (ASIDControlCap) = ASIDMasterClass" 227| "acap_class (PageCap dev x y sz z) = PhysicalClass" 228| "acap_class (PageTableCap x y) = PhysicalClass" 229| "acap_class (PageDirectoryCap x y) = PhysicalClass" 230 231definition 232 valid_ipc_buffer_cap_arch :: "arch_cap \<Rightarrow> word32 \<Rightarrow> bool" 233where 234 "valid_ipc_buffer_cap_arch ac bufptr \<equiv> 235 case ac of 236 (PageCap False ref rghts sz mapdata) \<Rightarrow> 237 is_aligned bufptr msg_align_bits (* \<and> bufptr \<noteq> 0 *) 238 | _ \<Rightarrow> False" 239 240declare valid_ipc_buffer_cap_arch_def[simp] 241 242definition 243 "valid_ipc_buffer_cap c bufptr \<equiv> 244 case c of NullCap \<Rightarrow> True 245 | ArchObjectCap acap \<Rightarrow> valid_ipc_buffer_cap_arch acap bufptr 246 | _ \<Rightarrow> False" 247 248definition "data_at \<equiv> \<lambda>sz p s. typ_at (AArch (AUserData sz)) p s 249 \<or> typ_at (AArch (ADeviceData sz)) p s" 250 251definition 252 valid_arch_tcb :: "arch_tcb \<Rightarrow> 'z::state_ext state \<Rightarrow> bool" 253where 254 "valid_arch_tcb \<equiv> \<lambda>a. \<top>" 255 256definition 257 valid_arch_idle :: "iarch_tcb \<Rightarrow> bool" 258where 259 "valid_arch_idle \<equiv> \<top>" 260 261primrec 262 valid_pte :: "pte \<Rightarrow> 'z::state_ext state \<Rightarrow> bool" 263where 264 "valid_pte (InvalidPTE) = \<top>" 265| "valid_pte (LargePagePTE ptr x y) = 266 (\<lambda>s. is_aligned ptr pageBits \<and> 267 data_at ARMLargePage (ptrFromPAddr ptr) s)" 268| "valid_pte (SmallPagePTE ptr x y) = 269 (\<lambda>s. is_aligned ptr pageBits \<and> 270 data_at ARMSmallPage (ptrFromPAddr ptr) s)" 271 272primrec 273 valid_pde :: "pde \<Rightarrow> 'z::state_ext state \<Rightarrow> bool" 274where 275 "valid_pde (InvalidPDE) = \<top>" 276| "valid_pde (SectionPDE ptr x y z) = 277 (\<lambda>s. is_aligned ptr pageBits \<and> 278 data_at ARMSection (ptrFromPAddr ptr) s)" 279| "valid_pde (SuperSectionPDE ptr x z) = 280 (\<lambda>s. is_aligned ptr pageBits \<and> 281 data_at ARMSuperSection (ptrFromPAddr ptr) s)" 282| "valid_pde (PageTablePDE ptr x z) = 283 (typ_at (AArch APageTable) (ptrFromPAddr ptr))" 284 285 286definition 287 kernel_mapping_slots :: "12 word set" where 288 "kernel_mapping_slots \<equiv> {x. x \<ge> ucast (kernel_base >> 20)}" 289 290primrec 291 valid_vspace_obj :: "arch_kernel_obj \<Rightarrow> 'z::state_ext state \<Rightarrow> bool" 292where 293 "valid_vspace_obj (ASIDPool pool) = 294 (\<lambda>s. \<forall>x \<in> ran pool. typ_at (AArch APageDirectory) x s)" 295| "valid_vspace_obj (PageDirectory pd) = 296 (\<lambda>s. \<forall>x \<in> -kernel_mapping_slots. valid_pde (pd x) s)" 297| "valid_vspace_obj (PageTable pt) = (\<lambda>s. \<forall>x. valid_pte (pt x) s)" 298| "valid_vspace_obj (DataPage dev sz) = \<top>" 299 300definition 301 wellformed_pte :: "pte \<Rightarrow> bool" 302where 303 "wellformed_pte pte \<equiv> case pte of 304 LargePagePTE p attr r \<Rightarrow> 305 ParityEnabled \<notin> attr \<and> r \<in> valid_vm_rights 306 | SmallPagePTE p attr r \<Rightarrow> 307 ParityEnabled \<notin> attr \<and> r \<in> valid_vm_rights 308 | _ \<Rightarrow> True" 309 310definition 311 wellformed_pde :: "pde \<Rightarrow> bool" 312where 313 "wellformed_pde pde \<equiv> case pde of 314 pde.PageTablePDE p attr mw \<Rightarrow> attr \<subseteq> {ParityEnabled} 315 | pde.SectionPDE p attr mw r \<Rightarrow> r \<in> valid_vm_rights 316 | pde.SuperSectionPDE p attr r \<Rightarrow> r \<in> valid_vm_rights 317 | _ \<Rightarrow> True" 318 319definition 320 wellformed_vspace_obj :: "arch_kernel_obj \<Rightarrow> bool" 321where 322 "wellformed_vspace_obj ao \<equiv> case ao of 323 PageTable pt \<Rightarrow> (\<forall>pte\<in>range pt. wellformed_pte pte) 324 | PageDirectory pd \<Rightarrow> (\<forall>pde\<in>range pd. wellformed_pde pde) 325 | _ \<Rightarrow> True" 326 327definition 328 arch_valid_obj :: "arch_kernel_obj \<Rightarrow> 'z::state_ext state \<Rightarrow> bool" 329where 330 "arch_valid_obj ao s \<equiv> wellformed_vspace_obj ao" 331 332lemmas 333 wellformed_pte_simps[simp] = 334 wellformed_pte_def[split_simps pte.split] 335 336lemmas 337 wellformed_pde_simps[simp] = 338 wellformed_pde_def[split_simps pde.split] 339 340lemmas 341 arch_valid_obj_simps[simp] = 342 arch_valid_obj_def[split_simps arch_kernel_obj.split] 343 344lemmas 345 wellformed_vspace_obj_simps[simp] = 346 wellformed_vspace_obj_def[split_simps arch_kernel_obj.split] 347 348lemma wellformed_arch_pspace: "\<And>ao. \<lbrakk>arch_valid_obj ao s; kheap s = kheap s'\<rbrakk> 349 \<Longrightarrow> arch_valid_obj ao s'" by simp 350 351section "Virtual Memory" 352 353definition 354 equal_kernel_mappings :: "'z::state_ext state \<Rightarrow> bool" 355where 356 "equal_kernel_mappings \<equiv> \<lambda>s. 357 \<forall>x y pd pd'. ko_at (ArchObj (PageDirectory pd)) x s \<and> ko_at (ArchObj (PageDirectory pd')) y s 358 \<longrightarrow> (\<forall>w \<in> kernel_mapping_slots. pd w = pd' w)" 359 360definition 361 pde_ref :: "pde \<Rightarrow> obj_ref option" 362where 363 "pde_ref pde \<equiv> case pde of 364 PageTablePDE ptr x z \<Rightarrow> Some (ptrFromPAddr ptr) 365 | _ \<Rightarrow> None" 366 367datatype vs_ref = VSRef word32 "aa_type option" 368 369definition 370 vs_ref_aatype :: "vs_ref \<Rightarrow> aa_type option" where 371 "vs_ref_aatype vsref \<equiv> case vsref of VSRef x atype \<Rightarrow> atype" 372 373definition 374 vs_refs_arch :: "arch_kernel_obj \<Rightarrow> (vs_ref \<times> obj_ref) set" where 375 "vs_refs_arch \<equiv> \<lambda>ko. case ko of 376 ASIDPool pool \<Rightarrow> 377 (\<lambda>(r,p). (VSRef (ucast r) (Some AASIDPool), p)) ` graph_of pool 378 | PageDirectory pd \<Rightarrow> 379 (\<lambda>(r,p). (VSRef (ucast r) (Some APageDirectory), p)) ` 380 graph_of (\<lambda>x. if x \<in> kernel_mapping_slots then None else pde_ref (pd x)) 381 | _ \<Rightarrow> {}" 382 383declare vs_refs_arch_def[simp] 384 385definition 386 "vs_refs = arch_obj_fun_lift vs_refs_arch {}" 387 388type_synonym vs_chain = "vs_ref list \<times> obj_ref" 389type_synonym 'a rel = "('a \<times> 'a) set" 390 391definition 392 vs_lookup1 :: "'z::state_ext state \<Rightarrow> vs_chain rel" where 393 "vs_lookup1 s \<equiv> {((rs,p),(rs',p')). \<exists>ko r. ko_at ko p s 394 \<and> rs' = (r # rs) 395 \<and> (r, p') \<in> vs_refs ko}" 396 397abbreviation (input) 398 vs_lookup_trans :: "'z::state_ext state \<Rightarrow> vs_chain rel" where 399 "vs_lookup_trans s \<equiv> (vs_lookup1 s)^*" 400 401abbreviation 402 vs_lookup1_abbr :: "vs_chain \<Rightarrow> vs_chain \<Rightarrow> 'z::state_ext state \<Rightarrow> bool" 403 ("_ \<rhd>1 _" [80,80] 81) where 404 "ref \<rhd>1 ref' \<equiv> \<lambda>s. (ref,ref') \<in> vs_lookup1 s" 405 406abbreviation 407 vs_lookup_trans_abbr :: "vs_chain \<Rightarrow> vs_chain \<Rightarrow> 'z::state_ext state \<Rightarrow> bool" 408 ("_ \<rhd>* _" [80,80] 81) where 409 "ref \<rhd>* ref' \<equiv> \<lambda>s. (ref,ref') \<in> vs_lookup_trans s" 410 411definition 412 vs_asid_refs :: "(7 word \<rightharpoonup> obj_ref) \<Rightarrow> vs_chain set" 413where 414 "vs_asid_refs t \<equiv> (\<lambda>(r,p). ([VSRef (ucast r) None], p)) ` graph_of t" 415 416definition 417 vs_lookup :: "'z::state_ext state \<Rightarrow> vs_chain set" 418where 419 "vs_lookup \<equiv> \<lambda>s. vs_lookup_trans s `` vs_asid_refs (arm_asid_table (arch_state s))" 420 421definition "second_level_tables \<equiv> arch_state.arm_global_pts" 422 423end 424 425context begin interpretation Arch . 426requalify_consts vs_lookup 427end 428 429abbreviation 430 vs_lookup_abbr 431 ("_ \<rhd> _" [80,80] 81) where 432 "rs \<rhd> p \<equiv> \<lambda>s. (rs,p) \<in> vs_lookup s" 433 434context Arch begin global_naming ARM 435 436abbreviation 437 is_reachable_abbr :: "obj_ref \<Rightarrow> 'z::state_ext state \<Rightarrow> bool" ("\<exists>\<rhd> _" [80] 81) where 438 "\<exists>\<rhd> p \<equiv> \<lambda>s. \<exists>ref. (ref \<rhd> p) s" 439 440definition 441 valid_vspace_objs :: "'z::state_ext state \<Rightarrow> bool" 442where 443 "valid_vspace_objs \<equiv> 444 \<lambda>s. \<forall>p rs ao. (rs \<rhd> p) s \<longrightarrow> ko_at (ArchObj ao) p s \<longrightarrow> valid_vspace_obj ao s" 445 446definition 447 pde_ref_pages :: "pde \<Rightarrow> obj_ref option" 448where 449 "pde_ref_pages pde \<equiv> case pde of 450 PageTablePDE ptr x z \<Rightarrow> Some (ptrFromPAddr ptr) 451 | SectionPDE ptr x y z \<Rightarrow> Some (ptrFromPAddr ptr) 452 | SuperSectionPDE ptr x z \<Rightarrow> Some (ptrFromPAddr ptr) 453 | _ \<Rightarrow> None" 454 455definition 456 pte_ref_pages :: "pte \<Rightarrow> obj_ref option" 457where 458 "pte_ref_pages pte \<equiv> case pte of 459 SmallPagePTE ptr x z \<Rightarrow> Some (ptrFromPAddr ptr) 460 | LargePagePTE ptr x z \<Rightarrow> Some (ptrFromPAddr ptr) 461 | _ \<Rightarrow> None" 462 463definition 464 vs_refs_pages_arch :: "arch_kernel_obj \<Rightarrow> (vs_ref \<times> obj_ref) set" where 465 "vs_refs_pages_arch \<equiv> \<lambda>ko. case ko of 466 (ASIDPool pool) \<Rightarrow> 467 (\<lambda>(r,p). (VSRef (ucast r) (Some AASIDPool), p)) ` graph_of pool 468 | (PageDirectory pd) \<Rightarrow> 469 (\<lambda>(r,p). (VSRef (ucast r) (Some APageDirectory), p)) ` 470 graph_of (\<lambda>x. if x \<in> kernel_mapping_slots then None else pde_ref_pages (pd x)) 471 | (PageTable pt) \<Rightarrow> 472 (\<lambda>(r,p). (VSRef (ucast r) (Some APageTable), p)) ` 473 graph_of (pte_ref_pages o pt) 474 | _ \<Rightarrow> {}" 475 476declare vs_refs_pages_arch_def[simp] 477 478definition 479 "vs_refs_pages \<equiv> arch_obj_fun_lift vs_refs_pages_arch {}" 480 481definition 482 vs_lookup_pages1 :: "'z :: state_ext state \<Rightarrow> vs_chain rel" where 483 "vs_lookup_pages1 s \<equiv> {((rs,p),(rs',p')). \<exists>ko r. ko_at ko p s 484 \<and> rs' = (r # rs) 485 \<and> (r, p') \<in> vs_refs_pages ko}" 486 487abbreviation (input) 488 vs_lookup_pages_trans :: "'z :: state_ext state \<Rightarrow> vs_chain rel" where 489 "vs_lookup_pages_trans s \<equiv> (vs_lookup_pages1 s)^*" 490 491abbreviation 492 vs_lookup_pages1_abbr :: "vs_chain \<Rightarrow> vs_chain \<Rightarrow> 'z :: state_ext state \<Rightarrow> bool" 493 ("_ \<unrhd>1 _" [80,80] 81) where 494 "ref \<unrhd>1 ref' \<equiv> \<lambda>s. (ref,ref') \<in> vs_lookup_pages1 s" 495 496abbreviation 497 vs_lookup_pages_trans_abbr :: "vs_chain \<Rightarrow> vs_chain \<Rightarrow> 'z :: state_ext state \<Rightarrow> bool" 498 ("_ \<unrhd>* _" [80,80] 81) where 499 "ref \<unrhd>* ref' \<equiv> \<lambda>s. (ref,ref') \<in> vs_lookup_pages_trans s" 500 501definition 502 vs_lookup_pages :: "'z ::state_ext state \<Rightarrow> vs_chain set" 503where 504 "vs_lookup_pages \<equiv> \<lambda>s. vs_lookup_pages_trans s `` vs_asid_refs (arm_asid_table (arch_state s))" 505 506 507end 508 509context begin interpretation Arch . 510requalify_consts vs_lookup_pages 511end 512 513abbreviation 514 vs_lookup_pages_abbr 515 ("_ \<unrhd> _" [80,80] 81) where 516 "rs \<unrhd> p \<equiv> \<lambda>s. (rs,p) \<in> vs_lookup_pages s" 517 518abbreviation 519 is_reachable_pages_abbr :: "obj_ref \<Rightarrow> 'z :: state_ext state \<Rightarrow> bool" ("\<exists>\<unrhd> _" [80] 81) where 520 "\<exists>\<unrhd> p \<equiv> \<lambda>s. \<exists>ref. (ref \<unrhd> p) s" 521 522 523context Arch begin global_naming ARM 524 525definition 526 "vspace_obj_fun_lift P F c \<equiv> case c of 527 ArchObj ac \<Rightarrow> P ac | 528 _ \<Rightarrow> F" 529lemma vspace_obj_fun_lift_expand[simp]: 530 "(vspace_obj_fun_lift (\<lambda> ako. case ako of 531 ASIDPool pool \<Rightarrow> P_ASIDPool pool 532 | PageTable pt \<Rightarrow> P_PageTable pt 533 | PageDirectory pd \<Rightarrow> P_PageDirectory pd 534 | DataPage dev s \<Rightarrow> P_DataPage dev s) 535 F) = (\<lambda>ko. 536 (case ko of 537 ArchObj (ASIDPool pool) \<Rightarrow> P_ASIDPool pool 538 | ArchObj (PageTable pt) \<Rightarrow> P_PageTable pt 539 | ArchObj (PageDirectory pd) \<Rightarrow> P_PageDirectory pd 540 | ArchObj (DataPage dev s) \<Rightarrow> P_DataPage dev s 541 | _ \<Rightarrow> F))" 542 apply (rule ext) 543 apply (auto simp: vspace_obj_fun_lift_def split: kernel_object.split arch_kernel_obj.split) 544 done 545 546definition 547 pde_mapping_bits :: "nat" 548where 549 "pde_mapping_bits \<equiv> pageBitsForSize ARMSection" 550 551definition 552 pte_mapping_bits :: "nat" 553where 554 "pte_mapping_bits \<equiv> pageBitsForSize ARMSmallPage" 555 556definition 557 valid_pte_kernel_mappings :: "pte \<Rightarrow> vspace_ref 558 \<Rightarrow> arm_vspace_region_uses \<Rightarrow> bool" 559where 560 "valid_pte_kernel_mappings pte vref uses \<equiv> case pte of 561 InvalidPTE \<Rightarrow> 562 \<forall>x \<in> {vref .. vref + 2 ^ pte_mapping_bits - 1}. 563 uses x \<noteq> ArmVSpaceKernelWindow 564 | SmallPagePTE ptr atts rghts \<Rightarrow> 565 ptrFromPAddr ptr = vref 566 \<and> (\<exists>use. (\<forall>x \<in> {vref .. vref + 2 ^ pte_mapping_bits - 1}. uses x = use) 567 \<and> (use = ArmVSpaceKernelWindow 568 \<or> use = ArmVSpaceDeviceWindow)) 569 \<and> rghts = {} 570 | LargePagePTE ptr atts rghts \<Rightarrow> 571 ptrFromPAddr ptr = (vref && ~~ mask (pageBitsForSize ARMLargePage)) 572 \<and> (\<exists>use. (\<forall>x \<in> {vref .. vref + 2 ^ pte_mapping_bits - 1}. uses x = use) 573 \<and> (use = ArmVSpaceKernelWindow 574 \<or> use = ArmVSpaceDeviceWindow)) 575 \<and> rghts = {}" 576 577definition 578 valid_pt_kernel_mappings_arch :: "vspace_ref \<Rightarrow> arm_vspace_region_uses \<Rightarrow> arch_kernel_obj \<Rightarrow> bool" 579where 580 "valid_pt_kernel_mappings_arch vref uses \<equiv> \<lambda> obj. case obj of 581 PageTable pt \<Rightarrow> 582 \<forall>x. valid_pte_kernel_mappings 583 (pt x) (vref + (ucast x << pte_mapping_bits)) uses 584 | _ \<Rightarrow> False" 585 586declare valid_pt_kernel_mappings_arch_def[simp] 587 588definition 589 "valid_pt_kernel_mappings vref uses = vspace_obj_fun_lift (valid_pt_kernel_mappings_arch vref uses) False" 590 591definition 592 valid_pde_kernel_mappings :: "pde \<Rightarrow> vspace_ref \<Rightarrow> arm_vspace_region_uses \<Rightarrow> 'z::state_ext state \<Rightarrow> bool" 593where 594 "valid_pde_kernel_mappings pde vref uses \<equiv> case pde of 595 InvalidPDE \<Rightarrow> 596 (\<lambda>s. \<forall>x \<in> {vref .. vref + 2 ^ pde_mapping_bits - 1}. 597 uses x \<noteq> ArmVSpaceKernelWindow) 598 | PageTablePDE ptr _ _ \<Rightarrow> 599 obj_at (valid_pt_kernel_mappings vref uses) 600 (ptrFromPAddr ptr) 601 | SectionPDE ptr atts _ rghts \<Rightarrow> 602 (\<lambda>s. ptrFromPAddr ptr = vref 603 \<and> (\<exists>use. (\<forall>x \<in> {vref .. vref + 2 ^ pde_mapping_bits - 1}. uses x = use) 604 \<and> (use = ArmVSpaceKernelWindow 605 \<or> use = ArmVSpaceDeviceWindow)) 606 \<and> rghts = {}) 607 | SuperSectionPDE ptr atts rghts \<Rightarrow> 608 (\<lambda>s. ptrFromPAddr ptr = (vref && ~~ mask (pageBitsForSize ARMSuperSection)) 609 \<and> (\<forall>x \<in> {vref .. vref + 2 ^ pde_mapping_bits - 1}. 610 uses x = ArmVSpaceKernelWindow) 611 \<and> rghts = {})" 612 613definition 614 valid_pd_kernel_mappings_arch :: "arm_vspace_region_uses \<Rightarrow> 'z::state_ext state 615 \<Rightarrow> arch_kernel_obj \<Rightarrow> bool" 616where 617 "valid_pd_kernel_mappings_arch uses \<equiv> \<lambda>s obj. 618 case obj of 619 PageDirectory pd \<Rightarrow> 620 (\<forall>x. valid_pde_kernel_mappings 621 (pd x) (ucast x << pde_mapping_bits) uses s) 622 | _ \<Rightarrow> False" 623 624declare valid_pd_kernel_mappings_arch_def[simp] 625 626definition 627 "valid_pd_kernel_mappings uses = (\<lambda>s. vspace_obj_fun_lift (valid_pd_kernel_mappings_arch uses s) False)" 628 629definition 630 valid_global_vspace_mappings :: "'z::state_ext state \<Rightarrow> bool" 631where 632 "valid_global_vspace_mappings \<equiv> \<lambda>s. 633 obj_at (valid_pd_kernel_mappings (arm_kernel_vspace (arch_state s)) s) 634 (arm_global_pd (arch_state s)) s" 635 636definition 637 valid_vso_at :: "obj_ref \<Rightarrow> 'z::state_ext state \<Rightarrow> bool" 638where 639 "valid_vso_at p \<equiv> \<lambda>s. \<exists>ao. ko_at (ArchObj ao) p s \<and> valid_vspace_obj ao s" 640 641definition 642 valid_ao_at :: "obj_ref \<Rightarrow> 'z::state_ext state \<Rightarrow> bool" 643where 644 "valid_ao_at p \<equiv> \<lambda>s. \<exists>ao. ko_at (ArchObj ao) p s \<and> valid_vspace_obj ao s" 645 646definition 647 "valid_pde_mappings pde \<equiv> case pde of 648 SectionPDE ptr _ _ _ \<Rightarrow> is_aligned ptr pageBits 649 | SuperSectionPDE ptr _ _ \<Rightarrow> is_aligned ptr pageBits 650 | _ \<Rightarrow> True" 651 652definition 653 "empty_table_arch S \<equiv> \<lambda> ko. 654 case ko of 655 PageDirectory pd \<Rightarrow> 656 \<forall>x. (\<forall>r. pde_ref (pd x) = Some r \<longrightarrow> r \<in> S) \<and> 657 valid_pde_mappings (pd x) \<and> 658 (x \<notin> kernel_mapping_slots \<longrightarrow> pd x = InvalidPDE) 659 | PageTable pt \<Rightarrow> \<forall>x. pt x = InvalidPTE 660 | _ \<Rightarrow> False" 661 662declare empty_table_arch_def[simp] 663 664definition 665 "empty_table S \<equiv> arch_obj_fun_lift (empty_table_arch S) False" 666 667definition 668 "valid_kernel_mappings_if_pd_arch S \<equiv> \<lambda> ko. case ko of 669 (PageDirectory pd) \<Rightarrow> 670 \<forall>x r. pde_ref (pd x) = Some r 671 \<longrightarrow> ((r \<in> S) = (x \<in> kernel_mapping_slots)) 672 | _ \<Rightarrow> True" 673 674declare valid_kernel_mappings_if_pd_arch_def[simp] 675 676definition 677 "valid_kernel_mappings_if_pd S \<equiv> arch_obj_fun_lift (valid_kernel_mappings_if_pd_arch S) True" 678 679definition 680 "aligned_pte pte \<equiv> 681 case pte of 682 LargePagePTE p _ _ \<Rightarrow> vmsz_aligned p ARMLargePage 683 | SmallPagePTE p _ _ \<Rightarrow> vmsz_aligned p ARMSmallPage 684 | _ \<Rightarrow> True" 685 686lemmas aligned_pte_simps[simp] = 687 aligned_pte_def[split_simps pte.split] 688 689 690definition 691 valid_global_objs :: "'z::state_ext state \<Rightarrow> bool" 692where 693 "valid_global_objs \<equiv> 694 \<lambda>s. valid_vso_at (arm_global_pd (arch_state s)) s \<and> 695 obj_at (empty_table (set (second_level_tables (arch_state s)))) 696 (arm_global_pd (arch_state s)) s \<and> 697 (\<forall>p\<in>set (arm_global_pts (arch_state s)). 698 \<exists>pt. ko_at (ArchObj (PageTable pt)) p s \<and> (\<forall>x. aligned_pte (pt x)))" 699 700definition 701 valid_asid_table :: "(7 word \<rightharpoonup> obj_ref) \<Rightarrow> 'z::state_ext state \<Rightarrow> bool" 702where 703 "valid_asid_table table \<equiv> \<lambda>s. (\<forall>p \<in> ran table. asid_pool_at p s) \<and> 704 inj_on table (dom table)" 705 706definition 707 valid_global_pts :: "'z :: state_ext state \<Rightarrow> bool" 708where 709 "valid_global_pts \<equiv> \<lambda>s. 710 \<forall>p \<in> set (arm_global_pts (arch_state s)). typ_at (AArch APageTable) p s" 711 712(* arch_live/hyp_live stub *) 713 714definition 715 arch_live :: "arch_kernel_obj \<Rightarrow> bool" 716where 717 "arch_live ao \<equiv> False" 718 719definition 720 hyp_live :: "kernel_object \<Rightarrow> bool" 721where 722 "hyp_live ko \<equiv> False" 723 724definition 725 valid_arch_state :: "'z::state_ext state \<Rightarrow> bool" 726where 727 "valid_arch_state \<equiv> \<lambda>s. 728 valid_asid_table (arm_asid_table (arch_state s)) s \<and> 729 page_directory_at (arm_global_pd (arch_state s)) s \<and> 730 valid_global_pts s \<and> 731 is_inv (arm_hwasid_table (arch_state s)) 732 (option_map fst o arm_asid_map (arch_state s))" 733 734definition 735 vs_cap_ref_arch :: "arch_cap \<Rightarrow> vs_ref list option" 736where 737 "vs_cap_ref_arch \<equiv> \<lambda> cap. case cap of 738 ASIDPoolCap _ asid \<Rightarrow> 739 Some [VSRef (ucast (asid_high_bits_of asid)) None] 740 | PageDirectoryCap _ (Some asid) \<Rightarrow> 741 Some [VSRef (asid && mask asid_low_bits) (Some AASIDPool), 742 VSRef (ucast (asid_high_bits_of asid)) None] 743 | PageTableCap _ (Some (asid, vptr)) \<Rightarrow> 744 Some [VSRef (vptr >> 20) (Some APageDirectory), 745 VSRef (asid && mask asid_low_bits) (Some AASIDPool), 746 VSRef (ucast (asid_high_bits_of asid)) None] 747 | PageCap dev word rights ARMSmallPage (Some (asid, vptr)) \<Rightarrow> 748 Some [VSRef ((vptr >> 12) && mask 8) (Some APageTable), 749 VSRef (vptr >> 20) (Some APageDirectory), 750 VSRef (asid && mask asid_low_bits) (Some AASIDPool), 751 VSRef (ucast (asid_high_bits_of asid)) None] 752 | PageCap dev word rights ARMLargePage (Some (asid, vptr)) \<Rightarrow> 753 Some [VSRef ((vptr >> 12) && mask 8) (Some APageTable), 754 VSRef (vptr >> 20) (Some APageDirectory), 755 VSRef (asid && mask asid_low_bits) (Some AASIDPool), 756 VSRef (ucast (asid_high_bits_of asid)) None] 757 | PageCap dev word rights ARMSection (Some (asid, vptr)) \<Rightarrow> 758 Some [VSRef (vptr >> 20) (Some APageDirectory), 759 VSRef (asid && mask asid_low_bits) (Some AASIDPool), 760 VSRef (ucast (asid_high_bits_of asid)) None] 761 | PageCap dev word rights ARMSuperSection (Some (asid, vptr)) \<Rightarrow> 762 Some [VSRef (vptr >> 20) (Some APageDirectory), 763 VSRef (asid && mask asid_low_bits) (Some AASIDPool), 764 VSRef (ucast (asid_high_bits_of asid)) None] 765 | _ \<Rightarrow> None" 766 767declare vs_cap_ref_arch_def[simp] 768 769definition 770 "vs_cap_ref cap \<equiv> arch_cap_fun_lift vs_cap_ref_arch None cap" 771 772definition 773 "is_pg_cap cap \<equiv> \<exists>dev p R sz m. cap = ArchObjectCap (PageCap dev p R sz m)" 774 775definition 776 "is_pd_cap c \<equiv> 777 \<exists>p asid. c = ArchObjectCap (PageDirectoryCap p asid)" 778 779definition 780 "is_pt_cap c \<equiv> \<exists>p asid. c = ArchObjectCap (PageTableCap p asid)" 781 782lemma is_arch_cap_simps: 783 "is_pg_cap cap = (\<exists>dev p R sz m. cap = (ArchObjectCap (PageCap dev p R sz m)))" 784 "is_pd_cap cap = (\<exists>p asid. cap = (ArchObjectCap (PageDirectoryCap p asid)))" 785 "is_pt_cap cap = (\<exists>p asid. cap = (ArchObjectCap (PageTableCap p asid)))" 786 by (auto simp add: is_pg_cap_def is_pd_cap_def is_pt_cap_def) 787 788definition 789 "cap_asid_arch cap \<equiv> case cap of 790 PageCap _ _ _ _ (Some (asid, _)) \<Rightarrow> Some asid 791 | PageTableCap _ (Some (asid, _)) \<Rightarrow> Some asid 792 | PageDirectoryCap _ (Some asid) \<Rightarrow> Some asid 793 | _ \<Rightarrow> None" 794 795declare cap_asid_arch_def[abs_def, simp] 796 797definition 798 "cap_asid cap = arch_cap_fun_lift cap_asid_arch None cap" 799 800 801 (* needed for retype: if reachable, then cap, if cap then protected by untyped cap. 802 strengthened for preservation in cap delete: ref in cap must unmap the right objects *) 803definition 804 "valid_vs_lookup \<equiv> \<lambda>s. \<forall>p ref. (ref \<unrhd> p) s \<longrightarrow> 805 ref \<noteq> [VSRef 0 (Some AASIDPool), VSRef 0 None] \<and> 806 (\<exists>p' cap. (caps_of_state s) p' = Some cap \<and> 807 p \<in> obj_refs cap \<and> vs_cap_ref cap = Some ref)" 808 809definition 810 global_refs :: "'z::state_ext state \<Rightarrow> obj_ref set" 811where 812 "global_refs \<equiv> \<lambda>s. 813 {idle_thread s, arm_global_pd (arch_state s)} \<union> 814 range (interrupt_irq_node s) \<union> 815 set (arm_global_pts (arch_state s))" 816 817definition 818 not_kernel_window_arch :: "arch_state \<Rightarrow> obj_ref set" 819where 820 "not_kernel_window_arch s \<equiv> {x. arm_kernel_vspace s x \<noteq> ArmVSpaceKernelWindow}" 821 822declare not_kernel_window_arch_def[simp] 823 824abbreviation 825 not_kernel_window :: "'z::state_ext state \<Rightarrow> obj_ref set" 826where 827 "not_kernel_window s \<equiv> not_kernel_window_arch (arch_state s)" 828 829 830 (* needed for map: installing new object should add only one mapping *) 831definition 832 "valid_table_caps \<equiv> \<lambda>s. 833 \<forall>r p cap. (caps_of_state s) p = Some cap \<longrightarrow> 834 (is_pd_cap cap \<or> is_pt_cap cap) \<longrightarrow> 835 cap_asid cap = None \<longrightarrow> 836 r \<in> obj_refs cap \<longrightarrow> 837 obj_at (empty_table (set (second_level_tables (arch_state s)))) r s" 838 839 (* needed to preserve valid_table_caps in map *) 840definition 841 "unique_table_caps \<equiv> \<lambda>cs. \<forall>p p' cap cap'. 842 cs p = Some cap \<longrightarrow> cs p' = Some cap' \<longrightarrow> 843 cap_asid cap = None \<longrightarrow> 844 obj_refs cap' = obj_refs cap \<longrightarrow> 845 (is_pd_cap cap \<longrightarrow> is_pd_cap cap' \<longrightarrow> p' = p) \<and> 846 (is_pt_cap cap \<longrightarrow> is_pt_cap cap' \<longrightarrow> p' = p)" 847 848definition 849 table_cap_ref_arch :: "arch_cap \<Rightarrow> vs_ref list option" 850where 851 "table_cap_ref_arch \<equiv> \<lambda> cap. case cap of 852 ASIDPoolCap _ asid \<Rightarrow> 853 Some [VSRef (ucast (asid_high_bits_of asid)) None] 854 | PageDirectoryCap _ (Some asid) \<Rightarrow> 855 Some [VSRef (asid && mask asid_low_bits) (Some AASIDPool), 856 VSRef (ucast (asid_high_bits_of asid)) None] 857 | PageTableCap _ (Some (asid, vptr)) \<Rightarrow> 858 Some [VSRef (vptr >> 20) (Some APageDirectory), 859 VSRef (asid && mask asid_low_bits) (Some AASIDPool), 860 VSRef (ucast (asid_high_bits_of asid)) None] 861 | _ \<Rightarrow> None" 862 863declare table_cap_ref_arch_def[simp] 864 865definition 866 "table_cap_ref cap = arch_cap_fun_lift table_cap_ref_arch None cap" 867 868 (* needed to avoid a single page insertion 869 resulting in multiple valid lookups *) 870definition 871 "unique_table_refs \<equiv> \<lambda>cs. \<forall>p p' cap cap'. 872 cs p = Some cap \<longrightarrow> cs p' = Some cap' \<longrightarrow> 873 obj_refs cap' = obj_refs cap \<longrightarrow> 874 table_cap_ref cap' = table_cap_ref cap" 875 876definition 877 valid_kernel_mappings :: "'z::state_ext state \<Rightarrow> bool" 878where 879 "valid_kernel_mappings \<equiv> 880 \<lambda>s. \<forall>ko \<in> ran (kheap s). 881 valid_kernel_mappings_if_pd 882 (set (arm_global_pts (arch_state s))) ko" 883 884definition 885 "valid_arch_caps \<equiv> valid_vs_lookup and valid_table_caps and 886 (\<lambda>s. unique_table_caps (caps_of_state s) 887 \<and> unique_table_refs (caps_of_state s))" 888 889 890text "objects live in the kernel window" 891definition 892 pspace_in_kernel_window :: "'z::state_ext state \<Rightarrow> bool" 893where 894 "pspace_in_kernel_window \<equiv> \<lambda>s. 895 \<forall>x ko. kheap s x = Some ko \<longrightarrow> 896 (\<forall>y \<in> {x .. x + (2 ^ obj_bits ko) - 1}. 897 arm_kernel_vspace (arch_state s) y = ArmVSpaceKernelWindow)" 898 899definition 900 arch_obj_bits_type :: "aa_type \<Rightarrow> nat" 901where 902 "arch_obj_bits_type T' \<equiv> (case T' of 903 AASIDPool \<Rightarrow> arch_kobj_size (ASIDPool undefined) 904 | ADeviceData sz \<Rightarrow> arch_kobj_size (DataPage True sz) 905 | AUserData sz \<Rightarrow> arch_kobj_size (DataPage False sz) 906 | APageDirectory \<Rightarrow> arch_kobj_size (PageDirectory undefined) 907 | APageTable \<Rightarrow> arch_kobj_size (PageTable undefined))" 908 909definition 910 vspace_at_asid :: "asid \<Rightarrow> obj_ref \<Rightarrow> 'z::state_ext state \<Rightarrow> bool" 911where 912 "vspace_at_asid asid pd \<equiv> \<lambda>s. 913 ([VSRef (asid && mask asid_low_bits) (Some AASIDPool), 914 VSRef (ucast (asid_high_bits_of asid)) None] \<rhd> pd) s" 915 916definition 917 valid_asid_map :: "'z::state_ext state \<Rightarrow> bool" 918where 919 "valid_asid_map \<equiv> 920 \<lambda>s. dom (arm_asid_map (arch_state s)) \<subseteq> {0 .. mask asid_bits} \<and> 921 (\<forall>(asid, hwasid, pd) \<in> graph_of (arm_asid_map (arch_state s)). 922 vspace_at_asid asid pd s \<and> asid \<noteq> 0)" 923 924definition 925 valid_ioports :: "'z::state_ext state \<Rightarrow> bool" 926where 927 "valid_ioports \<equiv> \<lambda>s. True" 928 929definition 930 "valid_arch_mdb r cs \<equiv> True" 931 932declare valid_ioports_def[simp] valid_arch_mdb_def[simp] 933 934section "Lemmas" 935 936lemma vmsz_aligned_ARMSection: 937 "vmsz_aligned vref ARMSection = is_aligned vref (pageBitsForSize ARMSection)" 938 by (simp add: vmsz_aligned_def pageBitsForSize_def) 939 940lemma valid_arch_cap_def2: 941 "valid_arch_cap c s \<equiv> wellformed_acap c \<and> valid_arch_cap_ref c s" 942 apply (rule eq_reflection) 943 apply (cases c) 944 by (auto simp add: wellformed_acap_simps valid_arch_cap_simps 945 valid_arch_cap_ref_simps vmsz_aligned_ARMSection 946 split: option.splits) 947 948lemmas vs_ref_aatype_simps[simp] = vs_ref_aatype_def[split_simps vs_ref.split] 949 950lemma vs_lookup1_obj_at: 951 "((rs,p) \<rhd>1 (r # rs,p')) s = obj_at (\<lambda>ko. (r, p') \<in> vs_refs ko) p s" 952 by (fastforce simp: vs_lookup1_def obj_at_def) 953 954lemma vs_lookup1I: 955 "\<lbrakk> ko_at ko p s; (r, p') \<in> vs_refs ko; 956 rs' = r # rs \<rbrakk> \<Longrightarrow> ((rs,p) \<rhd>1 (rs',p')) s" 957 by (fastforce simp add: vs_lookup1_def) 958 959lemma vs_lookup_pages1I: 960 "\<lbrakk> ko_at ko p s; (r, p') \<in> vs_refs_pages ko; 961 rs' = r # rs \<rbrakk> \<Longrightarrow> ((rs,p) \<unrhd>1 (rs',p')) s" 962 by (fastforce simp add: vs_lookup_pages1_def) 963 964lemma vs_lookup1D: 965 "(x \<rhd>1 y) s \<Longrightarrow> \<exists>rs r p p' ko. x = (rs,p) \<and> y = (r # rs,p') 966 \<and> ko_at ko p s \<and> (r,p') \<in> vs_refs ko" 967 by (cases x, cases y) (fastforce simp: vs_lookup1_def) 968 969lemma vs_lookup_pages1D: 970 "(x \<unrhd>1 y) s \<Longrightarrow> \<exists>rs r p p' ko. x = (rs,p) \<and> y = (r # rs,p') 971 \<and> ko_at ko p s \<and> (r,p') \<in> vs_refs_pages ko" 972 by (cases x, cases y) (fastforce simp: vs_lookup_pages1_def) 973 974lemma vs_lookup1_stateI: 975 assumes 1: "(r \<rhd>1 r') s" 976 assumes ko: "\<And>ko. ko_at ko (snd r) s \<Longrightarrow> obj_at (\<lambda>ko'. vs_refs ko \<subseteq> vs_refs ko') (snd r) s'" 977 shows "(r \<rhd>1 r') s'" using 1 ko 978 by (fastforce simp: obj_at_def vs_lookup1_def) 979 980lemma vs_lookup_pages1_stateI2: 981 assumes 1: "(r \<unrhd>1 r') s" 982 assumes ko: "\<And>ko. \<lbrakk> ko_at ko (snd r) s; vs_refs_pages ko \<noteq> {} \<rbrakk> 983 \<Longrightarrow> obj_at (\<lambda>ko'. vs_refs_pages ko \<subseteq> vs_refs_pages ko') (snd r) s'" 984 shows "(r \<unrhd>1 r') s'" using 1 ko 985 by (fastforce simp: obj_at_def vs_lookup_pages1_def) 986 987lemma vs_lookup_trans_sub: 988 assumes ko: "\<And>ko p. ko_at ko p s \<Longrightarrow> obj_at (\<lambda>ko'. vs_refs ko \<subseteq> vs_refs ko') p s'" 989 shows "vs_lookup_trans s \<subseteq> vs_lookup_trans s'" 990proof - 991 have "vs_lookup1 s \<subseteq> vs_lookup1 s'" 992 by (fastforce dest: ko elim: vs_lookup1_stateI) 993 thus ?thesis by (rule rtrancl_mono) 994qed 995 996lemma vs_lookup_sub: 997 assumes ko: "\<And>ko p. ko_at ko p s \<Longrightarrow> obj_at (\<lambda>ko'. vs_refs ko \<subseteq> vs_refs ko') p s'" 998 assumes table: "graph_of (arm_asid_table (arch_state s)) \<subseteq> graph_of (arm_asid_table (arch_state s'))" 999 shows "vs_lookup s \<subseteq> vs_lookup s'" 1000 unfolding vs_lookup_def 1001 apply (rule Image_mono) 1002 apply (rule vs_lookup_trans_sub) 1003 apply (erule ko) 1004 apply (unfold vs_asid_refs_def) 1005 apply (rule image_mono) 1006 apply (rule table) 1007 done 1008 1009lemma vs_lookup_pages1_stateI: 1010 assumes 1: "(r \<unrhd>1 r') s" 1011 assumes ko: "\<And>ko. ko_at ko (snd r) s \<Longrightarrow> obj_at (\<lambda>ko'. vs_refs_pages ko \<subseteq> vs_refs_pages ko') (snd r) s'" 1012 shows "(r \<unrhd>1 r') s'" using 1 ko 1013 by (fastforce simp: obj_at_def vs_lookup_pages1_def) 1014 1015lemma vs_lookup_pages_trans_sub: 1016 assumes ko: "\<And>ko p. ko_at ko p s \<Longrightarrow> 1017 obj_at (\<lambda>ko'. vs_refs_pages ko \<subseteq> vs_refs_pages ko') p s'" 1018 shows "vs_lookup_pages_trans s \<subseteq> vs_lookup_pages_trans s'" 1019proof - 1020 have "vs_lookup_pages1 s \<subseteq> vs_lookup_pages1 s'" 1021 by (fastforce simp add: ko elim: vs_lookup_pages1_stateI) 1022 thus ?thesis by (rule rtrancl_mono) 1023qed 1024 1025lemma vs_lookup_pages_sub: 1026 assumes ko: "\<And>ko p. ko_at ko p s \<Longrightarrow> 1027 obj_at (\<lambda>ko'. vs_refs_pages ko \<subseteq> vs_refs_pages ko') p s'" 1028 assumes table: 1029 "graph_of (arm_asid_table (arch_state s)) \<subseteq> 1030 graph_of (arm_asid_table (arch_state s'))" 1031 shows "vs_lookup_pages s \<subseteq> vs_lookup_pages s'" 1032 unfolding vs_lookup_pages_def 1033 apply (rule Image_mono) 1034 apply (rule vs_lookup_pages_trans_sub) 1035 apply (erule ko) 1036 apply (unfold vs_asid_refs_def) 1037 apply (rule image_mono) 1038 apply (rule table) 1039 done 1040 1041lemma vs_lookup_pagesI: 1042 "\<lbrakk> ref' \<in> vs_asid_refs (arm_asid_table (arch_state s)); 1043 (ref',(ref,p)) \<in> (vs_lookup_pages1 s)^* \<rbrakk> \<Longrightarrow> 1044 (ref \<unrhd> p) s" 1045 by (simp add: vs_lookup_pages_def) blast 1046 1047lemma vs_lookup_stateI: 1048 assumes 1: "(ref \<rhd> p) s" 1049 assumes ko: "\<And>ko p. ko_at ko p s \<Longrightarrow> obj_at (\<lambda>ko'. vs_refs ko \<subseteq> vs_refs ko') p s'" 1050 assumes table: "graph_of (arm_asid_table (arch_state s)) \<subseteq> graph_of (arm_asid_table (arch_state s'))" 1051 shows "(ref \<rhd> p) s'" 1052 using 1 vs_lookup_sub [OF ko table] by blast 1053 1054lemma valid_vspace_objsD: 1055 "\<lbrakk> (ref \<rhd> p) s; ko_at (ArchObj ao) p s; valid_vspace_objs s \<rbrakk> \<Longrightarrow> valid_vspace_obj ao s" 1056 by (fastforce simp add: valid_vspace_objs_def) 1057 1058lemma valid_arch_cap_typ: 1059 assumes P: "\<And>T p. \<lbrace>\<lambda>s. (typ_at (AArch T) p s )\<rbrace> f \<lbrace>\<lambda>rv s. (typ_at (AArch T) p s)\<rbrace>" 1060 shows "\<lbrace>\<lambda>s. valid_arch_cap c s\<rbrace> f \<lbrace>\<lambda>rv s. valid_arch_cap c s\<rbrace>" 1061 unfolding valid_arch_cap_def 1062 apply (case_tac c; simp) 1063 apply (wp P hoare_vcg_ball_lift hoare_vcg_imp_lift hoare_vcg_conj_lift | clarsimp)+ 1064 done 1065 1066lemma valid_vspace_obj_typ: 1067 assumes P: "\<And>p T. \<lbrace>\<lambda>s. (typ_at (AArch T) p s)\<rbrace> f \<lbrace>\<lambda>rv s. (typ_at (AArch T) p s)\<rbrace>" 1068 shows "\<lbrace>\<lambda>s. valid_vspace_obj ob s\<rbrace> f \<lbrace>\<lambda>rv s. valid_vspace_obj ob s\<rbrace>" 1069 apply (cases ob, simp_all add: valid_vspace_obj_def) 1070 apply (rule hoare_vcg_const_Ball_lift [OF P]) 1071 apply (rule hoare_vcg_all_lift) 1072 apply (rename_tac "fun" x) 1073 apply (case_tac "fun x",simp_all add: data_at_def hoare_vcg_prop P) 1074 apply (wp hoare_vcg_disj_lift P)+ 1075 apply (rule hoare_vcg_ball_lift) 1076 apply (rename_tac "fun" x) 1077 apply (case_tac "fun x", simp_all add: data_at_def hoare_vcg_prop P) 1078 apply (wp hoare_vcg_disj_lift P)+ 1079 done 1080 1081lemma atyp_at_eq_kheap_obj: 1082 "typ_at (AArch AASIDPool) p s \<longleftrightarrow> (\<exists>f. kheap s p = Some (ArchObj (ASIDPool f)))" 1083 "typ_at (AArch APageTable) p s \<longleftrightarrow> (\<exists>pt. kheap s p = Some (ArchObj (PageTable pt)))" 1084 "typ_at (AArch APageDirectory) p s \<longleftrightarrow> (\<exists>pd. kheap s p = Some (ArchObj (PageDirectory pd)))" 1085 "typ_at (AArch (AUserData sz)) p s \<longleftrightarrow> (kheap s p = Some (ArchObj (DataPage False sz)))" 1086 "typ_at (AArch (ADeviceData sz)) p s \<longleftrightarrow> (kheap s p = Some (ArchObj (DataPage True sz)))" 1087 apply (auto simp add: obj_at_def) 1088 apply (simp_all add: a_type_def 1089 split: if_split_asm kernel_object.splits arch_kernel_obj.splits) 1090 done 1091 1092 1093lemmas kernel_object_exhaust = 1094 kernel_object.exhaust 1095 [rotated -1, OF arch_kernel_obj.exhaust, of _ "\<lambda>x. x", simplified] 1096 1097lemma shows 1098 aa_type_AASIDPoolE: 1099 "\<lbrakk>a_type ko = AArch AASIDPool; 1100 (\<And>ap. ko = ArchObj (ASIDPool ap) \<Longrightarrow> R)\<rbrakk> 1101 \<Longrightarrow> R" and 1102 aa_type_APageDirectoryE: 1103 "\<lbrakk>a_type ko = AArch APageDirectory; 1104 (\<And>pd. ko = ArchObj (PageDirectory pd) \<Longrightarrow> R)\<rbrakk> 1105 \<Longrightarrow> R" and 1106 aa_type_APageTableE: 1107 "\<lbrakk>a_type ko = AArch APageTable; (\<And>pt. ko = ArchObj (PageTable pt) \<Longrightarrow> R)\<rbrakk> 1108 \<Longrightarrow> R" and 1109 aa_type_AUserDataE: 1110 "\<lbrakk>a_type ko = AArch (AUserData sz); ko = ArchObj (DataPage False sz) \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R" 1111 and 1112 aa_type_ADeviceDataE: 1113 "\<lbrakk>a_type ko = AArch (ADeviceData sz); ko = ArchObj (DataPage True sz) \<Longrightarrow> R\<rbrakk> \<Longrightarrow> R" 1114 by (rule kernel_object_exhaust[of ko]; clarsimp simp add: a_type_simps split: if_split_asm)+ 1115 1116lemmas aa_type_elims[elim!] = 1117 aa_type_AASIDPoolE aa_type_APageDirectoryE aa_type_APageTableE aa_type_AUserDataE 1118 aa_type_ADeviceDataE 1119 1120lemma wellformed_arch_typ: 1121 assumes P: "\<And>P p T. \<lbrace>\<lambda>s. P (typ_at T p s)\<rbrace> f \<lbrace>\<lambda>rv s. P (typ_at T p s)\<rbrace>" 1122 shows "\<lbrace>\<lambda>s. arch_valid_obj ao s\<rbrace> f \<lbrace>\<lambda>rv s. arch_valid_obj ao s\<rbrace>" 1123 by (cases ao; clarsimp; wp) 1124 1125lemma valid_vspace_objs_stateI: 1126 assumes 1: "valid_vspace_objs s" 1127 assumes ko: "\<And>ko p. ko_at ko p s' \<Longrightarrow> obj_at (\<lambda>ko'. vs_refs ko \<subseteq> vs_refs ko') p s" 1128 assumes arch: "graph_of (arm_asid_table (arch_state s')) \<subseteq> graph_of (arm_asid_table (arch_state s))" 1129 assumes vao: "\<And>p ref ao'. 1130 \<lbrakk> (ref \<rhd> p) s; (ref \<rhd> p) s'; \<forall>ao. ko_at (ArchObj ao) p s \<longrightarrow> valid_vspace_obj ao s; 1131 ko_at (ArchObj ao') p s' \<rbrakk> \<Longrightarrow> valid_vspace_obj ao' s'" 1132 shows "valid_vspace_objs s'" 1133 using 1 unfolding valid_vspace_objs_def 1134 apply clarsimp 1135 apply (frule vs_lookup_stateI) 1136 apply (erule ko) 1137 apply (rule arch) 1138 apply (erule allE, erule impE, fastforce) 1139 apply (erule (3) vao) 1140 done 1141 1142lemmas pageBitsForSize_simps[simp] = 1143 pageBitsForSize_def[split_simps vmpage_size.split] 1144 1145lemma arch_kobj_size_bounded: 1146 "arch_kobj_size obj < word_bits" 1147 apply (cases obj, simp_all add: word_bits_conv pageBits_def) 1148 apply (rename_tac vmpage_size) 1149 apply (case_tac vmpage_size, simp_all) 1150 done 1151 1152lemma valid_arch_sizes: 1153 "obj_bits (ArchObj obj) < word_bits" 1154 using arch_kobj_size_bounded word_bits_conv by auto 1155 1156lemma aobj_bits_T: 1157 "arch_kobj_size v = arch_obj_bits_type (aa_type v)" 1158 unfolding arch_obj_bits_type_def aa_type_def 1159 by (cases v; simp) 1160 1161lemma idle_global: 1162 "idle_thread s \<in> global_refs s" 1163 by (simp add: global_refs_def) 1164 1165lemma valid_ipc_buffer_cap_null: 1166 "valid_ipc_buffer_cap NullCap buf" 1167 by (simp add: valid_ipc_buffer_cap_def) 1168 1169lemma pageBits_clb_less_word_bits [simp]: 1170 "pageBits - cte_level_bits < word_bits" 1171 by (rule less_imp_diff_less, simp) 1172 1173end 1174 1175context Arch_pspace_update_eq begin 1176 1177lemma in_user_frame_update[iff]: 1178 "in_user_frame p (f s) = in_user_frame p s" 1179 by (simp add: in_user_frame_def pspace) 1180 1181lemma in_device_frame_update[iff]: 1182 "in_device_frame p (f s) = in_device_frame p s" 1183 by (simp add: in_device_frame_def obj_at_def pspace) 1184 1185lemma obj_at_update [iff]: 1186 "obj_at P p (f s) = obj_at P p s" 1187 by (fastforce intro: obj_at_pspaceI simp: pspace) 1188 1189lemma valid_asid_table_update [iff]: 1190 "valid_asid_table t (f s) = valid_asid_table t s" 1191 by (simp add: valid_asid_table_def) 1192 1193lemma valid_global_pts_update [iff]: 1194 "arm_global_pts (arch_state (f s)) = arm_global_pts (arch_state s) \<Longrightarrow> 1195 valid_global_pts (f s) = valid_global_pts s" 1196 by (simp add: valid_global_pts_def) 1197 1198lemma valid_pte_update [iff]: 1199 "valid_pte pte (f s) = valid_pte pte s" 1200 by (cases pte) (auto simp: data_at_def) 1201 1202lemma valid_pde_update [iff]: 1203 "valid_pde pde (f s) = valid_pde pde s" 1204 by (cases pde) (auto simp: data_at_def) 1205 1206lemma valid_vspace_obj_update [iff]: 1207 "valid_vspace_obj ao (f s) = valid_vspace_obj ao s" 1208 by (cases ao) auto 1209 1210lemma valid_ao_at_update [iff]: 1211 "valid_ao_at p (f s) = valid_ao_at p s" 1212 by (simp add: valid_ao_at_def) 1213 1214lemma valid_vso_at_update [iff]: 1215 "valid_vso_at p (f s) = valid_vso_at p s" 1216 by (simp add: valid_vso_at_def) 1217 1218lemma equal_kernel_mappings_update [iff]: 1219 "equal_kernel_mappings (f s) = equal_kernel_mappings s" 1220 by (simp add: equal_kernel_mappings_def) 1221 1222lemma valid_pt_kernel_mappings [iff]: 1223 "valid_pde_kernel_mappings pde vref uses (f s) 1224 = valid_pde_kernel_mappings pde vref uses s" 1225 by (cases pde, simp_all add: valid_pde_kernel_mappings_def) 1226 1227lemma valid_pd_kernel_mappings [iff]: 1228 "valid_pd_kernel_mappings uses (f s) 1229 = valid_pd_kernel_mappings uses s" 1230 by (rule ext, simp add: valid_pd_kernel_mappings_def) 1231 1232 1233(* FIXME: Clagged *) 1234lemma get_cap_update [iff]: 1235 "(fst (get_cap p (f s)) = {(cap, f s)}) = (fst (get_cap p s) = {(cap, s)})" 1236 apply (simp add: get_cap_def get_object_def bind_assoc 1237 exec_gets split_def assert_def pspace) 1238 apply (clarsimp simp: fail_def) 1239 apply (case_tac y, simp_all add: assert_opt_def split: option.splits) 1240 apply (simp_all add: return_def fail_def assert_def bind_def) 1241 done 1242 1243(* FIXME: Clagged *) 1244lemma caps_of_state_update [iff]: 1245 "caps_of_state (f s) = caps_of_state s" 1246 by (rule ext) (auto simp: caps_of_state_def) 1247 1248lemma arch_valid_obj_update: 1249 "\<And>ao. b = ArchObj ao \<Longrightarrow> arch_valid_obj ao (f s) = arch_valid_obj ao s" 1250 by clarsimp 1251 1252end 1253 1254context Arch_arch_idle_update_eq begin 1255 1256lemma global_refs_update [iff]: 1257 "global_refs (f s) = global_refs s" 1258 by (simp add: global_refs_def arch idle irq) 1259 1260end 1261 1262context Arch_p_arch_update_eq begin 1263 1264lemma vs_lookup1_update [iff]: 1265 "vs_lookup1 (f s) = vs_lookup1 s" 1266 by (simp add: vs_lookup1_def) 1267 1268lemma vs_lookup_trans_update [iff]: 1269 "vs_lookup_trans (f s) = vs_lookup_trans s" 1270 by simp 1271 1272lemma vs_lookup_update [iff]: 1273 "vs_lookup (f s) = vs_lookup s" 1274 by (simp add: vs_lookup_def arch) 1275 1276lemma vs_lookup_pages1_update [iff]: 1277 "vs_lookup_pages1 (f s) = vs_lookup_pages1 s" 1278 by (simp add: vs_lookup_pages1_def) 1279 1280lemma vs_lookup_pages_trans_update [iff]: 1281 "vs_lookup_pages_trans (f s) = vs_lookup_pages_trans s" 1282 by simp 1283 1284lemma vs_lookup_pages_update [iff]: 1285 "vs_lookup_pages (f s) = vs_lookup_pages s" 1286 by (simp add: vs_lookup_pages_def arch) 1287 1288lemma valid_vs_lookup_update [iff]: 1289 "valid_vs_lookup (f s) = valid_vs_lookup s" 1290 by (simp add: valid_vs_lookup_def arch) 1291 1292lemma valid_table_caps_update [iff]: 1293 "valid_table_caps (f s) = valid_table_caps s" 1294 by (simp add: valid_table_caps_def arch) 1295 1296lemma valid_vspace_objs_update' [iff]: 1297 "valid_vspace_objs (f s) = valid_vspace_objs s" 1298 by (simp add: valid_vspace_objs_def) 1299 1300 1301end 1302 1303context Arch begin global_naming ARM 1304 1305lemma global_refs_equiv: 1306 assumes "idle_thread s = idle_thread s'" 1307 assumes "interrupt_irq_node s = interrupt_irq_node s'" 1308 assumes "arm_globals_frame (arch_state s) = arm_globals_frame (arch_state s')" 1309 assumes "arm_global_pd (arch_state s) = arm_global_pd (arch_state s')" 1310 assumes "set (arm_global_pts (arch_state s)) = set (arm_global_pts (arch_state s'))" 1311 assumes "ran (arm_asid_table (arch_state s)) = ran (arm_asid_table (arch_state s'))" 1312 shows "global_refs s = global_refs s'" 1313 by (simp add: assms global_refs_def) 1314 1315lemma global_refs_lift: 1316 assumes arch: "\<And>P. \<lbrace>\<lambda>s. P (arch_state s)\<rbrace> f \<lbrace>\<lambda>_ s. P (arch_state s)\<rbrace>" 1317 assumes idle: "\<And>P. \<lbrace>\<lambda>s. P (idle_thread s)\<rbrace> f \<lbrace>\<lambda>_ s. P (idle_thread s)\<rbrace>" 1318 assumes irq: "\<And>P. \<lbrace>\<lambda>s. P (interrupt_irq_node s)\<rbrace> f \<lbrace>\<lambda>_ s. P (interrupt_irq_node s)\<rbrace>" 1319 shows "\<lbrace>\<lambda>s. P (global_refs s) \<rbrace> f \<lbrace>\<lambda>r s. P (global_refs s) \<rbrace>" 1320 unfolding global_refs_def 1321 apply (rule hoare_lift_Pf [where f="arch_state", OF _ arch]) 1322 apply (rule hoare_lift_Pf [where f="idle_thread", OF _ idle]) 1323 apply (rule hoare_lift_Pf [where f="interrupt_irq_node", OF _ irq]) 1324 apply (rule hoare_vcg_prop) 1325 done 1326 1327lemma valid_arch_state_lift: 1328 assumes typs: "\<And>T p. \<lbrace>typ_at (AArch T) p\<rbrace> f \<lbrace>\<lambda>_. typ_at (AArch T) p\<rbrace>" 1329 assumes arch: "\<And>P. \<lbrace>\<lambda>s. P (arch_state s)\<rbrace> f \<lbrace>\<lambda>_ s. P (arch_state s)\<rbrace>" 1330 shows "\<lbrace>valid_arch_state\<rbrace> f \<lbrace>\<lambda>_. valid_arch_state\<rbrace>" 1331 apply (simp add: valid_arch_state_def valid_asid_table_def 1332 valid_global_pts_def) 1333 apply (rule hoare_lift_Pf[where f="\<lambda>s. arch_state s"]) 1334 apply (wp arch typs hoare_vcg_conj_lift hoare_vcg_const_Ball_lift)+ 1335 done 1336 1337lemma aobj_at_default_arch_cap_valid: 1338 assumes "ty \<noteq> ASIDPoolObj" 1339 assumes "ko_at (ArchObj (default_arch_object ty dev us)) x s" 1340 shows "valid_arch_cap (arch_default_cap ty x us dev) s" 1341 using assms 1342 by (auto elim!: obj_at_weakenE 1343 simp add: arch_default_cap_def valid_arch_cap_def default_arch_object_def 1344 a_type_def 1345 valid_vm_rights_def 1346 split: apiobject_type.splits aobject_type.splits option.splits) 1347 1348lemma aobj_ref_default: 1349 "aobj_ref (arch_default_cap x6 x us dev) = Some x" 1350 by (auto simp add: arch_default_cap_def split: aobject_type.splits) 1351 1352lemma valid_pde_lift: 1353 assumes x: "\<And>T p. \<lbrace>typ_at (AArch T) p\<rbrace> f \<lbrace>\<lambda>rv. typ_at (AArch T) p\<rbrace>" 1354 shows "\<lbrace>\<lambda>s. valid_pde pde s\<rbrace> f \<lbrace>\<lambda>rv s. valid_pde pde s\<rbrace>" 1355 by (cases pde) (simp add: data_at_def | wp x hoare_vcg_disj_lift)+ 1356 1357lemma valid_pte_lift: 1358 assumes x: "\<And>T p. \<lbrace>typ_at (AArch T) p\<rbrace> f \<lbrace>\<lambda>rv. typ_at (AArch T) p\<rbrace>" 1359 shows "\<lbrace>\<lambda>s. valid_pte pte s\<rbrace> f \<lbrace>\<lambda>rv s. valid_pte pte s\<rbrace>" 1360 by (cases pte) (simp add: data_at_def| wp x hoare_vcg_disj_lift)+ 1361 1362lemma pde_at_atyp: 1363 assumes x: "\<And>p T. \<lbrace>typ_at (AArch T) p\<rbrace> f \<lbrace>\<lambda>rv. typ_at (AArch T) p\<rbrace>" 1364 shows "\<lbrace>pde_at p\<rbrace> f \<lbrace>\<lambda>rv. pde_at p\<rbrace>" 1365 by (simp add: pde_at_def | wp x)+ 1366 1367lemma pte_at_atyp: 1368 assumes x: "\<And>p T. \<lbrace>typ_at (AArch T) p\<rbrace> f \<lbrace>\<lambda>rv. typ_at (AArch T) p\<rbrace>" 1369 shows "\<lbrace>pte_at p\<rbrace> f \<lbrace>\<lambda>rv. pte_at p\<rbrace>" 1370 by (simp add: pte_at_def | wp x)+ 1371 1372lemmas abs_atyp_at_lifts = 1373 valid_pde_lift valid_pte_lift 1374 pde_at_atyp pte_at_atyp 1375 1376lemma page_directory_pde_atI: 1377 "\<lbrakk> page_directory_at p s; x < 2 ^ pageBits; 1378 pspace_aligned s \<rbrakk> \<Longrightarrow> pde_at (p + (x << 2)) s" 1379 apply (clarsimp simp: obj_at_def pde_at_def) 1380 apply (drule (1) pspace_alignedD[rotated]) 1381 apply (clarsimp simp: a_type_def 1382 split: kernel_object.splits arch_kernel_obj.splits if_split_asm) 1383 apply (simp add: aligned_add_aligned is_aligned_shiftl_self word_bits_conv) 1384 apply (subgoal_tac "p = (p + (x << 2) && ~~ mask pd_bits)") 1385 subgoal by auto 1386 apply (rule sym, rule add_mask_lower_bits) 1387 apply (simp add: pd_bits_def pageBits_def) 1388 apply simp 1389 apply (subst upper_bits_unset_is_l2p_32[unfolded word_bits_conv]) 1390 apply (simp add: pd_bits_def pageBits_def) 1391 apply (rule shiftl_less_t2n) 1392 apply (simp add: pd_bits_def pageBits_def) 1393 apply (simp add: pd_bits_def pageBits_def) 1394 done 1395 1396lemma page_table_pte_atI: 1397 "\<lbrakk> page_table_at p s; x < 2^(pt_bits - 2); pspace_aligned s \<rbrakk> \<Longrightarrow> pte_at (p + (x << 2)) s" 1398 apply (clarsimp simp: obj_at_def pte_at_def) 1399 apply (drule (1) pspace_alignedD[rotated]) 1400 apply (clarsimp simp: a_type_def 1401 split: kernel_object.splits arch_kernel_obj.splits if_split_asm) 1402 apply (simp add: aligned_add_aligned is_aligned_shiftl_self word_bits_conv) 1403 apply (subgoal_tac "p = (p + (x << 2) && ~~ mask pt_bits)") 1404 subgoal by auto 1405 apply (rule sym, rule add_mask_lower_bits) 1406 apply (simp add: pt_bits_def pageBits_def) 1407 apply simp 1408 apply (subst upper_bits_unset_is_l2p_32[unfolded word_bits_conv]) 1409 apply (simp add: pt_bits_def pageBits_def) 1410 apply (rule shiftl_less_t2n) 1411 apply (simp add: pt_bits_def pageBits_def) 1412 apply (simp add: pt_bits_def pageBits_def) 1413 done 1414 1415lemma physical_arch_cap_has_ref: 1416 "(acap_class arch_cap = PhysicalClass) = (\<exists>y. aobj_ref arch_cap = Some y)" 1417 by (cases arch_cap; simp) 1418 1419 1420subsection "vs_lookup" 1421 1422lemma vs_lookup1_ko_at_dest: 1423 "\<lbrakk> ((ref, p) \<rhd>1 (ref', p')) s; ko_at (ArchObj ao) p s; valid_vspace_obj ao s \<rbrakk> \<Longrightarrow> 1424 \<exists>ao'. ko_at (ArchObj ao') p' s \<and> (\<exists>tp. vs_ref_aatype (hd ref') = Some tp 1425 \<and> aa_type ao = tp)" 1426 apply (drule vs_lookup1D) 1427 apply (clarsimp simp: obj_at_def vs_refs_def) 1428 apply (cases ao, simp_all add: graph_of_def) 1429 apply clarsimp 1430 apply (drule bspec, fastforce simp: ran_def) 1431 apply (clarsimp simp add: aa_type_def obj_at_def) 1432 apply (clarsimp split: arch_kernel_obj.split_asm if_split_asm) 1433 apply (simp add: pde_ref_def aa_type_def 1434 split: pde.splits) 1435 apply (erule_tac x=a in ballE) 1436 apply (clarsimp simp add: obj_at_def) 1437 apply simp 1438 done 1439 1440lemma vs_lookup1_is_arch: 1441 "(a \<rhd>1 b) s \<Longrightarrow> \<exists>ao'. ko_at (ArchObj ao') (snd a) s" 1442 apply (clarsimp simp: vs_lookup1_def) 1443 apply (case_tac ko, auto simp: vs_refs_def) 1444 done 1445 1446lemma vs_lookup_trancl_step: 1447 "\<lbrakk> r \<in> vs_lookup s; (r, r') \<in> (vs_lookup1 s)^+ \<rbrakk> \<Longrightarrow> r' \<in> vs_lookup s" 1448 apply (clarsimp simp add: vs_lookup_def) 1449 apply (drule (1) rtrancl_trancl_trancl) 1450 apply (drule trancl_into_rtrancl)+ 1451 apply blast 1452 done 1453 1454lemma vs_lookup_pages_trancl_step: 1455 "\<lbrakk> r \<in> vs_lookup_pages s; (r, r') \<in> (vs_lookup_pages1 s)^+ \<rbrakk> \<Longrightarrow> r' \<in> vs_lookup_pages s" 1456 apply (clarsimp simp add: vs_lookup_pages_def) 1457 apply (drule (1) rtrancl_trancl_trancl) 1458 apply (drule trancl_into_rtrancl)+ 1459 apply blast 1460 done 1461 1462lemma vs_lookup_step: 1463 "\<lbrakk> (ref \<rhd> p) s; ((ref, p) \<rhd>1 (ref', p')) s \<rbrakk> \<Longrightarrow> (ref' \<rhd> p') s" 1464 unfolding vs_lookup_def 1465 apply clarsimp 1466 apply (drule rtrancl_trans) 1467 apply (erule r_into_rtrancl) 1468 apply blast 1469 done 1470 1471lemma vs_lookup_pages_step: 1472 "\<lbrakk> (ref \<unrhd> p) s; ((ref, p) \<unrhd>1 (ref', p')) s \<rbrakk> \<Longrightarrow> (ref' \<unrhd> p') s" 1473 unfolding vs_lookup_pages_def 1474 apply clarsimp 1475 apply (drule rtrancl_trans) 1476 apply (erule r_into_rtrancl) 1477 apply blast 1478 done 1479 1480lemma vs_asid_refsI: 1481 "table asid = Some p \<Longrightarrow> 1482 ([VSRef (ucast asid) None],p) \<in> vs_asid_refs table" 1483 by (fastforce simp: vs_asid_refs_def graph_of_def) 1484 1485(* Non-recursive introduction rules for vs_lookup and vs_lookup_pages 1486 NOTE: exhaustive if assuming valid_objs and valid_asid_table *) 1487lemma vs_lookup_atI: 1488 "arm_asid_table (arch_state s) a = Some p \<Longrightarrow> ([VSRef (ucast a) None] \<rhd> p) s" 1489 unfolding vs_lookup_def by (drule vs_asid_refsI) fastforce 1490 1491lemma vs_lookup_apI: 1492 "\<And>a p\<^sub>1 ap b. 1493 \<lbrakk>arm_asid_table (arch_state s) a = Some p\<^sub>1; 1494 kheap s p\<^sub>1 = Some (ArchObj (arch_kernel_obj.ASIDPool ap)); 1495 ap b = Some p\<rbrakk> 1496 \<Longrightarrow> ([VSRef (ucast b) (Some AASIDPool), VSRef (ucast a) None] \<rhd> p) s" 1497 apply (simp add: vs_lookup_def Image_def vs_asid_refs_def graph_of_def) 1498 apply (intro exI conjI, assumption) 1499 apply (rule rtrancl_into_rtrancl) 1500 apply (rule rtrancl_refl) 1501 apply (fastforce simp: vs_lookup1_def obj_at_def vs_refs_def graph_of_def image_def) 1502 done 1503 1504lemma vs_lookup_pdI: 1505 "\<And>a p\<^sub>1 ap b p\<^sub>2 pd c. 1506 \<lbrakk>arm_asid_table (arch_state s) a = Some p\<^sub>1; 1507 kheap s p\<^sub>1 = Some (ArchObj (arch_kernel_obj.ASIDPool ap)); 1508 ap b = Some p\<^sub>2; 1509 kheap s p\<^sub>2 = Some (ArchObj (PageDirectory pd)); 1510 c \<notin> kernel_mapping_slots; 1511 pd c = pde.PageTablePDE p f w\<rbrakk> 1512 \<Longrightarrow> ([VSRef (ucast c) (Some APageDirectory), 1513 VSRef (ucast b) (Some AASIDPool), VSRef (ucast a) None] 1514 \<rhd> ptrFromPAddr p) s" 1515 apply (simp add: vs_lookup_def Image_def vs_asid_refs_def graph_of_def) 1516 apply (intro exI conjI, assumption) 1517 apply (rule rtrancl_into_rtrancl) 1518 apply (rule rtrancl_into_rtrancl) 1519 apply (rule rtrancl_refl) 1520 apply (fastforce simp: vs_lookup1_def obj_at_def 1521 vs_refs_def graph_of_def image_def) 1522 apply (simp add: vs_lookup1_def obj_at_def vs_refs_def graph_of_def image_def) 1523 apply (rule_tac x=c in exI) 1524 apply (simp add: pde_ref_def ptrFormPAddr_addFromPPtr) 1525 done 1526 1527lemma vs_lookup_pages_vs_lookupI: "(ref \<rhd> p) s \<Longrightarrow> (ref \<unrhd> p) s" 1528 apply (clarsimp simp: vs_lookup_pages_def vs_lookup_def Image_def 1529 elim!: bexEI) 1530 apply (erule rtrancl.induct, simp_all) 1531 apply (rename_tac a b c) 1532 apply (subgoal_tac "(b \<unrhd>1 c) s", erule (1) rtrancl_into_rtrancl) 1533 apply (thin_tac "x : rtrancl r" for x r)+ 1534 apply (simp add: vs_lookup1_def vs_lookup_pages1_def split_def) 1535 apply (erule exEI) 1536 apply clarsimp 1537 apply (case_tac x, simp_all add: vs_refs_def vs_refs_pages_def 1538 split: arch_kernel_obj.splits) 1539 apply (clarsimp simp: split_def graph_of_def image_def split: if_split_asm) 1540 apply (intro exI conjI impI, assumption) 1541 apply (simp add: pde_ref_def pde_ref_pages_def 1542 split: pde.splits) 1543 apply (rule refl) 1544 done 1545 1546lemmas 1547 vs_lookup_pages_atI = vs_lookup_atI[THEN vs_lookup_pages_vs_lookupI] and 1548 vs_lookup_pages_apI = vs_lookup_apI[THEN vs_lookup_pages_vs_lookupI] 1549 1550lemma vs_lookup_pages_pdI: 1551 "\<lbrakk>arm_asid_table (arch_state s) a = Some p\<^sub>1; 1552 kheap s p\<^sub>1 = Some (ArchObj (arch_kernel_obj.ASIDPool ap)); 1553 ap b = Some p\<^sub>2; 1554 kheap s p\<^sub>2 = Some (ArchObj (PageDirectory pd)); 1555 c \<notin> kernel_mapping_slots; pde_ref_pages (pd c) = Some p\<rbrakk> 1556 \<Longrightarrow> ([VSRef (ucast c) (Some APageDirectory), 1557 VSRef (ucast b) (Some AASIDPool), VSRef (ucast a) None] \<unrhd> p) s" 1558 apply (frule (2) vs_lookup_pages_apI) 1559 apply (erule vs_lookup_pages_step) 1560 by (fastforce simp: vs_lookup_pages1_def obj_at_def 1561 vs_refs_pages_def graph_of_def image_def 1562 split: if_split_asm) 1563 1564lemma vs_lookup_pages_ptI: 1565 "\<lbrakk>arm_asid_table (arch_state s) a = Some p\<^sub>1; 1566 kheap s p\<^sub>1 = Some (ArchObj (arch_kernel_obj.ASIDPool ap)); 1567 ap b = Some p\<^sub>2; 1568 kheap s p\<^sub>2 = Some (ArchObj (PageDirectory pd)); 1569 c \<notin> kernel_mapping_slots; pd c = PageTablePDE addr x y; 1570 kheap s (ptrFromPAddr addr) = Some (ArchObj (PageTable pt)); 1571 pte_ref_pages (pt d) = Some p\<rbrakk> 1572 \<Longrightarrow> ([VSRef (ucast d) (Some APageTable), 1573 VSRef (ucast c) (Some APageDirectory), 1574 VSRef (ucast b) (Some AASIDPool), VSRef (ucast a) None] \<unrhd> p) s" 1575 apply (frule (5) vs_lookup_pdI[THEN vs_lookup_pages_vs_lookupI]) 1576 apply (erule vs_lookup_pages_step) 1577 by (fastforce simp: vs_lookup_pages1_def obj_at_def 1578 vs_refs_pages_def graph_of_def image_def 1579 split: if_split_asm) 1580 1581lemma stronger_vspace_objsD_lemma: 1582 "\<lbrakk>valid_vspace_objs s; r \<in> vs_lookup s; (r,r') \<in> (vs_lookup1 s)\<^sup>+ \<rbrakk> 1583 \<Longrightarrow> \<exists>ao. ko_at (ArchObj ao) (snd r') s \<and> 1584 valid_vspace_obj ao s" 1585 apply (erule trancl_induct) 1586 apply (frule vs_lookup1_is_arch) 1587 apply (cases r) 1588 apply clarsimp 1589 apply (frule (2) valid_vspace_objsD) 1590 apply (drule (1) vs_lookup_step) 1591 apply (drule (2) vs_lookup1_ko_at_dest) 1592 apply clarsimp 1593 apply (drule (2) valid_vspace_objsD) 1594 apply (fastforce simp: valid_vspace_obj_def) 1595 apply clarsimp 1596 apply (frule (2) vs_lookup1_ko_at_dest) 1597 apply (drule (1) vs_lookup_trancl_step) 1598 apply (drule (1) vs_lookup_step) 1599 apply clarsimp 1600 apply (drule (2) valid_vspace_objsD) 1601 apply (fastforce simp: valid_vspace_obj_def) 1602 done 1603 1604lemma stronger_vspace_objsD: 1605 "\<lbrakk> (ref \<rhd> p) s; 1606 valid_vspace_objs s; 1607 valid_asid_table (arm_asid_table (arch_state s)) s \<rbrakk> \<Longrightarrow> 1608 \<exists>ao. ko_at (ArchObj ao) p s \<and> 1609 valid_vspace_obj ao s" 1610 apply (clarsimp simp: vs_lookup_def vs_asid_refs_def graph_of_def) 1611 apply (clarsimp simp: valid_asid_table_def) 1612 apply (drule bspec, fastforce simp: ran_def) 1613 apply (drule rtranclD) 1614 apply (erule disjE) 1615 prefer 2 1616 apply clarsimp 1617 apply (drule stronger_vspace_objsD_lemma) 1618 apply (erule vs_lookup_atI) 1619 apply assumption 1620 apply clarsimp 1621 apply clarsimp 1622 apply (simp add: valid_vspace_objs_def) 1623 apply (erule_tac x=p in allE) 1624 apply (erule impE) 1625 apply (rule exI) 1626 apply (erule vs_lookup_atI) 1627 apply (clarsimp simp: obj_at_def) 1628 done 1629 1630(* An alternative definition for valid_vspace_objs. 1631 1632 The predicates valid_asid_table and valid_vspace_objs are very compact 1633 but sometimes hard to use. 1634 The lemma below basically unrolls vs_lookup. 1635 Though less elegant, this formulation better separates the relevant cases. *) 1636lemma valid_vspace_objs_alt: 1637 "(\<forall>p\<in>ran (arm_asid_table (arch_state s)). asid_pool_at p s) \<and> 1638 valid_vspace_objs s \<longleftrightarrow> 1639 (\<forall>a p. arm_asid_table (arch_state s) a = Some p \<longrightarrow> 1640 typ_at (AArch AASIDPool) p s) \<and> 1641 (\<forall>a p\<^sub>1 ap b p. 1642 arm_asid_table (arch_state s) a = Some p\<^sub>1 \<longrightarrow> 1643 kheap s p\<^sub>1 = Some (ArchObj (arch_kernel_obj.ASIDPool ap)) \<longrightarrow> 1644 ap b = Some p \<longrightarrow> page_directory_at p s) \<and> 1645 (\<forall>a p\<^sub>1 ap b p\<^sub>2 pd c. 1646 arm_asid_table (arch_state s) a = Some p\<^sub>1 \<longrightarrow> 1647 kheap s p\<^sub>1 = Some (ArchObj (arch_kernel_obj.ASIDPool ap)) \<longrightarrow> 1648 ap b = Some p\<^sub>2 \<longrightarrow> 1649 kheap s p\<^sub>2 = Some (ArchObj (PageDirectory pd)) \<longrightarrow> 1650 c \<notin> kernel_mapping_slots \<longrightarrow> valid_pde (pd c) s) \<and> 1651 (\<forall>a p\<^sub>1 ap b p\<^sub>2 pd c addr f w pt. 1652 arm_asid_table (arch_state s) a = Some p\<^sub>1 \<longrightarrow> 1653 kheap s p\<^sub>1 = Some (ArchObj (arch_kernel_obj.ASIDPool ap)) \<longrightarrow> 1654 ap b = Some p\<^sub>2 \<longrightarrow> 1655 kheap s p\<^sub>2 = Some (ArchObj (PageDirectory pd)) \<longrightarrow> 1656 c \<notin> kernel_mapping_slots \<longrightarrow> 1657 pd c = pde.PageTablePDE addr f w \<longrightarrow> 1658 kheap s (ptrFromPAddr addr) = 1659 Some (ArchObj (PageTable pt)) \<longrightarrow> 1660 (\<forall>d. valid_pte (pt d) s))" 1661 apply (intro iffI conjI) 1662 apply fastforce 1663 apply (clarsimp simp: obj_at_def) 1664 apply (thin_tac "Ball S P" for S P) 1665 apply (frule vs_lookup_atI) 1666 apply (drule valid_vspace_objsD) 1667 apply (simp add: obj_at_def) 1668 apply assumption 1669 apply (clarsimp simp: valid_vspace_obj_def obj_at_def ranI) 1670 apply (clarsimp simp: obj_at_def) 1671 apply (thin_tac "Ball S P" for S P) 1672 apply (frule (2) vs_lookup_apI) 1673 apply (drule valid_vspace_objsD) 1674 apply (simp add: obj_at_def valid_vspace_obj_def) 1675 apply assumption 1676 apply (fastforce simp: valid_vspace_obj_def) 1677 apply (clarsimp simp: obj_at_def) 1678 apply (thin_tac "Ball S P" for S P) 1679 apply (frule (5) vs_lookup_pdI) 1680 apply (drule valid_vspace_objsD) 1681 apply (simp add: obj_at_def) 1682 apply assumption 1683 apply (fastforce simp: valid_vspace_obj_def) 1684 apply (clarsimp simp: ran_def) 1685 apply (clarsimp simp: valid_vspace_objs_def vs_lookup_def) 1686 apply (erule converse_rtranclE) 1687 apply (clarsimp simp: vs_asid_refs_def graph_of_def) 1688 apply (drule spec, drule spec, erule impE, assumption) 1689 apply (clarsimp simp: obj_at_def ran_def) 1690 apply (erule converse_rtranclE) 1691 apply (drule vs_lookup1D) 1692 apply (clarsimp simp: vs_asid_refs_def graph_of_def) 1693 apply (drule spec, drule spec, erule impE, assumption) 1694 apply (drule spec, drule spec, erule impE, assumption) 1695 apply (drule spec, drule spec, erule impE, assumption) 1696 apply (clarsimp simp: obj_at_def) 1697 apply (clarsimp simp: vs_refs_def graph_of_def image_def) 1698 apply (drule spec, drule spec, erule impE, assumption) 1699 apply (drule spec, drule spec, erule impE, assumption) 1700 apply fastforce 1701 apply (erule converse_rtranclE) 1702 apply (clarsimp dest!: vs_lookup1D) 1703 apply (clarsimp simp: vs_asid_refs_def graph_of_def) 1704 apply (drule spec, drule spec, erule impE, assumption) 1705 apply (drule spec, drule spec, erule impE, assumption) 1706 apply (drule spec, drule spec, erule impE, assumption) 1707 apply (drule spec, drule spec, erule impE, assumption) 1708 apply (clarsimp simp: obj_at_def) 1709 apply (clarsimp simp: vs_refs_def graph_of_def image_def) 1710 apply (drule spec, drule spec, erule impE, assumption) 1711 apply (drule spec, drule spec, erule impE, assumption) 1712 apply (drule spec, drule spec, erule impE, assumption) 1713 apply (clarsimp simp: graph_of_def split: if_split_asm) 1714 apply (drule_tac x=ab in spec) 1715 apply (clarsimp simp: pde_ref_def obj_at_def 1716 split: pde.splits) 1717 apply (clarsimp dest!: vs_lookup1D) 1718 apply (clarsimp simp: vs_asid_refs_def graph_of_def) 1719 apply (drule spec, drule spec, erule impE, assumption) 1720 apply (drule spec, drule spec, erule impE, assumption) 1721 apply (drule spec, drule spec, erule impE, assumption) 1722 apply (drule spec, drule spec, erule impE, assumption) 1723 apply (clarsimp simp: obj_at_def) 1724 apply (clarsimp simp: vs_refs_def graph_of_def image_def) 1725 apply (drule spec, drule spec, erule impE, assumption) 1726 apply (drule spec, drule spec, erule impE, assumption) 1727 apply (drule spec, drule spec, erule impE, assumption) 1728 apply (clarsimp simp: graph_of_def split: if_split_asm) 1729 apply (drule_tac x=ab in spec) 1730 apply (clarsimp simp: pde_ref_def obj_at_def 1731 split: pde.splits) 1732 done 1733 1734lemma vs_lookupE: 1735 "\<lbrakk> (ref \<rhd> p) s; 1736 \<And>ref' p'. \<lbrakk> (ref',p') \<in> vs_asid_refs (arm_asid_table (arch_state s)); 1737 ((ref',p') \<rhd>* (ref,p)) s \<rbrakk> \<Longrightarrow> P \<rbrakk> 1738 \<Longrightarrow> P" 1739 by (auto simp: vs_lookup_def) 1740 1741(* Non-recursive elim rules for vs_lookup and vs_lookup_pages 1742 NOTE: effectively rely on valid_objs and valid_asid_table *) 1743lemma vs_lookupE_alt: 1744 assumes vl: "(ref \<rhd> p) s" 1745 assumes va: "valid_vspace_objs s" 1746 assumes vt: "(\<forall>p\<in>ran (arm_asid_table (arch_state s)). asid_pool_at p s)" 1747 assumes 0: "\<And>a. arm_asid_table (arch_state s) a = Some p \<Longrightarrow> 1748 typ_at (AArch AASIDPool) p s \<Longrightarrow> 1749 R [VSRef (ucast a) None] p" 1750 assumes 1: "\<And>a p\<^sub>1 ap b. 1751 \<lbrakk>arm_asid_table (arch_state s) a = Some p\<^sub>1; 1752 kheap s p\<^sub>1 = Some (ArchObj (arch_kernel_obj.ASIDPool ap)); 1753 ap b = Some p; page_directory_at p s\<rbrakk> 1754 \<Longrightarrow> R [VSRef (ucast b) (Some AASIDPool), VSRef (ucast a) None] p" 1755 assumes 2: "\<And>a p\<^sub>1 ap b p\<^sub>2 pd c. 1756 \<lbrakk>arm_asid_table (arch_state s) a = Some p\<^sub>1; 1757 kheap s p\<^sub>1 = Some (ArchObj (arch_kernel_obj.ASIDPool ap)); 1758 ap b = Some p\<^sub>2; 1759 kheap s p\<^sub>2 = Some (ArchObj (PageDirectory pd)); 1760 c \<notin> kernel_mapping_slots; pde_ref (pd c) = Some p; page_table_at p s\<rbrakk> 1761 \<Longrightarrow> R [VSRef (ucast c) (Some APageDirectory), 1762 VSRef (ucast b) (Some AASIDPool), VSRef (ucast a) None] p" 1763 shows "R ref p" 1764proof - 1765 note vao = valid_vspace_objs_alt[THEN iffD1, OF conjI[OF vt va]] 1766 note vat = vao[THEN conjunct1, rule_format] 1767 note vap = vao[THEN conjunct2, THEN conjunct1, rule_format] 1768 note vpd = vao[THEN conjunct2, THEN conjunct2, THEN conjunct1, rule_format] 1769 1770 from vl 1771 show ?thesis 1772 apply (clarsimp simp: vs_lookup_def) 1773 apply (clarsimp simp: Image_def vs_asid_refs_def graph_of_def) 1774 apply (frule vat) 1775 apply (erule converse_rtranclE) 1776 apply clarsimp 1777 apply (erule (1) 0) 1778 apply (clarsimp simp: vs_refs_def graph_of_def obj_at_def 1779 dest!: vs_lookup1D) 1780 apply (frule (2) vap) 1781 apply (erule converse_rtranclE) 1782 apply clarsimp 1783 apply (erule (3) 1) 1784 apply (clarsimp simp: vs_refs_def graph_of_def obj_at_def 1785 dest!: vs_lookup1D split: if_split_asm) 1786 apply (frule (4) vpd) 1787 apply (erule converse_rtranclE) 1788 apply clarsimp 1789 apply (erule (5) 2) 1790 apply (simp add: valid_pde_def pde_ref_def split: pde.splits) 1791 by (clarsimp simp: obj_at_def pde_ref_def vs_refs_def 1792 split: pde.splits 1793 dest!: vs_lookup1D) 1794qed 1795 1796lemma vs_lookup_pagesE_alt: 1797 assumes vl: "(ref \<unrhd> p) s" 1798 assumes va: "valid_vspace_objs s" 1799 assumes vt: "(\<forall>p\<in>ran (arm_asid_table (arch_state s)). asid_pool_at p s)" 1800 assumes 0: "\<And>a. arm_asid_table (arch_state s) a = Some p \<Longrightarrow> 1801 typ_at (AArch AASIDPool) p s \<Longrightarrow> 1802 R [VSRef (ucast a) None] p" 1803 assumes 1: "\<And>a p\<^sub>1 ap b. 1804 \<lbrakk>arm_asid_table (arch_state s) a = Some p\<^sub>1; 1805 kheap s p\<^sub>1 = Some (ArchObj (arch_kernel_obj.ASIDPool ap)); 1806 ap b = Some p; page_directory_at p s\<rbrakk> 1807 \<Longrightarrow> R [VSRef (ucast b) (Some AASIDPool), VSRef (ucast a) None] p" 1808 assumes 2: "\<And>a p\<^sub>1 ap b p\<^sub>2 pd c. 1809 \<lbrakk>arm_asid_table (arch_state s) a = Some p\<^sub>1; 1810 kheap s p\<^sub>1 = Some (ArchObj (arch_kernel_obj.ASIDPool ap)); 1811 ap b = Some p\<^sub>2; 1812 kheap s p\<^sub>2 = Some (ArchObj (PageDirectory pd)); 1813 c \<notin> kernel_mapping_slots; 1814 pde_ref_pages (pd c) = Some p; valid_pde (pd c) s\<rbrakk> 1815 \<Longrightarrow> R [VSRef (ucast c) (Some APageDirectory), 1816 VSRef (ucast b) (Some AASIDPool), VSRef (ucast a) None] p" 1817 assumes 3: "\<And>a p\<^sub>1 ap b p\<^sub>2 pd c addr x y pt d. 1818 \<lbrakk>arm_asid_table (arch_state s) a = Some p\<^sub>1; 1819 kheap s p\<^sub>1 = Some (ArchObj (arch_kernel_obj.ASIDPool ap)); 1820 ap b = Some p\<^sub>2; 1821 kheap s p\<^sub>2 = Some (ArchObj (PageDirectory pd)); 1822 c \<notin> kernel_mapping_slots; pd c = PageTablePDE addr x y; 1823 kheap s (ptrFromPAddr addr) = Some (ArchObj (PageTable pt)); 1824 pte_ref_pages (pt d) = Some p; valid_pte (pt d) s\<rbrakk> 1825 \<Longrightarrow> R [VSRef (ucast d) (Some APageTable), 1826 VSRef (ucast c) (Some APageDirectory), 1827 VSRef (ucast b) (Some AASIDPool), VSRef (ucast a) None] p" 1828 shows "R ref p" 1829proof - 1830 note vao = valid_vspace_objs_alt[THEN iffD1, OF conjI[OF vt va]] 1831 note vat = vao[THEN conjunct1, rule_format] 1832 note vap = vao[THEN conjunct2, THEN conjunct1, rule_format] 1833 note vpd = vao[THEN conjunct2, THEN conjunct2, THEN conjunct1, rule_format] 1834 note vpt = vao[THEN conjunct2, THEN conjunct2, THEN conjunct2, rule_format] 1835 1836 from vl 1837 show ?thesis 1838 apply (clarsimp simp: vs_lookup_pages_def) 1839 apply (clarsimp simp: Image_def vs_asid_refs_def graph_of_def) 1840 apply (frule vat) 1841 apply (erule converse_rtranclE) 1842 apply clarsimp 1843 apply (erule (1) 0) 1844 apply (clarsimp simp: vs_refs_pages_def graph_of_def obj_at_def 1845 dest!: vs_lookup_pages1D) 1846 apply (frule (2) vap) 1847 apply (erule converse_rtranclE) 1848 apply clarsimp 1849 apply (erule (3) 1) 1850 apply (clarsimp simp: vs_refs_pages_def graph_of_def obj_at_def 1851 dest!: vs_lookup_pages1D split: if_split_asm) 1852 apply (frule (4) vpd) 1853 apply (erule converse_rtranclE) 1854 apply clarsimp 1855 apply (erule (6) 2) 1856 apply (clarsimp simp: vs_refs_pages_def graph_of_def obj_at_def 1857 pde_ref_pages_def data_at_def 1858 dest!: vs_lookup_pages1D elim!: disjE 1859 split: if_split_asm pde.splits) 1860 apply (frule_tac d=ac in vpt, assumption+) 1861 apply (erule converse_rtranclE) 1862 apply clarsimp 1863 apply (erule (8) 3) 1864 apply (auto simp: vs_refs_pages_def graph_of_def obj_at_def 1865 pte_ref_pages_def data_at_def 1866 dest!: vs_lookup_pages1D 1867 split: pte.splits) 1868 done 1869qed 1870 1871lemma valid_asid_tableD: 1872 "\<lbrakk> T x = Some p; valid_asid_table T s \<rbrakk> \<Longrightarrow> asid_pool_at p s" 1873 by (auto simp: valid_asid_table_def ran_def) 1874 1875declare graph_of_empty[simp] 1876 1877lemma pde_graph_ofI: 1878 "\<lbrakk>pd x = pde; x \<notin> kernel_mapping_slots; pde_ref pde = Some v\<rbrakk> 1879 \<Longrightarrow> (x, v) \<in> graph_of (\<lambda>x. if x \<in> kernel_mapping_slots then None 1880 else pde_ref (pd x))" 1881 by (rule graph_ofI, simp) 1882 1883lemma vs_refs_pdI: 1884 "\<lbrakk>pd (ucast r) = PageTablePDE x a b; 1885 ucast r \<notin> kernel_mapping_slots; \<forall>n \<ge> 12. n < 32 \<longrightarrow> \<not> r !! n\<rbrakk> 1886 \<Longrightarrow> (VSRef r (Some APageDirectory), ptrFromPAddr x) 1887 \<in> vs_refs (ArchObj (PageDirectory pd))" 1888 apply (simp add: vs_refs_def) 1889 apply (rule image_eqI[rotated]) 1890 apply (rule pde_graph_ofI) 1891 apply (simp add: pde_ref_def)+ 1892 apply (simp add: ucast_ucast_mask) 1893 apply (rule word_eqI) 1894 apply (simp add: word_size) 1895 apply (rule ccontr, auto) 1896 done 1897 1898lemma aa_type_pdD: 1899 "aa_type ko = APageDirectory \<Longrightarrow> \<exists>pd. ko = PageDirectory pd" 1900 by (clarsimp simp: aa_type_def 1901 split: arch_kernel_obj.splits if_split_asm) 1902 1903lemma empty_table_is_valid: 1904 "\<lbrakk>empty_table (set (arm_global_pts (arch_state s))) (ArchObj ao); 1905 valid_arch_state s\<rbrakk> 1906 \<Longrightarrow> valid_vspace_obj ao s" 1907 by (cases ao, simp_all add: empty_table_def) 1908 1909lemma empty_table_pde_refD: 1910 "\<lbrakk> pde_ref (pd x) = Some r; empty_table S (ArchObj (PageDirectory pd)) \<rbrakk> \<Longrightarrow> 1911 r \<in> S" 1912 by (simp add: empty_table_def) 1913 1914lemma valid_global_ptsD: 1915 "\<lbrakk>r \<in> set (arm_global_pts (arch_state s)); valid_global_objs s\<rbrakk> 1916 \<Longrightarrow> \<exists>pt. ko_at (ArchObj (PageTable pt)) r s \<and> (\<forall>x. aligned_pte (pt x))" 1917 by (clarsimp simp: valid_global_objs_def) 1918 1919lemma valid_table_caps_pdD: 1920 "\<lbrakk> caps_of_state s p = Some (ArchObjectCap (PageDirectoryCap pd None)); 1921 valid_table_caps s \<rbrakk> \<Longrightarrow> 1922 obj_at (empty_table (set (second_level_tables (arch_state s)))) pd s" 1923 apply (clarsimp simp: valid_table_caps_def simp del: split_paired_All) 1924 apply (erule allE)+ 1925 apply (erule (1) impE) 1926 apply (fastforce simp add: is_pd_cap_def cap_asid_def) 1927 done 1928 1929lemma valid_vs_lookupD: 1930 "\<lbrakk> (ref \<unrhd> p) s; valid_vs_lookup s \<rbrakk> \<Longrightarrow> 1931 (\<exists>slot cap. caps_of_state s slot = Some cap \<and> p \<in> obj_refs cap \<and> vs_cap_ref cap = Some ref)" 1932 by (simp add: valid_vs_lookup_def) 1933 1934lemma vs_lookup_induct: 1935 assumes r: "(ref \<rhd> p) s" 1936 assumes a: "\<And>asid p. \<lbrakk> arm_asid_table (arch_state s) asid = Some p \<rbrakk> \<Longrightarrow> P [VSRef (ucast asid) None] p s" 1937 assumes s: "\<And>ref p ref' p'. \<lbrakk> (ref \<rhd> p) s; ((ref,p) \<rhd>1 (ref',p')) s; P ref p s \<rbrakk> \<Longrightarrow> P ref' p' s" 1938 shows "P ref p s" 1939 using r 1940 apply (clarsimp simp: vs_lookup_def) 1941 apply (drule rtranclD) 1942 apply (clarsimp simp: vs_asid_refs_def graph_of_def) 1943 apply (frule a) 1944 apply (erule disjE, simp) 1945 apply clarsimp 1946 apply (drule vs_lookup_atI) 1947 apply (erule trancl_induct2) 1948 apply (erule (2) s) 1949 apply (drule (1) vs_lookup_trancl_step) 1950 apply (erule (2) s) 1951 done 1952 1953lemma vs_lookup_pages_induct: 1954 assumes r: "(ref \<unrhd> p) s" 1955 assumes a: "\<And>asid p. \<lbrakk> arm_asid_table (arch_state s) asid = Some p \<rbrakk> \<Longrightarrow> P [VSRef (ucast asid) None] p s" 1956 assumes s: "\<And>ref p ref' p'. \<lbrakk> (ref \<unrhd> p) s; ((ref,p) \<unrhd>1 (ref',p')) s; P ref p s \<rbrakk> \<Longrightarrow> P ref' p' s" 1957 shows "P ref p s" 1958 using r 1959 apply (clarsimp simp: vs_lookup_pages_def) 1960 apply (drule rtranclD) 1961 apply (clarsimp simp: vs_asid_refs_def graph_of_def) 1962 apply (frule a) 1963 apply (erule disjE, simp) 1964 apply clarsimp 1965 apply (drule vs_lookup_pages_atI) 1966 apply (erule trancl_induct2) 1967 apply (erule (2) s) 1968 apply (drule (1) vs_lookup_pages_trancl_step) 1969 apply (erule (2) s) 1970 done 1971 1972lemma vs_ref_order: 1973 "\<lbrakk> (r \<rhd> p) s; valid_vspace_objs s; valid_arch_state s \<rbrakk> 1974 \<Longrightarrow> \<exists>tp. r \<noteq> [] \<and> typ_at (AArch tp) p s \<and> 1975 rev (Some tp # map vs_ref_aatype r) 1976 \<le> [None, Some AASIDPool, Some APageDirectory, Some APageTable]" 1977 apply (erule vs_lookup_induct) 1978 apply (clarsimp simp: valid_arch_state_def valid_asid_table_def ranI) 1979 apply (clarsimp dest!: vs_lookup1D elim!: obj_atE) 1980 apply (clarsimp simp: vs_refs_def a_type_simps 1981 split: kernel_object.split_asm arch_kernel_obj.split_asm 1982 dest!: graph_ofD) 1983 apply (drule valid_vspace_objsD) apply (simp add: obj_at_def) apply (assumption) 1984 apply (case_tac rs; simp) 1985 apply (case_tac list; simp add: ranI) 1986 apply (case_tac lista; simp) 1987 apply (frule prefix_length_le, clarsimp) 1988 apply (drule valid_vspace_objsD, simp add: obj_at_def, assumption) 1989 apply (clarsimp simp: pde_ref_def 1990 split: pde.split_asm if_split_asm) 1991 apply (drule_tac x=a in bspec, simp) 1992 apply (case_tac rs; simp) 1993 apply (case_tac list; simp) 1994 apply (case_tac lista; simp) 1995 apply (frule prefix_length_le, clarsimp) 1996 done 1997 1998 1999lemma addrFromPPtr_ptrFromPAddr_id[simp]: 2000 "addrFromPPtr (ptrFromPAddr x) = x" 2001by (simp add: addrFromPPtr_def ptrFromPAddr_def) 2002 2003lemma valid_pte_lift2: 2004 assumes x: "\<And>T p. \<lbrace>Q and typ_at (AArch T) p\<rbrace> f \<lbrace>\<lambda>rv. typ_at (AArch T) p\<rbrace>" 2005 shows "\<lbrace>\<lambda>s. Q s \<and> valid_pte pte s\<rbrace> f \<lbrace>\<lambda>rv s. valid_pte pte s\<rbrace>" 2006 by (cases pte) (simp add: data_at_def | wp hoare_vcg_disj_lift x)+ 2007 2008lemma valid_pde_lift2: 2009 assumes x: "\<And>T p. \<lbrace>Q and typ_at (AArch T) p\<rbrace> f \<lbrace>\<lambda>rv. typ_at (AArch T) p\<rbrace>" 2010 shows "\<lbrace>\<lambda>s. Q s \<and> valid_pde pde s\<rbrace> f \<lbrace>\<lambda>rv s. valid_pde pde s\<rbrace>" 2011 by (cases pde) (simp add: data_at_def | wp hoare_vcg_disj_lift x)+ 2012 2013lemma valid_vspace_obj_typ2: 2014 assumes P: "\<And>P p T. \<lbrace>\<lambda>s. Q s \<and> P (typ_at (AArch T) p s)\<rbrace> f \<lbrace>\<lambda>rv s. P (typ_at (AArch T) p s)\<rbrace>" 2015 shows "\<lbrace>\<lambda>s. Q s \<and> valid_vspace_obj ob s\<rbrace> f \<lbrace>\<lambda>rv s. valid_vspace_obj ob s\<rbrace>" 2016 by (cases ob; (wpsimp wp: hoare_vcg_all_lift hoare_vcg_const_Ball_lift 2017 valid_pte_lift2[where Q=Q] valid_pde_lift2[where Q=Q] P)) 2018 2019lemma valid_vspace_objsI [intro?]: 2020 "(\<And>p ao. \<lbrakk> (\<exists>\<rhd> p) s; ko_at (ArchObj ao) p s \<rbrakk> \<Longrightarrow> valid_vspace_obj ao s) \<Longrightarrow> valid_vspace_objs s" 2021 by (simp add: valid_vspace_objs_def) 2022 2023 2024lemma vs_lookup1_stateI2: 2025 assumes 1: "(r \<rhd>1 r') s" 2026 assumes ko: "\<And>ko. \<lbrakk> ko_at ko (snd r) s; vs_refs ko \<noteq> {} \<rbrakk> \<Longrightarrow> obj_at (\<lambda>ko'. vs_refs ko \<subseteq> vs_refs ko') (snd r) s'" 2027 shows "(r \<rhd>1 r') s'" using 1 ko 2028 by (fastforce simp: obj_at_def vs_lookup1_def) 2029 2030 2031lemma vs_lookupI: 2032 "\<lbrakk> ref' \<in> vs_asid_refs (arm_asid_table (arch_state s)); 2033 (ref',(ref,p)) \<in> (vs_lookup1 s)^* \<rbrakk> \<Longrightarrow> 2034 (ref \<rhd> p) s" 2035 by (simp add: vs_lookup_def) blast 2036 2037lemma vs_lookup1_trans_is_append': 2038 "(a, b) \<in> (vs_lookup1 s)\<^sup>* \<Longrightarrow> \<exists>zs. fst b = zs @ fst a" 2039 by (erule rtrancl_induct) (auto dest!: vs_lookup1D) 2040 2041lemma vs_lookup1_trans_is_append: 2042 "((xs, a), (ys, b)) \<in> (vs_lookup1 s)\<^sup>* \<Longrightarrow> \<exists>zs. ys = zs @ xs" 2043 by (drule vs_lookup1_trans_is_append') auto 2044 2045lemma vs_lookup_trans_ptr_eq': 2046 "(a, b) \<in> (vs_lookup1 s)\<^sup>* \<Longrightarrow> fst a = fst b \<longrightarrow> snd b = snd a" 2047 apply (erule rtrancl_induct) 2048 apply simp 2049 apply clarsimp 2050 apply (cases a) 2051 apply clarsimp 2052 apply (drule vs_lookup1D) 2053 apply clarsimp 2054 apply (frule vs_lookup1_trans_is_append) 2055 apply simp 2056 done 2057 2058lemma vs_lookup_trans_ptr_eq: 2059 "((r,p), (r,p')) \<in> (vs_lookup1 s)\<^sup>* \<Longrightarrow> p = p'" 2060 by (drule vs_lookup_trans_ptr_eq') simp 2061 2062lemma vs_lookup_atD: 2063 "([VSRef (ucast asid) None] \<rhd> p) s \<Longrightarrow> arm_asid_table (arch_state s) asid = Some p" 2064 apply (simp add: vs_lookup_def) 2065 apply (clarsimp simp: vs_asid_refs_def graph_of_def) 2066 apply (drule rtranclD) 2067 apply (erule disjE) 2068 apply (clarsimp simp: up_ucast_inj_eq) 2069 apply clarsimp 2070 apply (drule tranclD2) 2071 apply (clarsimp simp: up_ucast_inj_eq) 2072 apply (drule vs_lookup1D) 2073 apply (clarsimp simp: vs_refs_def) 2074 apply (clarsimp split: split: kernel_object.splits arch_kernel_obj.splits) 2075 done 2076 2077lemma vs_lookup_atE: 2078 "([VSRef (ucast asid) None] \<rhd> p) s \<Longrightarrow> (arm_asid_table (arch_state s) asid = Some p \<Longrightarrow> P) \<Longrightarrow> P" 2079 by (blast dest: vs_lookup_atD) 2080 2081lemma vs_lookup_2ConsD: 2082 "((v # v' # vs) \<rhd> p) s \<Longrightarrow> \<exists>p'. ((v'#vs) \<rhd> p') s \<and> ((v' # vs,p') \<rhd>1 (v # v' # vs, p)) s" 2083 apply (clarsimp simp: vs_lookup_def) 2084 apply (erule rtranclE) 2085 apply (clarsimp simp: vs_asid_refs_def) 2086 apply (fastforce simp: vs_lookup1_def) 2087 done 2088 2089lemma global_refs_asid_table_update [iff]: 2090 "global_refs (s\<lparr>arch_state := arm_asid_table_update f (arch_state s)\<rparr>) = global_refs s" 2091 by (simp add: global_refs_def) 2092 2093lemma pspace_in_kernel_window_arch_update[simp]: 2094 "arm_kernel_vspace (f (arch_state s)) = arm_kernel_vspace (arch_state s) 2095 \<Longrightarrow> pspace_in_kernel_window (arch_state_update f s) = pspace_in_kernel_window s" 2096 by (simp add: pspace_in_kernel_window_def) 2097 2098lemmas vs_cap_ref_simps = 2099 vs_cap_ref_def [simplified vs_cap_ref_arch_def[abs_def] arch_cap_fun_lift_def[abs_def], 2100 split_simps cap.split arch_cap.split vmpage_size.split] 2101 2102lemmas table_cap_ref_simps = 2103 table_cap_ref_def [simplified table_cap_ref_arch_def[abs_def] arch_cap_fun_lift_def[abs_def], 2104 split_simps cap.split arch_cap.split] 2105 2106lemma table_cap_ref_vs_cap_ref_eq: 2107 "table_cap_ref cap = Some ref \<Longrightarrow> table_cap_ref cap' = Some ref \<Longrightarrow> 2108 vs_cap_ref cap = vs_cap_ref cap'" 2109 by (auto simp: table_cap_ref_def vs_cap_ref_simps 2110 split: cap.splits arch_cap.splits option.splits) 2111 2112lemma vs_cap_ref_eq_imp_table_cap_ref_eq: 2113 "is_pg_cap cap = is_pg_cap cap' \<Longrightarrow> vs_cap_ref cap = vs_cap_ref cap' 2114 \<Longrightarrow> table_cap_ref cap = table_cap_ref cap'" 2115 by (auto simp: is_arch_cap_simps vs_cap_ref_def table_cap_ref_simps 2116 arch_cap_fun_lift_def 2117 split: cap.splits arch_cap.splits vmpage_size.splits option.splits) 2118 2119 2120lemma valid_validate_vm_rights[simp]: 2121 "validate_vm_rights rs \<in> valid_vm_rights" 2122and validate_vm_rights_subseteq[simp]: 2123 "validate_vm_rights rs \<subseteq> rs" 2124and validate_vm_rights_simps[simp]: 2125 "validate_vm_rights vm_read_write = vm_read_write" 2126 "validate_vm_rights vm_read_only = vm_read_only" 2127 "validate_vm_rights vm_kernel_only = vm_kernel_only" 2128 by (simp_all add: validate_vm_rights_def valid_vm_rights_def 2129 vm_read_write_def vm_read_only_def vm_kernel_only_def) 2130 2131lemma validate_vm_rights_inter: (* NOTE: unused *) 2132 "validate_vm_rights (validate_vm_rights fun \<inter> msk) = 2133 validate_vm_rights (fun \<inter> msk)" 2134 by (simp add: validate_vm_rights_def vm_read_write_def vm_read_only_def 2135 vm_kernel_only_def) 2136 2137lemma validate_vm_rights_def': 2138 "validate_vm_rights rs = 2139 (THE rs'. rs' \<subseteq> rs \<and> rs' : valid_vm_rights \<and> 2140 (\<forall>rs''. rs'' \<subseteq> rs \<longrightarrow> rs'' : valid_vm_rights \<longrightarrow> rs'' \<subseteq> rs'))" 2141 apply (rule the_equality[symmetric]) 2142 apply (auto simp add: validate_vm_rights_def valid_vm_rights_def 2143 vm_read_write_def vm_read_only_def vm_kernel_only_def)[1] 2144 apply (simp add: validate_vm_rights_def valid_vm_rights_def 2145 vm_read_write_def vm_read_only_def vm_kernel_only_def) 2146 apply safe 2147 apply simp+ 2148 apply (drule_tac x="{AllowRead, AllowWrite}" in spec, simp+) 2149 apply (drule_tac x="{AllowRead, AllowWrite}" in spec, simp+) 2150 apply (drule_tac x="{AllowRead, AllowWrite}" in spec, simp+) 2151 apply (drule_tac x="{AllowRead}" in spec, simp) 2152 done 2153 2154lemma validate_vm_rights_eq[simp]: 2155 "rs : valid_vm_rights \<Longrightarrow> validate_vm_rights rs = rs" 2156 by (auto simp add: validate_vm_rights_def valid_vm_rights_def 2157 vm_read_write_def vm_read_only_def vm_kernel_only_def) 2158 2159lemma acap_rights_update_id [intro!, simp]: 2160 "\<lbrakk>wellformed_acap cap\<rbrakk> \<Longrightarrow> acap_rights_update (acap_rights cap) cap = cap" 2161 unfolding wellformed_acap_def acap_rights_update_def 2162 by (auto split: arch_cap.splits) 2163 2164lemmas cap_asid_simps [simp] = 2165 cap_asid_def [simplified, split_simps cap.split arch_cap.split option.split prod.split] 2166 2167lemma in_user_frame_def: 2168 "in_user_frame p \<equiv> \<lambda>s. 2169 \<exists>sz. typ_at (AArch (AUserData sz)) (p && ~~ mask (pageBitsForSize sz)) s" 2170 apply (rule eq_reflection, rule ext) 2171 apply (simp add: in_user_frame_def obj_at_def) 2172 apply (rule_tac f=Ex in arg_cong) 2173 apply (rule ext, rule iffI) 2174 apply (simp add: a_type_simps) 2175 apply clarsimp 2176 done 2177 2178lemma in_user_frame_lift: 2179 assumes typ_at: "\<And>T p. \<lbrace>typ_at (AArch T) p\<rbrace> f \<lbrace>\<lambda>_. typ_at (AArch T) p\<rbrace>" 2180 shows "\<lbrace>in_user_frame p\<rbrace> f \<lbrace>\<lambda>_. in_user_frame p\<rbrace>" 2181 unfolding in_user_frame_def 2182 by (wp hoare_vcg_ex_lift typ_at) 2183 2184lemma wellformed_arch_default: 2185 "arch_valid_obj (default_arch_object aobject_type dev us) s" 2186 unfolding arch_valid_obj_def default_arch_object_def 2187 by (cases aobject_type; simp) 2188 2189lemma valid_vspace_obj_default': 2190 "valid_vspace_obj (default_arch_object aobject_type dev us) s" 2191 unfolding default_arch_object_def 2192 by (cases aobject_type; simp) 2193 2194text {* arch specific symrefs *} (* hyp_ref stubs : for compatibility with arm-hyp *) 2195 2196definition 2197 tcb_hyp_refs :: "arch_tcb \<Rightarrow> (obj_ref \<times> reftype) set" 2198where 2199 "tcb_hyp_refs atcb \<equiv> {}" 2200 2201lemma tcb_hyp_refs_of_simps[simp]: 2202 "tcb_hyp_refs atcb = {}" 2203 by (auto simp: tcb_hyp_refs_def) 2204 2205definition refs_of_a :: "arch_kernel_obj \<Rightarrow> (obj_ref \<times> reftype) set" 2206where 2207 "refs_of_a x \<equiv> {}" 2208 2209lemma refs_of_a_simps[simp]: 2210 "refs_of_a ao = {}" 2211 by (auto simp: refs_of_a_def) 2212 2213definition 2214 hyp_refs_of :: "kernel_object \<Rightarrow> (obj_ref \<times> reftype) set" 2215where 2216 "hyp_refs_of x \<equiv> case x of 2217 CNode sz fun => {} 2218 | TCB tcb => tcb_hyp_refs (tcb_arch tcb) 2219 | Endpoint ep => {} 2220 | Notification ntfn => {} 2221 | ArchObj ao => refs_of_a ao" 2222 2223lemma hyp_refs_of_simps[simp]: 2224 "hyp_refs_of (CNode sz fun) = {}" 2225 "hyp_refs_of (TCB tcb) = tcb_hyp_refs (tcb_arch tcb)" 2226 "hyp_refs_of (Endpoint ep) = {}" 2227 "hyp_refs_of (Notification ntfn) = {}" 2228 "hyp_refs_of (ArchObj ao) = refs_of_a ao" 2229 by (auto simp: hyp_refs_of_def) 2230 2231definition 2232 state_hyp_refs_of :: "'z::state_ext state \<Rightarrow> obj_ref \<Rightarrow> (obj_ref \<times> reftype) set" 2233where 2234 "state_hyp_refs_of s \<equiv> \<lambda>x. case (kheap s x) of Some ko \<Rightarrow> hyp_refs_of ko | None \<Rightarrow> {}" 2235 2236definition 2237 state_refs_of_a :: "'z::state_ext state \<Rightarrow> obj_ref \<Rightarrow> (obj_ref \<times> reftype) set" 2238where 2239 "state_refs_of_a s \<equiv> \<lambda>x. case (kheap s x) of 2240 Some ko \<Rightarrow> (case ko of ArchObj ao \<Rightarrow> refs_of_a ao | _ \<Rightarrow> {}) 2241 | None \<Rightarrow> {}" 2242 2243lemma state_hyp_refs_of_elemD: 2244 "\<lbrakk> ref \<in> state_hyp_refs_of s x \<rbrakk> \<Longrightarrow> obj_at (\<lambda>obj. ref \<in> hyp_refs_of obj) x s" 2245 by (clarsimp simp add: state_hyp_refs_of_def obj_at_def 2246 split: option.splits) 2247 2248lemma state_hyp_refs_of_eqD: 2249 "\<lbrakk> state_hyp_refs_of s x = S; S \<noteq> {} \<rbrakk> \<Longrightarrow> obj_at (\<lambda>obj. hyp_refs_of obj = S) x s" 2250 by (clarsimp simp add: state_hyp_refs_of_def obj_at_def 2251 split: option.splits) 2252 2253lemma obj_at_state_hyp_refs_ofD: 2254 "obj_at P p s \<Longrightarrow> \<exists>ko. P ko \<and> state_hyp_refs_of s p = hyp_refs_of ko" 2255 apply (clarsimp simp: obj_at_def state_hyp_refs_of_def) 2256 apply fastforce 2257 done 2258 2259lemma ko_at_state_hyp_refs_ofD: 2260 "ko_at ko p s \<Longrightarrow> state_hyp_refs_of s p = hyp_refs_of ko" 2261 by (clarsimp dest!: obj_at_state_hyp_refs_ofD) 2262 2263lemma hyp_sym_refs_obj_atD: 2264 "\<lbrakk> obj_at P p s; sym_refs (state_hyp_refs_of s) \<rbrakk> \<Longrightarrow> 2265 \<exists>ko. P ko \<and> state_hyp_refs_of s p = hyp_refs_of ko \<and> 2266 (\<forall>(x, tp)\<in>hyp_refs_of ko. obj_at (\<lambda>ko. (p, symreftype tp) \<in> hyp_refs_of ko) x s)" 2267 apply (drule obj_at_state_hyp_refs_ofD) 2268 apply (erule exEI, clarsimp) 2269 apply (drule sym, simp) 2270 apply (drule(1) sym_refsD) 2271 apply (erule state_hyp_refs_of_elemD) 2272 done 2273 2274lemma hyp_sym_refs_ko_atD: 2275 "\<lbrakk> ko_at ko p s; sym_refs (state_hyp_refs_of s) \<rbrakk> \<Longrightarrow> 2276 state_hyp_refs_of s p = hyp_refs_of ko \<and> 2277 (\<forall>(x, tp)\<in>hyp_refs_of ko. obj_at (\<lambda>ko. (p, symreftype tp) \<in> hyp_refs_of ko) x s)" 2278 by (drule(1) hyp_sym_refs_obj_atD, simp) 2279 2280lemma state_hyp_refs_of_pspaceI: 2281 "\<lbrakk> P (state_hyp_refs_of s); kheap s = kheap s' \<rbrakk> \<Longrightarrow> P (state_hyp_refs_of s')" 2282 unfolding state_hyp_refs_of_def 2283 by simp 2284 2285lemma state_hyp_refs_update[iff]: 2286 "kheap (f s) = kheap s \<Longrightarrow> state_hyp_refs_of (f s) = state_hyp_refs_of s" 2287 by (clarsimp simp: state_hyp_refs_of_def 2288 split: option.splits cong: option.case_cong) 2289 2290lemma hyp_refs_of_hyp_live: 2291 "hyp_refs_of ko \<noteq> {} \<Longrightarrow> hyp_live ko" 2292 apply (cases ko, simp_all add: hyp_refs_of_def) 2293 done 2294 2295lemma hyp_refs_of_hyp_live_obj: 2296 "\<lbrakk> obj_at P p s; \<And>ko. \<lbrakk> P ko; hyp_refs_of ko = {} \<rbrakk> \<Longrightarrow> False \<rbrakk> \<Longrightarrow> obj_at hyp_live p s" 2297 by (fastforce simp: obj_at_def hyp_refs_of_hyp_live) 2298 2299(* use tcb_arch_ref to handle obj_refs in tcb_arch: currently there is a vcpu ref only *) 2300 2301definition tcb_arch_ref :: "tcb \<Rightarrow> obj_ref option" 2302where "tcb_arch_ref t \<equiv> None" 2303 2304lemma valid_tcb_arch_ref_lift: 2305 "tcb_arch_ref t = tcb_arch_ref t' \<Longrightarrow> valid_arch_tcb (tcb_arch t) = valid_arch_tcb (tcb_arch t')" 2306 by (simp add: valid_arch_tcb_def tcb_arch_ref_def) 2307 2308lemma valid_arch_tcb_context_update[simp]: 2309 "valid_arch_tcb (tcb_context_update f t) = valid_arch_tcb t" 2310 unfolding valid_arch_tcb_def obj_at_def by simp 2311 2312lemma valid_arch_arch_tcb_context_set[simp]: 2313 "valid_arch_tcb (arch_tcb_context_set a t) = valid_arch_tcb t" 2314 by (simp add: arch_tcb_context_set_def) 2315 2316lemma tcb_arch_ref_context_update: 2317 "tcb_arch_ref (t\<lparr>tcb_arch := (arch_tcb_context_set a (tcb_arch t))\<rparr>) = tcb_arch_ref t" 2318 by (simp add: tcb_arch_ref_def arch_tcb_context_set_def) 2319 2320lemma tcb_arch_ref_set_registers: 2321 "tcb_arch_ref (tcb\<lparr>tcb_arch := arch_tcb_set_registers regs (tcb_arch tcb)\<rparr>) = tcb_arch_ref tcb" 2322 by (simp add: tcb_arch_ref_def) 2323 2324lemma valid_arch_arch_tcb_set_registers[simp]: 2325 "valid_arch_tcb (arch_tcb_set_registers a t) = valid_arch_tcb t" 2326 by (simp add: arch_tcb_set_registers_def) 2327 2328lemma tcb_arch_ref_ipc_buffer_update: "\<And>tcb. 2329 tcb_arch_ref (tcb_ipc_buffer_update f tcb) = tcb_arch_ref tcb" 2330 by (simp add: tcb_arch_ref_def) 2331 2332lemma tcb_arch_ref_mcpriority_update: "\<And>tcb. 2333 tcb_arch_ref (tcb_mcpriority_update f tcb) = tcb_arch_ref tcb" 2334 by (simp add: tcb_arch_ref_def) 2335 2336lemma tcb_arch_ref_ctable_update: "\<And>tcb. 2337 tcb_arch_ref (tcb_ctable_update f tcb) = tcb_arch_ref tcb" 2338 by (simp add: tcb_arch_ref_def) 2339 2340lemma tcb_arch_ref_vtable_update: "\<And>tcb. 2341 tcb_arch_ref (tcb_vtable_update f tcb) = tcb_arch_ref tcb" 2342 by (simp add: tcb_arch_ref_def) 2343 2344lemma tcb_arch_ref_reply_update: "\<And>tcb. 2345 tcb_arch_ref (tcb_reply_update f tcb) = tcb_arch_ref tcb" 2346 by (simp add: tcb_arch_ref_def) 2347 2348lemma tcb_arch_ref_caller_update: "\<And>tcb. 2349 tcb_arch_ref (tcb_caller_update f tcb) = tcb_arch_ref tcb" 2350 by (simp add: tcb_arch_ref_def) 2351 2352lemma tcb_arch_ref_ipcframe_update: "\<And>tcb. 2353 tcb_arch_ref (tcb_ipcframe_update f tcb) = tcb_arch_ref tcb" 2354 by (simp add: tcb_arch_ref_def) 2355 2356lemma tcb_arch_ref_state_update: "\<And>tcb. 2357 tcb_arch_ref (tcb_state_update f tcb) = tcb_arch_ref tcb" 2358 by (simp add: tcb_arch_ref_def) 2359 2360lemma tcb_arch_ref_fault_handler_update: "\<And>tcb. 2361 tcb_arch_ref (tcb_fault_handler_update f tcb) = tcb_arch_ref tcb" 2362 by (simp add: tcb_arch_ref_def) 2363 2364lemma tcb_arch_ref_fault_update: "\<And>tcb. 2365 tcb_arch_ref (tcb_fault_update f tcb) = tcb_arch_ref tcb" 2366 by (simp add: tcb_arch_ref_def) 2367 2368lemma tcb_arch_ref_bound_notification_update: "\<And>tcb. 2369 tcb_arch_ref (tcb_bound_notification_update f tcb) = tcb_arch_ref tcb" 2370 by (simp add: tcb_arch_ref_def) 2371 2372 2373lemmas tcb_arch_ref_simps[simp] = tcb_arch_ref_ipc_buffer_update tcb_arch_ref_mcpriority_update 2374 tcb_arch_ref_ctable_update tcb_arch_ref_vtable_update tcb_arch_ref_reply_update 2375 tcb_arch_ref_caller_update tcb_arch_ref_ipcframe_update tcb_arch_ref_state_update 2376 tcb_arch_ref_fault_handler_update tcb_arch_ref_fault_update tcb_arch_ref_bound_notification_update 2377 tcb_arch_ref_context_update tcb_arch_ref_set_registers 2378 2379lemma hyp_live_tcb_def: "hyp_live (TCB tcb) = bound (tcb_arch_ref tcb)" 2380 by (clarsimp simp: hyp_live_def tcb_arch_ref_def) 2381 2382lemma hyp_live_tcb_simps[simp]: 2383"\<And>tcb f. hyp_live (TCB (tcb_ipc_buffer_update f tcb)) = hyp_live (TCB tcb)" 2384"\<And>tcb f. hyp_live (TCB (tcb_mcpriority_update f tcb)) = hyp_live (TCB tcb)" 2385"\<And>tcb f. hyp_live (TCB (tcb_ctable_update f tcb)) = hyp_live (TCB tcb)" 2386"\<And>tcb f. hyp_live (TCB (tcb_vtable_update f tcb)) = hyp_live (TCB tcb)" 2387"\<And>tcb f. hyp_live (TCB (tcb_reply_update f tcb)) = hyp_live (TCB tcb)" 2388"\<And>tcb f. hyp_live (TCB (tcb_caller_update f tcb)) = hyp_live (TCB tcb)" 2389"\<And>tcb f. hyp_live (TCB (tcb_ipcframe_update f tcb)) = hyp_live (TCB tcb)" 2390"\<And>tcb f. hyp_live (TCB (tcb_state_update f tcb)) = hyp_live (TCB tcb)" 2391"\<And>tcb f. hyp_live (TCB (tcb_fault_handler_update f tcb)) = hyp_live (TCB tcb)" 2392"\<And>tcb f. hyp_live (TCB (tcb_fault_update f tcb)) = hyp_live (TCB tcb)" 2393"\<And>tcb f. hyp_live (TCB (tcb_bound_notification_update f tcb)) = hyp_live (TCB tcb)" 2394 by (simp_all add: hyp_live_tcb_def) 2395 2396 2397lemma valid_arch_tcb_pspaceI: 2398 "\<lbrakk> valid_arch_tcb t s; kheap s = kheap s' \<rbrakk> \<Longrightarrow> valid_arch_tcb t s'" 2399 unfolding valid_arch_tcb_def obj_at_def by (simp) 2400 2401lemma valid_arch_tcb_typ_at: 2402 "\<lbrakk> valid_arch_tcb t s; \<And>T p. typ_at T p s \<Longrightarrow> typ_at T p s' \<rbrakk> \<Longrightarrow> valid_arch_tcb t s'" 2403 by (simp add: valid_arch_tcb_def) 2404 2405lemma valid_arch_tcb_lift: 2406 "(\<And>T p. f \<lbrace>typ_at T p\<rbrace>) \<Longrightarrow> f \<lbrace>valid_arch_tcb t\<rbrace>" 2407 unfolding valid_arch_tcb_def 2408 by (wp hoare_vcg_all_lift hoare_vcg_imp_lift; simp) 2409 2410 2411lemma arch_gen_obj_refs_inD: 2412 "x \<in> arch_gen_obj_refs cap \<Longrightarrow> arch_gen_obj_refs cap = {x}" 2413 by (simp add: arch_gen_obj_refs_def) 2414 2415lemma obj_ref_not_arch_gen_ref: 2416 "x \<in> obj_refs cap \<Longrightarrow> arch_gen_refs cap = {}" 2417 by (cases cap; simp add: arch_gen_obj_refs_def) 2418 2419lemma arch_gen_ref_not_obj_ref: 2420 "x \<in> arch_gen_refs cap \<Longrightarrow> obj_refs cap = {}" 2421 by (cases cap; simp add: arch_gen_obj_refs_def) 2422 2423lemma arch_gen_obj_refs_simps[simp]: 2424 "arch_gen_obj_refs (ASIDPoolCap a b) = {}" 2425 "arch_gen_obj_refs (PageTableCap c d) = {}" 2426 "arch_gen_obj_refs (PageDirectoryCap e f) = {}" 2427 "arch_gen_obj_refs (ASIDControlCap) = {}" 2428 "arch_gen_obj_refs (PageCap x1 x2 x3 x4 x5) = {}" 2429 by (simp add: arch_gen_obj_refs_def)+ 2430 2431lemma same_aobject_same_arch_gen_refs: 2432 "same_aobject_as ac ac' \<Longrightarrow> arch_gen_obj_refs ac = arch_gen_obj_refs ac'" 2433 by (clarsimp simp: arch_gen_obj_refs_def split: arch_cap.split_asm) 2434 2435lemma valid_arch_mdb_eqI: 2436 assumes "valid_arch_mdb (is_original_cap s) (caps_of_state s)" 2437 assumes "caps_of_state s = caps_of_state s'" 2438 assumes "is_original_cap s = is_original_cap s'" 2439 shows "valid_arch_mdb (is original_cap s') (caps_of_state s')" 2440 by (clarsimp simp: valid_arch_mdb_def) 2441 2442end 2443 2444setup {* Add_Locale_Code_Defs.setup "ARM" *} 2445setup {* Add_Locale_Code_Defs.setup "ARM_A" *} 2446 2447end 2448