target-sh4: fix reset on r2d

Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
Aurelien Jarno 2011-01-14 20:39:18 +01:00
parent fd4bab102c
commit 4f6493ff8a
3 changed files with 36 additions and 19 deletions

View File

@ -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) {

View File

@ -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;

View File

@ -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;
}