Commit f3d6b95e835ba12e9cfdca76124897122c47cd1b
1 parent
5adb4839
ARM reabbot support (orginal patch by Aurelien Jarno).
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2476 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
4 changed files
with
57 additions
and
23 deletions
hw/arm_boot.c
| @@ -24,6 +24,17 @@ static uint32_t bootloader[] = { | @@ -24,6 +24,17 @@ static uint32_t bootloader[] = { | ||
| 24 | 0 /* Kernel entry point. Set by integratorcp_init. */ | 24 | 0 /* Kernel entry point. Set by integratorcp_init. */ |
| 25 | }; | 25 | }; |
| 26 | 26 | ||
| 27 | +static void main_cpu_reset(void *opaque) | ||
| 28 | +{ | ||
| 29 | + CPUState *env = opaque; | ||
| 30 | + | ||
| 31 | + cpu_reset(env); | ||
| 32 | + if (env->kernel_filename) | ||
| 33 | + arm_load_kernel(env, env->ram_size, env->kernel_filename, | ||
| 34 | + env->kernel_cmdline, env->initrd_filename, | ||
| 35 | + env->board_id); | ||
| 36 | +} | ||
| 37 | + | ||
| 27 | static void set_kernel_args(uint32_t ram_size, int initrd_size, | 38 | static void set_kernel_args(uint32_t ram_size, int initrd_size, |
| 28 | const char *kernel_cmdline) | 39 | const char *kernel_cmdline) |
| 29 | { | 40 | { |
| @@ -81,6 +92,14 @@ void arm_load_kernel(CPUState *env, int ram_size, const char *kernel_filename, | @@ -81,6 +92,14 @@ void arm_load_kernel(CPUState *env, int ram_size, const char *kernel_filename, | ||
| 81 | exit(1); | 92 | exit(1); |
| 82 | } | 93 | } |
| 83 | 94 | ||
| 95 | + if (!env->kernel_filename) { | ||
| 96 | + env->ram_size = ram_size; | ||
| 97 | + env->kernel_filename = kernel_filename; | ||
| 98 | + env->kernel_cmdline = kernel_cmdline; | ||
| 99 | + env->initrd_filename = initrd_filename; | ||
| 100 | + env->board_id = board_id; | ||
| 101 | + qemu_register_reset(main_cpu_reset, env); | ||
| 102 | + } | ||
| 84 | /* Assume that raw images are linux kernels, and ELF images are not. */ | 103 | /* Assume that raw images are linux kernels, and ELF images are not. */ |
| 85 | kernel_size = load_elf(kernel_filename, 0, &elf_entry); | 104 | kernel_size = load_elf(kernel_filename, 0, &elf_entry); |
| 86 | entry = elf_entry; | 105 | entry = elf_entry; |
hw/arm_sysctl.c
| @@ -149,7 +149,7 @@ static void arm_sysctl_write(void *opaque, target_phys_addr_t offset, | @@ -149,7 +149,7 @@ static void arm_sysctl_write(void *opaque, target_phys_addr_t offset, | ||
| 149 | if (s->lockval == LOCK_VALUE) { | 149 | if (s->lockval == LOCK_VALUE) { |
| 150 | s->resetlevel = val; | 150 | s->resetlevel = val; |
| 151 | if (val & 0x100) | 151 | if (val & 0x100) |
| 152 | - cpu_abort(cpu_single_env, "Board reset\n"); | 152 | + qemu_system_reset_request (); |
| 153 | } | 153 | } |
| 154 | break; | 154 | break; |
| 155 | case 0x44: /* PCICTL */ | 155 | case 0x44: /* PCICTL */ |
target-arm/cpu.h
| @@ -122,6 +122,12 @@ typedef struct CPUARMState { | @@ -122,6 +122,12 @@ typedef struct CPUARMState { | ||
| 122 | 122 | ||
| 123 | CPU_COMMON | 123 | CPU_COMMON |
| 124 | 124 | ||
| 125 | + /* These fields after the common ones so thes are preserved on reset. */ | ||
| 126 | + int ram_size; | ||
| 127 | + const char *kernel_filename; | ||
| 128 | + const char *kernel_cmdline; | ||
| 129 | + const char *initrd_filename; | ||
| 130 | + int board_id; | ||
| 125 | } CPUARMState; | 131 | } CPUARMState; |
| 126 | 132 | ||
| 127 | CPUARMState *cpu_arm_init(void); | 133 | CPUARMState *cpu_arm_init(void); |
target-arm/helper.c
| @@ -5,8 +5,37 @@ | @@ -5,8 +5,37 @@ | ||
| 5 | #include "cpu.h" | 5 | #include "cpu.h" |
| 6 | #include "exec-all.h" | 6 | #include "exec-all.h" |
| 7 | 7 | ||
| 8 | +static inline void set_feature(CPUARMState *env, int feature) | ||
| 9 | +{ | ||
| 10 | + env->features |= 1u << feature; | ||
| 11 | +} | ||
| 12 | + | ||
| 13 | +static void cpu_reset_model_id(CPUARMState *env, uint32_t id) | ||
| 14 | +{ | ||
| 15 | + env->cp15.c0_cpuid = id; | ||
| 16 | + switch (id) { | ||
| 17 | + case ARM_CPUID_ARM926: | ||
| 18 | + set_feature(env, ARM_FEATURE_VFP); | ||
| 19 | + env->vfp.xregs[ARM_VFP_FPSID] = 0x41011090; | ||
| 20 | + break; | ||
| 21 | + case ARM_CPUID_ARM1026: | ||
| 22 | + set_feature(env, ARM_FEATURE_VFP); | ||
| 23 | + set_feature(env, ARM_FEATURE_AUXCR); | ||
| 24 | + env->vfp.xregs[ARM_VFP_FPSID] = 0x410110a0; | ||
| 25 | + break; | ||
| 26 | + default: | ||
| 27 | + cpu_abort(env, "Bad CPU ID: %x\n", id); | ||
| 28 | + break; | ||
| 29 | + } | ||
| 30 | +} | ||
| 31 | + | ||
| 8 | void cpu_reset(CPUARMState *env) | 32 | void cpu_reset(CPUARMState *env) |
| 9 | { | 33 | { |
| 34 | + uint32_t id; | ||
| 35 | + id = env->cp15.c0_cpuid; | ||
| 36 | + memset(env, 0, offsetof(CPUARMState, breakpoints)); | ||
| 37 | + if (id) | ||
| 38 | + cpu_reset_model_id(env, id); | ||
| 10 | #if defined (CONFIG_USER_ONLY) | 39 | #if defined (CONFIG_USER_ONLY) |
| 11 | env->uncached_cpsr = ARM_CPU_MODE_USR; | 40 | env->uncached_cpsr = ARM_CPU_MODE_USR; |
| 12 | env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30; | 41 | env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30; |
| @@ -16,6 +45,7 @@ void cpu_reset(CPUARMState *env) | @@ -16,6 +45,7 @@ void cpu_reset(CPUARMState *env) | ||
| 16 | env->vfp.xregs[ARM_VFP_FPEXC] = 0; | 45 | env->vfp.xregs[ARM_VFP_FPEXC] = 0; |
| 17 | #endif | 46 | #endif |
| 18 | env->regs[15] = 0; | 47 | env->regs[15] = 0; |
| 48 | + tlb_flush(env, 1); | ||
| 19 | } | 49 | } |
| 20 | 50 | ||
| 21 | CPUARMState *cpu_arm_init(void) | 51 | CPUARMState *cpu_arm_init(void) |
| @@ -27,15 +57,9 @@ CPUARMState *cpu_arm_init(void) | @@ -27,15 +57,9 @@ CPUARMState *cpu_arm_init(void) | ||
| 27 | return NULL; | 57 | return NULL; |
| 28 | cpu_exec_init(env); | 58 | cpu_exec_init(env); |
| 29 | cpu_reset(env); | 59 | cpu_reset(env); |
| 30 | - tlb_flush(env, 1); | ||
| 31 | return env; | 60 | return env; |
| 32 | } | 61 | } |
| 33 | 62 | ||
| 34 | -static inline void set_feature(CPUARMState *env, int feature) | ||
| 35 | -{ | ||
| 36 | - env->features |= 1u << feature; | ||
| 37 | -} | ||
| 38 | - | ||
| 39 | struct arm_cpu_t { | 63 | struct arm_cpu_t { |
| 40 | uint32_t id; | 64 | uint32_t id; |
| 41 | const char *name; | 65 | const char *name; |
| @@ -74,22 +98,7 @@ void cpu_arm_set_model(CPUARMState *env, const char *name) | @@ -74,22 +98,7 @@ void cpu_arm_set_model(CPUARMState *env, const char *name) | ||
| 74 | cpu_abort(env, "Unknown CPU '%s'", name); | 98 | cpu_abort(env, "Unknown CPU '%s'", name); |
| 75 | return; | 99 | return; |
| 76 | } | 100 | } |
| 77 | - | ||
| 78 | - env->cp15.c0_cpuid = id; | ||
| 79 | - switch (id) { | ||
| 80 | - case ARM_CPUID_ARM926: | ||
| 81 | - set_feature(env, ARM_FEATURE_VFP); | ||
| 82 | - env->vfp.xregs[ARM_VFP_FPSID] = 0x41011090; | ||
| 83 | - break; | ||
| 84 | - case ARM_CPUID_ARM1026: | ||
| 85 | - set_feature(env, ARM_FEATURE_VFP); | ||
| 86 | - set_feature(env, ARM_FEATURE_AUXCR); | ||
| 87 | - env->vfp.xregs[ARM_VFP_FPSID] = 0x410110a0; | ||
| 88 | - break; | ||
| 89 | - default: | ||
| 90 | - cpu_abort(env, "Bad CPU ID: %x\n", id); | ||
| 91 | - break; | ||
| 92 | - } | 101 | + cpu_reset_model_id(env, id); |
| 93 | } | 102 | } |
| 94 | 103 | ||
| 95 | void cpu_arm_close(CPUARMState *env) | 104 | void cpu_arm_close(CPUARMState *env) |