target-sh4: fix reset on r2d
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
fd4bab102c
commit
4f6493ff8a
21
hw/r2d.c
21
hw/r2d.c
@ -208,6 +208,20 @@ static int r2d_pci_map_irq(PCIDevice *d, int irq_num)
|
|||||||
return intx[d->devfn >> 3];
|
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__))
|
static struct __attribute__((__packed__))
|
||||||
{
|
{
|
||||||
int mount_root_rdonly;
|
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)
|
const char *initrd_filename, const char *cpu_model)
|
||||||
{
|
{
|
||||||
CPUState *env;
|
CPUState *env;
|
||||||
|
ResetData *reset_info;
|
||||||
struct SH7750State *s;
|
struct SH7750State *s;
|
||||||
ram_addr_t sdram_addr;
|
ram_addr_t sdram_addr;
|
||||||
qemu_irq *irq;
|
qemu_irq *irq;
|
||||||
@ -242,6 +257,10 @@ static void r2d_init(ram_addr_t ram_size,
|
|||||||
fprintf(stderr, "Unable to find CPU definition\n");
|
fprintf(stderr, "Unable to find CPU definition\n");
|
||||||
exit(1);
|
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 */
|
/* Allocate memory space */
|
||||||
sdram_addr = qemu_ram_alloc(NULL, "r2d.sdram", SDRAM_SIZE);
|
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 */
|
/* initialization which should be done by firmware */
|
||||||
stl_phys(SH7750_BCR1, 1<<3); /* cs3 SDRAM */
|
stl_phys(SH7750_BCR1, 1<<3); /* cs3 SDRAM */
|
||||||
stw_phys(SH7750_BCR2, 3<<(3*2)); /* cs3 32bit */
|
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) {
|
if (initrd_filename) {
|
||||||
|
@ -136,8 +136,6 @@ typedef struct memory_content {
|
|||||||
} memory_content;
|
} memory_content;
|
||||||
|
|
||||||
typedef struct CPUSH4State {
|
typedef struct CPUSH4State {
|
||||||
int id; /* CPU model */
|
|
||||||
|
|
||||||
uint32_t flags; /* general execution flags */
|
uint32_t flags; /* general execution flags */
|
||||||
uint32_t gregs[24]; /* general registers */
|
uint32_t gregs[24]; /* general registers */
|
||||||
float32 fregs[32]; /* floating point registers */
|
float32 fregs[32]; /* floating point registers */
|
||||||
@ -173,14 +171,18 @@ typedef struct CPUSH4State {
|
|||||||
uint32_t expevt; /* exception event register */
|
uint32_t expevt; /* exception event register */
|
||||||
uint32_t intevt; /* interrupt 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 pvr; /* Processor Version Register */
|
||||||
uint32_t prr; /* Processor Revision Register */
|
uint32_t prr; /* Processor Revision Register */
|
||||||
uint32_t cvr; /* Cache Version 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;
|
void *intc_handle;
|
||||||
int intr_at_halt; /* SR_BL ignored during sleep */
|
int intr_at_halt; /* SR_BL ignored during sleep */
|
||||||
memory_content *movcal_backup;
|
memory_content *movcal_backup;
|
||||||
|
@ -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)) {
|
if (qemu_loglevel_mask(CPU_LOG_RESET)) {
|
||||||
qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
|
qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
|
||||||
log_cpu_state(env, 0);
|
log_cpu_state(env, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_USER_ONLY)
|
memset(env, 0, offsetof(CPUSH4State, breakpoints));
|
||||||
env->sr = 0;
|
tlb_flush(env, 1);
|
||||||
#else
|
|
||||||
env->sr = SR_MD | SR_RB | SR_BL | SR_I3 | SR_I2 | SR_I1 | SR_I0;
|
|
||||||
#endif
|
|
||||||
env->vbr = 0;
|
|
||||||
env->pc = 0xA0000000;
|
env->pc = 0xA0000000;
|
||||||
#if defined(CONFIG_USER_ONLY)
|
#if defined(CONFIG_USER_ONLY)
|
||||||
env->fpscr = FPSCR_PR; /* value for userspace according to the kernel */
|
env->fpscr = FPSCR_PR; /* value for userspace according to the kernel */
|
||||||
set_float_rounding_mode(float_round_nearest_even, &env->fp_status); /* ?! */
|
set_float_rounding_mode(float_round_nearest_even, &env->fp_status); /* ?! */
|
||||||
#else
|
#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 */
|
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_float_rounding_mode(float_round_to_zero, &env->fp_status);
|
||||||
set_flush_to_zero(1, &env->fp_status);
|
set_flush_to_zero(1, &env->fp_status);
|
||||||
#endif
|
#endif
|
||||||
set_default_nan_mode(1, &env->fp_status);
|
set_default_nan_mode(1, &env->fp_status);
|
||||||
env->mmucr = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
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);
|
(*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->pvr = def->pvr;
|
||||||
env->prr = def->prr;
|
env->prr = def->prr;
|
||||||
@ -289,9 +286,8 @@ CPUSH4State *cpu_sh4_init(const char *cpu_model)
|
|||||||
env->movcal_backup_tail = &(env->movcal_backup);
|
env->movcal_backup_tail = &(env->movcal_backup);
|
||||||
sh4_translate_init();
|
sh4_translate_init();
|
||||||
env->cpu_model_str = cpu_model;
|
env->cpu_model_str = cpu_model;
|
||||||
cpu_sh4_reset(env);
|
cpu_reset(env);
|
||||||
cpu_sh4_register(env, def);
|
cpu_register(env, def);
|
||||||
tlb_flush(env, 1);
|
|
||||||
qemu_init_vcpu(env);
|
qemu_init_vcpu(env);
|
||||||
return env;
|
return env;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user