diff --git a/aarch64/src/fdt.rs b/aarch64/src/fdt.rs index 9606982eea..6b318e7187 100644 --- a/aarch64/src/fdt.rs +++ b/aarch64/src/fdt.rs @@ -8,7 +8,8 @@ use std::io::Read; use arch::fdt::{ begin_node, end_node, finish_fdt, generate_prop32, generate_prop64, property, property_cstring, - property_null, property_string, property_u32, property_u64, start_fdt, Error, Result, + property_null, property_string, property_string_list, property_u32, property_u64, start_fdt, + Error, Result, }; use arch::SERIAL_ADDR; use devices::{PciAddress, PciInterruptPin}; @@ -184,17 +185,14 @@ fn create_serial_nodes(fdt: &mut Vec) -> Result<()> { } fn create_psci_node(fdt: &mut Vec, version: &PsciVersion) -> Result<()> { - let compatible = if version.major == 1 { + let mut compatible = vec![format!("arm,psci-{}.{}", version.major, version.minor)]; + if version.major == 1 { // Put `psci-0.2` as well because PSCI 1.0 is compatible with PSCI 0.2. - format!( - "\"arm,psci-{}.{}\", \"arm,psci-0.2\"", - version.major, version.minor - ) - } else { - format!("arm,psci-{}.{}", version.major, version.minor) + compatible.push(format!("arm,psci-0.2")) }; + begin_node(fdt, "psci")?; - property_string(fdt, "compatible", &compatible)?; + property_string_list(fdt, "compatible", compatible)?; // Only support aarch64 guest property_string(fdt, "method", "hvc")?; end_node(fdt)?; diff --git a/arch/src/fdt.rs b/arch/src/fdt.rs index a3861d53ab..658777df54 100644 --- a/arch/src/fdt.rs +++ b/arch/src/fdt.rs @@ -156,17 +156,16 @@ pub fn property_null(fdt: &mut Vec, name: &str) -> Result<()> { Ok(()) } -pub fn property_cstring(fdt: &mut Vec, name: &str, cstr_value: &CStr) -> Result<()> { - let value_bytes = cstr_value.to_bytes_with_nul(); +pub fn property_bytes(fdt: &mut Vec, name: &str, bytes: &[u8]) -> Result<()> { let cstr_name = CString::new(name).unwrap(); - // Safe because we allocated fdt, converted name and value to CStrings + // Safe because we allocated fdt, converted name to CStrings let fdt_ret = unsafe { fdt_property( fdt.as_mut_ptr() as *mut c_void, cstr_name.as_ptr(), - value_bytes.as_ptr() as *mut c_void, - value_bytes.len() as i32, + bytes.as_ptr() as *mut c_void, + bytes.len() as i32, ) }; if fdt_ret != 0 { @@ -175,11 +174,30 @@ pub fn property_cstring(fdt: &mut Vec, name: &str, cstr_value: &CStr) -> Res Ok(()) } +pub fn property_cstring(fdt: &mut Vec, name: &str, cstr_value: &CStr) -> Result<()> { + let value_bytes = cstr_value.to_bytes_with_nul(); + property_bytes(fdt, name, value_bytes) +} + pub fn property_string(fdt: &mut Vec, name: &str, value: &str) -> Result<()> { let cstr_value = CString::new(value).unwrap(); property_cstring(fdt, name, &cstr_value) } +pub fn property_string_list(fdt: &mut Vec, name: &str, values: Vec) -> Result<()> { + let bytes = values + .into_iter() + .map(|s| { + let mut bytes = s.into_bytes(); + // Each value must be null-terminated. + bytes.push(0); + bytes + }) + .flatten() + .collect::>(); + property_bytes(fdt, name, &bytes) +} + pub fn start_fdt(fdt: &mut Vec, fdt_max_size: usize) -> Result<()> { // Safe since we allocated this array with fdt_max_size let mut fdt_ret = unsafe { fdt_create(fdt.as_mut_ptr() as *mut c_void, fdt_max_size as c_int) };