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/option.h"
 | 
				
			||||||
#include "qemu/config-file.h"
 | 
					#include "qemu/config-file.h"
 | 
				
			||||||
 | 
					#include "qemu/error-report.h"
 | 
				
			||||||
#include "qemu-common.h"
 | 
					#include "qemu-common.h"
 | 
				
			||||||
#include "sysemu/device_tree.h"
 | 
					#include "sysemu/device_tree.h"
 | 
				
			||||||
#include "sysemu/sysemu.h"
 | 
					#include "sysemu/sysemu.h"
 | 
				
			||||||
@ -39,6 +40,8 @@ static struct
 | 
				
			|||||||
    void (*machine_cpu_reset)(MicroBlazeCPU *);
 | 
					    void (*machine_cpu_reset)(MicroBlazeCPU *);
 | 
				
			||||||
    uint32_t bootstrap_pc;
 | 
					    uint32_t bootstrap_pc;
 | 
				
			||||||
    uint32_t cmdline;
 | 
					    uint32_t cmdline;
 | 
				
			||||||
 | 
					    uint32_t initrd_start;
 | 
				
			||||||
 | 
					    uint32_t initrd_end;
 | 
				
			||||||
    uint32_t fdt;
 | 
					    uint32_t fdt;
 | 
				
			||||||
} boot_info;
 | 
					} boot_info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -49,6 +52,7 @@ static void main_cpu_reset(void *opaque)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    cpu_reset(CPU(cpu));
 | 
					    cpu_reset(CPU(cpu));
 | 
				
			||||||
    env->regs[5] = boot_info.cmdline;
 | 
					    env->regs[5] = boot_info.cmdline;
 | 
				
			||||||
 | 
					    env->regs[6] = boot_info.initrd_start;
 | 
				
			||||||
    env->regs[7] = boot_info.fdt;
 | 
					    env->regs[7] = boot_info.fdt;
 | 
				
			||||||
    env->sregs[SR_PC] = boot_info.bootstrap_pc;
 | 
					    env->sregs[SR_PC] = boot_info.bootstrap_pc;
 | 
				
			||||||
    if (boot_info.machine_cpu_reset) {
 | 
					    if (boot_info.machine_cpu_reset) {
 | 
				
			||||||
@ -58,6 +62,8 @@ static void main_cpu_reset(void *opaque)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static int microblaze_load_dtb(hwaddr addr,
 | 
					static int microblaze_load_dtb(hwaddr addr,
 | 
				
			||||||
                               uint32_t ramsize,
 | 
					                               uint32_t ramsize,
 | 
				
			||||||
 | 
					                               uint32_t initrd_start,
 | 
				
			||||||
 | 
					                               uint32_t initrd_end,
 | 
				
			||||||
                               const char *kernel_cmdline,
 | 
					                               const char *kernel_cmdline,
 | 
				
			||||||
                               const char *dtb_filename)
 | 
					                               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);
 | 
					    cpu_physical_memory_write(addr, fdt, fdt_size);
 | 
				
			||||||
    return 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,
 | 
					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 *))
 | 
					                            void (*machine_cpu_reset)(MicroBlazeCPU *))
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    QemuOpts *machine_opts;
 | 
					    QemuOpts *machine_opts;
 | 
				
			||||||
@ -151,6 +167,25 @@ void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
 | 
				
			|||||||
            high = (ddr_base + kernel_size + 3) & ~3;
 | 
					            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;
 | 
					        boot_info.cmdline = high + 4096;
 | 
				
			||||||
        if (kernel_cmdline && strlen(kernel_cmdline)) {
 | 
					        if (kernel_cmdline && strlen(kernel_cmdline)) {
 | 
				
			||||||
            pstrcpy_targphys("cmdline", boot_info.cmdline, 256, 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.  */
 | 
					        /* Provide a device-tree.  */
 | 
				
			||||||
        boot_info.fdt = boot_info.cmdline + 4096;
 | 
					        boot_info.fdt = boot_info.cmdline + 4096;
 | 
				
			||||||
        microblaze_load_dtb(boot_info.fdt, ram_size,
 | 
					        microblaze_load_dtb(boot_info.fdt, ram_size,
 | 
				
			||||||
 | 
					                            boot_info.initrd_start,
 | 
				
			||||||
 | 
					                            boot_info.initrd_end,
 | 
				
			||||||
                            kernel_cmdline,
 | 
					                            kernel_cmdline,
 | 
				
			||||||
                            dtb_filename);
 | 
					                            dtb_filename);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,9 @@
 | 
				
			|||||||
#include "hw/hw.h"
 | 
					#include "hw/hw.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void microblaze_load_kernel(MicroBlazeCPU *cpu, hwaddr ddr_base,
 | 
					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 *));
 | 
					                            void (*machine_cpu_reset)(MicroBlazeCPU *));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __MICROBLAZE_BOOT __ */
 | 
					#endif /* __MICROBLAZE_BOOT __ */
 | 
				
			||||||
 | 
				
			|||||||
@ -177,6 +177,7 @@ petalogix_ml605_init(QEMUMachineInitArgs *args)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    microblaze_load_kernel(cpu, ddr_base, ram_size,
 | 
					    microblaze_load_kernel(cpu, ddr_base, ram_size,
 | 
				
			||||||
 | 
					                           args->initrd_filename,
 | 
				
			||||||
                           BINARY_DEVICE_TREE_FILE,
 | 
					                           BINARY_DEVICE_TREE_FILE,
 | 
				
			||||||
                           machine_cpu_reset);
 | 
					                           machine_cpu_reset);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -108,7 +108,9 @@ petalogix_s3adsp1800_init(QEMUMachineInitArgs *args)
 | 
				
			|||||||
    xilinx_ethlite_create(&nd_table[0], ETHLITE_BASEADDR, irq[1], 0, 0);
 | 
					    xilinx_ethlite_create(&nd_table[0], ETHLITE_BASEADDR, irq[1], 0, 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    microblaze_load_kernel(cpu, ddr_base, ram_size,
 | 
					    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 = {
 | 
					static QEMUMachine petalogix_s3adsp1800_machine = {
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user