-
Notifications
You must be signed in to change notification settings - Fork 0
/
RootTask_SI.thy
966 lines (846 loc) · 43.8 KB
/
RootTask_SI.thy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
(*
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: GPL-2.0-only
*)
(*
* The layout of the capability space and other parts of the system-initialiser.
*)
theory RootTask_SI
imports WellFormed_SI SysInit_SI
begin
(******************************************************************
* Definition of the CSpace of the root task. *
* This requires a default cap to all of the objects created, *
* and a copy of caps to all of the CNodes (for installing caps). *
******************************************************************)
consts
si_cnode_id :: cdl_object_id
si_asidpool_id :: cdl_object_id
si_asidpool_base :: nat
definition
si_cnode_size :: cdl_size_bits
where
"si_cnode_size = 12"
(* If we axioimise this size, we need it to be smaller than the word size.
* We need this to prove that:
- word_bits - si_cnode_size + si_cnode_size = word_bits.
- offset (of_nat slot) si_cnode_size = slot
*)
lemma si_cnode_size_less_than_word_size [simp]:
"si_cnode_size < word_bits"
by (clarsimp simp: si_cnode_size_def word_bits_def)
lemma si_cnode_size_less_than_eq_word_size [simp]:
"si_cnode_size \<le> word_bits"
by (rule less_imp_le_nat, simp)
lemma si_cnode_size_greater_than_1 [simp]:
"1 < si_cnode_size"
by (clarsimp simp: si_cnode_size_def)
lemma si_cnode_size_greater_than_2 [simp]:
"2 < si_cnode_size"
by (clarsimp simp: si_cnode_size_def)
lemma unat_less_2_si_cnode_size:
"unat (cptr::32 word) < 2 ^ si_cnode_size
\<Longrightarrow> cptr < 2 ^ si_cnode_size"
by (metis si_cnode_size_less_than_word_size unat_power_lower32 word_less_nat_alt)
lemma unat_less_2_si_cnode_size':
"(cptr::32 word) < 2 ^ si_cnode_size
\<Longrightarrow> unat cptr < 2 ^ si_cnode_size"
by (metis unat_less_helper word_unat_power)
(* This is stored in the root TCB. *)
definition
si_cspace_cap :: cdl_cap
where
"si_cspace_cap = CNodeCap si_cnode_id 0 (word_bits - si_cnode_size) si_cnode_size"
(* This is the cap the root TCB has to its own root cnode (stored in its root CNode). *)
definition
si_cnode_cap :: cdl_cap
where
"si_cnode_cap = CNodeCap si_cnode_id 0 (word_bits - si_cnode_size) si_cnode_size"
definition
root_tcb :: cdl_object
where
"root_tcb = update_slots [tcb_cspace_slot \<mapsto> si_cspace_cap,
tcb_vspace_slot \<mapsto> undefined,
tcb_replycap_slot \<mapsto> undefined,
tcb_caller_slot \<mapsto> undefined,
tcb_ipcbuffer_slot \<mapsto> undefined,
tcb_pending_op_slot \<mapsto> undefined] (Tcb (default_tcb minBound))"
definition
empty_asid :: cdl_asid_pool
where
"empty_asid = \<lparr>cdl_asid_pool_caps = empty_cap_map asid_low_bits\<rparr>"
definition
si_asid :: "sep_state \<Rightarrow> bool"
where
"si_asid \<equiv>
(si_cnode_id, unat seL4_CapInitThreadASIDPool) \<mapsto>c AsidPoolCap si_asidpool_id si_asidpool_base \<and>*
si_asidpool_id \<mapsto>f AsidPool empty_asid \<and>*
(\<And>* offset\<in>{offset. offset < 2 ^ asid_low_bits}.
(si_asidpool_id, offset) \<mapsto>c -)"
abbreviation "si_tcb_id \<equiv> root_tcb_id"
definition si_objects :: "sep_state \<Rightarrow> bool"
where
"si_objects \<equiv>
si_tcb_id \<mapsto>f root_tcb \<and>*
si_cnode_id \<mapsto>f CNode (empty_cnode si_cnode_size) \<and>*
(si_tcb_id, tcb_cspace_slot) \<mapsto>c si_cspace_cap \<and>*
(si_tcb_id, tcb_pending_op_slot) \<mapsto>c RunningCap \<and>*
(si_cnode_id, unat seL4_CapInitThreadCNode) \<mapsto>c si_cnode_cap \<and>*
(si_cnode_id, unat seL4_CapIRQControl) \<mapsto>c IrqControlCap \<and>*
si_asid"
definition
si_objects_extra_caps' :: "cdl_object_id set \<Rightarrow> cdl_cptr list \<Rightarrow> cdl_cptr list \<Rightarrow> sep_state \<Rightarrow> bool"
where
"si_objects_extra_caps' obj_ids free_cptrs untyped_cptrs \<equiv> \<lambda>s.
\<exists>untyped_caps all_available_ids.
((\<And>* (cptr, cap) \<in> set (zip untyped_cptrs untyped_caps). (si_cnode_id, unat cptr) \<mapsto>c cap) \<and>*
(\<And>* cptr \<in> set (drop (card obj_ids) free_cptrs). (si_cnode_id, unat cptr) \<mapsto>c NullCap) \<and>*
(\<And>* obj_id\<in>all_available_ids. obj_id \<mapsto>o Untyped)) s"
definition
si_objects_extra_caps :: "cdl_object_id set \<Rightarrow> cdl_cptr list \<Rightarrow> cdl_cptr list
\<Rightarrow> cdl_state \<Rightarrow> sep_state \<Rightarrow> bool"
where
"si_objects_extra_caps obj_ids free_cptrs untyped_cptrs spec \<equiv> \<lambda>s.
\<exists>untyped_caps all_available_ids.
((\<And>* (cptr, cap) \<in> set (zip untyped_cptrs untyped_caps). (si_cnode_id, unat cptr) \<mapsto>c cap) \<and>*
(\<And>* cptr \<in> set (drop (card obj_ids + card {obj_id \<in> obj_ids. cnode_or_tcb_at obj_id spec}) free_cptrs).
(si_cnode_id, unat cptr) \<mapsto>c NullCap) \<and>*
(\<And>* obj_id\<in>all_available_ids. obj_id \<mapsto>o Untyped)) s"
lemma distinct_take_drop_append:
"distinct xs \<Longrightarrow> set (take b (drop a xs)) \<inter> set (drop (a + b) xs) = {}"
by (metis distinct_append distinct_drop take_drop_append)
lemma si_objects_extra_caps'_si_objects_extra_caps:
"distinct free_slots \<Longrightarrow>
si_objects_extra_caps' obj_ids free_slots untyped_cptrs =
(si_objects_extra_caps obj_ids free_slots untyped_cptrs spec \<and>*
(\<And>* cptr \<in> set (take (card {obj_id \<in> obj_ids. cnode_or_tcb_at obj_id spec})
(drop (card obj_ids) free_slots)).
(si_cnode_id, unat cptr) \<mapsto>c NullCap))"
apply (rule ext)
apply (clarsimp simp: si_objects_extra_caps'_def si_objects_extra_caps_def sep_conj_exists)
apply (rule ex_eqI)+
apply (subst take_drop_append [where a="card obj_ids" and
b="card {obj_id \<in> obj_ids. cnode_or_tcb_at obj_id spec}"])
apply clarsimp
apply (subst sep.prod.union_disjoint, (simp add: distinct_take_drop_append)+)+
apply (clarsimp simp: sep_conj_ac)
done
definition
si_irq_nodes :: "cdl_state \<Rightarrow> sep_state \<Rightarrow> bool"
where
"si_irq_nodes spec \<equiv>
(\<lambda>s. \<exists>k_irq_table. (\<And>* irq\<in>used_irqs spec. irq \<mapsto>irq k_irq_table irq \<and>*
k_irq_table irq \<mapsto>o IRQNode empty_irq_node) s)"
(***************************************
* Lemmas about the root task objects. *
***************************************)
lemma is_cnode_cap_si_cspace_cap [simp]:
"is_cnode_cap si_cspace_cap"
by (clarsimp simp: si_cspace_cap_def)
lemma is_cnode_cap_si_cnode_cap [simp]:
"is_cnode_cap si_cnode_cap"
by (clarsimp simp: si_cnode_cap_def)
lemma is_tcb_root_tcb [simp]:
"is_tcb root_tcb"
by (clarsimp simp: root_tcb_def)
lemma cap_guard_size_si_cnode_cap_plus_si_cnode_size [simp]:
"cap_guard_size si_cnode_cap + si_cnode_size = word_bits"
by (clarsimp simp: si_cnode_cap_def)
lemma cap_object_si_cspace_cap [simp]:
"cap_object si_cspace_cap = si_cnode_id"
by (clarsimp simp: cap_object_def cap_has_object_def si_cspace_cap_def)
lemma cap_object_si_cnode_cap [simp]:
"cap_object si_cnode_cap = si_cnode_id"
by (clarsimp simp: cap_object_def cap_has_object_def si_cnode_cap_def)
lemma offset_slot_si_cnode_size:
"slot < 2^si_cnode_size \<Longrightarrow> offset (of_nat slot) si_cnode_size = slot"
by (clarsimp simp: offset_slot)
lemma offset_slot_si_cnode_size':
"slot < 2^si_cnode_size \<Longrightarrow> offset slot si_cnode_size = unat slot"
by (clarsimp simp: offset_slot')
lemma guard_equal_si_cspace_cap:
"src_index < 2 ^ si_cnode_size \<Longrightarrow> guard_equal si_cspace_cap src_index 32"
apply (clarsimp simp: si_cspace_cap_def guard_equal_def Let_unfold)
apply (subst and_mask_eq_iff_shiftr_0 [THEN iffD1])
apply (clarsimp simp: word_bits_def)
apply (erule less_mask_eq)
apply (clarsimp simp: mask_def)
done
lemma guard_equal_si_cspace_cap':
"src_index < 2 ^ si_cnode_size \<Longrightarrow> guard_equal si_cspace_cap src_index word_bits"
by (drule guard_equal_si_cspace_cap, simp add: word_bits_def)
lemma guard_equal_si_cnode_cap:
"src_index < 2 ^ si_cnode_size \<Longrightarrow> guard_equal si_cnode_cap src_index 32"
apply (clarsimp simp: si_cnode_cap_def guard_equal_def Let_unfold)
apply (subst and_mask_eq_iff_shiftr_0 [THEN iffD1])
apply (clarsimp simp: word_bits_def)
apply (erule less_mask_eq)
apply (clarsimp simp: mask_def)
done
lemma seL4_CapInitThreadASIDPool_si_cnode_size [simp]:
"seL4_CapInitThreadASIDPool < 2 ^ si_cnode_size"
by (clarsimp simp: seL4_CapInitThreadASIDPool_def si_cnode_size_def)
lemma guard_equal_si_cspace_cap_seL4_CapInitThreadASIDPool [simp]:
"guard_equal si_cspace_cap seL4_CapInitThreadASIDPool word_bits"
by (rule guard_equal_si_cspace_cap', simp)
lemma si_cspace_cap_guard_equal:
"guard_equal si_cnode_cap src_index 32 \<Longrightarrow> src_index < 2 ^ si_cnode_size"
apply (clarsimp simp: si_cnode_cap_def guard_equal_def
Let_unfold si_cnode_size_def)
apply (subst (asm) shiftr_mask_eq')
apply (simp add: word_bits_size word_bits_def)
apply (subst (asm) le_mask_iff [symmetric])
apply (clarsimp simp: mask_def)
apply (insert word32_less_sub_le [where x=src_index and n=12])
apply (clarsimp simp: word_bits_def)
done
lemma one_lvl_lookup_si_cspace_cap [simp]:
"one_lvl_lookup si_cspace_cap word_bits si_cnode_size"
by (clarsimp simp: one_lvl_lookup_def si_cspace_cap_def)
lemmas one_lvl_lookup_si_cspace_cap' [simp] =
one_lvl_lookup_si_cspace_cap [simplified word_bits_def, simplified]
lemma one_lvl_lookup_si_cnode_cap [simp]:
"one_lvl_lookup si_cnode_cap word_bits si_cnode_size"
by (clarsimp simp: one_lvl_lookup_def si_cnode_cap_def)
lemmas one_lvl_lookup_si_cnode_cap' [simp] =
one_lvl_lookup_si_cnode_cap [simplified word_bits_def, simplified]
lemma obj_tcb_root_tcb [simp]:
"Tcb (obj_tcb root_tcb) = root_tcb"
by (clarsimp simp: obj_tcb_def root_tcb_def update_slots_def)
(***************************
* Lemmas about word size. *
***************************)
lemma seL4_CapInitThreadCNode_less_than_si_cnode_size [simp]:
"seL4_CapInitThreadCNode < 2 ^ si_cnode_size"
apply (insert si_cnode_size_greater_than_1)
apply (insert power_strict_increasing [where n=1 and a="(2::nat)" and N=si_cnode_size, simplified])
apply (clarsimp)
apply (drule of_nat_less_pow_32)
apply (clarsimp simp: seL4_CapInitThreadCNode_def)+
done
lemma offset_seL4_CapInitThreadCNode [simp]:
"offset seL4_CapInitThreadCNode si_cnode_size = unat seL4_CapInitThreadCNode"
by (rule offset_slot', simp)
lemma seL4_CapIRQControl_less_than_si_cnode_size [simp]:
"seL4_CapIRQControl < 2 ^ si_cnode_size"
apply (simp add: seL4_CapIRQControl_def)
apply (insert si_cnode_size_greater_than_2)
apply (insert power_strict_increasing [where n=2 and a="(2::nat)" and N=si_cnode_size, simplified])
apply (drule of_nat_less_pow_32, simp_all)
done
lemma offset_seL4_CapIRQControl [simp]:
"offset seL4_CapIRQControl si_cnode_size = unat seL4_CapIRQControl"
by (rule offset_slot', simp)
(* There is a cap in the root cnode that points to the obj_id specified.
* This cap should be the default cap to that object.
*
* This predicate can be used for spec objects, or the duplicated cnode caps.
*)
definition si_cap_at :: "(cdl_object_id \<Rightarrow> cdl_object_id option) \<Rightarrow>
(cdl_object_id \<Rightarrow> cdl_cptr option) \<Rightarrow> cdl_state \<Rightarrow> bool \<Rightarrow>
cdl_object_id \<Rightarrow> sep_pred"
where
"si_cap_at t si_caps spec dev obj_id \<equiv> \<lambda>s.
\<exists>cap_ptr slot obj kobj_id.
((si_cnode_id, slot) \<mapsto>c default_cap (object_type obj) {kobj_id} (object_size_bits obj) dev) s \<and>
si_caps obj_id = Some cap_ptr \<and>
unat cap_ptr = slot \<and>
cap_ptr < 2 ^ si_cnode_size \<and>
cdl_objects spec obj_id = Some obj \<and>
t obj_id = Some kobj_id"
definition si_irq_cap_at :: "(cdl_irq \<Rightarrow> cdl_cptr option) \<Rightarrow> cdl_state \<Rightarrow>
cdl_irq \<Rightarrow> sep_pred"
where
"si_irq_cap_at si_irq_caps spec irq \<equiv> \<lambda>s.
\<exists>cap_ptr slot.
((si_cnode_id, slot) \<mapsto>c IrqHandlerCap irq) s \<and>
si_irq_caps irq = Some cap_ptr \<and>
unat cap_ptr = slot \<and>
cap_ptr < 2 ^ si_cnode_size"
definition si_caps_at :: "(cdl_object_id \<Rightarrow> cdl_object_id option) \<Rightarrow>
(cdl_object_id \<Rightarrow> cdl_cptr option) \<Rightarrow> cdl_state \<Rightarrow> bool \<Rightarrow>
cdl_object_id set \<Rightarrow> sep_pred"
where
"si_caps_at t si_caps spec dev obj_ids \<equiv>
\<And>* obj_id \<in> obj_ids. (si_cap_at t si_caps spec) dev obj_id"
definition si_irq_caps_at :: "(cdl_irq \<Rightarrow> cdl_cptr option) \<Rightarrow> cdl_state \<Rightarrow>
cdl_irq set \<Rightarrow> sep_pred"
where
"si_irq_caps_at si_irq_caps spec irqs \<equiv>
\<And>* irq \<in> irqs. si_irq_cap_at si_irq_caps spec irq"
definition
si_obj_cap_at' :: " (cdl_object_id \<Rightarrow> cdl_object_id option) \<Rightarrow>
(cdl_object_id \<Rightarrow> cdl_cptr option) \<Rightarrow> cdl_state \<Rightarrow> bool \<Rightarrow>
cdl_object_id \<Rightarrow> cdl_cnode_index \<Rightarrow> sep_pred"
where
"si_obj_cap_at' t si_caps spec dev obj_id slot \<equiv> \<lambda>s. \<exists> spec_cap.
si_cap_at t si_caps spec dev (cap_object spec_cap) s \<and>
opt_cap (obj_id, slot) spec = Some spec_cap"
definition si_obj_cap_at where
"si_obj_cap_at t si_caps spec dev obj_id slot \<equiv>
if original_cap_at (obj_id, slot) spec \<and> cap_at cap_has_object (obj_id, slot) spec
then si_obj_cap_at' t si_caps spec dev obj_id slot
else \<box>"
definition
si_obj_caps_at :: "(cdl_object_id \<Rightarrow> cdl_object_id option) \<Rightarrow>
(cdl_object_id \<Rightarrow> cdl_cptr option) \<Rightarrow> cdl_state \<Rightarrow> bool \<Rightarrow>
cdl_object_id \<Rightarrow> sep_pred"
where
"si_obj_caps_at t si_caps spec dev obj_id \<equiv>
\<And>* slot \<in> dom (slots_of obj_id spec). si_obj_cap_at t si_caps spec dev obj_id slot"
definition
si_objs_caps_at :: "(cdl_object_id \<Rightarrow> cdl_object_id option) \<Rightarrow>
(cdl_object_id \<Rightarrow> cdl_cptr option) \<Rightarrow> cdl_state \<Rightarrow> bool \<Rightarrow>
cdl_object_id set \<Rightarrow> sep_pred"
where
"si_objs_caps_at t si_caps spec dev obj_ids \<equiv>
\<And>* obj_id \<in> obj_ids. (si_obj_caps_at t si_caps spec) dev obj_id"
definition
si_spec_irq_cap_at' :: "(cdl_irq \<Rightarrow> cdl_cptr option) \<Rightarrow> cdl_state \<Rightarrow>
cdl_object_id \<Rightarrow> cdl_cnode_index \<Rightarrow> sep_pred"
where
"si_spec_irq_cap_at' si_irq_caps spec obj_id slot \<equiv> \<lambda>s. \<exists> spec_cap.
si_irq_cap_at si_irq_caps spec (cap_irq spec_cap) s \<and>
opt_cap (obj_id, slot) spec = Some spec_cap"
definition si_spec_irq_cap_at where
"si_spec_irq_cap_at si_irq_caps spec obj_id slot \<equiv>
if irqhandler_cap_at (obj_id, slot) spec
then si_spec_irq_cap_at' si_irq_caps spec obj_id slot
else \<box>"
definition
si_spec_irq_caps_at :: "(cdl_irq \<Rightarrow> cdl_cptr option) \<Rightarrow> cdl_state \<Rightarrow>
cdl_object_id \<Rightarrow> sep_pred"
where
"si_spec_irq_caps_at si_irq_caps spec obj_id \<equiv>
\<And>* slot \<in> dom (slots_of obj_id spec). si_spec_irq_cap_at si_irq_caps spec obj_id slot"
definition
si_spec_irqs_caps_at :: "(cdl_irq \<Rightarrow> cdl_cptr option) \<Rightarrow> cdl_state \<Rightarrow>
cdl_object_id set \<Rightarrow> sep_pred"
where
"si_spec_irqs_caps_at si_irq_caps spec obj_ids \<equiv>
\<And>* obj_id \<in> obj_ids. si_spec_irq_caps_at si_irq_caps spec obj_id"
definition
"si_null_cap_at t si_irq_caps spec obj_id \<equiv>
\<lambda>s. \<exists>cap_ptr slot obj kobj_id.
((si_cnode_id, slot) \<mapsto>c NullCap) s \<and>
si_irq_caps obj_id = Some cap_ptr \<and>
unat cap_ptr = slot \<and>
cap_ptr < 2 ^ si_cnode_size \<and>
cdl_objects spec obj_id = Some obj \<and> t obj_id = Some kobj_id"
definition
"si_null_irq_cap_at si_irq_caps spec irq \<equiv>
\<lambda>s. \<exists>cap_ptr slot.
((si_cnode_id, slot) \<mapsto>c NullCap) s \<and>
si_irq_caps irq = Some cap_ptr \<and>
unat cap_ptr = slot \<and>
cap_ptr < 2 ^ si_cnode_size"
definition
si_spec_obj_null_cap_at' :: " (cdl_object_id \<Rightarrow> cdl_object_id option) \<Rightarrow>
(cdl_object_id \<Rightarrow> cdl_cptr option) \<Rightarrow> cdl_state \<Rightarrow>
cdl_object_id \<Rightarrow> cdl_cnode_index \<Rightarrow> sep_pred"
where
"si_spec_obj_null_cap_at' t si_irq_caps spec obj_id slot \<equiv> \<lambda>s. \<exists> spec_cap.
si_null_cap_at t si_irq_caps spec (cap_object spec_cap) s \<and>
opt_cap (obj_id, slot) spec = Some spec_cap"
definition si_spec_obj_null_cap_at where
"si_spec_obj_null_cap_at t si_irq_caps spec obj_id slot \<equiv>
if original_cap_at (obj_id, slot) spec \<and> cap_at cap_has_object (obj_id, slot) spec
then si_spec_obj_null_cap_at' t si_irq_caps spec obj_id slot
else \<box>"
definition
si_spec_obj_null_caps_at :: "(cdl_object_id \<Rightarrow> cdl_object_id option) \<Rightarrow>
(cdl_object_id \<Rightarrow> cdl_cptr option) \<Rightarrow> cdl_state \<Rightarrow>
cdl_object_id \<Rightarrow> sep_pred"
where
"si_spec_obj_null_caps_at t si_irq_caps spec obj_id \<equiv>
\<And>* slot \<in> dom (slots_of obj_id spec). si_spec_obj_null_cap_at t si_irq_caps spec obj_id slot"
definition
si_spec_objs_null_caps_at :: "(cdl_object_id \<Rightarrow> cdl_object_id option) \<Rightarrow>
(cdl_object_id \<Rightarrow> cdl_cptr option) \<Rightarrow> cdl_state \<Rightarrow>
cdl_object_id set \<Rightarrow> sep_pred"
where
"si_spec_objs_null_caps_at t si_irq_caps spec obj_ids \<equiv>
\<And>* obj_id \<in> obj_ids. si_spec_obj_null_caps_at t si_irq_caps spec obj_id"
definition
si_spec_irq_null_cap_at' :: "(cdl_irq \<Rightarrow> cdl_cptr option) \<Rightarrow> cdl_state \<Rightarrow>
cdl_object_id \<Rightarrow> cdl_cnode_index \<Rightarrow> sep_pred"
where
"si_spec_irq_null_cap_at' si_irq_caps spec obj_id slot \<equiv> \<lambda>s. \<exists> spec_cap.
si_null_irq_cap_at si_irq_caps spec (cap_irq spec_cap) s \<and>
opt_cap (obj_id, slot) spec = Some spec_cap \<and> \<not>is_untyped_cap spec_cap"
definition si_spec_irq_null_cap_at where
"si_spec_irq_null_cap_at si_irq_caps spec obj_id slot \<equiv>
if irqhandler_cap_at (obj_id, slot) spec
then si_spec_irq_null_cap_at' si_irq_caps spec obj_id slot
else \<box>"
definition
si_spec_irq_null_caps_at :: "(cdl_irq \<Rightarrow> cdl_cptr option) \<Rightarrow> cdl_state \<Rightarrow>
cdl_object_id \<Rightarrow> sep_pred"
where
"si_spec_irq_null_caps_at si_irq_caps spec obj_id \<equiv>
\<And>* slot \<in> dom (slots_of obj_id spec). si_spec_irq_null_cap_at si_irq_caps spec obj_id slot"
definition
si_spec_irqs_null_caps_at :: "(cdl_irq \<Rightarrow> cdl_cptr option) \<Rightarrow> cdl_state \<Rightarrow>
cdl_object_id set \<Rightarrow> sep_pred"
where
"si_spec_irqs_null_caps_at si_irq_caps spec obj_ids \<equiv>
\<And>* obj_id \<in> obj_ids. si_spec_irq_null_caps_at si_irq_caps spec obj_id"
definition si_null_caps_at :: "(cdl_object_id \<Rightarrow> cdl_object_id option) \<Rightarrow>
(cdl_object_id \<Rightarrow> cdl_cptr option) \<Rightarrow> cdl_state \<Rightarrow>
cdl_object_id set \<Rightarrow> sep_pred"
where
"si_null_caps_at t si_caps spec obj_ids \<equiv>
\<And>* obj_id \<in> obj_ids. si_null_cap_at t si_caps spec obj_id"
lemma si_cap_at_less_si_cnode_size:
"\<lbrakk>\<guillemotleft>si_cap_at t opt_sel4_cap spec dev obj_id \<and>* R\<guillemotright> s;
Some cap_ptr = opt_sel4_cap obj_id\<rbrakk>
\<Longrightarrow> cap_ptr < 2 ^ si_cnode_size"
by (clarsimp simp: si_cap_at_def sep_conj_exists)
lemma si_irq_cap_at_less_si_cnode_size:
"\<lbrakk>\<guillemotleft>si_irq_cap_at opt_sel4_cap spec obj_id \<and>* R\<guillemotright> s;
Some cap_ptr = opt_sel4_cap obj_id\<rbrakk>
\<Longrightarrow> cap_ptr < 2 ^ si_cnode_size"
by (clarsimp simp: si_irq_cap_at_def sep_conj_exists)
lemma si_cap_at_has_k_obj_id:
"\<lbrakk>\<guillemotleft>si_cap_at t opt_sel4_cap spec dev obj_id \<and>* R\<guillemotright> s\<rbrakk>
\<Longrightarrow> \<exists>cap_object_id. t obj_id = Some cap_object_id"
by (clarsimp simp: si_cap_at_def sep_conj_exists)
(******************************************************
* Using just si_cap_at when you have si_caps_at. *
******************************************************)
lemma valid_si_caps_at_si_cap_at:
"\<lbrakk>finite obj_ids; obj_id \<in> obj_ids;
(\<And>R. \<lbrace>\<guillemotleft>si_cap_at t orig_caps spec dev obj_id \<and>* P \<and>* R\<guillemotright>\<rbrace>
f
\<lbrace>\<lambda>_.\<guillemotleft>si_cap_at t orig_caps spec dev obj_id \<and>* Q \<and>* R\<guillemotright>\<rbrace>)\<rbrakk>
\<Longrightarrow>
\<lbrace>\<guillemotleft>si_caps_at t orig_caps spec dev obj_ids \<and>* P \<and>* R\<guillemotright>\<rbrace>
f
\<lbrace>\<lambda>_.\<guillemotleft>si_caps_at t orig_caps spec dev obj_ids \<and>* Q \<and>* R\<guillemotright>\<rbrace>"
apply (clarsimp simp: si_caps_at_def)
apply (drule sep_set_conj_map_singleton_wp [where f=f and
I="si_cap_at t orig_caps spec dev" and P=P and Q=Q and R=R, rotated])
apply (clarsimp simp: sep_conj_ac)+
done
(*******************************************************
* Frames have been duplicated. *
*******************************************************)
abbreviation (input)
"cap_object_from_slot obj_id slot P s \<equiv> \<exists>cap. opt_cap (obj_id, slot) s = Some cap
\<and> cap \<noteq> NullCap
\<and> P (cap_object cap) s"
abbreviation "get_obj obj_id slot spec \<equiv> (cap_object o the) (opt_cap (obj_id, slot) spec)"
abbreviation "ref_obj spec obj_id slot \<equiv> cap_ref_object (obj_id, slot) spec"
abbreviation "real_frame_cap_of dev ptr rights n t \<equiv> FrameCap dev ((the o t) ptr) rights n Real None"
abbreviation (input) "the_cap spec pt_id pt_slot \<equiv> the (opt_cap (pt_id, pt_slot) spec)"
definition conjure_real_frame_cap ::
"cdl_cap \<Rightarrow> (cdl_object_id \<Rightarrow> cdl_object_id option) \<Rightarrow> cdl_cap"
where
"conjure_real_frame_cap cap t \<equiv>
case cap of FrameCap _ ptr _ n _ _ \<Rightarrow> real_frame_cap_of False ptr vm_read_write n t | _ \<Rightarrow> cap"
definition frame_duplicates_empty ::
"(cdl_object_id \<times> nat \<Rightarrow> word32) \<Rightarrow> cdl_object_id \<Rightarrow> cdl_state \<Rightarrow> (sep_state \<Rightarrow> bool)"
where
"frame_duplicates_empty cptr_map pd_id spec \<equiv>
sep_map_set_conj
(\<lambda>x. let pt_id = get_obj pd_id x spec in
sep_map_set_conj (\<lambda>y. (si_cnode_id, unat $ cptr_map (pt_id, y)) \<mapsto>c NullCap)
{slot \<in> dom (slots_of pt_id spec). cap_at ((\<noteq>) NullCap) (pt_id, slot) spec})
{slot \<in> dom (slots_of pd_id spec). cap_at (\<lambda>cap. cap \<noteq> NullCap \<and> pt_at (cap_object cap) spec)
(pd_id, slot) spec} \<and>*
sep_map_set_conj
(\<lambda>x. let frame_id = get_obj pd_id x spec in
(si_cnode_id, unat $ cptr_map (pd_id, x)) \<mapsto>c NullCap)
{slot \<in> dom (slots_of pd_id spec). cap_at (\<lambda>cap. cap \<noteq> NullCap \<and> frame_at (cap_object cap) spec)
(pd_id, slot) spec}"
definition frame_duplicates_copied ::
"(cdl_object_id \<times> nat \<Rightarrow> word32) \<Rightarrow> cdl_object_id \<Rightarrow> cdl_state
\<Rightarrow> (cdl_object_id \<Rightarrow> cdl_object_id option) \<Rightarrow> (sep_state \<Rightarrow> bool)"
where
"frame_duplicates_copied cptr_map pd_id spec t \<equiv>
sep_map_set_conj
(\<lambda>x. let pt_id = get_obj pd_id x spec in
sep_map_set_conj (\<lambda>y. (si_cnode_id, unat $ cptr_map (pt_id, y)) \<mapsto>c
conjure_real_frame_cap (the_cap spec pt_id y) t)
{slot \<in> dom (slots_of pt_id spec). cap_at ((\<noteq>) NullCap) (pt_id, slot) spec})
{slot \<in> dom (slots_of pd_id spec). cap_at (\<lambda>cap. cap \<noteq> NullCap \<and> pt_at (cap_object cap) spec)
(pd_id, slot) spec} \<and>*
sep_map_set_conj
(\<lambda>x. let frame_id = get_obj pd_id x spec in
(si_cnode_id, unat $ cptr_map (pd_id, x)) \<mapsto>c
conjure_real_frame_cap (the_cap spec pd_id x) t)
{slot \<in> dom (slots_of pd_id spec). cap_at (\<lambda>cap. cap \<noteq> NullCap \<and> frame_at (cap_object cap) spec)
(pd_id, slot) spec}"
(**********************************************************
* The pre and post conditions of the system initialiser. *
**********************************************************)
(* That the boot info is valid, and that there are enough free slots to initialise a system. *)
definition
valid_boot_info
where
"valid_boot_info bootinfo spec \<equiv> \<lambda>s.
\<exists>untyped_caps fstart fend ustart uend obj_ids.
((\<And>*(cptr, cap) \<in> set (zip [ustart .e. uend - 1] untyped_caps). (si_cnode_id, unat cptr) \<mapsto>c cap) \<and>*
(\<And>* cptr \<in> set [fstart .e. fend - 1]. (si_cnode_id, unat cptr) \<mapsto>c NullCap) \<and>*
(\<And>* obj_id\<in>(\<Union>cap\<in>set untyped_caps. cap_free_ids cap). obj_id \<mapsto>o Untyped) \<and>*
(SETSEPCONJ pd_id | pd_at pd_id spec.
frame_duplicates_empty (make_frame_cap_map obj_ids
(drop (card (dom (cdl_objects spec))) [fstart .e. fend - 1]) spec)
pd_id spec) \<and>*
si_objects \<and>*
si_irq_nodes spec) s \<and>
obj_ids = sorted_list_of_set (dom (cdl_objects spec)) \<and>
card (dom (cdl_objects spec)) +
card {obj_id. cnode_or_tcb_at obj_id spec} +
card (\<Union>(set ` get_frame_caps spec ` {obj. pd_at obj spec})) \<le> unat fend - unat fstart \<and>
length untyped_caps = unat uend - unat ustart \<and>
distinct_sets (map cap_free_ids untyped_caps) \<and>
list_all is_full_untyped_cap untyped_caps \<and>
list_all well_formed_untyped_cap untyped_caps \<and>
list_all (\<lambda>c. \<not> is_device_cap c) untyped_caps \<and>
bi_untypes bootinfo = (ustart, uend) \<and>
bi_free_slots bootinfo = (fstart, fend) \<and>
ustart < 2 ^ si_cnode_size \<and>
(uend - 1) < 2 ^ si_cnode_size \<and>
fstart < 2 ^ si_cnode_size \<and>
(fend - 1) < 2 ^ si_cnode_size \<and>
uend \<noteq> 0 \<and> fend \<noteq> 0"
definition
si_final_objects :: "cdl_state \<Rightarrow> (cdl_object_id \<Rightarrow> cdl_object_id option) \<Rightarrow> sep_pred"
where
"si_final_objects spec t \<equiv> \<lambda>s.
\<exists>dup_caps (untyped_cptrs::32 word list) (free_cptrs::32 word list) untyped_caps all_available_ids.
((\<And>* cptr \<in> set (take (card (dom (cdl_objects spec))) free_cptrs).
(si_cnode_id, unat cptr) \<mapsto>c NullCap) \<and>*
(\<And>* cptr \<in> set (drop (card (dom (cdl_objects spec)) +
card ({obj_id. cnode_or_tcb_at obj_id spec})) free_cptrs).
(si_cnode_id, unat cptr) \<mapsto>c NullCap) \<and>*
(\<And>* (cptr, untyped_cap) \<in> set (zip untyped_cptrs untyped_caps).
(si_cnode_id, unat cptr) \<mapsto>c untyped_cap) \<and>*
(\<And>* obj_id \<in> all_available_ids. obj_id \<mapsto>o Untyped) \<and>*
(\<And>* obj_id \<in> {obj_id. cnode_or_tcb_at obj_id spec}. (si_cap_at t dup_caps spec False obj_id)) \<and>*
si_objects) s"
(********************************************************
* Conversion of si_objs_caps_at to si_caps_at *
********************************************************)
lemma orig_cap_rewrite:
"Set.filter (\<lambda>cap_ref. original_cap_at cap_ref spec \<and> cap_at cap_has_object cap_ref spec)
(SIGMA obj_id:{obj_id. cnode_at obj_id spec}.
dom (slots_of obj_id spec)) =
{cap_ref. original_cap_at cap_ref spec \<and> object_cap_ref cap_ref spec}"
by (auto simp: object_cap_ref_def opt_cap_def object_at_def cap_at_def real_object_at_def
split: option.splits)
lemma slots_tcb:
"\<lbrakk>well_formed spec; opt_cap (obj_id, slot) spec = Some cap;
cdl_objects spec obj_id = Some obj; obj = Tcb tcb\<rbrakk> \<Longrightarrow>
slot = 0 \<or>
slot = 1 \<or>
slot = 2 \<or>
slot = 3 \<or>
slot = 4 \<or>
slot = 5 \<or>
slot = 6"
apply (frule (1) well_formed_object_slots)
apply (drule (1) well_formed_well_formed_tcb)
apply (clarsimp simp: well_formed_tcb_def opt_cap_def slots_of_def)
apply (drule (1) dom_eqD)
apply (clarsimp simp: object_default_state_def2 dom_object_slots_default_tcb
tcb_pending_op_slot_def tcb_boundntfn_slot_def)
done
lemma object_at_dom_cdl_objects:
"object_at P obj_id s \<Longrightarrow> obj_id \<in> dom (cdl_objects s)"
by (clarsimp simp: object_at_def)
lemma foo:
"\<lbrakk>well_formed spec; irq_node_at obj_id spec\<rbrakk>
\<Longrightarrow> obj_id \<in> irq_nodes spec"
by (metis irq_nodes_def mem_Collect_eq)
lemma well_formed_irqhandler_cap_in_cnode:
"\<lbrakk>well_formed spec; opt_cap (obj_id, slot) spec = Some cap;
is_irqhandler_cap cap; cdl_objects spec obj_id = Some obj\<rbrakk>
\<Longrightarrow> is_cnode obj"
apply (case_tac obj)
apply (fastforce simp: opt_cap_def slots_of_def object_slots_def
is_cnode_def object_at_def is_asidpool_def)+
apply (frule (3) slots_tcb)
apply (drule (1) well_formed_well_formed_tcb)
apply (clarsimp simp: well_formed_tcb_def opt_cap_def slots_of_def)
apply (erule allE [where x=slot])
apply (simp add: tcb_slot_defs cap_type_def split: cdl_cap.splits)
apply (fastforce simp: opt_cap_def slots_of_def object_slots_def
is_cnode_def object_at_def is_asidpool_def)
apply (frule_tac obj_id=obj_id in well_formed_asidpool_at, simp add: object_at_def)
apply (frule (1) well_formed_pt, simp add: object_at_def, simp+)
apply (frule (1) well_formed_pd, simp add: object_at_def, simp+)
apply (clarsimp simp: is_fake_pt_cap_def split: cdl_cap.splits)
apply (fastforce simp: opt_cap_def slots_of_def object_slots_def
is_cnode_def object_at_def is_asidpool_def)+
apply (frule (1) well_formed_well_formed_irq_node)
apply (fastforce simp: well_formed_irq_node_def opt_cap_def slots_of_def
object_at_def irq_nodes_def is_irq_node_def)
done
lemma well_formed_irqhandler_cap_in_cnode_at:
"\<lbrakk>well_formed spec; opt_cap (obj_id, slot) spec = Some cap; is_irqhandler_cap cap\<rbrakk>
\<Longrightarrow> cnode_at obj_id spec"
apply (frule opt_cap_cdl_objects, clarsimp)
apply (drule (3) well_formed_irqhandler_cap_in_cnode)
apply (clarsimp simp: object_at_def)
done
lemma irqhandler_cap_rewrite:
"well_formed spec \<Longrightarrow>
Set.filter (\<lambda>irq. irqhandler_cap_at irq spec)
(SIGMA obj_id:{obj_id. cnode_at obj_id spec}.
dom (slots_of obj_id spec)) =
{cap_ref. irqhandler_cap_at cap_ref spec}"
apply (clarsimp simp: object_cap_ref_def object_at_def cap_at_def
split: option.splits)
apply rule
apply clarsimp
apply clarsimp
apply (frule opt_cap_dom_cdl_objects)
apply (frule opt_cap_dom_slots_of, clarsimp)
apply (frule (3) well_formed_irqhandler_cap_in_cnode)
apply (frule (1) well_formed_well_formed_irq_node)
apply (clarsimp simp: well_formed_irq_node_def object_at_def
opt_cap_def slots_of_def dom_def)
done
lemma well_formed_object_cap_real:
"well_formed spec
\<Longrightarrow> object_cap_ref cap_ref spec =
(cap_at_to_real_object cap_ref spec \<and>
cnode_at (fst cap_ref) spec)"
apply (clarsimp simp: cap_at_def cap_at_to_real_object_def object_cap_ref_def)
apply (rule iffI)
apply clarsimp
apply (drule (1) well_formed_well_formed_cap_to_real_object', simp)
apply (clarsimp simp: well_formed_cap_to_real_object_def real_object_at_def)
apply (clarsimp simp: real_object_at_def opt_cap_dom_cdl_objects)
done
(* This lemma converts between the two represenatations of the fact that the
* root task has orig caps to each of the objects.
*
* This can be specified either:
* - on the objects themselves.
* - on the cap slots of CNodes that have a orig cap in them.
*
* This relies on the bijection between orig capabilities and objects in the spec.
*)
lemma si_caps_at_conversion:
"\<lbrakk>well_formed spec;
real_ids = {obj_id. real_object_at obj_id spec};
cnode_ids = {obj_id. cnode_at obj_id spec}\<rbrakk>
\<Longrightarrow> si_objs_caps_at t si_caps spec dev cnode_ids =
si_caps_at t si_caps spec dev real_ids"
apply (clarsimp simp: si_objs_caps_at_def si_obj_caps_at_def [abs_def]
si_obj_cap_at_def [abs_def] si_caps_at_def)
apply (subst sep.prod.Sigma, clarsimp+)
apply (clarsimp simp: split_def)
apply (subst sep_map_set_conj_restrict_predicate)
apply (rule finite_SigmaI, clarsimp+)
apply (subst orig_cap_rewrite)
apply (frule well_formed_bij)
apply (clarsimp simp: bij_betw_def)
apply (rule sep_map_set_conj_reindex_cong [where f="\<lambda>cap_ref. cap_ref_object cap_ref spec", symmetric])
apply (subst well_formed_object_cap_real, simp+)
apply (simp add: real_objects_def real_object_at_def)
apply (subst well_formed_object_cap_real, simp+)
apply (clarsimp simp: cap_ref_object_def object_cap_ref_def si_obj_cap_at'_def)
done
lemma si_null_caps_at_conversion:
"\<lbrakk>well_formed spec;
real_ids = {obj_id. real_object_at obj_id spec};
cnode_ids = {obj_id. cnode_at obj_id spec}\<rbrakk>
\<Longrightarrow> si_spec_objs_null_caps_at t si_caps spec cnode_ids =
si_null_caps_at t si_caps spec real_ids"
apply (clarsimp simp: si_spec_objs_null_caps_at_def si_spec_obj_null_caps_at_def [abs_def]
si_spec_obj_null_cap_at_def [abs_def] si_null_caps_at_def)
apply (subst sep.prod.Sigma, clarsimp+)
apply (clarsimp simp: split_def)
apply (subst sep_map_set_conj_restrict_predicate)
apply (rule finite_SigmaI, clarsimp+)
apply (subst orig_cap_rewrite)
apply (frule well_formed_bij)
apply (clarsimp simp: bij_betw_def)
apply (rule sep_map_set_conj_reindex_cong [where f="\<lambda>cap_ref. cap_ref_object cap_ref spec"
and h="(si_null_cap_at t si_caps spec)"
and B="{obj_id. real_object_at obj_id spec}", symmetric])
apply (subst well_formed_object_cap_real, simp+)
apply (simp add: real_objects_def real_object_at_def)
apply (subst well_formed_object_cap_real, simp+)
apply (clarsimp simp: cap_ref_object_def object_cap_ref_def si_spec_obj_null_cap_at'_def)
done
lemma si_null_caps_at_reindex:
"\<lbrakk>distinct (obj_ids::32 word list); distinct (free_cptrs);
orig_caps = map_of (zip obj_ids free_cptrs);
length obj_ids \<le> length free_cptrs\<rbrakk>
\<Longrightarrow> (\<And>* obj_id\<in>set obj_ids.
(\<lambda>s. \<exists>cap_ptr. ((si_cnode_id, unat cap_ptr) \<mapsto>c NullCap) s \<and>
orig_caps obj_id = Some cap_ptr))
= (\<And>* cptr\<in>set (take (length obj_ids) free_cptrs).
(si_cnode_id, unat cptr) \<mapsto>c NullCap)"
apply (rule sep_map_set_conj_reindex_cong [symmetric, where
f="\<lambda>obj_id. the (orig_caps obj_id)"
and h="\<lambda>cptr. (si_cnode_id, unat cptr) \<mapsto>c NullCap"
and B="set (take (length obj_ids) free_cptrs)"])
apply clarsimp
apply (erule (2) map_of_zip_inj')
apply clarsimp
apply (subst zip_take_length[symmetric])
apply (subst map_of_zip_range)
apply (clarsimp simp: min_def)
apply assumption
apply simp
apply clarsimp
apply (rule ext)
apply rule
apply clarsimp
apply (rule_tac x="the (map_of (zip obj_ids free_cptrs) a)" in exI)
apply clarsimp
apply (frule_tac x=a in map_of_zip_is_Some', clarsimp)
done
lemma si_null_caps_at_simplified_helper:
"\<lbrakk>(si_null_caps_at t orig_caps spec obj_ids) s\<rbrakk> \<Longrightarrow>
(\<And>* obj_id \<in> obj_ids. (\<lambda>s. \<exists>cap_ptr. ((si_cnode_id, unat cap_ptr) \<mapsto>c NullCap) s \<and>
orig_caps obj_id = Some cap_ptr)) s"
apply (clarsimp simp: si_null_caps_at_def si_null_cap_at_def [abs_def])
apply (erule sep_map_set_conj_impl)
apply blast
apply clarsimp
done
lemma si_null_caps_at_simplified:
"\<lbrakk>(si_spec_objs_null_caps_at t si_caps spec cnode_ids) s;
well_formed spec;
cnode_ids = {obj_id. cnode_at obj_id spec};
real_ids = {obj_id. real_object_at obj_id spec};
real_ids = set obj_ids;
distinct obj_ids; distinct free_cptrs;
si_caps = map_of (zip obj_ids free_cptrs);
length obj_ids \<le> length free_cptrs\<rbrakk> \<Longrightarrow>
(\<And>* cptr \<in> set (take (length obj_ids) free_cptrs). ((si_cnode_id, unat cptr) \<mapsto>c NullCap)) s"
apply (subst (asm) si_null_caps_at_conversion, assumption+)
apply (drule si_null_caps_at_simplified_helper)
apply (subst si_null_caps_at_reindex [symmetric], simp+)
done
lemma map_of_zip_range':
"\<lbrakk>length xs = length ys; distinct xs; set xs = X\<rbrakk>
\<Longrightarrow> (\<lambda>x. (the (map_of (zip xs ys) x))) ` X = set ys"
by (metis map_of_zip_range)
lemma si_irq_caps_at_conversion:
"\<lbrakk>well_formed spec;
cnode_ids = {obj_id. cnode_at obj_id spec};
irqs = used_irqs spec\<rbrakk>
\<Longrightarrow> si_spec_irqs_caps_at irq_caps spec cnode_ids =
si_irq_caps_at irq_caps spec irqs"
apply (clarsimp simp: si_spec_irqs_caps_at_def si_irq_caps_at_def
si_spec_irq_caps_at_def [abs_def]
si_spec_irq_cap_at_def [abs_def])
apply (subst sep.prod.Sigma, clarsimp+)
apply (clarsimp simp: split_def)
apply (subst sep_map_set_conj_restrict_predicate)
apply (rule finite_SigmaI, clarsimp+)
apply (subst irqhandler_cap_rewrite, assumption)
apply (frule well_formed_irqhandler_bij)
apply (clarsimp simp: bij_betw_def)
apply (rule sep_map_set_conj_reindex_cong [where f="\<lambda>cap_ref. cap_ref_irq cap_ref spec", symmetric], simp+)
apply (clarsimp simp: si_spec_irq_cap_at'_def cap_ref_irq_def cap_at_def)
done
definition si_null_irq_caps_at :: "(cdl_irq \<Rightarrow> cdl_cptr option) \<Rightarrow> cdl_state \<Rightarrow>
cdl_irq set \<Rightarrow> sep_pred"
where
"si_null_irq_caps_at si_irq_caps spec irqs \<equiv>
\<And>* irq \<in> irqs. si_null_irq_cap_at si_irq_caps spec irq"
lemma si_null_irq_caps_at_simplified_helper:
"\<lbrakk>(si_null_irq_caps_at si_irq_caps spec irqs) s\<rbrakk> \<Longrightarrow>
(\<And>* irq \<in> irqs. (\<lambda>s. \<exists>cap_ptr. ((si_cnode_id, unat cap_ptr) \<mapsto>c NullCap) s \<and>
si_irq_caps irq = Some cap_ptr)) s"
apply (clarsimp simp: si_null_irq_caps_at_def si_null_irq_cap_at_def)
apply (erule sep_map_set_conj_impl)
apply blast
apply clarsimp
done
lemma map_of_zip_inj2:
"\<lbrakk>distinct xs; distinct ys; length xs \<le> length ys; set xs = X\<rbrakk>
\<Longrightarrow> inj_on (\<lambda>x. the (map_of (zip xs ys) x)) X"
by (metis map_of_zip_inj')
lemma opt_cap_has_slots:
"\<lbrakk>opt_cap (obj_id, slot) spec = Some cap\<rbrakk>
\<Longrightarrow> object_at has_slots obj_id spec"
by (auto simp: object_at_def has_slots_def opt_cap_def slots_of_def object_slots_def
split: option.splits cdl_object.splits)
lemma well_formed_non_ntfn_in_real_object:
"\<lbrakk>well_formed spec; opt_cap (obj_id, slot) spec = Some cap; \<not>is_ntfn_cap cap; cap \<noteq> NullCap\<rbrakk>
\<Longrightarrow> real_object_at obj_id spec"
apply (frule opt_cap_cdl_objects, clarsimp)
apply (frule (1) well_formed_well_formed_irq_node)
apply (clarsimp simp: well_formed_irq_node_def real_object_at_def
opt_cap_def slots_of_def opt_cap_dom_cdl_objects)
done
lemma irqhandler_cap_at_simp:
"well_formed spec \<Longrightarrow>
{(obj_id, slot). cnode_at obj_id spec \<and> irqhandler_cap_at (obj_id, slot) spec} =
{(obj_id, slot). irqhandler_cap_at (obj_id, slot) spec}"
apply (safe)
apply (clarsimp simp: cap_at_def)
apply (frule (2) well_formed_irqhandler_cap_in_cnode_at)
apply (frule (1) well_formed_non_ntfn_in_real_object, simp+)
done
lemma orig_cap_rewrite_v2:
"(SIGMA obj_id:{obj_id. cnode_at obj_id spec}. dom (slots_of obj_id spec)) =
{(obj_id, slot). cnode_at obj_id spec \<and> slots_of obj_id spec slot \<noteq> None}"
by auto
lemma rewrite_irqhandler_cap_at:
"well_formed spec \<Longrightarrow>
Set.filter (\<lambda>cap_ref. irqhandler_cap_at cap_ref spec)
(SIGMA obj_id:{obj_id. cnode_at obj_id spec}. dom (slots_of obj_id spec)) =
{(obj_id, slot). irqhandler_cap_at (obj_id, slot) spec}"
apply (subst irqhandler_cap_at_simp [symmetric])
by (auto simp: opt_cap_def cap_at_def)
lemma well_formed_used_irqs_rewrite:
"well_formed spec \<Longrightarrow>
(\<lambda>cap_ref. cap_ref_irq cap_ref spec) ` {(obj_id, slot). irqhandler_cap_at (obj_id, slot) spec} =
used_irqs spec"
apply (drule well_formed_irqhandler_bij)
apply (auto simp: bij_betw_def)
done
lemma si_irq_null_caps_at_simplified:
"\<lbrakk>(si_spec_irqs_null_caps_at irq_caps spec {obj_id. cnode_at obj_id spec}) s;
well_formed spec;
distinct irqs; distinct free_cptrs;
set irqs = used_irqs spec;
irq_caps = map_of (zip irqs free_cptrs);
length irqs \<le> length free_cptrs\<rbrakk> \<Longrightarrow>
(\<And>* cptr \<in> set (take (length irqs) free_cptrs). ((si_cnode_id, unat cptr) \<mapsto>c NullCap)) s"
apply (clarsimp simp: si_spec_irqs_null_caps_at_def si_spec_irq_null_caps_at_def
si_spec_irq_null_cap_at_def si_spec_irqs_caps_at_def)
apply (subst (asm) sep.prod.Sigma, clarsimp+)
apply (clarsimp simp: split_def)
apply (subst (asm) sep_map_set_conj_restrict_predicate, rule finite_SigmaI, clarsimp+)
apply (subst (asm) rewrite_irqhandler_cap_at, simp)
apply (subst (asm) sep_map_set_conj_reindex_cong [where
f = "\<lambda>cap_ref. cap_ref_irq cap_ref spec"
and h = "si_null_irq_cap_at (map_of (zip irqs free_cptrs)) spec", symmetric])
apply (drule well_formed_irqhandler_bij)
apply (clarsimp simp: bij_betw_def cond_case_prod_eta)
apply simp
apply (clarsimp simp: si_spec_irq_null_cap_at'_def cap_at_def cap_ref_irq_def)
apply clarsimp
apply (drule si_null_irq_caps_at_simplified_helper [simplified si_null_irq_caps_at_def])
apply (subst (asm) sep_map_set_conj_reindex_cong [symmetric, where
f = "\<lambda>irq. the ( map_of (zip irqs free_cptrs) irq)"
and h = "\<lambda>cptr. (si_cnode_id, unat cptr) \<mapsto>c NullCap"
and B = "set (take (length irqs) free_cptrs)"])
apply (subst well_formed_used_irqs_rewrite, assumption)
apply (metis map_of_zip_inj')
apply (subst well_formed_used_irqs_rewrite, assumption)
apply (subst zip_take_length[symmetric], subst map_of_zip_range', simp+)
apply (rule ext)
apply rule
apply clarsimp
apply (rule_tac x="the (map_of (zip irqs free_cptrs) a)" in exI)
apply clarsimp
apply (frule_tac x1="(cap_irq (the (opt_cap (aa, b) spec)))" in map_of_zip_is_Some'[THEN iffD1], clarsimp)
apply (fastforce simp: cap_at_def used_irqs_def all_caps_def)
apply (clarsimp simp: cap_ref_irq_def)
apply simp
done
end