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:
		
							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)) { | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Lars Munch
						Lars Munch