hw/microblaze: Add support for loading initrd images
Signed-off-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
This commit is contained in:
		
							parent
							
								
									d0b022a0e9
								
							
						
					
					
						commit
						ec426ff808
					
				| @ -26,6 +26,7 @@ | ||||
| 
 | ||||
| #include "qemu/option.h" | ||||
| #include "qemu/config-file.h" | ||||
| #include "qemu/error-report.h" | ||||
| #include "qemu-common.h" | ||||
| #include "sysemu/device_tree.h" | ||||
| #include "sysemu/sysemu.h" | ||||
| @ -39,6 +40,8 @@ static struct | ||||
|     void (*machine_cpu_reset)(MicroBlazeCPU *); | ||||
|     uint32_t bootstrap_pc; | ||||
|     uint32_t cmdline; | ||||
|     uint32_t initrd_start; | ||||
|     uint32_t initrd_end; | ||||
|     uint32_t fdt; | ||||
| } boot_info; | ||||
| 
 | ||||
| @ -49,6 +52,7 @@ static void main_cpu_reset(void *opaque) | ||||
| 
 | ||||
|     cpu_reset(CPU(cpu)); | ||||
|     env->regs[5] = boot_info.cmdline; | ||||
|     env->regs[6] = boot_info.initrd_start; | ||||
|     env->regs[7] = boot_info.fdt; | ||||
|     env->sregs[SR_PC] = boot_info.bootstrap_pc; | ||||
|     if (boot_info.machine_cpu_reset) { | ||||
| @ -58,6 +62,8 @@ static void main_cpu_reset(void *opaque) | ||||
| 
 | ||||
| static int microblaze_load_dtb(hwaddr addr, | ||||
|                                uint32_t ramsize, | ||||
|                                uint32_t initrd_start, | ||||
|                                uint32_t initrd_end, | ||||
|                                const char *kernel_cmdline, | ||||
|                                const char *dtb_filename) | ||||
| { | ||||
| @ -80,6 +86,14 @@ static int microblaze_load_dtb(hwaddr addr, | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (initrd_start) { | ||||
|         qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-start", | ||||
|                                   initrd_start); | ||||
| 
 | ||||
|         qemu_devtree_setprop_cell(fdt, "/chosen", "linux,initrd-end", | ||||
|                                   initrd_end); | ||||
|     } | ||||
| 
 | ||||
|     cpu_physical_memory_write(addr, fdt, fdt_size); | ||||
|     return fdt_size; | ||||
| } | ||||
| @ -90,7 +104,9 @@ static uint64_t translate_kernel_address(void *opaque, uint64_t addr) | ||||
| } | ||||
| 
 | ||||
| void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base, | ||||
|                             uint32_t ramsize, const char *dtb_filename, | ||||
|                             uint32_t ramsize, | ||||
|                             const char *initrd_filename, | ||||
|                             const char *dtb_filename, | ||||
|                             void (*machine_cpu_reset)(MicroBlazeCPU *)) | ||||
| { | ||||
|     QemuOpts *machine_opts; | ||||
| @ -151,6 +167,25 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base, | ||||
|             high = (ddr_base + kernel_size + 3) & ~3; | ||||
|         } | ||||
| 
 | ||||
|         if (initrd_filename) { | ||||
|             int initrd_size; | ||||
|             uint32_t initrd_offset; | ||||
| 
 | ||||
|             high = ROUND_UP(high + kernel_size, 4); | ||||
|             boot_info.initrd_start = high; | ||||
|             initrd_offset = boot_info.initrd_start - ddr_base; | ||||
|             initrd_size = load_image_targphys(initrd_filename, | ||||
|                                               boot_info.initrd_start, | ||||
|                                               ram_size - initrd_offset); | ||||
|             if (initrd_size < 0) { | ||||
|                 error_report("qemu: could not load initrd '%s'\n", | ||||
|                              initrd_filename); | ||||
|                 exit(EXIT_FAILURE); | ||||
|             } | ||||
|             boot_info.initrd_end = boot_info.initrd_start + initrd_size; | ||||
|             high = ROUND_UP(high + initrd_size, 4); | ||||
|         } | ||||
| 
 | ||||
|         boot_info.cmdline = high + 4096; | ||||
|         if (kernel_cmdline && strlen(kernel_cmdline)) { | ||||
|             pstrcpy_targphys("cmdline", boot_info.cmdline, 256, kernel_cmdline); | ||||
| @ -158,6 +193,8 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base, | ||||
|         /* Provide a device-tree.  */ | ||||
|         boot_info.fdt = boot_info.cmdline + 4096; | ||||
|         microblaze_load_dtb(boot_info.fdt, ram_size, | ||||
|                             boot_info.initrd_start, | ||||
|                             boot_info.initrd_end, | ||||
|                             kernel_cmdline, | ||||
|                             dtb_filename); | ||||
|     } | ||||
|  | ||||
| @ -4,7 +4,9 @@ | ||||
| #include "hw/hw.h" | ||||
| 
 | ||||
| void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base, | ||||
|                             uint32_t ramsize, const char *dtb_filename, | ||||
|                             uint32_t ramsize, | ||||
|                             const char *initrd_filename, | ||||
|                             const char *dtb_filename, | ||||
|                             void (*machine_cpu_reset)(MicroBlazeCPU *)); | ||||
| 
 | ||||
| #endif /* __MICROBLAZE_BOOT __ */ | ||||
|  | ||||
| @ -177,6 +177,7 @@ petalogix_ml605_init(QEMUMachineInitArgs *args) | ||||
|     } | ||||
| 
 | ||||
|     microblaze_load_kernel(cpu, ddr_base, ram_size, | ||||
|                            args->initrd_filename, | ||||
|                            BINARY_DEVICE_TREE_FILE, | ||||
|                            machine_cpu_reset); | ||||
| 
 | ||||
|  | ||||
| @ -108,7 +108,9 @@ petalogix_s3adsp1800_init(QEMUMachineInitArgs *args) | ||||
|     xilinx_ethlite_create(&nd_table[0], ETHLITE_BASEADDR, irq[1], 0, 0); | ||||
| 
 | ||||
|     microblaze_load_kernel(cpu, ddr_base, ram_size, | ||||
|                            BINARY_DEVICE_TREE_FILE, machine_cpu_reset); | ||||
|                            args->initrd_filename, | ||||
|                            BINARY_DEVICE_TREE_FILE, | ||||
|                            machine_cpu_reset); | ||||
| } | ||||
| 
 | ||||
| static QEMUMachine petalogix_s3adsp1800_machine = { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Edgar E. Iglesias
						Edgar E. Iglesias