(fdt: &mut FdtWriter, guest_mem: &GuestMemoryMmap)
| 147 | } |
| 148 | |
| 149 | fn create_memory_node(fdt: &mut FdtWriter, guest_mem: &GuestMemoryMmap) -> FdtWriterResult<()> { |
| 150 | // Note: memory regions from "GuestMemory" are sorted and non-zero sized. |
| 151 | let ram_regions = { |
| 152 | let mut ram_regions = Vec::new(); |
| 153 | let mut current_start = guest_mem |
| 154 | .iter() |
| 155 | .next() |
| 156 | .map(GuestMemoryRegion::start_addr) |
| 157 | .expect("GuestMemory must have one memory region at least") |
| 158 | .raw_value(); |
| 159 | let mut current_end = current_start; |
| 160 | |
| 161 | for (start, size) in guest_mem |
| 162 | .iter() |
| 163 | .map(|m| (m.start_addr().raw_value(), m.len())) |
| 164 | { |
| 165 | if current_end == start { |
| 166 | // This zone is continuous with the previous one. |
| 167 | current_end += size; |
| 168 | } else { |
| 169 | ram_regions.push((current_start, current_end)); |
| 170 | |
| 171 | current_start = start; |
| 172 | current_end = start + size; |
| 173 | } |
| 174 | } |
| 175 | |
| 176 | ram_regions.push((current_start, current_end)); |
| 177 | |
| 178 | ram_regions |
| 179 | }; |
| 180 | |
| 181 | let mut mem_reg_property = Vec::new(); |
| 182 | for region in ram_regions { |
| 183 | let mem_size = region.1 - region.0; |
| 184 | mem_reg_property.push(region.0); |
| 185 | mem_reg_property.push(mem_size); |
| 186 | } |
| 187 | |
| 188 | let ram_start = super::layout::RAM_START.raw_value(); |
| 189 | let memory_node_name = format!("memory@{ram_start:x}"); |
| 190 | let memory_node = fdt.begin_node(&memory_node_name)?; |
| 191 | fdt.property_string("device_type", "memory")?; |
| 192 | fdt.property_array_u64("reg", &mem_reg_property)?; |
| 193 | fdt.end_node(memory_node)?; |
| 194 | |
| 195 | Ok(()) |
| 196 | } |
| 197 | |
| 198 | fn create_chosen_node( |
| 199 | fdt: &mut FdtWriter, |
no test coverage detected