2013-08-23 02:57:00 +02:00
|
|
|
/* $Id: s3c2410_arm.c,v 1.7 2008/12/11 12:18:17 ecd Exp $
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#include <unistd.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
#include <cpu.h>
|
|
|
|
|
|
|
|
#include <x49gp.h>
|
|
|
|
#include <s3c2410.h>
|
|
|
|
|
|
|
|
#include "cpu-all.h"
|
|
|
|
|
|
|
|
static int
|
|
|
|
s3c2410_arm_load(x49gp_module_t *module, GKeyFile *key)
|
|
|
|
{
|
|
|
|
struct CPUARMState *env = module->user_data;
|
|
|
|
char name[32];
|
|
|
|
int error = 0;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
#ifdef DEBUG_X49GP_MODULES
|
|
|
|
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
cpu_reset(env);
|
|
|
|
tlb_flush(env, 1);
|
|
|
|
|
2017-10-26 11:41:01 +02:00
|
|
|
for (i = 0; i < (sizeof(env->regs) / sizeof(env->regs[0])); i++) {
|
2013-08-23 02:57:00 +02:00
|
|
|
sprintf(name, "reg-%02u", i);
|
|
|
|
if (x49gp_module_get_u32(module, key, name, 0, &env->regs[i]))
|
|
|
|
error = -EAGAIN;
|
|
|
|
}
|
|
|
|
if (x49gp_module_get_u32(module, key, "cpsr", 0, &env->uncached_cpsr))
|
|
|
|
error = -EAGAIN;
|
|
|
|
if (x49gp_module_get_u32(module, key, "spsr", 0, &env->spsr))
|
|
|
|
error = -EAGAIN;
|
2017-10-26 11:41:01 +02:00
|
|
|
for (i = 0; i < (sizeof(env->banked_spsr) / sizeof(env->banked_spsr[0])); i++) {
|
2013-08-23 02:57:00 +02:00
|
|
|
sprintf(name, "banked-spsr-%02u", i);
|
|
|
|
if (x49gp_module_get_u32(module, key, name, 0, &env->banked_spsr[i]))
|
|
|
|
error = -EAGAIN;
|
2017-10-26 15:52:19 +02:00
|
|
|
}
|
|
|
|
for (i = 0; i < (sizeof(env->banked_r13) / sizeof(env->banked_r13[0])); i++) {
|
2013-08-23 02:57:00 +02:00
|
|
|
sprintf(name, "banked-r13-%02u", i);
|
|
|
|
if (x49gp_module_get_u32(module, key, name, 0, &env->banked_r13[i]))
|
|
|
|
error = -EAGAIN;
|
2017-10-26 15:52:19 +02:00
|
|
|
}
|
|
|
|
for (i = 0; i < (sizeof(env->banked_r14) / sizeof(env->banked_r14[0])); i++) {
|
2013-08-23 02:57:00 +02:00
|
|
|
sprintf(name, "banked-r14-%02u", i);
|
|
|
|
if (x49gp_module_get_u32(module, key, name, 0, &env->banked_r14[i]))
|
|
|
|
error = -EAGAIN;
|
|
|
|
}
|
2017-10-26 11:41:01 +02:00
|
|
|
for (i = 0; i < (sizeof(env->usr_regs) / sizeof(env->usr_regs[0])); i++) {
|
2013-08-23 02:57:00 +02:00
|
|
|
sprintf(name, "reg-usr-%02u", i);
|
|
|
|
if (x49gp_module_get_u32(module, key, name,
|
|
|
|
0, &env->usr_regs[i]))
|
|
|
|
error = -EAGAIN;
|
2017-10-26 15:52:19 +02:00
|
|
|
}
|
|
|
|
for (i = 0; i < (sizeof(env->fiq_regs) / sizeof(env->fiq_regs[0])); i++) {
|
2013-08-23 02:57:00 +02:00
|
|
|
sprintf(name, "reg-fiq-%02u", i);
|
|
|
|
if (x49gp_module_get_u32(module, key, name,
|
|
|
|
0, &env->fiq_regs[i]))
|
|
|
|
error = -EAGAIN;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (x49gp_module_get_u32(module, key, "CF", 0, &env->CF))
|
|
|
|
error = -EAGAIN;
|
|
|
|
if (x49gp_module_get_u32(module, key, "VF", 0, &env->VF))
|
|
|
|
error = -EAGAIN;
|
|
|
|
if (x49gp_module_get_u32(module, key, "NF", 0, &env->NF))
|
|
|
|
error = -EAGAIN;
|
|
|
|
if (x49gp_module_get_u32(module, key, "ZF", 0, &env->ZF))
|
|
|
|
error = -EAGAIN;
|
|
|
|
if (x49gp_module_get_u32(module, key, "QF", 0, &env->QF))
|
|
|
|
error = -EAGAIN;
|
2017-10-26 11:41:01 +02:00
|
|
|
if (x49gp_module_get_u32(module, key, "thumb", 0, &env->thumb))
|
2013-08-23 02:57:00 +02:00
|
|
|
error = -EAGAIN;
|
|
|
|
|
|
|
|
if (x49gp_module_get_u32(module, key, "cp15-c0-cpuid", 0, &env->cp15.c0_cpuid))
|
|
|
|
error = -EAGAIN;
|
|
|
|
if (x49gp_module_get_u32(module, key, "cp15-c1-sys", 0, &env->cp15.c1_sys))
|
|
|
|
error = -EAGAIN;
|
|
|
|
if (x49gp_module_get_u32(module, key, "cp15-c1-coproc", 0, &env->cp15.c1_coproc))
|
|
|
|
error = -EAGAIN;
|
|
|
|
if (x49gp_module_get_u32(module, key, "cp15-c2-base0", 0, &env->cp15.c2_base0))
|
|
|
|
error = -EAGAIN;
|
|
|
|
if (x49gp_module_get_u32(module, key, "cp15-c2-base1", 0, &env->cp15.c2_base1))
|
|
|
|
error = -EAGAIN;
|
|
|
|
if (x49gp_module_get_u32(module, key, "cp15-c2-control", 0, &env->cp15.c2_control))
|
|
|
|
error = -EAGAIN;
|
|
|
|
if (x49gp_module_get_u32(module, key, "cp15-c2-mask", 0, &env->cp15.c2_mask))
|
|
|
|
error = -EAGAIN;
|
|
|
|
if (x49gp_module_get_u32(module, key, "cp15-c2-base-mask", 0, &env->cp15.c2_base_mask))
|
|
|
|
error = -EAGAIN;
|
|
|
|
if (x49gp_module_get_u32(module, key, "cp15-c2-data", 0, &env->cp15.c2_data))
|
|
|
|
error = -EAGAIN;
|
|
|
|
if (x49gp_module_get_u32(module, key, "cp15-c2-insn", 0, &env->cp15.c2_insn))
|
|
|
|
error = -EAGAIN;
|
|
|
|
if (x49gp_module_get_u32(module, key, "cp15-c3", 0, &env->cp15.c3))
|
|
|
|
error = -EAGAIN;
|
|
|
|
if (x49gp_module_get_u32(module, key, "cp15-c5-insn", 0, &env->cp15.c5_insn))
|
|
|
|
error = -EAGAIN;
|
|
|
|
if (x49gp_module_get_u32(module, key, "cp15-c5-data", 0, &env->cp15.c5_data))
|
|
|
|
error = -EAGAIN;
|
|
|
|
if (x49gp_module_get_u32(module, key, "cp15-c6-insn", 0, &env->cp15.c6_insn))
|
|
|
|
error = -EAGAIN;
|
|
|
|
if (x49gp_module_get_u32(module, key, "cp15-c6-data", 0, &env->cp15.c6_data))
|
|
|
|
error = -EAGAIN;
|
|
|
|
if (x49gp_module_get_u32(module, key, "cp15-c9-insn", 0, &env->cp15.c9_insn))
|
|
|
|
error = -EAGAIN;
|
|
|
|
if (x49gp_module_get_u32(module, key, "cp15-c9-data", 0, &env->cp15.c9_data))
|
|
|
|
error = -EAGAIN;
|
|
|
|
if (x49gp_module_get_u32(module, key, "cp15-c13-fcse", 0, &env->cp15.c13_fcse))
|
|
|
|
error = -EAGAIN;
|
|
|
|
if (x49gp_module_get_u32(module, key, "cp15-c13-context", 0, &env->cp15.c13_context))
|
|
|
|
error = -EAGAIN;
|
|
|
|
|
|
|
|
if (x49gp_module_get_u32(module, key, "features", 0, &env->features))
|
|
|
|
error = -EAGAIN;
|
|
|
|
|
|
|
|
if (x49gp_module_get_int(module, key, "exception-index", 0, &env->exception_index))
|
|
|
|
error = -EAGAIN;
|
2017-10-26 11:41:01 +02:00
|
|
|
if (x49gp_module_get_u32(module, key, "interrupt-request", 0, &env->interrupt_request))
|
2013-08-23 02:57:00 +02:00
|
|
|
error = -EAGAIN;
|
2017-10-26 11:41:01 +02:00
|
|
|
if (x49gp_module_get_u32(module, key, "halted", 0, &env->halted))
|
2013-08-23 02:57:00 +02:00
|
|
|
error = -EAGAIN;
|
|
|
|
|
|
|
|
env->exception_index = -1;
|
|
|
|
|
|
|
|
if (0 == error) {
|
|
|
|
if (env->halted)
|
|
|
|
module->x49gp->arm_idle = 1;
|
|
|
|
} else {
|
|
|
|
memset(&env->cp15, 0, sizeof(env->cp15));
|
|
|
|
}
|
|
|
|
|
|
|
|
// s3c2410_arm_dump_state(state);
|
|
|
|
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
s3c2410_arm_save(x49gp_module_t *module, GKeyFile *key)
|
|
|
|
{
|
|
|
|
struct CPUARMState *env = module->user_data;
|
|
|
|
char name[32];
|
|
|
|
int i;
|
|
|
|
|
|
|
|
#ifdef DEBUG_X49GP_MODULES
|
|
|
|
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
|
|
|
#endif
|
|
|
|
|
2017-10-26 11:41:01 +02:00
|
|
|
for (i = 0; i < (sizeof(env->regs) / sizeof(env->regs[0])); i++) {
|
2013-08-23 02:57:00 +02:00
|
|
|
sprintf(name, "reg-%02u", i);
|
|
|
|
x49gp_module_set_u32(module, key, name, env->regs[i]);
|
|
|
|
}
|
|
|
|
x49gp_module_set_u32(module, key, "cpsr", env->uncached_cpsr);
|
|
|
|
x49gp_module_set_u32(module, key, "spsr", env->spsr);
|
2017-10-26 11:41:01 +02:00
|
|
|
for (i = 0; i < (sizeof(env->banked_spsr) / sizeof(env->banked_spsr[0])); i++) {
|
2013-08-23 02:57:00 +02:00
|
|
|
sprintf(name, "banked-spsr-%02u", i);
|
|
|
|
x49gp_module_set_u32(module, key, name, env->banked_spsr[i]);
|
2017-10-26 15:52:19 +02:00
|
|
|
}
|
|
|
|
for (i = 0; i < (sizeof(env->banked_r13) / sizeof(env->banked_r13[0])); i++) {
|
2013-08-23 02:57:00 +02:00
|
|
|
sprintf(name, "banked-r13-%02u", i);
|
|
|
|
x49gp_module_set_u32(module, key, name, env->banked_r13[i]);
|
2017-10-26 15:52:19 +02:00
|
|
|
}
|
|
|
|
for (i = 0; i < (sizeof(env->banked_r14) / sizeof(env->banked_r14[0])); i++) {
|
2013-08-23 02:57:00 +02:00
|
|
|
sprintf(name, "banked-r14-%02u", i);
|
|
|
|
x49gp_module_set_u32(module, key, name, env->banked_r14[i]);
|
|
|
|
}
|
2017-10-26 11:41:01 +02:00
|
|
|
for (i = 0; i < (sizeof(env->usr_regs) / sizeof(env->usr_regs[0])); i++) {
|
2013-08-23 02:57:00 +02:00
|
|
|
sprintf(name, "reg-usr-%02u", i);
|
|
|
|
x49gp_module_set_u32(module, key, name, env->usr_regs[i]);
|
2017-10-26 15:52:19 +02:00
|
|
|
}
|
|
|
|
for (i = 0; i < (sizeof(env->fiq_regs) / sizeof(env->fiq_regs[0])); i++) {
|
2013-08-23 02:57:00 +02:00
|
|
|
sprintf(name, "reg-fiq-%02u", i);
|
|
|
|
x49gp_module_set_u32(module, key, name, env->fiq_regs[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
x49gp_module_set_u32(module, key, "CF", env->CF);
|
|
|
|
x49gp_module_set_u32(module, key, "VF", env->VF);
|
|
|
|
x49gp_module_set_u32(module, key, "NF", env->NF);
|
|
|
|
x49gp_module_set_u32(module, key, "ZF", env->ZF);
|
|
|
|
x49gp_module_set_u32(module, key, "QF", env->QF);
|
|
|
|
x49gp_module_set_int(module, key, "thumb", env->thumb);
|
|
|
|
|
|
|
|
x49gp_module_set_u32(module, key, "cp15-c0-cpuid", env->cp15.c0_cpuid);
|
|
|
|
x49gp_module_set_u32(module, key, "cp15-c1-sys", env->cp15.c1_sys);
|
|
|
|
x49gp_module_set_u32(module, key, "cp15-c1-coproc", env->cp15.c1_coproc);
|
|
|
|
x49gp_module_set_u32(module, key, "cp15-c2-base0", env->cp15.c2_base0);
|
|
|
|
x49gp_module_set_u32(module, key, "cp15-c2-base1", env->cp15.c2_base1);
|
|
|
|
x49gp_module_set_u32(module, key, "cp15-c2-control", env->cp15.c2_control);
|
|
|
|
x49gp_module_set_u32(module, key, "cp15-c2-mask", env->cp15.c2_mask);
|
|
|
|
x49gp_module_set_u32(module, key, "cp15-c2-base-mask", env->cp15.c2_base_mask);
|
|
|
|
x49gp_module_set_u32(module, key, "cp15-c2-data", env->cp15.c2_data);
|
|
|
|
x49gp_module_set_u32(module, key, "cp15-c2-insn", env->cp15.c2_insn);
|
|
|
|
x49gp_module_set_u32(module, key, "cp15-c3", env->cp15.c3);
|
|
|
|
x49gp_module_set_u32(module, key, "cp15-c5-insn", env->cp15.c5_insn);
|
|
|
|
x49gp_module_set_u32(module, key, "cp15-c5-data", env->cp15.c5_data);
|
|
|
|
x49gp_module_set_u32(module, key, "cp15-c6-insn", env->cp15.c6_insn);
|
|
|
|
x49gp_module_set_u32(module, key, "cp15-c6-data", env->cp15.c6_data);
|
|
|
|
x49gp_module_set_u32(module, key, "cp15-c9-insn", env->cp15.c9_insn);
|
|
|
|
x49gp_module_set_u32(module, key, "cp15-c9-data", env->cp15.c9_data);
|
|
|
|
x49gp_module_set_u32(module, key, "cp15-c13-fcse", env->cp15.c13_fcse);
|
|
|
|
x49gp_module_set_u32(module, key, "cp15-c13-context", env->cp15.c13_context);
|
|
|
|
|
|
|
|
x49gp_module_set_u32(module, key, "features", env->features);
|
|
|
|
|
|
|
|
x49gp_module_set_int(module, key, "exception-index", env->exception_index);
|
|
|
|
x49gp_module_set_int(module, key, "interrupt-request", env->interrupt_request);
|
|
|
|
x49gp_module_set_int(module, key, "halted", env->halted);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
s3c2410_arm_reset(x49gp_module_t *module, x49gp_reset_t reset)
|
|
|
|
{
|
|
|
|
struct CPUARMState *env = module->user_data;
|
|
|
|
|
|
|
|
#ifdef DEBUG_X49GP_MODULES
|
|
|
|
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
cpu_reset(env);
|
|
|
|
tlb_flush(env, 1);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
s3c2410_arm_init(x49gp_module_t *module)
|
|
|
|
{
|
|
|
|
x49gp_t *x49gp = module->x49gp;
|
|
|
|
|
|
|
|
#ifdef DEBUG_X49GP_MODULES
|
|
|
|
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
module->user_data = x49gp->env;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
s3c2410_arm_exit(x49gp_module_t *module)
|
|
|
|
{
|
|
|
|
#ifdef DEBUG_X49GP_MODULES
|
|
|
|
printf("%s: %s:%u\n", module->name, __FUNCTION__, __LINE__);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
x49gp_s3c2410_arm_init(x49gp_t *x49gp)
|
|
|
|
{
|
|
|
|
x49gp_module_t *module;
|
|
|
|
|
|
|
|
if (x49gp_module_init(x49gp, "s3c2410-arm",
|
|
|
|
s3c2410_arm_init,
|
|
|
|
s3c2410_arm_exit,
|
|
|
|
s3c2410_arm_reset,
|
|
|
|
s3c2410_arm_load,
|
|
|
|
s3c2410_arm_save,
|
|
|
|
NULL, &module)) {
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
return x49gp_module_register(module);
|
|
|
|
}
|