forked from seL4/l4v
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathInterrupt_DR.thy
647 lines (603 loc) · 29.8 KB
/
Interrupt_DR.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
(*
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
*
* SPDX-License-Identifier: GPL-2.0-only
*)
theory Interrupt_DR
imports Ipc_DR
begin
context begin interpretation Arch . (*FIXME: arch_split*)
lemma arch_decode_irq_control_error_corres:
"\<not> (\<exists> ui. (Some (IrqControlIntent ui)) = (transform_intent (invocation_type label) args)) \<Longrightarrow>
dcorres (dc \<oplus> anyrel) \<top> \<top>
(throwError e)
(Decode_A.arch_decode_irq_control_invocation label args slot (map fst excaps))"
unfolding arch_decode_irq_control_invocation_def
apply (cases "invocation_type label"; simp add: arch_decode_irq_control_invocation_def)
apply (simp add: transform_intent_def arch_transform_intent_issue_irq_handler_def
split: list.splits arch_invocation_label.splits)
done
lemma decode_irq_control_error_corres:
"\<not> (\<exists> ui. (Some (IrqControlIntent ui)) = (transform_intent (invocation_type label) args)) \<Longrightarrow>
dcorres (dc \<oplus> anyrel) \<top> \<top>
(throwError e)
(Decode_A.decode_irq_control_invocation label args slot (map fst excaps))"
unfolding decode_irq_control_invocation_def
apply (cases "invocation_type label"; simp add: arch_decode_irq_control_invocation_def
arch_decode_irq_control_error_corres)
apply (clarsimp simp: transform_intent_def transform_intent_issue_irq_handler_def
arch_transform_intent_issue_irq_handler_def
simp flip: gen_invocation_type_eq
split: list.splits arch_invocation_label.splits)+
done
(* Interrupt Control Invocations *)
primrec (nonexhaustive) translate_irq_control_invocation ::
"Invocations_A.irq_control_invocation \<Rightarrow> cdl_irq_control_invocation"
where
"translate_irq_control_invocation (Invocations_A.IRQControl irq p slot) =
IssueIrqHandler irq (transform_cslot_ptr slot) (transform_cslot_ptr p)"
| "translate_irq_control_invocation (Invocations_A.ArchIRQControl arch_label) =
(case arch_label of ArchIRQControlIssue irq p slot t \<Rightarrow>
(IssueIrqHandler irq (transform_cslot_ptr slot) (transform_cslot_ptr p)))"
definition
cdl_irq_control_invocation_relation :: "cdl_irq_control_invocation \<Rightarrow> Invocations_A.irq_control_invocation \<Rightarrow> bool"
where
"cdl_irq_control_invocation_relation x y \<equiv> x = translate_irq_control_invocation y"
lemma decode_irq_control_corres:
"\<lbrakk> Some (IrqControlIntent ui) = transform_intent (invocation_type label') args';
cap = transform_cap cap';
cap' = cap.IRQControlCap;
slot = transform_cslot_ptr slot';
excaps = transform_cap_list excaps' \<rbrakk> \<Longrightarrow>
dcorres (dc \<oplus> cdl_irq_control_invocation_relation)
\<top>
(valid_objs and (\<lambda>s. \<forall>e \<in> set excaps'. valid_cap (fst e) s)
and valid_global_refs
and valid_idle
and valid_etcbs)
(Interrupt_D.decode_irq_control_invocation cap slot excaps ui)
(Decode_A.decode_irq_control_invocation label' args' slot' (map fst excaps'))"
apply (cases "invocation_type label' = GenInvocationLabel IRQIssueIRQHandler")
subgoal (* generic case *)
apply (unfold Interrupt_D.decode_irq_control_invocation_def
Decode_A.decode_irq_control_invocation_def
arch_check_irq_def)
apply clarsimp
apply (simp add: transform_intent_def transform_intent_issue_irq_handler_def
flip: gen_invocation_type_eq
split: list.splits)
apply (rule conjI)
prefer 2 \<comment> \<open>error case\<close>
apply clarsimp
apply (rule corres_guard_imp)
apply (rule dcorres_alternative_throw)
apply (rule TrueI, rule TrueI)
apply (clarsimp simp: Let_def)
apply (rule dcorres_whenE_throwError_abstract')
apply (rule corres_guard_imp, rule dcorres_alternative_throw)
apply (rule TrueI, rule TrueI)
apply (rule dcorres_symb_exec_rE)
apply (rule dcorres_whenE_throwError_abstract')
apply (rule corres_guard_imp)
apply (rule dcorres_alternative_throw)
apply (rule TrueI, rule TrueI)
apply (simp add: get_index_def transform_cap_list_def throw_on_none_def)
apply (cases "excaps' = []", simp_all)
apply (rule corres_alternative_throw_splitE)
apply (rule corres_alternate1)
apply (rule lookup_slot_for_cnode_op_corres)
apply simp+
apply (clarsimp simp: split_def,simp)
apply (rule corres_throw_skip_r)
apply (rule corres_alternate1)
apply (rule corres_returnOk [where P=\<top> and P'=\<top>])
apply (simp add: cdl_irq_control_invocation_relation_def)
apply wp[1]
apply simp
apply (wp+)[3]
apply simp
apply (rule hoare_pre, wp)
apply simp
apply wp
apply (cases excaps', auto)[1]
apply wp
done
apply (cases "invocation_type label' = ArchInvocationLabel ARMIRQIssueIRQHandler")
subgoal (* arch case *)
apply (unfold Interrupt_D.decode_irq_control_invocation_def
Interrupt_D.arch_decode_irq_control_invocation_def
Decode_A.decode_irq_control_invocation_def
arch_decode_irq_control_invocation_def
arch_check_irq_def)
apply clarsimp
apply (simp add: transform_intent_def transform_intent_issue_irq_handler_def
arch_transform_intent_issue_irq_handler_def
flip: gen_invocation_type_eq
split: list.splits)
apply (rule conjI)
prefer 2 \<comment> \<open>error case\<close>
apply clarsimp
apply (rule corres_guard_imp)
apply (rule dcorres_alternative_throw)
apply (rule TrueI, rule TrueI)
apply (clarsimp simp: Let_def)
apply (rule dcorres_whenE_throwError_abstract')
apply (rule corres_guard_imp, rule dcorres_alternative_throw)
apply (rule TrueI, rule TrueI)
apply (rule dcorres_symb_exec_rE)
apply (rule dcorres_whenE_throwError_abstract')
apply (rule corres_guard_imp)
apply (rule dcorres_alternative_throw)
apply (rule TrueI, rule TrueI)
apply (simp add: get_index_def transform_cap_list_def throw_on_none_def)
apply (cases "excaps' = []", simp_all)
apply (rule corres_alternative_throw_splitE)
apply (rule corres_alternate1)
apply (rule lookup_slot_for_cnode_op_corres)
apply simp+
apply (clarsimp simp: split_def,simp)
apply (rule corres_throw_skip_r)
apply (rule corres_alternate1)
apply (rule corres_returnOk [where P=\<top> and P'=\<top>])
apply (simp add: cdl_irq_control_invocation_relation_def)
apply wp[1]
apply simp
apply (wp+)[3]
apply simp
apply (rule hoare_pre, wp)
apply simp
apply wp
apply (cases excaps', auto)[1]
apply wp
done
subgoal (* arch case *)
apply (unfold Interrupt_D.decode_irq_control_invocation_def
Interrupt_D.arch_decode_irq_control_invocation_def
Decode_A.decode_irq_control_invocation_def
arch_decode_irq_control_invocation_def
arch_check_irq_def)
apply clarsimp
apply (cases ui; simp)
apply (simp add: corres_alternate2 flip: gen_invocation_type_eq)
apply(rename_tac ARMIRQControlIntent)
apply (case_tac ARMIRQControlIntent; simp)
apply (simp add: corres_alternate2 flip: gen_invocation_type_eq)
done
done
(* Interrupt Handler Invocations *)
lemma decode_irq_handler_error_corres:
"\<not> (\<exists> ui. (Some (IrqHandlerIntent ui)) = (transform_intent (invocation_type label') undefined)) \<Longrightarrow>
dcorres (dc \<oplus> anyrel) \<top> \<top>
(throwError e)
(Decode_A.decode_irq_handler_invocation label' x' excaps')"
by (auto simp: Decode_A.decode_irq_handler_invocation_def transform_intent_def
simp flip: gen_invocation_type_eq split: list.splits )
primrec
translate_irq_handler_invocation :: "Invocations_A.irq_handler_invocation \<Rightarrow> cdl_irq_handler_invocation"
where
"translate_irq_handler_invocation (ACKIrq irq) =
AckIrq irq"
| "translate_irq_handler_invocation (Invocations_A.SetIRQHandler irq cap slot) =
SetIrqHandler irq (transform_cap cap) (transform_cslot_ptr slot)"
| "translate_irq_handler_invocation (Invocations_A.ClearIRQHandler irq) =
ClearIrqHandler irq"
definition
cdl_irq_handler_invocation_relation :: "cdl_irq_handler_invocation \<Rightarrow> Invocations_A.irq_handler_invocation \<Rightarrow> bool"
where
"cdl_irq_handler_invocation_relation x y \<equiv> x = translate_irq_handler_invocation y"
lemma decode_irq_handler_corres:
"\<And> slot. \<lbrakk> Some (IrqHandlerIntent ui) = transform_intent (invocation_type label') args';
cap = transform_cap (Structures_A.IRQHandlerCap x');
excaps = transform_cap_list excaps' \<rbrakk> \<Longrightarrow>
dcorres (dc \<oplus> cdl_irq_handler_invocation_relation) \<top> \<top>
(Interrupt_D.decode_irq_handler_invocation cap slot excaps ui)
(Decode_A.decode_irq_handler_invocation label' x' excaps')"
apply (unfold Interrupt_D.decode_irq_handler_invocation_def Decode_A.decode_irq_handler_invocation_def)
apply (cases "invocation_type label' = GenInvocationLabel IRQAckIRQ")
apply (simp add: transform_intent_def cdl_cap_irq_def assert_opt_def
flip: returnOk_liftE gen_invocation_type_eq)
apply (rule corres_alternate1)
apply (rule dcorres_returnOk)
apply (simp add: cdl_irq_handler_invocation_relation_def
translate_irq_handler_invocation_def)
apply (cases "invocation_type label' = GenInvocationLabel IRQSetIRQHandler")
apply (simp add: transform_intent_def cdl_cap_irq_def flip: gen_invocation_type_eq)
apply (rule conjI)
prefer 2 \<comment> \<open>excaps' = []\<close>
apply (clarsimp intro!: corres_alternate2)
apply (clarsimp simp: neq_Nil_conv)
apply (rule conjI)
prefer 2
apply (clarsimp intro!: corres_alternate2)
apply clarsimp
apply (rule corres_alternate1)
apply (simp add: get_index_def transform_cap_list_def
throw_on_none_def assert_opt_def
returnOk_liftE[symmetric])
apply (clarsimp simp: is_cap_simps)
apply (rule dcorres_returnOk)
apply (simp add: cdl_irq_handler_invocation_relation_def
translate_irq_handler_invocation_def)
apply (cases "invocation_type label' = GenInvocationLabel IRQClearIRQHandler")
apply (simp add: transform_intent_def cdl_cap_irq_def assert_opt_def
flip: gen_invocation_type_eq returnOk_liftE)
apply (rule corres_alternate1)
apply (rule dcorres_returnOk)
apply (simp add: cdl_irq_handler_invocation_relation_def
translate_irq_handler_invocation_def)
apply (cases ui, auto simp: dcorres_alternative_throw simp flip: gen_invocation_type_eq)
done
lemma option_get_cap_corres:
"ptr' = transform_cslot_ptr ptr \<Longrightarrow>
dcorres (\<lambda>rv rv'. rv = Some (transform_cap rv')) \<top>
(valid_idle and not_idle_thread (fst ptr) and valid_etcbs)
(gets (KHeap_D.opt_cap ptr'))
(CSpaceAcc_A.get_cap ptr)"
apply (case_tac ptr)
apply (clarsimp simp:CSpaceAcc_A.get_cap_def[simplified tcb_cnode_map_def] gets_def get_object_def gets_the_def bind_assoc)
apply (rule dcorres_get)
apply (clarsimp simp:assert_def corres_free_fail assert_opt_def)
apply (case_tac y)
apply (simp_all add:assert_def corres_free_fail)
apply (rename_tac "fun")
apply (case_tac "fun b")
apply (simp add:corres_free_fail)
apply clarsimp
apply (subst cap_slot_cnode_property_lift, assumption, simp_all)[1]
apply fastforce
apply (clarsimp simp: transform_cap_def)
apply (clarsimp simp:transform_tcb_slot_simp[simplified])
apply (rename_tac tcb)
apply (subgoal_tac "get_tcb a x = Some tcb")
apply (frule(1) valid_etcbs_get_tcb_get_etcb)
apply (clarsimp simp:lift_simp not_idle_thread_def)
apply (clarsimp simp: get_tcb_def)
done
lemma maskInterrupt_underlying_memory[wp]:
"\<lbrace>\<lambda>ms. underlying_memory ms = m\<rbrace> maskInterrupt a x \<lbrace>\<lambda>x ms. underlying_memory ms = m\<rbrace>"
by (simp add:maskInterrupt_def | wp)+
lemma ackInterrupt_underlying_memory[wp]:
"\<lbrace>\<lambda>ms. underlying_memory ms = m\<rbrace> ackInterrupt x \<lbrace>\<lambda>rv ms. underlying_memory ms = m\<rbrace>"
by (simp add:ackInterrupt_def | wp)+
lemma resetTimer_underlying_memory[wp]:
"\<lbrace>\<lambda>ms. underlying_memory ms = m\<rbrace> resetTimer \<lbrace>\<lambda>rv ms. underlying_memory ms = m\<rbrace>"
apply (simp add:resetTimer_def machine_op_lift_def)
apply (simp add:machine_rest_lift_def ignore_failure_def split_def)
apply wp
apply (clarsimp simp:valid_def simpler_modify_def)
done
lemma valid_state_get_cap_wp:
"\<lbrace>valid_state\<rbrace> CSpaceAcc_A.get_cap xa \<lbrace>\<lambda>rv s. (is_ntfn_cap rv \<longrightarrow> ntfn_at (obj_ref_of rv) s)\<rbrace>"
apply (wp get_cap_wp)
apply (clarsimp simp: is_cap_simps)
apply (drule cte_wp_valid_cap)
apply (fastforce simp: valid_state_def)
apply (clarsimp simp: valid_cap_def)
done
lemma handle_interrupt_corres_branch:
"dcorres dc \<top> \<top> (return ())
(do y \<leftarrow> do_machine_op (maskInterrupt True x);
do_machine_op (ackInterrupt x)
od)"
apply (rule corres_dummy_return_pl)
apply (rule corres_guard_imp)
apply (rule corres_split_deprecated[OF _ dcorres_machine_op_noop])
apply (clarsimp simp:dc_def[symmetric])
apply (rule dcorres_machine_op_noop)
apply (wp|clarsimp)+
done
lemma irq_state_IRQSignal_NullCap:
"\<lbrakk> caps_of_state s (interrupt_irq_node s irq, []) \<noteq> None;
interrupt_states s irq \<noteq> irq_state.IRQSignal;
if_unsafe_then_cap s; valid_global_refs s;
valid_irq_node s; valid_irq_handlers s \<rbrakk>
\<Longrightarrow> caps_of_state s (interrupt_irq_node s irq, []) = Some cap.NullCap"
apply (rule ccontr, clarsimp)
apply (drule(1) if_unsafe_then_capD[OF caps_of_state_cteD])
apply simp
apply (clarsimp simp: ex_cte_cap_wp_to_def cte_wp_at_caps_of_state)
apply (frule(1) valid_global_refsD2)
apply (case_tac cap, simp_all add: cap_range_def global_refs_def)
apply (safe, simp_all)
apply (clarsimp simp: valid_irq_node_def inj_on_eq_iff[where f="interrupt_irq_node s"])
apply (simp add: valid_irq_handlers_def)
apply (drule bspec, erule ranI)
apply (simp add: irq_issued_def)
done
lemma transform_domain_time_update[iff]:
"transform (s\<lparr>domain_time := a\<rparr>) = transform s"
by (auto simp: transform_def transform_cdt_def transform_current_thread_def transform_asid_table_def transform_objects_def)
lemma dec_domain_time_transform: "\<lbrace>\<lambda>ps. transform ps = cs\<rbrace> dec_domain_time \<lbrace>\<lambda>r s. transform s = cs\<rbrace>"
by (clarsimp simp: dec_domain_time_def | wp)+
lemma thread_set_time_slice_transform: "\<lbrace>\<lambda>ps. transform ps = cs\<rbrace> thread_set_time_slice tptr time \<lbrace>\<lambda>r s. transform s = cs\<rbrace>"
apply (clarsimp simp: thread_set_time_slice_def ethread_set_def set_eobject_def | wp)+
apply (clarsimp simp: transform_def transform_objects_def transform_cdt_def transform_current_thread_def transform_asid_table_def)
apply (rule_tac y="\<lambda>ptr. map_option (transform_object (machine_state s) ptr ((ekheap s |` (- {idle_thread s})) ptr)) ((kheap s |` (- {idle_thread s})) ptr)" in arg_cong)
apply (rule ext)
apply (rule_tac y="transform_object (machine_state s) ptr ((ekheap s |` (- {idle_thread s})) ptr)" in arg_cong)
apply (rule ext)
apply (clarsimp simp: transform_object_def transform_tcb_def restrict_map_def get_etcb_def split: option.splits Structures_A.kernel_object.splits)
done
lemma timer_tick_dcorres: "dcorres dc P P' (return ()) timer_tick"
apply (rule corres_noop)
apply (simp add: timer_tick_def reschedule_required_def set_scheduler_action_def etcb_at_def split: option.splits | wp tcb_sched_action_transform dec_domain_time_transform thread_set_time_slice_transform | wpc | wp (once) hoare_vcg_all_lift hoare_drop_imps)+
done
lemma handle_interrupt_corres:
"dcorres dc \<top> (invs and valid_etcbs) (Interrupt_D.handle_interrupt x) (Interrupt_A.handle_interrupt x)"
apply (clarsimp simp:Interrupt_A.handle_interrupt_def)
apply (clarsimp simp:get_irq_state_def gets_def bind_assoc)
apply (rule conjI; rule impI)
apply (subst Interrupt_D.handle_interrupt_def, simp)
apply (subst Retype_AI.do_machine_op_bind)
apply (rule maskInterrupt_empty_fail)
apply (rule ackInterrupt_empty_fail)
using corres_guard2_imp handle_interrupt_corres_branch apply blast
apply (rule dcorres_absorb_get_r)+
apply (clarsimp split:irq_state.splits simp:corres_free_fail | rule conjI)+
apply (simp add:Interrupt_D.handle_interrupt_def bind_assoc)
apply (rule corres_guard_imp)
apply (rule_tac Q'="(=) s'" in corres_split_deprecated[OF _ dcorres_get_irq_slot])
apply (rule_tac R'="\<lambda>rv. (\<lambda>s. (is_ntfn_cap rv \<longrightarrow> ntfn_at (obj_ref_of rv) s)) and invs and valid_etcbs"
in corres_split_deprecated[OF _ option_get_cap_corres])
apply (case_tac rv'a)
prefer 4
apply (simp_all add:when_def)
apply (clarsimp simp:transform_cap_def when_def is_ntfn_cap_def | rule conjI)+
apply (rule corres_dummy_return_l)
apply (rule corres_underlying_split [where P'="\<lambda>rv. \<top>" and P = "\<lambda>rv. \<top>"])
apply (rule corres_guard_imp[OF send_signal_corres])
apply (simp+)
apply (clarsimp simp:handle_interrupt_corres_branch dc_def[symmetric])+
apply (simp add: corres_guard_imp[OF handle_interrupt_corres_branch])+
apply (clarsimp simp:transform_cap_def when_def is_ntfn_cap_def
split:arch_cap.splits)+
apply (simp add: corres_guard_imp[OF handle_interrupt_corres_branch])+
apply (wp hoare_vcg_prop[where P=True] valid_state_get_cap_wp|simp add:get_irq_slot_def)+
apply (clarsimp simp:invs_def )
apply (strengthen irq_node_image_not_idle,simp add:valid_state_def)
apply (clarsimp simp:Interrupt_D.handle_interrupt_def gets_def)
apply (rule conjI; rule impI)
apply (rule dcorres_absorb_get_l)+
apply (clarsimp simp:CSpace_D.get_irq_slot_def)
apply (subgoal_tac "caps_of_state s'b (interrupt_irq_node s'b x,[])\<noteq> None")
apply (drule irq_state_IRQSignal_NullCap)
apply ((simp add:invs_def valid_state_def)+)
apply (frule caps_of_state_transform_opt_cap)
apply clarsimp
apply clarsimp
apply (drule(1) irq_node_image_not_idle[where y = x])
apply (clarsimp simp:not_idle_thread_def)
apply (clarsimp simp:transform_cslot_ptr_def)
apply (subgoal_tac "cdl_irq_node (transform s'b) x = (interrupt_irq_node s'b x)")
apply clarsimp
apply (rule corres_guard_imp,rule corres_dummy_return_pl)
apply (simp add: bind_assoc)
apply (rule dcorres_rhs_noop_above[OF timer_tick_dcorres])
apply (rule dcorres_symb_exec_r[OF dcorres_machine_op_noop])
apply (wp dmo_dwp hoare_TrueI| simp)+
apply (clarsimp simp:transform_def invs_def valid_state_def dest!: valid_irq_node_cte_at_irq_slot)+
apply (simp add:cte_wp_at_caps_of_state)
apply (rule dcorres_absorb_get_l)+
apply (clarsimp simp:CSpace_D.get_irq_slot_def handle_reserved_irq_def)
apply (subgoal_tac "caps_of_state s'b (interrupt_irq_node s'b x,[])\<noteq> None")
apply (drule irq_state_IRQSignal_NullCap)
apply ((simp add:invs_def valid_state_def)+)
apply (frule caps_of_state_transform_opt_cap)
apply clarsimp
apply clarsimp
apply (drule(1) irq_node_image_not_idle[where y = x])
apply (clarsimp simp:not_idle_thread_def)
apply (clarsimp simp:transform_cslot_ptr_def)
apply (subgoal_tac "cdl_irq_node (transform s'b) x = (interrupt_irq_node s'b x)")
apply clarsimp
apply (rule corres_guard_imp)
apply (rule dcorres_machine_op_noop)
apply wp
apply (clarsimp simp:transform_def invs_def valid_state_def dest!: valid_irq_node_cte_at_irq_slot)+
apply (simp add:cte_wp_at_caps_of_state)
done
lemma set_irq_state_original:
"\<lbrace>\<lambda>s. P (is_original_cap s slot)\<rbrace> set_irq_state a b
\<lbrace>\<lambda>rv s. P (is_original_cap s slot)\<rbrace>"
by (clarsimp simp:set_irq_state_def | wp)+
lemma set_irq_state_dwp:
"\<lbrace>\<lambda>ps. transform ps = cs\<rbrace>
set_irq_state irq_state.IRQSignal word \<lbrace>\<lambda>r s. transform s = cs\<rbrace>"
apply (simp add:set_irq_state_def)
apply (wp do_machine_op_wp)
apply clarsimp
apply (wp maskInterrupt_underlying_memory)+
apply (clarsimp simp:transform_def transform_objects_def transform_cdt_def
transform_current_thread_def transform_asid_table_def)
done
lemma dmo_setIRQTrigger_dcorres:
"dcorres dc \<top> \<top> (return ()) (do_machine_op (setIRQTrigger irq trigger))"
by (wpsimp simp: setIRQTrigger_def wp: dcorres_machine_op_noop)
lemma dcorres_invoke_irq_control_body:
"\<And>word p1 p2.
dcorres dc (\<lambda>_. True)
(invs and (cte_wp_at ((=) cap.NullCap) p1
and cte_wp_at ((=) cap.IRQControlCap) p2
and ex_cte_cap_wp_to Structures_A.is_cnode_cap p1
and real_cte_at p1 and (\<lambda>y. word \<le> maxIRQ))
and valid_etcbs)
(insert_cap_child (IrqHandlerCap word) (transform_cslot_ptr p2) (transform_cslot_ptr p1))
(liftE (do y <- set_irq_state irq_state.IRQSignal word;
cap_insert (cap.IRQHandlerCap word) p2 p1
od))"
apply (clarsimp simp:liftE_def bind_assoc)
apply (rule dcorres_symb_exec_r_strong)
apply (rule corres_dummy_return_l)
apply (rule corres_guard_imp)
apply (rule corres_split_deprecated[OF corres_trivial])
apply (rule corres_free_return)
apply (subgoal_tac "IrqHandlerCap word = transform_cap (cap.IRQHandlerCap word)")
apply (simp only:)
apply (rule insert_cap_child_corres)
apply (simp add:transform_cap_def)
apply (wp|clarsimp)+
apply simp
apply (simp add:valid_cap_def cap_aligned_def word_bits_def)
apply (rule hoare_pre)
apply (rule hoare_vcg_conj_lift)
apply (rule_tac Q = "\<lambda>r s. cte_wp_at ((=) cap.IRQControlCap) (aa,ba) s
\<and> is_original_cap s (aa, ba)" in hoare_strengthen_post)
apply (wp set_irq_state_cte_wp_at set_irq_state_original)
apply (simp add:cte_wp_at_def should_be_parent_of_def)
apply (simp add: not_idle_thread_def)
apply wp
apply (strengthen invs_valid_idle invs_mdb)
apply (wp set_irq_state_invs)
apply (clarsimp simp:invs_def valid_state_def valid_pspace_def)
apply (rule conjI)
apply (clarsimp simp:cte_wp_at_caps_of_state)
apply (erule irq_revocableD)
apply (simp add:caps_of_state_cteD invs_def valid_state_def valid_pspace_def valid_mdb_def)
apply (rule conjI)
apply (drule ex_cte_cap_wp_to_not_idle, auto simp: not_idle_thread_def)[1]
apply (drule_tac p = "(aa,ba)" in if_unsafe_then_capD)
apply clarsimp
apply simp
apply (drule_tac r = "(aa,ba)" in ex_cte_cap_wp_to_not_idle)
apply (clarsimp simp:not_idle_thread_def)+
apply (wp set_irq_state_dwp, simp)
done
lemma dcorres_arch_invoke_irq_control:
"dcorres dc \<top> (invs and arch_irq_control_inv_valid arch_irq_control_invocation and valid_etcbs)
(Interrupt_D.invoke_irq_control (
translate_irq_control_invocation (
irq_control_invocation.ArchIRQControl arch_irq_control_invocation)))
(arch_invoke_irq_control arch_irq_control_invocation)"
apply (case_tac arch_irq_control_invocation)
apply (simp add:Interrupt_D.invoke_irq_control_def arch_irq_control_inv_valid_def)
apply (rename_tac word p1 p2 t)
apply (subst liftE_distrib)
apply (simp add: liftE_bindE)
apply (rule corres_dummy_return_pl)
apply (rule corres_guard_imp)
apply (rule corres_split_deprecated [OF _ dmo_setIRQTrigger_dcorres])
apply clarsimp
apply (rule dcorres_invoke_irq_control_body)
apply wpsimp+
done
lemma dcorres_invoke_irq_control:
"dcorres dc \<top> (invs and irq_control_inv_valid irq_control_invocation and valid_etcbs)
(Interrupt_D.invoke_irq_control (translate_irq_control_invocation irq_control_invocation))
(Interrupt_A.invoke_irq_control irq_control_invocation)"
apply (case_tac irq_control_invocation)
apply (simp add:corres_free_fail Interrupt_D.invoke_irq_control_def dcorres_invoke_irq_control_body)
apply (simp add: dcorres_arch_invoke_irq_control[simplified])
done
lemma op_eq_simp: "((=) y) = (\<lambda>x. x = y)" by auto
lemma get_irq_slot_not_idle_wp:
"\<lbrace>valid_idle and valid_irq_node \<rbrace> KHeap_A.get_irq_slot word \<lbrace>\<lambda>rv. not_idle_thread (fst rv)\<rbrace>"
apply (wpsimp simp:get_irq_slot_def)
apply (rule irq_node_image_not_idle)
apply simp+
done
lemma get_irq_slot_ex_cte_cap_wp_to:
"\<lbrace>\<lambda>s. valid_irq_node s \<and> (\<exists>slot. cte_wp_at ((=) (cap.IRQHandlerCap w)) slot s)\<rbrace> KHeap_A.get_irq_slot w
\<lbrace>\<lambda>rv s. (ex_cte_cap_wp_to (\<lambda>a. True) rv s) \<rbrace>"
apply (wpsimp simp:get_irq_slot_def)
apply (clarsimp simp:ex_cte_cap_wp_to_def valid_irq_node_def)
apply (rule exI)+
apply (erule cte_wp_at_weakenE)
apply clarsimp
done
crunch is_original[wp] : fast_finalise "\<lambda>s::'z::state_ext state. is_original_cap s slot"
(wp: crunch_wps dxo_wp_weak simp: crunch_simps)
lemma cap_delete_one_original:
"slot \<noteq> slot' \<Longrightarrow> \<lbrace>\<lambda>s. is_original_cap s slot\<rbrace> cap_delete_one slot'
\<lbrace>\<lambda>r s. is_original_cap s slot\<rbrace>"
apply (clarsimp simp:cap_delete_one_def unless_def)
apply (wp hoare_when_wp)
apply (clarsimp simp:empty_slot_def)
apply wp
apply (clarsimp simp:set_cdt_def)
apply (wp dxo_wp_weak | clarsimp)+
done
lemma cte_wp_at_neq_slot_set_cap:
"slot\<noteq> slot' \<Longrightarrow> \<lbrace>cte_wp_at P slot and cte_at slot'\<rbrace>
CSpaceAcc_A.set_cap cap.NullCap slot' \<lbrace>\<lambda>rv. cte_wp_at P slot\<rbrace>"
apply (wp set_cap_cte_wp_at_cases)
apply (clarsimp simp:cte_wp_at_def)
done
lemma cte_wp_at_neq_slot_cap_delete_one:
"slot\<noteq> slot' \<Longrightarrow> \<lbrace>cte_wp_at P slot\<rbrace> cap_delete_one slot'
\<lbrace>\<lambda>rv. cte_wp_at P slot\<rbrace>"
supply send_signal_interrupt_states [wp_unsafe del] validNF_prop [wp_unsafe del]
apply (clarsimp simp:cap_delete_one_def unless_def)
apply (wp hoare_when_wp)
apply (clarsimp simp:empty_slot_def)
apply (wp cte_wp_at_neq_slot_set_cap)
apply clarsimp
apply (wp dxo_wp_weak | simp)+
apply (clarsimp simp:set_cdt_def)
apply (wp | clarsimp)+
apply (rule_tac Q = "\<lambda>r s. cte_wp_at P slot s \<and> cte_at slot' s" in hoare_strengthen_post)
apply (rule hoare_vcg_conj_lift)
apply wp
apply (wp get_cap_cte)
apply (clarsimp|wp)+
done
lemma cap_delete_one_not_idle [wp]:
"\<lbrace>not_idle_thread t\<rbrace> cap_delete_one slot \<lbrace>\<lambda>_. not_idle_thread t\<rbrace>"
apply (simp add: not_idle_thread_def)
apply wp
done
lemma is_ntfn_capD:
"is_ntfn_cap cap \<Longrightarrow> \<exists>ptr b rights. cap = cap.NotificationCap ptr b rights"
by (case_tac cap,simp_all)
lemma dcorres_invoke_irq_handler:
"dcorres dc \<top> (invs and irq_handler_inv_valid irq_handler_invocation and valid_etcbs)
(Interrupt_D.invoke_irq_handler
(translate_irq_handler_invocation irq_handler_invocation))
(Interrupt_A.invoke_irq_handler irq_handler_invocation)"
apply (case_tac irq_handler_invocation)
(* ACKIrq *)
apply (clarsimp simp:Interrupt_D.invoke_irq_handler_def)
apply (rule corres_dummy_return_r)
apply (rule dcorres_symb_exec_r_strong)
apply (rule corres_free_return[where P'=\<top> ])
apply wp
apply (wp do_machine_op_wp,clarsimp)
apply (wp maskInterrupt_underlying_memory|clarsimp simp:Interrupt_D.invoke_irq_handler_def)+
(* SetIRQHandler *)
apply (rule dcorres_expand_pfx)
apply (clarsimp dest!:is_ntfn_capD simp:valid_cap_def)
apply (rule corres_guard_imp)
apply (rule corres_split_deprecated[OF _ dcorres_get_irq_slot])
apply (rule_tac F="irq_slot\<noteq> (a,b)" in corres_gen_asm2)
apply simp
apply (rule corres_split_deprecated[OF _ delete_cap_simple_corres])
apply (subst alternative_com)
apply (rule dcorres_insert_cap_combine,simp)
apply wp
apply (wp delete_one_deletes[unfolded op_eq_simp[symmetric]])
apply (wp cte_wp_at_neq_slot_cap_delete_one)
apply simp
apply (wp cte_wp_at_neq_slot_cap_delete_one)
apply (strengthen invs_valid_idle invs_valid_objs)
apply (wp delete_one_invs)
apply (simp add:valid_cap_def)
apply (wp get_irq_slot_not_idle_wp get_irq_slot_ex_cte_cap_wp_to)
apply (wp get_irq_slot_different get_irq_slot_not_idle_wp)
apply simp+
apply (clarsimp simp:invs_valid_idle interrupt_derived_def)
apply (frule_tac p = "(a,b)" in if_unsafe_then_capD)
apply clarsimp+
apply (clarsimp simp: cte_wp_at_caps_of_state invs_valid_global_refs is_cap_simps
cap_master_cap_simps interrupt_derived_def dest!:cap_master_cap_eqDs)+
apply (drule ex_cte_cap_wp_to_not_idle)
apply clarsimp+
(* ClearIRQHandler *)
apply (clarsimp simp: Interrupt_D.invoke_irq_handler_def)
apply (rule corres_guard_imp)
apply (rule corres_split_deprecated[OF _ dcorres_get_irq_slot])
apply (clarsimp)
apply (rule delete_cap_simple_corres)
apply (wp get_irq_slot_not_idle_wp,clarsimp)+
apply (clarsimp simp:invs_def valid_state_def)
done
end
end