2014-07-14 19:32:44 +00:00
|
|
|
(*
|
2020-03-09 06:18:30 +00:00
|
|
|
* Copyright 2020, Data61, CSIRO (ABN 41 687 119 230)
|
2014-07-14 19:32:44 +00:00
|
|
|
*
|
2020-03-09 06:18:30 +00:00
|
|
|
* SPDX-License-Identifier: GPL-2.0-only
|
2014-07-14 19:32:44 +00:00
|
|
|
*)
|
|
|
|
|
|
|
|
(*
|
|
|
|
* Operations on page table objects and frames.
|
|
|
|
*)
|
|
|
|
|
|
|
|
theory Asid_D
|
|
|
|
imports
|
|
|
|
Invocations_D
|
|
|
|
CSpace_D
|
|
|
|
Untyped_D
|
|
|
|
begin
|
|
|
|
|
|
|
|
definition
|
|
|
|
decode_asid_control_invocation :: "cdl_cap \<Rightarrow> cdl_cap_ref \<Rightarrow> (cdl_cap \<times> cdl_cap_ref) list \<Rightarrow>
|
|
|
|
cdl_asid_control_intent \<Rightarrow> cdl_asid_control_invocation except_monad"
|
|
|
|
where
|
|
|
|
"decode_asid_control_invocation target target_ref caps intent \<equiv> case intent of
|
|
|
|
AsidControlMakePoolIntent index depth \<Rightarrow>
|
|
|
|
doE
|
|
|
|
base \<leftarrow> liftE $ select {x. x < 2 ^ asid_high_bits};
|
|
|
|
|
2019-05-27 08:32:17 +00:00
|
|
|
\<comment> \<open>Fetch the untyped item, and ensure it is valid.\<close>
|
2014-07-14 19:32:44 +00:00
|
|
|
(untyped_cap, untyped_cap_ref) \<leftarrow> throw_on_none $ get_index caps 0;
|
|
|
|
(case untyped_cap of
|
2016-08-12 04:24:37 +00:00
|
|
|
UntypedCap _ s _ \<Rightarrow> returnOk ()
|
2014-07-14 19:32:44 +00:00
|
|
|
| _ \<Rightarrow> throw);
|
|
|
|
ensure_no_children untyped_cap_ref;
|
|
|
|
|
2019-05-27 08:32:17 +00:00
|
|
|
\<comment> \<open>Fetch the slot we plan to put the generated cap into.\<close>
|
2014-07-14 19:32:44 +00:00
|
|
|
(cspace_cap, _) \<leftarrow> throw_on_none $ get_index caps 1;
|
|
|
|
target_slot \<leftarrow> lookup_slot_for_cnode_op cspace_cap index (unat depth);
|
|
|
|
ensure_empty target_slot;
|
|
|
|
|
2014-07-17 16:22:50 +00:00
|
|
|
returnOk $ MakePool (set_available_range untyped_cap {}) untyped_cap_ref
|
2014-09-05 04:48:22 +00:00
|
|
|
(cap_objects untyped_cap) target_slot base
|
2014-07-14 19:32:44 +00:00
|
|
|
odE \<sqinter> throw"
|
|
|
|
|
|
|
|
definition
|
|
|
|
decode_asid_pool_invocation :: "cdl_cap \<Rightarrow> cdl_cap_ref \<Rightarrow> (cdl_cap \<times> cdl_cap_ref) list \<Rightarrow>
|
|
|
|
cdl_asid_pool_intent \<Rightarrow> cdl_asid_pool_invocation except_monad"
|
|
|
|
where
|
|
|
|
"decode_asid_pool_invocation target target_ref caps intent \<equiv> case intent of
|
2014-09-09 05:57:52 +00:00
|
|
|
AsidPoolAssignIntent \<Rightarrow>
|
2014-07-14 19:32:44 +00:00
|
|
|
doE
|
|
|
|
(pd_cap, pd_cap_ref) \<leftarrow> throw_on_none $ get_index caps 0;
|
|
|
|
(case pd_cap of
|
|
|
|
PageDirectoryCap _ _ _ \<Rightarrow> returnOk ()
|
|
|
|
| _ \<Rightarrow> throw);
|
|
|
|
|
|
|
|
base \<leftarrow> (case target of
|
2014-09-05 04:48:22 +00:00
|
|
|
AsidPoolCap p base \<Rightarrow> returnOk $ base
|
2014-07-14 19:32:44 +00:00
|
|
|
| _ \<Rightarrow> throw);
|
|
|
|
offset \<leftarrow> liftE $ select {x. x < 2 ^ asid_low_bits};
|
|
|
|
returnOk $ Assign (base, offset) pd_cap_ref (cap_object target, offset)
|
2017-07-12 05:13:51 +00:00
|
|
|
odE \<sqinter> throw"
|
2014-07-14 19:32:44 +00:00
|
|
|
|
|
|
|
definition
|
|
|
|
invoke_asid_control :: "cdl_asid_control_invocation \<Rightarrow> unit k_monad"
|
|
|
|
where
|
|
|
|
"invoke_asid_control params \<equiv>
|
|
|
|
case params of
|
|
|
|
MakePool untyped_cap untyped_cap_ref untyped_covers target_slot base \<Rightarrow>
|
|
|
|
do
|
2019-05-27 08:32:17 +00:00
|
|
|
\<comment> \<open>Untype the region. A choice may be made about whether to detype
|
|
|
|
objects with Untyped addresses.\<close>
|
2014-07-14 19:32:44 +00:00
|
|
|
modify (detype untyped_covers);
|
|
|
|
set_cap untyped_cap_ref untyped_cap;
|
|
|
|
targets \<leftarrow> generate_object_ids 1 AsidPoolType untyped_covers;
|
|
|
|
|
2019-05-27 08:32:17 +00:00
|
|
|
\<comment> \<open>Retype the region.\<close>
|
2014-07-14 19:32:44 +00:00
|
|
|
retype_region 0 AsidPoolType targets;
|
|
|
|
assert (targets \<noteq> []);
|
|
|
|
|
2019-05-27 08:32:17 +00:00
|
|
|
\<comment> \<open>Insert the cap.\<close>
|
2014-07-14 19:32:44 +00:00
|
|
|
frame \<leftarrow> return $ pick (hd targets);
|
|
|
|
insert_cap_child (AsidPoolCap frame base) untyped_cap_ref target_slot;
|
|
|
|
|
2019-05-27 08:32:17 +00:00
|
|
|
\<comment> \<open>Update the asid table.\<close>
|
2014-07-14 19:32:44 +00:00
|
|
|
asid_table \<leftarrow> gets cdl_asid_table;
|
2014-09-05 04:48:22 +00:00
|
|
|
asid_table' \<leftarrow> return $ asid_table (base \<mapsto> AsidPoolCap frame 0);
|
2014-07-14 19:32:44 +00:00
|
|
|
modify (\<lambda>s. s \<lparr>cdl_asid_table := asid_table'\<rparr>)
|
|
|
|
|
|
|
|
od"
|
|
|
|
|
|
|
|
definition
|
|
|
|
invoke_asid_pool :: "cdl_asid_pool_invocation \<Rightarrow> unit k_monad"
|
|
|
|
where
|
|
|
|
"invoke_asid_pool params \<equiv>
|
|
|
|
case params of
|
|
|
|
Assign asid pd_cap_ref ap_target_slot \<Rightarrow> do
|
|
|
|
pd_cap \<leftarrow> get_cap pd_cap_ref;
|
|
|
|
case pd_cap of
|
|
|
|
PageDirectoryCap pd_id _ _ \<Rightarrow> do
|
|
|
|
set_cap pd_cap_ref (PageDirectoryCap pd_id Real (Some asid));
|
|
|
|
set_cap ap_target_slot (PageDirectoryCap pd_id Fake None)
|
|
|
|
od
|
|
|
|
| _ \<Rightarrow> fail
|
|
|
|
od"
|
|
|
|
|
|
|
|
end
|