73 lines
3.3 KiB
Diff
73 lines
3.3 KiB
Diff
--- a/tool/microkit/src/sdf/cspace.rs
|
|||
|
|
+++ b/tool/microkit/src/sdf/cspace.rs
|
||
|
|
@@ -17,6 +17,7 @@
|
||
|
|
Tcb,
|
||
|
|
Sc,
|
||
|
|
VSpace,
|
||
|
|
+ Frame,
|
||
|
|
}
|
||
|
|
|
||
|
|
#[derive(Debug, PartialEq, Eq)]
|
||
|
|
@@ -45,9 +46,9 @@
|
||
|
|
// At the moment the four cap maps we support all have the 'pd' element,
|
||
|
|
// so we can include it here. When that stops being the case we will
|
||
|
|
// have to rework this a bit.
|
||
|
|
- check_attributes(xml_sdf, node, &["slot", "pd"])?;
|
||
|
|
-
|
||
|
|
- let pd = Rc::from(checked_lookup(xml_sdf, node, "pd")?);
|
||
|
|
+ let source = if cap_type == CapMapType::Frame { "mr" } else { "pd" };
|
||
|
|
+ check_attributes(xml_sdf, node, &["slot", source])?;
|
||
|
|
+ let pd = Rc::from(checked_lookup(xml_sdf, node, source)?);
|
||
|
|
|
||
|
|
let slot: u64 = sdf_parse_required_attribute(xml_sdf, node, "slot")?;
|
||
|
|
|
||
|
|
@@ -91,6 +92,7 @@
|
||
|
|
"cap_tcb" => CapMap::from_xml(CapMapType::Tcb, xml_sdf, &*child)?,
|
||
|
|
"cap_sc" => CapMap::from_xml(CapMapType::Sc, xml_sdf, &*child)?,
|
||
|
|
"cap_vspace" => CapMap::from_xml(CapMapType::VSpace, xml_sdf, &*child)?,
|
||
|
|
+ "cap_frame" => CapMap::from_xml(CapMapType::Frame, xml_sdf, &*child)?,
|
||
|
|
child_name => {
|
||
|
|
let location = loc_string(xml_sdf, child.range().start);
|
||
|
|
if let Some(type_name) = child_name.strip_prefix("cap_") {
|
||
|
|
--- a/tool/microkit/src/sdf.rs
|
||
|
|
+++ b/tool/microkit/src/sdf.rs
|
||
|
|
@@ -310,7 +310,11 @@
|
||
|
|
|
||
|
|
for pd in pds.values() {
|
||
|
|
for cap_map in pd.cap_maps.iter() {
|
||
|
|
- if !pds.contains_key(&cap_map.pd) {
|
||
|
|
+ if cap_map.cap_type == CapMapType::Frame {
|
||
|
|
+ if !mrs.iter().any(|mr| mr.name.as_str() == cap_map.pd.as_ref()) {
|
||
|
|
+ return Err(format!("Unknown frame region {}", cap_map.pd));
|
||
|
|
+ }
|
||
|
|
+ } else if !pds.contains_key(&cap_map.pd) {
|
||
|
|
return Err(format!(
|
||
|
|
"Error: unknown PD name '{}': {}",
|
||
|
|
cap_map.pd,
|
||
|
|
--- a/tool/microkit/src/capdl/builder.rs
|
||
|
|
+++ b/tool/microkit/src/capdl/builder.rs
|
||
|
|
@@ -1332,12 +1332,23 @@
|
||
|
|
for cap_map in pd.cap_maps.iter() {
|
||
|
|
// TODO: Once we add more CapMap options, they might not all have
|
||
|
|
// the pd_name. But for now, they do.
|
||
|
|
- let pd_src_shadow_cspace = &pd_shadow_cspaces[&cap_map.pd];
|
||
|
|
+ let pd_src_shadow_cspace = if cap_map.cap_type == CapMapType::Frame {
|
||
|
|
+ &pd_shadow_cspaces[&pd.name]
|
||
|
|
+ } else {
|
||
|
|
+ &pd_shadow_cspaces[&cap_map.pd]
|
||
|
|
+ };
|
||
|
|
|
||
|
|
let cap_map_obj = match cap_map.cap_type {
|
||
|
|
CapMapType::Tcb => capdl_util_make_tcb_cap(pd_src_shadow_cspace.tcb),
|
||
|
|
CapMapType::Sc => capdl_util_make_sc_cap(pd_src_shadow_cspace.sched_context),
|
||
|
|
CapMapType::VSpace => capdl_util_make_page_table_cap(pd_src_shadow_cspace.vspace),
|
||
|
|
+ CapMapType::Frame => {
|
||
|
|
+ let frames = &mr_name_to_frames[cap_map.pd.as_ref()];
|
||
|
|
+ if frames.len() != 1 {
|
||
|
|
+ return Err(format!("Frame region {} must contain one page", cap_map.pd));
|
||
|
|
+ }
|
||
|
|
+ capdl_util_make_frame_cap(frames[0], true, true, false, true)
|
||
|
|
+ },
|
||
|
|
};
|
||
|
|
|
||
|
|
// Map this into the destination pd's cspace and the specified slot.
|