@@ -7,6 +7,7 @@ use core::ptr::NonNull;
77use  axaddrspace:: GuestPhysAddr ; 
88use  axvm:: { VMMemoryRegion ,  config:: AxVMCrateConfig } ; 
99use  fdt_parser:: { Fdt ,  Node } ; 
10+ use  memory_addr:: MemoryAddr ; 
1011use  vm_fdt:: { FdtWriter ,  FdtWriterNode } ; 
1112
1213use  crate :: vmm:: { VMRef ,  images:: load_vm_image_from_memory} ; 
@@ -259,7 +260,7 @@ fn add_memory_node(new_memory: &[VMMemoryRegion], new_fdt: &mut FdtWriter) {
259260    new_fdt. property_string ( "device_type" ,  "memory" ) . unwrap ( ) ; 
260261} 
261262
262- pub  fn  update_fdt ( dest_addr :   GuestPhysAddr ,   fdt_src :  NonNull < u8 > ,  dtb_size :  usize ,  vm :  VMRef )  { 
263+ pub  fn  update_fdt ( fdt_src :  NonNull < u8 > ,  dtb_size :  usize ,  vm :  VMRef )  { 
263264    let  mut  new_fdt = FdtWriter :: new ( ) . unwrap ( ) ; 
264265    let  mut  previous_node_level = 0 ; 
265266    let  mut  node_stack:  Vec < FdtWriterNode >  = Vec :: new ( ) ; 
@@ -315,12 +316,54 @@ pub fn update_fdt(dest_addr: GuestPhysAddr, fdt_src: NonNull<u8>, dtb_size: usiz
315316    let  new_fdt_bytes = new_fdt. finish ( ) . unwrap ( ) ; 
316317
317318    // crate::vmm::fdt::print::print_guest_fdt(new_fdt_bytes.as_slice()); 
318- 
319+     let  vm_clone = vm. clone ( ) ; 
320+     let  dest_addr = calculate_dtb_load_addr ( vm,  new_fdt_bytes. len ( ) ) ; 
321+     info ! ( "New FDT will be loaded at {:x}" ,  dest_addr) ; 
319322    // Load the updated FDT into VM 
320-     load_vm_image_from_memory ( & new_fdt_bytes,  dest_addr,  vm . clone ( ) ) 
323+     load_vm_image_from_memory ( & new_fdt_bytes,  dest_addr,  vm_clone ) 
321324        . expect ( "Failed to load VM images" ) ; 
322325} 
323326
327+ fn  calculate_dtb_load_addr ( vm :  VMRef ,  fdt_size :  usize )  -> GuestPhysAddr  { 
328+     const  MB :  usize  = 1024  *  1024 ; 
329+ 
330+     // Get main memory from VM memory regions outside the closure 
331+     let  main_memory = vm
332+         . memory_regions ( ) 
333+         . first ( ) 
334+         . cloned ( ) 
335+         . expect ( "VM must have at least one memory region" ) ; 
336+ 
337+     vm. with_config ( |config| { 
338+         let  dtb_addr = if  let  Some ( addr)  = config. image_config . dtb_load_gpa  { 
339+             // If dtb_load_gpa is already set, use the original value 
340+             addr
341+         }  else  { 
342+             // If dtb_load_gpa is None, calculate based on memory size and FDT size 
343+             if  main_memory. size ( )  > 512  *  MB  { 
344+                 // When memory size is greater than 512MB, place in the last area of the first 512MB 
345+                 let  available_space = 2  *  MB ; 
346+                 if  fdt_size <= available_space { 
347+                     ( main_memory. gpa  + 512  *  MB  - available_space) . align_down ( 2  *  MB ) 
348+                 }  else  { 
349+                     // If FDT is larger than available space, place it at the end of main memory 
350+                     ( main_memory. gpa  + main_memory. size ( )  - fdt_size) . align_down ( 2  *  MB ) 
351+                 } 
352+             }  else  { 
353+                 // When memory size is less than or equal to 512MB, place at the end of main_memory 
354+                 if  fdt_size <= main_memory. size ( )  { 
355+                     ( main_memory. gpa  + main_memory. size ( )  - fdt_size) . align_down ( 2  *  MB ) 
356+                 }  else  { 
357+                     // This shouldn't happen, but just in case 
358+                     main_memory. gpa . align_down ( 2  *  MB ) 
359+                 } 
360+             } 
361+         } ; 
362+         config. image_config . dtb_load_gpa  = Some ( dtb_addr) ; 
363+         dtb_addr
364+     } ) 
365+ } 
366+ 
324367pub  fn  update_cpu_node ( fdt :  & Fdt ,  host_fdt :  & Fdt ,  crate_config :  & AxVMCrateConfig )  -> Vec < u8 >  { 
325368    let  mut  new_fdt = FdtWriter :: new ( ) . unwrap ( ) ; 
326369    let  mut  previous_node_level = 0 ; 
0 commit comments