Merge changes Ife13eb84,I22ae4bbb
* changes:
pvmfw: Add swiotlb <reg> to platform.dts
pvmfw: Accept either swiotlb DT reg or size/align
diff --git a/libs/libfdt/Android.bp b/libs/libfdt/Android.bp
index 72399b0..5a729f1 100644
--- a/libs/libfdt/Android.bp
+++ b/libs/libfdt/Android.bp
@@ -37,6 +37,7 @@
],
rustlibs: [
"liblibfdt_bindgen",
+ "libzerocopy_nostd",
],
whole_static_libs: [
"libfdt",
diff --git a/libs/libfdt/src/lib.rs b/libs/libfdt/src/lib.rs
index 9785941..df1058e 100644
--- a/libs/libfdt/src/lib.rs
+++ b/libs/libfdt/src/lib.rs
@@ -26,6 +26,7 @@
use core::fmt;
use core::mem;
use core::result;
+use zerocopy::AsBytes as _;
/// Error type corresponding to libfdt error codes.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
@@ -441,6 +442,13 @@
fdt_err_expect_zero(ret)
}
+ /// Replace the value of the given (address, size) pair property with the given value, and
+ /// ensure that the given value has the same length as the current value length
+ pub fn setprop_addrrange_inplace(&mut self, name: &CStr, addr: u64, size: u64) -> Result<()> {
+ let pair = [addr.to_be(), size.to_be()];
+ self.setprop_inplace(name, pair.as_bytes())
+ }
+
/// Create or change a flag-like empty property.
pub fn setprop_empty(&mut self, name: &CStr) -> Result<()> {
self.setprop(name, &[])
@@ -459,6 +467,17 @@
fdt_err_expect_zero(ret)
}
+ /// Overwrite the given property with FDT_NOP, effectively removing it from the DT.
+ pub fn nop_property(&mut self, name: &CStr) -> Result<()> {
+ // SAFETY - Accesses are constrained to the DT totalsize (validated by ctor) when the
+ // library locates the node's property.
+ let ret = unsafe {
+ libfdt_bindgen::fdt_nop_property(self.fdt.as_mut_ptr(), self.offset, name.as_ptr())
+ };
+
+ fdt_err_expect_zero(ret)
+ }
+
/// Reduce the size of the given property to new_size
pub fn trimprop(&mut self, name: &CStr, new_size: usize) -> Result<()> {
let (prop, len) =
diff --git a/pvmfw/platform.dts b/pvmfw/platform.dts
index a7b1de7..74439d9 100644
--- a/pvmfw/platform.dts
+++ b/pvmfw/platform.dts
@@ -37,6 +37,7 @@
ranges;
swiotlb: restricted_dma_reserved {
compatible = "restricted-dma-pool";
+ reg = <PLACEHOLDER4>;
size = <PLACEHOLDER2>;
alignment = <PLACEHOLDER2>;
};
diff --git a/pvmfw/src/fdt.rs b/pvmfw/src/fdt.rs
index 98802b4..c0241ca 100644
--- a/pvmfw/src/fdt.rs
+++ b/pvmfw/src/fdt.rs
@@ -440,7 +440,7 @@
pub struct SwiotlbInfo {
addr: Option<usize>,
size: usize,
- align: usize,
+ align: Option<usize>,
}
impl SwiotlbInfo {
@@ -452,17 +452,16 @@
fn read_swiotlb_info_from(fdt: &Fdt) -> libfdt::Result<SwiotlbInfo> {
let node =
fdt.compatible_nodes(cstr!("restricted-dma-pool"))?.next().ok_or(FdtError::NotFound)?;
- let align =
- node.getprop_u64(cstr!("alignment"))?.ok_or(FdtError::NotFound)?.try_into().unwrap();
- let (addr, size) = if let Some(mut reg) = node.reg()? {
+ let (addr, size, align) = if let Some(mut reg) = node.reg()? {
let reg = reg.next().ok_or(FdtError::NotFound)?;
let size = reg.size.ok_or(FdtError::NotFound)?;
reg.addr.checked_add(size).ok_or(FdtError::BadValue)?;
- (Some(reg.addr.try_into().unwrap()), size.try_into().unwrap())
+ (Some(reg.addr.try_into().unwrap()), size.try_into().unwrap(), None)
} else {
- let size = node.getprop_u64(cstr!("size"))?.ok_or(FdtError::NotFound)?.try_into().unwrap();
- (None, size)
+ let size = node.getprop_u64(cstr!("size"))?.ok_or(FdtError::NotFound)?;
+ let align = node.getprop_u64(cstr!("alignment"))?.ok_or(FdtError::NotFound)?;
+ (None, size.try_into().unwrap(), Some(align.try_into().unwrap()))
};
Ok(SwiotlbInfo { addr, size, align })
@@ -480,7 +479,7 @@
return Err(RebootReason::InvalidFdt);
}
- if (align % GUEST_PAGE_SIZE) != 0 {
+ if let Some(align) = align.filter(|&a| a % GUEST_PAGE_SIZE != 0) {
error!("Invalid swiotlb alignment {:#x}", align);
return Err(RebootReason::InvalidFdt);
}
@@ -498,16 +497,19 @@
fn patch_swiotlb_info(fdt: &mut Fdt, swiotlb_info: &SwiotlbInfo) -> libfdt::Result<()> {
let mut node =
fdt.root_mut()?.next_compatible(cstr!("restricted-dma-pool"))?.ok_or(FdtError::NotFound)?;
- node.setprop_inplace(cstr!("alignment"), &swiotlb_info.align.to_be_bytes())?;
if let Some(range) = swiotlb_info.fixed_range() {
- node.appendprop_addrrange(
+ node.setprop_addrrange_inplace(
cstr!("reg"),
range.start.try_into().unwrap(),
range.len().try_into().unwrap(),
)?;
+ node.nop_property(cstr!("size"))?;
+ node.nop_property(cstr!("alignment"))?;
} else {
+ node.nop_property(cstr!("reg"))?;
node.setprop_inplace(cstr!("size"), &swiotlb_info.size.to_be_bytes())?;
+ node.setprop_inplace(cstr!("alignment"), &swiotlb_info.align.unwrap().to_be_bytes())?;
}
Ok(())