arm: fix arm kernel boot for non zero start addr
Booting an arm kernel has been broken a while when booting from non zero start address. This is due to the order of events: board init loads the kernel and sets register 15 to the start address and then qemu_system_reset reset the cpu making register 15 zero again. This patch fixes the usage of the register 15 start address trick in combination with arm_load_kernel. Signed-off-by: Lars Munch <lars@segv.dk> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
		
				
					committed by
					
						
						Aurelien Jarno
					
				
			
			
				
	
			
			
			
						parent
						
							0f89cc7b6c
						
					
				
				
					commit
					e03c22a98c
				
			@@ -187,6 +187,7 @@ static void main_cpu_reset(void *opaque)
 | 
			
		||||
            env->regs[15] = info->entry & 0xfffffffe;
 | 
			
		||||
            env->thumb = info->entry & 1;
 | 
			
		||||
        } else {
 | 
			
		||||
            env->regs[15] = info->loader_start;
 | 
			
		||||
            if (old_param) {
 | 
			
		||||
                set_kernel_args_old(info, info->initrd_size,
 | 
			
		||||
                                    info->loader_start);
 | 
			
		||||
 
 | 
			
		||||
@@ -74,8 +74,6 @@ static void connex_init(ram_addr_t ram_size,
 | 
			
		||||
        exit(1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cpu->env->regs[15] = 0x00000000;
 | 
			
		||||
 | 
			
		||||
    /* Interrupt line of NIC is connected to GPIO line 36 */
 | 
			
		||||
    smc91c111_init(&nd_table[0], 0x04000300,
 | 
			
		||||
                    pxa2xx_gpio_in_get(cpu->gpio)[36]);
 | 
			
		||||
@@ -114,8 +112,6 @@ static void verdex_init(ram_addr_t ram_size,
 | 
			
		||||
        exit(1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    cpu->env->regs[15] = 0x00000000;
 | 
			
		||||
 | 
			
		||||
    /* Interrupt line of NIC is connected to GPIO line 99 */
 | 
			
		||||
    smc91c111_init(&nd_table[0], 0x04000300,
 | 
			
		||||
                    pxa2xx_gpio_in_get(cpu->gpio)[99]);
 | 
			
		||||
 
 | 
			
		||||
@@ -89,9 +89,6 @@ static void mainstone_common_init(ram_addr_t ram_size,
 | 
			
		||||
    cpu_register_physical_memory(0, MAINSTONE_ROM,
 | 
			
		||||
                    qemu_ram_alloc(MAINSTONE_ROM) | IO_MEM_ROM);
 | 
			
		||||
 | 
			
		||||
    /* Setup initial (reset) machine state */
 | 
			
		||||
    cpu->env->regs[15] = mainstone_binfo.loader_start;
 | 
			
		||||
 | 
			
		||||
#ifdef TARGET_WORDS_BIGENDIAN
 | 
			
		||||
    be = 1;
 | 
			
		||||
#else
 | 
			
		||||
 
 | 
			
		||||
@@ -1016,7 +1016,6 @@ static void n8x0_boot_init(void *opaque)
 | 
			
		||||
    n800_dss_init(&s->blizzard);
 | 
			
		||||
 | 
			
		||||
    /* CPU setup */
 | 
			
		||||
    s->cpu->env->regs[15] = s->cpu->env->boot_info->loader_start;
 | 
			
		||||
    s->cpu->env->GE = 0x5;
 | 
			
		||||
 | 
			
		||||
    /* If the machine has a slided keyboard, open it */
 | 
			
		||||
@@ -1317,11 +1316,6 @@ static void n8x0_init(ram_addr_t ram_size, const char *boot_device,
 | 
			
		||||
    if (usb_enabled)
 | 
			
		||||
        n8x0_usb_setup(s);
 | 
			
		||||
 | 
			
		||||
    /* Setup initial (reset) machine state */
 | 
			
		||||
 | 
			
		||||
    /* Start at the OneNAND bootloader.  */
 | 
			
		||||
    s->cpu->env->regs[15] = 0;
 | 
			
		||||
 | 
			
		||||
    if (kernel_filename) {
 | 
			
		||||
        /* Or at the linux loader.  */
 | 
			
		||||
        binfo->kernel_filename = kernel_filename;
 | 
			
		||||
@@ -1330,7 +1324,6 @@ static void n8x0_init(ram_addr_t ram_size, const char *boot_device,
 | 
			
		||||
        arm_load_kernel(s->cpu->env, binfo);
 | 
			
		||||
 | 
			
		||||
        qemu_register_reset(n8x0_boot_init, s);
 | 
			
		||||
        n8x0_boot_init(s);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (option_rom[0] && (boot_device[0] == 'n' || !kernel_filename)) {
 | 
			
		||||
 
 | 
			
		||||
@@ -195,15 +195,10 @@ static void sx1_init(ram_addr_t ram_size,
 | 
			
		||||
 | 
			
		||||
    /* Load the kernel.  */
 | 
			
		||||
    if (kernel_filename) {
 | 
			
		||||
        /* Start at bootloader.  */
 | 
			
		||||
        cpu->env->regs[15] = sx1_binfo.loader_start;
 | 
			
		||||
 | 
			
		||||
        sx1_binfo.kernel_filename = kernel_filename;
 | 
			
		||||
        sx1_binfo.kernel_cmdline = kernel_cmdline;
 | 
			
		||||
        sx1_binfo.initrd_filename = initrd_filename;
 | 
			
		||||
        arm_load_kernel(cpu->env, &sx1_binfo);
 | 
			
		||||
    } else {
 | 
			
		||||
        cpu->env->regs[15] = 0x00000000;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* TODO: fix next line */
 | 
			
		||||
 
 | 
			
		||||
@@ -243,7 +243,6 @@ static void palmte_init(ram_addr_t ram_size,
 | 
			
		||||
            rom_size = load_image_targphys(option_rom[0], OMAP_CS0_BASE,
 | 
			
		||||
                                           flash_size);
 | 
			
		||||
            rom_loaded = 1;
 | 
			
		||||
            cpu->env->regs[15] = 0x00000000;
 | 
			
		||||
        }
 | 
			
		||||
        if (rom_size < 0) {
 | 
			
		||||
            fprintf(stderr, "%s: error loading '%s'\n",
 | 
			
		||||
@@ -258,9 +257,6 @@ static void palmte_init(ram_addr_t ram_size,
 | 
			
		||||
 | 
			
		||||
    /* Load the kernel.  */
 | 
			
		||||
    if (kernel_filename) {
 | 
			
		||||
        /* Start at bootloader.  */
 | 
			
		||||
        cpu->env->regs[15] = palmte_binfo.loader_start;
 | 
			
		||||
 | 
			
		||||
        palmte_binfo.kernel_filename = kernel_filename;
 | 
			
		||||
        palmte_binfo.kernel_cmdline = kernel_cmdline;
 | 
			
		||||
        palmte_binfo.initrd_filename = initrd_filename;
 | 
			
		||||
 
 | 
			
		||||
@@ -993,9 +993,6 @@ static void spitz_common_init(ram_addr_t ram_size,
 | 
			
		||||
        /* A 4.0 GB microdrive is permanently sitting in CF slot 0.  */
 | 
			
		||||
        spitz_microdrive_attach(cpu, 0);
 | 
			
		||||
 | 
			
		||||
    /* Setup initial (reset) machine state */
 | 
			
		||||
    cpu->env->regs[15] = spitz_binfo.loader_start;
 | 
			
		||||
 | 
			
		||||
    spitz_binfo.kernel_filename = kernel_filename;
 | 
			
		||||
    spitz_binfo.kernel_cmdline = kernel_cmdline;
 | 
			
		||||
    spitz_binfo.initrd_filename = initrd_filename;
 | 
			
		||||
 
 | 
			
		||||
@@ -229,9 +229,6 @@ static void tosa_init(ram_addr_t ram_size,
 | 
			
		||||
 | 
			
		||||
    tosa_tg_init(cpu);
 | 
			
		||||
 | 
			
		||||
    /* Setup initial (reset) machine state */
 | 
			
		||||
    cpu->env->regs[15] = tosa_binfo.loader_start;
 | 
			
		||||
 | 
			
		||||
    tosa_binfo.kernel_filename = kernel_filename;
 | 
			
		||||
    tosa_binfo.kernel_cmdline = kernel_cmdline;
 | 
			
		||||
    tosa_binfo.initrd_filename = initrd_filename;
 | 
			
		||||
 
 | 
			
		||||
@@ -207,7 +207,6 @@ void cpu_reset(CPUARMState *env)
 | 
			
		||||
#else
 | 
			
		||||
    /* SVC mode with interrupts disabled.  */
 | 
			
		||||
    env->uncached_cpsr = ARM_CPU_MODE_SVC | CPSR_A | CPSR_F | CPSR_I;
 | 
			
		||||
    env->regs[15] = 0;
 | 
			
		||||
    /* On ARMv7-M the CPSR_I is the value of the PRIMASK register, and is
 | 
			
		||||
       clear at reset.  Initial SP and PC are loaded from ROM.  */
 | 
			
		||||
    if (IS_M(env)) {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user