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 | 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 | 38 | static void set_kernel_args(uint32_t ram_size, int initrd_size, |
| 28 | 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 | 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 | 103 | /* Assume that raw images are linux kernels, and ELF images are not. */ |
| 85 | 104 | kernel_size = load_elf(kernel_filename, 0, &elf_entry); |
| 86 | 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 | 149 | if (s->lockval == LOCK_VALUE) { |
| 150 | 150 | s->resetlevel = val; |
| 151 | 151 | if (val & 0x100) |
| 152 | - cpu_abort(cpu_single_env, "Board reset\n"); | |
| 152 | + qemu_system_reset_request (); | |
| 153 | 153 | } |
| 154 | 154 | break; |
| 155 | 155 | case 0x44: /* PCICTL */ | ... | ... |
target-arm/cpu.h
| ... | ... | @@ -122,6 +122,12 @@ typedef struct CPUARMState { |
| 122 | 122 | |
| 123 | 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 | 131 | } CPUARMState; |
| 126 | 132 | |
| 127 | 133 | CPUARMState *cpu_arm_init(void); | ... | ... |
target-arm/helper.c
| ... | ... | @@ -5,8 +5,37 @@ |
| 5 | 5 | #include "cpu.h" |
| 6 | 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 | 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 | 39 | #if defined (CONFIG_USER_ONLY) |
| 11 | 40 | env->uncached_cpsr = ARM_CPU_MODE_USR; |
| 12 | 41 | env->vfp.xregs[ARM_VFP_FPEXC] = 1 << 30; |
| ... | ... | @@ -16,6 +45,7 @@ void cpu_reset(CPUARMState *env) |
| 16 | 45 | env->vfp.xregs[ARM_VFP_FPEXC] = 0; |
| 17 | 46 | #endif |
| 18 | 47 | env->regs[15] = 0; |
| 48 | + tlb_flush(env, 1); | |
| 19 | 49 | } |
| 20 | 50 | |
| 21 | 51 | CPUARMState *cpu_arm_init(void) |
| ... | ... | @@ -27,15 +57,9 @@ CPUARMState *cpu_arm_init(void) |
| 27 | 57 | return NULL; |
| 28 | 58 | cpu_exec_init(env); |
| 29 | 59 | cpu_reset(env); |
| 30 | - tlb_flush(env, 1); | |
| 31 | 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 | 63 | struct arm_cpu_t { |
| 40 | 64 | uint32_t id; |
| 41 | 65 | const char *name; |
| ... | ... | @@ -74,22 +98,7 @@ void cpu_arm_set_model(CPUARMState *env, const char *name) |
| 74 | 98 | cpu_abort(env, "Unknown CPU '%s'", name); |
| 75 | 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 | 104 | void cpu_arm_close(CPUARMState *env) | ... | ... |