diff options
author | Aurelien Jarno <aurelien@aurel32.net> | 2011-01-14 20:39:18 +0100 |
---|---|---|
committer | Aurelien Jarno <aurelien@aurel32.net> | 2011-01-14 20:39:18 +0100 |
commit | 4f6493ff8a73bbb24ad81b080cc256c1c896b7fb (patch) | |
tree | 07bd6488f47f13e7be449b508727e4de05d0b9df | |
parent | fd4bab102c14171f8a5a6b04def6434b75a658a2 (diff) |
target-sh4: fix reset on r2d
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
-rw-r--r-- | hw/r2d.c | 21 | ||||
-rw-r--r-- | target-sh4/cpu.h | 14 | ||||
-rw-r--r-- | target-sh4/translate.c | 20 |
3 files changed, 36 insertions, 19 deletions
@@ -208,6 +208,20 @@ static int r2d_pci_map_irq(PCIDevice *d, int irq_num) return intx[d->devfn >> 3]; } +typedef struct ResetData { + CPUState *env; + uint32_t vector; +} ResetData; + +static void main_cpu_reset(void *opaque) +{ + ResetData *s = (ResetData *)opaque; + CPUState *env = s->env; + + cpu_reset(env); + env->pc = s->vector; +} + static struct __attribute__((__packed__)) { int mount_root_rdonly; @@ -228,6 +242,7 @@ static void r2d_init(ram_addr_t ram_size, const char *initrd_filename, const char *cpu_model) { CPUState *env; + ResetData *reset_info; struct SH7750State *s; ram_addr_t sdram_addr; qemu_irq *irq; @@ -242,6 +257,10 @@ static void r2d_init(ram_addr_t ram_size, fprintf(stderr, "Unable to find CPU definition\n"); exit(1); } + reset_info = qemu_mallocz(sizeof(ResetData)); + reset_info->env = env; + reset_info->vector = env->pc; + qemu_register_reset(main_cpu_reset, reset_info); /* Allocate memory space */ sdram_addr = qemu_ram_alloc(NULL, "r2d.sdram", SDRAM_SIZE); @@ -290,7 +309,7 @@ static void r2d_init(ram_addr_t ram_size, /* initialization which should be done by firmware */ stl_phys(SH7750_BCR1, 1<<3); /* cs3 SDRAM */ stw_phys(SH7750_BCR2, 3<<(3*2)); /* cs3 32bit */ - env->pc = (SDRAM_BASE + LINUX_LOAD_OFFSET) | 0xa0000000; /* Start from P2 area */ + reset_info->vector = (SDRAM_BASE + LINUX_LOAD_OFFSET) | 0xa0000000; /* Start from P2 area */ } if (initrd_filename) { diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h index fe33b8afc0..95df6d2a75 100644 --- a/target-sh4/cpu.h +++ b/target-sh4/cpu.h @@ -136,8 +136,6 @@ typedef struct memory_content { } memory_content; typedef struct CPUSH4State { - int id; /* CPU model */ - uint32_t flags; /* general execution flags */ uint32_t gregs[24]; /* general registers */ float32 fregs[32]; /* floating point registers */ @@ -173,14 +171,18 @@ typedef struct CPUSH4State { uint32_t expevt; /* exception event register */ uint32_t intevt; /* interrupt event register */ + tlb_t itlb[ITLB_SIZE]; /* instruction translation table */ + tlb_t utlb[UTLB_SIZE]; /* unified translation table */ + + uint32_t ldst; + + CPU_COMMON + + int id; /* CPU model */ uint32_t pvr; /* Processor Version Register */ uint32_t prr; /* Processor Revision Register */ uint32_t cvr; /* Cache Version Register */ - uint32_t ldst; - - CPU_COMMON tlb_t utlb[UTLB_SIZE]; /* unified translation table */ - tlb_t itlb[ITLB_SIZE]; /* instruction translation table */ void *intc_handle; int intr_at_halt; /* SR_BL ignored during sleep */ memory_content *movcal_backup; diff --git a/target-sh4/translate.c b/target-sh4/translate.c index 69d507d864..04bc94a0b1 100644 --- a/target-sh4/translate.c +++ b/target-sh4/translate.c @@ -185,30 +185,27 @@ void cpu_dump_state(CPUState * env, FILE * f, } } -static void cpu_sh4_reset(CPUSH4State * env) +void cpu_reset(CPUSH4State * env) { if (qemu_loglevel_mask(CPU_LOG_RESET)) { qemu_log("CPU Reset (CPU %d)\n", env->cpu_index); log_cpu_state(env, 0); } -#if defined(CONFIG_USER_ONLY) - env->sr = 0; -#else - env->sr = SR_MD | SR_RB | SR_BL | SR_I3 | SR_I2 | SR_I1 | SR_I0; -#endif - env->vbr = 0; + memset(env, 0, offsetof(CPUSH4State, breakpoints)); + tlb_flush(env, 1); + env->pc = 0xA0000000; #if defined(CONFIG_USER_ONLY) env->fpscr = FPSCR_PR; /* value for userspace according to the kernel */ set_float_rounding_mode(float_round_nearest_even, &env->fp_status); /* ?! */ #else + env->sr = SR_MD | SR_RB | SR_BL | SR_I3 | SR_I2 | SR_I1 | SR_I0; env->fpscr = FPSCR_DN | FPSCR_RM_ZERO; /* CPU reset value according to SH4 manual */ set_float_rounding_mode(float_round_to_zero, &env->fp_status); set_flush_to_zero(1, &env->fp_status); #endif set_default_nan_mode(1, &env->fp_status); - env->mmucr = 0; } typedef struct { @@ -267,7 +264,7 @@ void sh4_cpu_list(FILE *f, fprintf_function cpu_fprintf) (*cpu_fprintf)(f, "%s\n", sh4_defs[i].name); } -static void cpu_sh4_register(CPUSH4State *env, const sh4_def_t *def) +static void cpu_register(CPUSH4State *env, const sh4_def_t *def) { env->pvr = def->pvr; env->prr = def->prr; @@ -289,9 +286,8 @@ CPUSH4State *cpu_sh4_init(const char *cpu_model) env->movcal_backup_tail = &(env->movcal_backup); sh4_translate_init(); env->cpu_model_str = cpu_model; - cpu_sh4_reset(env); - cpu_sh4_register(env, def); - tlb_flush(env, 1); + cpu_reset(env); + cpu_register(env, def); qemu_init_vcpu(env); return env; } |