-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathInterrupt_R.thy
854 lines (774 loc) · 35.5 KB
/
Interrupt_R.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
(*
* Copyright 2014, General Dynamics C4 Systems
*
* This software may be distributed and modified according to the terms of
* the GNU General Public License version 2. Note that NO WARRANTY is provided.
* See "LICENSE_GPLv2.txt" for details.
*
* @TAG(GD_GPL)
*)
(*
Refinement for interrupt controller operations
*)
theory Interrupt_R
imports Ipc_R Invocations_R
begin
primrec
irq_handler_inv_relation :: "irq_handler_invocation \<Rightarrow> irqhandler_invocation \<Rightarrow> bool"
where
"irq_handler_inv_relation (Invocations_A.ACKIrq irq) x = (x = AckIRQ irq)"
| "irq_handler_inv_relation (Invocations_A.ClearIRQHandler irq) x = (x = ClearIRQHandler irq)"
| "irq_handler_inv_relation (Invocations_A.SetIRQHandler irq cap ptr) x =
(\<exists>cap'. x = SetIRQHandler irq cap' (cte_map ptr) \<and> cap_relation cap cap')"
consts
interrupt_control_relation :: "arch_interrupt_control \<Rightarrow> interrupt_control \<Rightarrow> bool"
primrec
irq_control_inv_relation :: "irq_control_invocation \<Rightarrow> irqcontrol_invocation \<Rightarrow> bool"
where
"irq_control_inv_relation (Invocations_A.IRQControl irq slot slot') x
= (x = IssueIRQHandler irq (cte_map slot) (cte_map slot'))"
| "irq_control_inv_relation (Invocations_A.InterruptControl ivk) x
= (\<exists>ivk'. x = InterruptControl ivk' \<and> interrupt_control_relation ivk ivk')"
primrec
irq_handler_inv_valid' :: "irqhandler_invocation \<Rightarrow> kernel_state \<Rightarrow> bool"
where
"irq_handler_inv_valid' (AckIRQ irq) = (\<lambda>s. intStateIRQTable (ksInterruptState s) irq \<noteq> IRQInactive)"
| "irq_handler_inv_valid' (ClearIRQHandler irq) = \<top>"
| "irq_handler_inv_valid' (SetIRQHandler irq cap cte_ptr)
= (valid_cap' cap and valid_cap' (IRQHandlerCap irq)
and K (isAsyncEndpointCap cap)
and cte_wp_at' (badge_derived' cap \<circ> cteCap) cte_ptr
and (\<lambda>s. \<exists>ptr'. cte_wp_at' (\<lambda>cte. cteCap cte = IRQHandlerCap irq) ptr' s)
and ex_cte_cap_wp_to' isCNodeCap cte_ptr)"
primrec
irq_control_inv_valid' :: "irqcontrol_invocation \<Rightarrow> kernel_state \<Rightarrow> bool"
where
"irq_control_inv_valid' (InterruptControl ivk) = \<bottom>"
| "irq_control_inv_valid' (IssueIRQHandler irq ptr ptr') =
(cte_wp_at' (\<lambda>cte. cteCap cte = NullCap) ptr and
cte_wp_at' (\<lambda>cte. cteCap cte = IRQControlCap) ptr' and
ex_cte_cap_to' ptr and real_cte_at' ptr and
(Not o irq_issued' irq) and K (irq \<le> maxIRQ))"
lemma decode_irq_handler_corres:
"\<lbrakk> list_all2 cap_relation (map fst caps) (map fst caps');
list_all2 (\<lambda>p pa. snd pa = cte_map (snd p)) caps caps' \<rbrakk> \<Longrightarrow>
corres (ser \<oplus> irq_handler_inv_relation) invs invs'
(decode_irq_handler_invocation label irq caps)
(decodeIRQHandlerInvocation label irq caps')"
apply (simp add: decode_irq_handler_invocation_def decodeIRQHandlerInvocation_def
split del: split_if)
apply (cases caps)
apply (simp add: returnOk_def split: invocation_label.split)
apply (clarsimp simp: list_all2_Cons1 split del: split_if)
apply (simp add: returnOk_def split: invocation_label.split)
apply (clarsimp split: cap_relation_split_asm arch_cap.split_asm simp: returnOk_def)
done
crunch inv[wp]: decodeIRQHandlerInvocation "P"
(simp: crunch_simps)
lemma decode_irq_handler_valid'[wp]:
"\<lbrace>\<lambda>s. invs' s \<and> (\<forall>cap \<in> set caps. s \<turnstile>' fst cap)
\<and> (\<exists>ptr'. cte_wp_at' (\<lambda>cte. cteCap cte = IRQHandlerCap irq) ptr' s)
\<and> (\<forall>cap \<in> set caps. \<forall>r \<in> cte_refs' (fst cap) (irq_node' s). ex_cte_cap_to' r s)
\<and> (\<forall>cap \<in> set caps. ex_cte_cap_wp_to' isCNodeCap (snd cap) s)
\<and> (\<forall>cap \<in> set caps. cte_wp_at' (badge_derived' (fst cap) \<circ> cteCap) (snd cap) s)
\<and> s \<turnstile>' IRQHandlerCap irq\<rbrace>
decodeIRQHandlerInvocation label irq caps
\<lbrace>irq_handler_inv_valid'\<rbrace>,-"
apply (simp add: decodeIRQHandlerInvocation_def Let_def split_def
split del: split_if)
apply (rule hoare_pre)
apply (wp | wpc | simp)+
apply (clarsimp simp: neq_Nil_conv isCap_simps)
apply (rule conjI)
apply (clarsimp simp: cte_wp_at_ctes_of)
apply (drule (1) valid_irq_handlers_ctes_ofD)
apply (simp add: invs'_def valid_state'_def)
apply (simp add: irq_issued'_def)
apply clarsimp
done
lemma is_irq_active_corres:
"corres op = \<top> \<top> (is_irq_active irq) (isIRQActive irq)"
apply (simp add: is_irq_active_def isIRQActive_def get_irq_state_def
getIRQState_def getInterruptState_def)
apply (clarsimp simp: state_relation_def interrupt_state_relation_def)
apply (drule_tac x=irq in spec)+
apply (simp add: irq_state_relation_def
split: irqstate.split_asm irq_state.split_asm)
done
crunch inv: isIRQActive "P"
lemma isIRQActive_wp:
"\<lbrace>\<lambda>s. \<forall>rv. (irq_issued' irq s \<longrightarrow> rv) \<longrightarrow> Q rv s\<rbrace> isIRQActive irq \<lbrace>Q\<rbrace>"
apply (simp add: isIRQActive_def getIRQState_def
getInterruptState_def)
apply wp
apply (clarsimp simp: irq_issued'_def)
done
lemma whenE_rangeCheck_eq:
"(rangeCheck (x :: 'a :: {linorder, integral}) y z) =
(whenE (x < fromIntegral y \<or> fromIntegral z < x)
(throwError (RangeError (fromIntegral y) (fromIntegral z))))"
by (simp add: rangeCheck_def unlessE_whenE ucast_id linorder_not_le[symmetric])
lemma decode_irq_control_corres:
"list_all2 cap_relation caps caps' \<Longrightarrow>
corres (ser \<oplus> irq_control_inv_relation)
(invs and (\<lambda>s. \<forall>cp \<in> set caps. s \<turnstile> cp)) (invs' and (\<lambda>s. \<forall>cp \<in> set caps'. s \<turnstile>' cp))
(decode_irq_control_invocation label args slot caps)
(decodeIRQControlInvocation label args (cte_map slot) caps')"
apply (clarsimp simp: decode_irq_control_invocation_def decodeIRQControlInvocation_def
decodeInterruptControl_def arch_decode_interrupt_control_def
split del: split_if cong: if_cong
split: invocation_label.split)
apply (cases caps, simp split: list.split)
apply (case_tac "\<exists>n. length args = Suc (Suc (Suc n))")
apply (clarsimp simp: list_all2_Cons1 Let_def split_def liftE_bindE
lookup_target_slot_def lookupTargetSlot_def
whenE_rangeCheck_eq length_Suc_conv)
apply (rule corres_guard_imp)
apply (rule whenE_throwError_corres)
apply (simp add: minIRQ_def maxIRQ_def)
apply (simp add: minIRQ_def ucast_nat_def)
apply (simp add: linorder_not_less)
apply (simp add: maxIRQ_def word_le_nat_alt toEnum_of_nat)
apply (simp add: ucast_nat_def)
apply (rule corres_split_eqr [OF _ is_irq_active_corres])
apply (rule whenE_throwError_corres, simp, simp)
apply (rule corres_splitEE [OF _ lsfc_corres])
apply (rule corres_splitEE [OF _ ensure_empty_corres])
apply (rule corres_trivial, clarsimp simp: returnOk_def)
apply clarsimp
apply (wp isIRQActive_inv | simp only: simp_thms | wp_once hoare_drop_imps)+
apply fastforce
apply fastforce
apply (subgoal_tac "length args \<le> 2", clarsimp split: list.split)
apply arith
done
crunch inv[wp]: decodeIRQControlInvocation "P"
(simp: crunch_simps decodeInterruptControl_def)
(* Levity: added (20090201 10:50:27) *)
declare ensureEmptySlot_stronger [wp]
lemma lsfco_real_cte_at'[wp]:
"\<lbrace>valid_objs' and valid_cap' root\<rbrace>
lookupSlotForCNodeOp is_src root ptr depth
\<lbrace>\<lambda>rv s. real_cte_at' rv s\<rbrace>,-"
apply (simp add: lookupSlotForCNodeOp_def split_def unlessE_def
whenE_def
split del: split_if
cong: if_cong list.case_cong capability.case_cong)
apply (rule hoare_pre)
apply (wp resolveAddressBits_real_cte_at'
| simp
| wpc | wp_once hoare_drop_imps)+
done
lemma decode_irq_control_valid'[wp]:
"\<lbrace>\<lambda>s. invs' s \<and> (\<forall>cap \<in> set caps. s \<turnstile>' cap)
\<and> (\<forall>cap \<in> set caps. \<forall>r \<in> cte_refs' cap (irq_node' s). ex_cte_cap_to' r s)
\<and> cte_wp_at' (\<lambda>cte. cteCap cte = IRQControlCap) slot s\<rbrace>
decodeIRQControlInvocation label args slot caps
\<lbrace>irq_control_inv_valid'\<rbrace>,-"
apply (simp add: decodeIRQControlInvocation_def Let_def split_def
rangeCheck_def unlessE_whenE
split del: split_if cong: if_cong list.case_cong
invocation_label.case_cong)
apply (rule hoare_pre)
apply (wp ensureEmptySlot_stronger isIRQActive_wp
whenE_throwError_wp
| simp add: decodeInterruptControl_def | wpc
| wp_once hoare_drop_imps)+
apply (clarsimp simp: minIRQ_def maxIRQ_def
toEnum_of_nat word_le_nat_alt unat_of_nat)
done
lemma valid_globals_ex_cte_cap_irq:
"\<lbrakk> ex_cte_cap_wp_to' isCNodeCap ptr s; valid_global_refs' s;
valid_objs' s \<rbrakk>
\<Longrightarrow> ptr \<noteq> intStateIRQNode (ksInterruptState s) + 2 ^ cte_level_bits * ucast (irq :: word8)"
apply (clarsimp simp: cte_wp_at_ctes_of ex_cte_cap_wp_to'_def)
apply (drule(1) ctes_of_valid'[rotated])
apply (drule(1) valid_global_refsD')
apply (drule subsetD[rotated], erule cte_refs_capRange)
apply (clarsimp simp: isCap_simps)
apply (subgoal_tac "irq_node' s + 2 ^ cte_level_bits * ucast irq \<in> global_refs' s")
apply blast
apply (simp add: global_refs'_def cte_level_bits_def)
done
lemma vmdb_invs'_strg:
"invs' s \<longrightarrow> valid_mdb' s"
by clarsimp
lemma invoke_irq_handler_corres:
"irq_handler_inv_relation i i' \<Longrightarrow>
corres dc (einvs and irq_handler_inv_valid i)
(invs' and sch_act_simple and irq_handler_inv_valid' i')
(invoke_irq_handler i)
(invokeIRQHandler i')"
apply (cases i, simp_all add: invokeIRQHandler_def)
apply (rule corres_guard_imp, rule corres_machine_op)
apply (rule corres_Id, simp_all)
apply (rule no_fail_maskInterrupt)
apply clarsimp
apply (rule corres_guard_imp)
apply (rule corres_split [OF _ get_irq_slot_corres])
apply simp
apply (rule corres_split_nor [OF _ cap_delete_one_corres])
apply (rule cins_corres, simp+)
apply (rule_tac Q="\<lambda>rv s. einvs s \<and> cte_wp_at (\<lambda>c. c = cap.NullCap) irq_slot s
\<and> (a, b) \<noteq> irq_slot
\<and> cte_wp_at (is_derived (cdt s) (a, b) cap) (a, b) s"
in hoare_post_imp)
apply fastforce
apply (wp cap_delete_one_still_derived)
apply (strengthen vmdb_invs'_strg)
apply wp
apply (simp add: conj_ac eq_commute)
apply (wp get_irq_slot_different hoare_drop_imps)
apply (clarsimp simp: valid_state_def invs_def)
apply (erule cte_wp_at_weakenE, simp add: is_derived_use_interrupt)
apply fastforce
apply (rule corres_guard_imp)
apply (rule corres_split [OF _ get_irq_slot_corres])
apply simp
apply (rule cap_delete_one_corres)
apply wp
apply simp+
done
lemma aep_badge_derived_enough_strg:
"cte_wp_at' (\<lambda>cte. isAsyncEndpointCap cap \<and> badge_derived' cap (cteCap cte)) ptr s
\<longrightarrow> cte_wp_at' (is_derived' ctes ptr cap \<circ> cteCap) ptr s"
by (clarsimp simp: cte_wp_at_ctes_of isCap_simps
badge_derived'_def is_derived'_def vsCapRef_def)
lemma cteDeleteOne_ex_cte_cap_to'[wp]:
"\<lbrace>ex_cte_cap_wp_to' P p\<rbrace> cteDeleteOne ptr \<lbrace>\<lambda>rv. ex_cte_cap_wp_to' P p\<rbrace>"
apply (simp add: ex_cte_cap_to'_def)
apply (rule hoare_pre)
apply (rule hoare_use_eq_irq_node' [OF cteDeleteOne_irq_node'])
apply (wp hoare_vcg_ex_lift cteDeleteOne_cte_wp_at_preserved)
apply (case_tac cap, simp_all add: finaliseCap_def isCap_simps)
done
lemma cteDeleteOne_other_cap:
"\<lbrace>(\<lambda>s. cte_wp_at' (P o cteCap) p s) and K (p \<noteq> p')\<rbrace>
cteDeleteOne p'
\<lbrace>\<lambda>rv s. cte_wp_at' (P o cteCap) p s\<rbrace>"
apply (rule hoare_gen_asm)
apply (simp add: tree_cte_cteCap_eq)
apply (wp cteDeleteOne_cteCaps_of)
apply simp
done
lemma isnt_irq_handler_strg:
"(\<not> isIRQHandlerCap cap) \<longrightarrow> (\<forall>irq. cap = IRQHandlerCap irq \<longrightarrow> P irq)"
by (clarsimp simp: isCap_simps)
lemma ct_in_current_domain_ksMachineState:
"ct_idle_or_in_cur_domain' (ksMachineState_update p s) = ct_idle_or_in_cur_domain' s"
apply (simp add:ct_idle_or_in_cur_domain'_def)
apply (simp add:tcb_in_cur_domain'_def)
done
lemma invoke_irq_handler_invs'[wp]:
"\<lbrace>invs' and irq_handler_inv_valid' i\<rbrace>
invokeIRQHandler i \<lbrace>\<lambda>rv. invs'\<rbrace>"
apply (cases i, simp_all add: invokeIRQHandler_def)
apply (wp dmo_maskInterrupt)
apply (clarsimp simp add: invs'_def valid_state'_def valid_irq_masks'_def
valid_machine_state'_def ct_not_inQ_def
ct_in_current_domain_ksMachineState)
apply (wp cteInsert_invs)
apply (strengthen aep_badge_derived_enough_strg isnt_irq_handler_strg)
apply (wp cteDeleteOne_other_cap[unfolded o_def])[1]
apply (simp add: getInterruptState_def getIRQSlot_def locateSlot_conv)
apply wp
apply (clarsimp simp: ucast_nat_def)
apply (drule_tac irq=word1 in valid_globals_ex_cte_cap_irq)
apply clarsimp+
apply (clarsimp simp: cte_wp_at_ctes_of ex_cte_cap_to'_def
isCap_simps)
apply (fastforce simp: cte_level_bits_def badge_derived'_def)+
done
lemma IRQHandler_valid':
"(s' \<turnstile>' IRQHandlerCap irq) = (irq \<le> maxIRQ)"
by (simp add: valid_cap'_def capAligned_def word_bits_conv)
lemma valid_mdb_interrupts'[simp]:
"valid_mdb' (ksInterruptState_update f s) = valid_mdb' s"
by (simp add: valid_mdb'_def)
crunch valid_mdb'[wp]: setIRQState "valid_mdb'"
crunch cte_wp_at[wp]: setIRQState "cte_wp_at' P p"
lemma invoke_irq_control_corres:
"irq_control_inv_relation i i' \<Longrightarrow>
corres (intr \<oplus> dc) (einvs and irq_control_inv_valid i)
(invs' and irq_control_inv_valid' i')
(invoke_irq_control i)
(invokeIRQControl i')"
apply (cases i, simp_all add: invokeIRQControl_def)
apply (rule corres_guard_imp)
apply (rule corres_split_nor [OF _ set_irq_state_corres])
apply (rule cins_corres_simple)
apply (wp | simp add: irq_state_relation_def
IRQHandler_valid IRQHandler_valid')+
apply (clarsimp simp: invs_def valid_state_def valid_pspace_def
cte_wp_at_caps_of_state is_simple_cap_def
is_cap_simps safe_parent_for_def)
apply (clarsimp simp: invs'_def valid_state'_def valid_pspace'_def
IRQHandler_valid IRQHandler_valid' is_simple_cap'_def
isCap_simps)
apply (clarsimp simp: safe_parent_for'_def cte_wp_at_ctes_of)
apply (case_tac ctea)
apply (clarsimp simp: isCap_simps sameRegionAs_def3)
apply (auto dest: valid_irq_handlers_ctes_ofD)[1]
apply (clarsimp simp: arch_invoke_irq_control_def invokeInterruptControl_def)
done
crunch valid_cap'[wp]: setIRQState "valid_cap' cap"
lemma setIRQState_cte_cap_to'[wp]:
"\<lbrace>ex_cte_cap_to' p\<rbrace> setIRQState st irq \<lbrace>\<lambda>_. ex_cte_cap_to' p\<rbrace>"
apply (simp add: setIRQState_def doMachineOp_def
split_def setInterruptState_def getInterruptState_def)
apply wp
apply (clarsimp simp: ex_cte_cap_to'_def)
done
lemma setIRQState_issued[wp]:
"\<lbrace>K (st = IRQNotifyAEP)\<rbrace> setIRQState st irq \<lbrace>\<lambda>rv. irq_issued' irq\<rbrace>"
apply (simp add: setIRQState_def irq_issued'_def setInterruptState_def
getInterruptState_def)
apply wp
apply clarsimp
done
lemma invoke_irq_control_invs'[wp]:
"\<lbrace>invs' and irq_control_inv_valid' i\<rbrace> invokeIRQControl i \<lbrace>\<lambda>rv. invs'\<rbrace>"
apply (cases i, simp_all add: invokeIRQControl_def)
apply (rule hoare_pre)
apply (wp cteInsert_simple_invs | simp add: cte_wp_at_ctes_of)+
apply (clarsimp simp: cte_wp_at_ctes_of IRQHandler_valid'
is_simple_cap'_def isCap_simps
safe_parent_for'_def sameRegionAs_def3)
apply (case_tac ctea)
apply (auto dest: valid_irq_handlers_ctes_ofD
simp: invs'_def valid_state'_def)
done
lemma get_irq_state_corres:
"corres irq_state_relation \<top> \<top>
(get_irq_state irq) (getIRQState irq)"
apply (simp add: get_irq_state_def getIRQState_def getInterruptState_def)
apply (clarsimp simp: state_relation_def interrupt_state_relation_def)
done
lemma getIRQState_prop:
"\<lbrace>\<lambda>s. P (intStateIRQTable (ksInterruptState s) irq)\<rbrace>
getIRQState irq
\<lbrace>\<lambda>rv s. P rv\<rbrace>"
apply (simp add: getIRQState_def getInterruptState_def)
apply wp
apply simp
done
lemma num_domains[simp]:
"num_domains = numDomains"
apply(simp add: num_domains_def numDomains_def)
done
lemma dec_domain_time_corres:
"corres dc \<top> \<top> dec_domain_time decDomainTime"
apply (simp add:dec_domain_time_def corres_underlying_def
decDomainTime_def simpler_modify_def)
apply (clarsimp simp:state_relation_def)
done
lemma weak_sch_act_wf_updateDomainTime[simp]:
"weak_sch_act_wf m (s\<lparr>ksDomainTime := t\<rparr>)
= weak_sch_act_wf m s"
by (simp add:weak_sch_act_wf_def tcb_in_cur_domain'_def )
lemma tcbSchedAppend_valid_objs':
"\<lbrace>valid_objs'\<rbrace>tcbSchedAppend t \<lbrace>\<lambda>r. valid_objs'\<rbrace>"
apply (simp add:tcbSchedAppend_def)
apply (wp hoare_unless_wp
threadSet_valid_objs' threadGet_wp
| simp add:valid_tcb_tcbQueued)+
apply (clarsimp simp add:obj_at'_def typ_at'_def)
done
lemma tcbSchedAppend_sch_act_wf:
"\<lbrace>\<lambda>s. sch_act_wf (ksSchedulerAction s) s\<rbrace> tcbSchedAppend thread
\<lbrace>\<lambda>rv s. sch_act_wf (ksSchedulerAction s) s\<rbrace>"
apply (simp add:tcbSchedAppend_def)
apply (wp hoare_unless_wp setQueue_sch_act threadGet_wp)
apply (fastforce simp:typ_at'_def obj_at'_def)
done
lemma valid_tcb_tcbTimeSlice_update[simp]:
"valid_tcb' (tcbTimeSlice_update (\<lambda>_. timeSlice) tcb) s = valid_tcb' tcb s"
by (simp add:valid_tcb'_def tcb_cte_cases_def)
lemma thread_state_case_if:
"(case state of Structures_A.thread_state.Running \<Rightarrow> f | _ \<Rightarrow> g) =
(if state = Structures_A.thread_state.Running then f else g)"
by (case_tac state,auto)
lemma threadState_case_if:
"(case state of Structures_H.thread_state.Running \<Rightarrow> f | _ \<Rightarrow> g) =
(if state = Structures_H.thread_state.Running then f else g)"
by (case_tac state,auto)
lemma tcbSchedAppend_invs_but_ct_not_inQ':
"\<lbrace>invs' and st_tcb_at' runnable' t \<rbrace>
tcbSchedAppend t \<lbrace>\<lambda>_. all_invs_but_ct_not_inQ'\<rbrace>"
apply (simp add: invs'_def valid_state'_def)
thm ct_idle_or_in_cur_domain'_lift2
thm valid_queues_def
apply (wp sch_act_wf_lift valid_irq_node_lift irqs_masked_lift
valid_irq_handlers_lift' cur_tcb_lift ct_idle_or_in_cur_domain'_lift2
| simp add: cteCaps_of_def
| fastforce elim!: st_tcb_ex_cap'' split: thread_state.split_asm)+
done
lemma timerTick_corres:
"corres dc (cur_tcb and valid_sched)
invs'
timer_tick timerTick"
apply (simp add: timerTick_def timer_tick_def)
apply (simp add:thread_state_case_if threadState_case_if)
apply (rule_tac Q="\<top> and (cur_tcb and valid_sched)" and Q'="\<top> and invs'" in corres_guard_imp)
apply (rule corres_guard_imp)
apply (rule corres_split [OF _ gct_corres])
apply simp
apply (rule corres_split [OF _ gts_corres])
apply (rename_tac state state')
apply (rule corres_split[where r' = dc ])
apply simp
apply (rule corres_when,simp)
apply (rule corres_split[OF _ dec_domain_time_corres])
apply (rule corres_split[OF _ domain_time_corres])
apply (rule corres_when,simp)
apply (rule rescheduleRequired_corres)
apply (wp hoare_drop_imp)
apply (simp add:dec_domain_time_def)
apply wp
apply (simp add:decDomainTime_def)
apply wp
apply (rule corres_if[where Q = \<top> and Q' = \<top>])
apply (case_tac state,simp_all)[1]
apply (simp add: Let_def)
apply (rule_tac r'="op =" in corres_split [OF _ ethreadget_corres])
apply (rename_tac ts ts')
apply (rule_tac R="1 < ts" in corres_cases)
apply (simp)
apply (unfold thread_set_time_slice_def)
apply (fold dc_def)
apply (rule ethread_set_corres, simp+)
apply (clarsimp simp: etcb_relation_def)
apply simp
apply (rule corres_split [OF _ ethread_set_corres])
apply (rule corres_split [OF _ tcbSchedAppend_corres])
apply (fold dc_def)
apply (rule rescheduleRequired_corres)
apply (wp)[1]
apply (rule hoare_strengthen_post)
apply (wp tcbSchedAppend_invs_but_ct_not_inQ', clarsimp simp: sch_act_wf_weak)
apply (simp add: sch_act_wf_weak etcb_relation_def
time_slice_def timeSlice_def pred_conj_def)+
apply (wp threadSet_timeslice_invs threadSet_valid_queues
threadSet_valid_queues'
threadSet_st_tcb_at_state)
apply (simp add:etcb_relation_def)
apply (wp threadSet_timeslice_invs threadSet_valid_queues
threadSet_valid_queues'
threadSet_st_tcb_at_state)
apply simp
apply (wp|wpc|unfold Let_def|simp)+
apply (wp static_imp_wp threadSet_timeslice_invs threadSet_valid_queues threadSet_valid_queues'
threadSet_st_tcb_at_state threadSet_weak_sch_act_wf tcbSchedAppend_valid_objs'
rescheduleRequired_weak_sch_act_wf tcbSchedAppend_valid_queues| simp)+
apply (strengthen impI[OF sch_act_wf_weak])
apply (clarsimp simp:conj_ac)
apply (wp tcbSchedAppend_valid_queues tcbSchedAppend_sch_act_wf)
apply simp
apply (wp threadSet_valid_queues threadSet_st_tcb_at_state threadSet_sch_act
threadSet_tcbDomain_triv threadSet_valid_queues' threadSet_valid_objs'| simp)+
apply (wp threadGet_wp gts_wp gts_wp')
apply (clarsimp simp: cur_tcb_def tcb_at_is_etcb_at valid_sched_def valid_sched_action_def)
apply (subgoal_tac "is_etcb_at thread s \<and> tcb_at thread s \<and> valid_etcbs s \<and> weak_valid_sched_action s")
prefer 2
apply assumption
apply clarsimp
apply (wp gts_wp')
apply (clarsimp simp add:cur_tcb_def valid_sched_def
valid_sched_action_def valid_etcbs_def is_tcb_def
is_etcb_at_def st_tcb_at_def obj_at_def
dest!:get_tcb_SomeD)
apply (simp split:Structures_A.kernel_object.splits)
apply (drule_tac x = "cur_thread s" in spec)
apply clarsimp
apply (clarsimp simp: invs'_def valid_state'_def
sch_act_wf_weak
cur_tcb'_def inQ_def
ct_in_state'_def obj_at'_def)
apply (clarsimp simp:st_tcb_at'_def
valid_idle'_def ct_idle_or_in_cur_domain'_def
obj_at'_def projectKO_eq)
apply simp
apply simp
done
lemma handle_interrupt_corres:
"corres dc
(invs and valid_sched)
(invs' and (\<lambda>s. intStateIRQTable (ksInterruptState s) irq \<noteq> IRQInactive))
(handle_interrupt irq) (handleInterrupt irq)"
(is "corres dc (invs and valid_sched) ?P' ?f ?g")
apply (simp add: handle_interrupt_def handleInterrupt_def)
apply (rule corres_guard_imp)
apply (rule corres_split [OF _ get_irq_state_corres,
where R="\<lambda>rv. invs and valid_sched" and R'="\<lambda>rv. invs' and (\<lambda>s. rv \<noteq> IRQInactive)"])
defer
apply (wp getIRQState_prop getIRQState_inv)
apply simp+
apply (rule corres_gen_asm2)
apply (rule corres_split'[where r'=dc, rotated])
apply (rule corres_machine_op)
apply (rule corres_Id, simp+)
apply wp
apply (case_tac st, simp_all add: irq_state_relation_def split: irqstate.split_asm)
apply (simp add: getSlotCap_def bind_assoc)
apply (rule corres_guard_imp)
apply (rule corres_split [OF _ get_irq_slot_corres])
apply simp
apply (rule corres_split [OF _ get_cap_corres,
where R="\<lambda>rv. invs and valid_sched and valid_cap rv"
and R'="\<lambda>rv. invs' and valid_cap' (cteCap rv)"])
apply (rule corres_split'[where r'=dc])
apply (case_tac cap, simp_all add: when_False when_True doMachineOp_return)[1]
apply (clarsimp simp add: when_def doMachineOp_return)
apply (simp add: word_bits_def word_size)
apply (rule corres_guard_imp, rule send_async_ipc_corres)
apply (clarsimp simp: valid_cap_def)
apply (clarsimp simp: valid_cap'_def)
apply (clarsimp simp: doMachineOp_return)
apply (rule corres_machine_op)
apply (rule corres_Id, simp+)
apply (wp | simp)+
apply clarsimp
apply clarsimp
apply fastforce
apply (rule corres_guard_imp)
apply (rule corres_split [OF corres_machine_op timerTick_corres])
apply (rule corres_Id, simp+)
apply wp
apply (clarsimp simp: invs_def valid_state_def valid_sched_def
valid_sched_action_def weak_valid_sched_action_def)+
done
lemma invs_ChooseNewThread:
"invs' s \<Longrightarrow> invs' (s\<lparr>ksSchedulerAction := ChooseNewThread\<rparr>)"
by (auto simp add: invs'_def valid_state'_def valid_queues'_def
valid_queues_def valid_irq_node'_def cur_tcb'_def
ct_not_inQ_def)
lemma ksDomainTime_invs[simp]:
"invs' (a\<lparr>ksDomainTime := t\<rparr>) = invs' a"
by (simp add:invs'_def valid_state'_def
cur_tcb'_def ct_not_inQ_def ct_idle_or_in_cur_domain'_def
tcb_in_cur_domain'_def valid_machine_state'_def)
lemma valid_machine_state'_ksDomainTime[simp]:
"valid_machine_state' (a\<lparr>ksDomainTime := t\<rparr>) = valid_machine_state' a"
by (simp add:valid_machine_state'_def)
lemma cur_tcb'_ksDomainTime[simp]:
"cur_tcb' (a\<lparr>ksDomainTime := 0\<rparr>) = cur_tcb' a"
by (simp add:cur_tcb'_def)
lemma ct_idle_or_in_cur_domain'_ksDomainTime[simp]:
"ct_idle_or_in_cur_domain' (a\<lparr>ksDomainTime := t \<rparr>) = ct_idle_or_in_cur_domain' a"
by (simp add:ct_idle_or_in_cur_domain'_def tcb_in_cur_domain'_def)
lemma threadSet_ksDomainTime[wp]:
"\<lbrace>\<lambda>s. P (ksDomainTime s)\<rbrace> threadSet f ptr \<lbrace>\<lambda>rv s. P (ksDomainTime s)\<rbrace>"
apply (simp add: threadSet_def setObject_def split_def)
apply (wp crunch_wps | simp add:updateObject_default_def)+
done
crunch ksDomainTime[wp]: rescheduleRequired "\<lambda>s. P (ksDomainTime s)"
(simp:tcbSchedEnqueue_def wp:hoare_unless_wp)
crunch ksDomainTime[wp]: tcbSchedAppend "\<lambda>s. P (ksDomainTime s)"
(simp:tcbSchedEnqueue_def wp:hoare_unless_wp)
lemma updateTimeSlice_valid_pspace[wp]:
"\<lbrace>valid_pspace'\<rbrace> threadSet (tcbTimeSlice_update (\<lambda>_. ts')) thread
\<lbrace>\<lambda>r. valid_pspace'\<rbrace>"
apply (wp threadSet_valid_pspace'T)
apply (auto simp:tcb_cte_cases_def)
done
lemma updateTimeSlice_sch_act_wf[wp]:
"\<lbrace>\<lambda>s. sch_act_wf (ksSchedulerAction s) s \<rbrace>
threadSet (tcbTimeSlice_update (\<lambda>_. ts')) thread
\<lbrace>\<lambda>r s. sch_act_wf (ksSchedulerAction s) s\<rbrace>"
by (wp threadSet_sch_act,simp)
lemma updateTimeSlice_valid_queues[wp]:
"\<lbrace>\<lambda>s. Invariants_H.valid_queues s \<rbrace>
threadSet (tcbTimeSlice_update (\<lambda>_. ts')) thread
\<lbrace>\<lambda>r s. Invariants_H.valid_queues s\<rbrace>"
apply (wp threadSet_valid_queues,simp)
apply (clarsimp simp:obj_at'_def inQ_def)
done
lemma updateTimeSlice_sym_refs[wp]:
"\<lbrace>\<lambda>s. sym_refs (state_refs_of' s)\<rbrace>
threadSet (tcbTimeSlice_update (\<lambda>_. ts')) thread
\<lbrace>\<lambda>r s. sym_refs (state_refs_of' s)\<rbrace>"
apply (simp add: threadSet_def setObject_def split_def)
apply (wp crunch_wps getObject_tcb_wp
| simp add: updateObject_default_def loadObject_default_def
| wpc)+
apply (clarsimp simp:state_refs_of'_def
obj_at'_def lookupAround2_known1)
apply (subst lookupAround2_known1)
apply simp
apply (erule_tac f1 = sym_refs in arg_cong[THEN iffD1,rotated])
apply (rule ext)
apply (subst the.simps)
apply (subst fst_conv)+
apply (clarsimp simp:projectKO_eq the.simps
projectKO_opt_tcb split:Structures_H.kernel_object.splits)
apply (simp add:objBits_simps)
apply (frule_tac s' = s and
v' = "(KOTCB (tcbTimeSlice_update (\<lambda>_. ts') obj))" in ps_clear_updE)
apply simp
apply (clarsimp simp:fun_upd_def)
apply (rule set_eqI)
apply (rule iffI)
apply (clarsimp split:option.splits split_if_asm)
apply (intro conjI impI)
apply simp
apply clarsimp
apply (drule_tac s' = s and y = thread and x = x and
v' = "(KOTCB (tcbTimeSlice_update (\<lambda>_. ts') obj))"
in ps_clear_updE[rotated])
apply simp
apply (clarsimp simp:fun_upd_def)
apply (clarsimp split:option.splits split_if_asm)
apply (intro conjI impI)
apply simp
apply clarsimp
apply (drule_tac y = thread and x = x and s' = s and
v' = "KOTCB obj"
in ps_clear_updE)
apply simp
apply (simp add:fun_upd_def[symmetric])
apply (subgoal_tac "s\<lparr>ksPSpace := ksPSpace s(thread \<mapsto> KOTCB obj)\<rparr> = s")
apply simp
apply (case_tac s)
apply simp
apply (rule ext,simp)
done
lemma updateTimeSlice_if_live_then_nonz_cap'[wp]:
"\<lbrace>\<lambda>s. if_live_then_nonz_cap' s\<rbrace>
threadSet (tcbTimeSlice_update (\<lambda>_. ts')) thread
\<lbrace>\<lambda>r s. if_live_then_nonz_cap' s\<rbrace>"
apply (wp threadSet_iflive'T)
apply (simp add:tcb_cte_cases_def)
apply (clarsimp simp:if_live_then_nonz_cap'_def
ko_wp_at'_def)
apply (intro conjI)
apply (clarsimp simp:obj_at'_real_def)+
done
lemma updateTimeSlice_if_unsafe_then_cap'[wp]:
"\<lbrace>\<lambda>s. if_unsafe_then_cap' s\<rbrace>
threadSet (tcbTimeSlice_update (\<lambda>_. ts')) thread
\<lbrace>\<lambda>r s. if_unsafe_then_cap' s\<rbrace>"
apply (wp threadSet_ifunsafe'T)
apply (simp add:tcb_cte_cases_def)
done
lemma updateTimeSlice_valid_idle'[wp]:
"\<lbrace>\<lambda>s. valid_idle' s\<rbrace>
threadSet (tcbTimeSlice_update (\<lambda>_. ts')) thread
\<lbrace>\<lambda>r s. valid_idle' s\<rbrace>"
apply (wp threadSet_idle'T)
apply (simp add:tcb_cte_cases_def)
apply (clarsimp simp:valid_idle'_def)
done
lemma updateTimeSlice_valid_global_refs'[wp]:
"\<lbrace>\<lambda>s. valid_global_refs' s\<rbrace>
threadSet (tcbTimeSlice_update (\<lambda>_. ts')) thread
\<lbrace>\<lambda>r s. valid_global_refs' s\<rbrace>"
apply (wp threadSet_idle'T)
apply (simp add:tcb_cte_cases_def)+
done
lemma updateTimeSlice_valid_irq_node'[wp]:
"\<lbrace>\<lambda>s. valid_irq_node' (irq_node' s) s\<rbrace>
threadSet (tcbTimeSlice_update (\<lambda>_. ts')) thread
\<lbrace>\<lambda>r s. valid_irq_node' (irq_node' s) s\<rbrace>"
apply (rule hoare_pre)
apply wps
apply (simp add: valid_irq_node'_def
| wp hoare_vcg_all_lift)+
done
lemma updateTimeSlice_irq_handlers'[wp]:
"\<lbrace>\<lambda>s. valid_irq_handlers' s\<rbrace>
threadSet (tcbTimeSlice_update (\<lambda>_. ts')) thread
\<lbrace>\<lambda>r s. valid_irq_handlers' s\<rbrace>"
apply (rule hoare_pre)
apply (wp threadSet_irq_handlers' |
simp add: tcb_cte_cases_def)+
done
lemma updateTimeSlice_valid_queues'[wp]:
"\<lbrace>\<lambda>s. valid_queues' s \<rbrace>
threadSet (tcbTimeSlice_update (\<lambda>_. ts')) thread
\<lbrace>\<lambda>r s. valid_queues' s\<rbrace>"
apply (wp threadSet_valid_queues')
apply (auto simp:inQ_def)
done
lemma rescheduleRequired_valid_irq_node'[wp]:
"\<lbrace>\<lambda>s. valid_irq_node' (irq_node' s) s\<rbrace> rescheduleRequired
\<lbrace>\<lambda>rv s. valid_irq_node' (irq_node' s) s \<rbrace>"
apply (simp add:rescheduleRequired_def valid_irq_node'_def)
apply (wp hoare_vcg_all_lift | wpc |simp)+
apply (simp add:tcbSchedEnqueue_def)
apply (wp hoare_unless_wp)
apply (wp threadSet_typ_at_lifts | wps)+
apply simp
done
lemma rescheduleRequired_cur_tcb'[wp]:
"\<lbrace>\<lambda>s. cur_tcb' s\<rbrace> rescheduleRequired
\<lbrace>\<lambda>rv s. cur_tcb' s \<rbrace>"
apply (simp add:rescheduleRequired_def)
apply wp
apply (simp add:cur_tcb'_def)
apply (wp|wpc)+
apply simp
done
lemma timerTick_invs'[wp]:
"\<lbrace>invs'\<rbrace> timerTick \<lbrace>\<lambda>rv. invs'\<rbrace>"
apply (simp add: numDomains_def timerTick_def)
apply (wp threadSet_invs_trivial threadSet_st_tcb_no_state
rescheduleRequired_all_invs_but_ct_not_inQ
tcbSchedAppend_invs_but_ct_not_inQ'
| simp add: tcb_cte_cases_def numDomains_def invs_ChooseNewThread
| wpc)+
apply (simp add:decDomainTime_def)
apply wp
apply simp
apply (rule_tac Q="\<lambda>rv. invs'"
in hoare_post_imp)
apply (clarsimp simp add:invs'_def valid_state'_def)
apply (wp threadGet_wp threadSet_cur threadSet_timeslice_invs
rescheduleRequired_all_invs_but_ct_not_inQ
hoare_vcg_imp_lift threadSet_ct_idle_or_in_cur_domain'
|wpc | simp)+
apply (rule hoare_strengthen_post[OF tcbSchedAppend_invs_but_ct_not_inQ'])
apply (clarsimp simp:valid_pspace'_def sch_act_wf_weak)
apply wp
apply (wp threadSet_st_tcb_no_state threadSet_tcbDomain_triv
threadSet_valid_objs' threadSet_timeslice_invs
| simp)+
apply (wp threadGet_wp)
apply (wp gts_wp')
apply (clarsimp simp:invs'_def st_tcb_at'_def obj_at'_def
valid_state'_def numDomains_def)
done
lemma resetTimer_invs'[wp]:
"\<lbrace>invs'\<rbrace> doMachineOp resetTimer \<lbrace>\<lambda>_. invs'\<rbrace>"
apply (wp dmo_invs' no_irq_resetTimer)
apply clarsimp
apply (drule_tac Q="%_ b. underlying_memory b p = underlying_memory m p"
in use_valid)
apply (simp add: resetTimer_def
machine_op_lift_def machine_rest_lift_def split_def)
apply wp
apply clarsimp+
done
lemma hint_invs[wp]:
"\<lbrace>invs'\<rbrace> handleInterrupt irq \<lbrace>\<lambda>rv. invs'\<rbrace>"
apply (simp add: handleInterrupt_def getSlotCap_def ackInterrupt_def
cong: irqstate.case_cong)
apply (wp dmo_maskInterrupt_True getCTE_wp'
| wpc | simp)+
apply (rule_tac Q="\<lambda>rv. invs'" in hoare_post_imp)
apply (clarsimp simp: cte_wp_at_ctes_of ex_nonz_cap_to'_def)
apply fastforce
apply (wp threadSet_invs_trivial | simp add: inQ_def)+
apply (rule hoare_strengthen_post, rule getIRQState_inv)
apply (auto simp add: tcb_at_invs')
done
crunch st_tcb_at'[wp]: timerTick "st_tcb_at' P t"
(wp: threadSet_st_tcb_no_state)
lemma handleInterrupt_runnable:
"\<lbrace>st_tcb_at' runnable' t\<rbrace> handleInterrupt irq \<lbrace>\<lambda>_. st_tcb_at' runnable' t\<rbrace>"
apply (simp add: handleInterrupt_def)
apply (rule hoare_pre)
apply (wp sai_st_tcb' hoare_vcg_all_lift hoare_drop_imps
threadSet_st_tcb_no_state getIRQState_inv haskell_fail_wp
|wpc|simp)+
done
end