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