Skip to content

Commit

Permalink
sh4 target (Samuel Tardieu)
Browse files Browse the repository at this point in the history
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1861 c046a42c-6fe2-441c-8c8c-71466251a162
  • Loading branch information
bellard committed Apr 27, 2006
1 parent 66a93e0 commit fdf9b3e
Show file tree
Hide file tree
Showing 24 changed files with 5,905 additions and 6 deletions.
20 changes: 20 additions & 0 deletions Makefile.target
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,10 @@ ifeq ($(TARGET_BASE_ARCH), arm)
LIBOBJS+= op_helper.o helper.o
endif

ifeq ($(TARGET_BASE_ARCH), sh4)
LIBOBJS+= op_helper.o helper.o
endif

# NOTE: the disassembler code is only needed for debugging
LIBOBJS+=disas.o
ifeq ($(findstring i386, $(TARGET_ARCH) $(ARCH)),i386)
Expand Down Expand Up @@ -254,6 +258,9 @@ endif
ifeq ($(findstring m68k, $(TARGET_ARCH) $(ARCH)),m68k)
LIBOBJS+=m68k-dis.o
endif
ifeq ($(findstring sh4, $(TARGET_ARCH) $(ARCH)),sh4)
LIBOBJS+=sh4-dis.o
endif

ifdef CONFIG_GDBSTUB
OBJS+=gdbstub.o
Expand Down Expand Up @@ -341,6 +348,9 @@ ifeq ($(TARGET_BASE_ARCH), arm)
VL_OBJS+= integratorcp.o versatilepb.o ps2.o smc91c111.o arm_pic.o arm_timer.o
VL_OBJS+= pl011.o pl050.o pl080.o pl110.o pl190.o
endif
ifeq ($(TARGET_BASE_ARCH), sh4)
VL_OBJS+= shix.o sh7750.o sh7750_regnames.o tc58128.o
endif
ifdef CONFIG_GDBSTUB
VL_OBJS+=gdbstub.o
endif
Expand Down Expand Up @@ -462,6 +472,16 @@ endif

loader.o: loader.c elf_ops.h

ifeq ($(TARGET_ARCH), sh4)
op.o: op.c op_mem.c cpu.h
op_helper.o: op_helper.c exec.h cpu.h
helper.o: helper.c exec.h cpu.h
sh7750.o: sh7750.c sh7750.h sh7750_regs.h sh7750_regnames.h cpu.h
shix.o: shix.c sh7750.h sh7750_regs.h sh7750_regnames.h tc58128.h
sh7750_regnames.o: sh7750_regnames.c sh7750_regnames.h sh7750_regs.h
tc58128.o: tc58128.c tc58128.h sh7750.h
endif

%.o: %.c
$(CC) $(CFLAGS) $(DEFINES) -c -o $@ $<

Expand Down
6 changes: 5 additions & 1 deletion configure
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ if test -z "$target_list" ; then
fi
# the following are Linux specific
if [ "$user" = "yes" ] ; then
target_list="i386-user arm-user armeb-user sparc-user ppc-user mips-user mipsel-user $target_list"
target_list="i386-user arm-user armeb-user sparc-user ppc-user mips-user mipsel-user sh4-user $target_list"
fi
else
target_list=`echo "$target_list" | sed -e 's/,/ /g'`
Expand Down Expand Up @@ -807,6 +807,10 @@ elif test "$target_cpu" = "mips" -o "$target_cpu" = "mipsel" ; then
echo "TARGET_ARCH=mips" >> $config_mak
echo "#define TARGET_ARCH \"mips\"" >> $config_h
echo "#define TARGET_MIPS 1" >> $config_h
elif test "$target_cpu" = "sh4" ; then
echo "TARGET_ARCH=sh4" >> $config_mak
echo "#define TARGET_ARCH \"sh4\"" >> $config_h
echo "#define TARGET_SH4 1" >> $config_h
else
echo "Unsupported target CPU"
exit 1
Expand Down
7 changes: 7 additions & 0 deletions cpu-all.h
Original file line number Diff line number Diff line change
Expand Up @@ -732,6 +732,13 @@ void page_unprotect_range(target_ulong data, target_ulong data_size);
#define cpu_gen_code cpu_mips_gen_code
#define cpu_signal_handler cpu_mips_signal_handler

#elif defined(TARGET_SH4)
#define CPUState CPUSH4State
#define cpu_init cpu_sh4_init
#define cpu_exec cpu_sh4_exec
#define cpu_gen_code cpu_sh4_gen_code
#define cpu_signal_handler cpu_sh4_signal_handler

#else

#error unsupported target CPU
Expand Down
63 changes: 63 additions & 0 deletions cpu-exec.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,10 @@ static inline TranslationBlock *tb_find_fast(void)
flags = env->hflags & (MIPS_HFLAG_TMASK | MIPS_HFLAG_BMASK);
cs_base = 0;
pc = env->PC;
#elif defined(TARGET_SH4)
flags = env->sr & (SR_MD | SR_RB);
cs_base = 0; /* XXXXX */
pc = env->pc;
#else
#error unsupported CPU
#endif
Expand Down Expand Up @@ -363,6 +367,8 @@ int cpu_exec(CPUState *env1)
#endif
#elif defined(TARGET_PPC)
#elif defined(TARGET_MIPS)
#elif defined(TARGET_SH4)
/* XXXXX */
#else
#error unsupported target CPU
#endif
Expand Down Expand Up @@ -407,6 +413,8 @@ int cpu_exec(CPUState *env1)
do_interrupt(env->exception_index);
#elif defined(TARGET_ARM)
do_interrupt(env);
#elif defined(TARGET_SH4)
do_interrupt(env);
#endif
}
env->exception_index = -1;
Expand Down Expand Up @@ -550,6 +558,8 @@ int cpu_exec(CPUState *env1)
env->exception_index = EXCP_IRQ;
do_interrupt(env);
}
#elif defined(TARGET_SH4)
/* XXXXX */
#endif
if (env->interrupt_request & CPU_INTERRUPT_EXITTB) {
env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
Expand Down Expand Up @@ -608,6 +618,8 @@ int cpu_exec(CPUState *env1)
cpu_dump_state(env, logfile, fprintf, 0);
#elif defined(TARGET_MIPS)
cpu_dump_state(env, logfile, fprintf, 0);
#elif defined(TARGET_SH4)
cpu_dump_state(env, logfile, fprintf, 0);
#else
#error unsupported target CPU
#endif
Expand Down Expand Up @@ -817,6 +829,8 @@ int cpu_exec(CPUState *env1)
#endif
#elif defined(TARGET_PPC)
#elif defined(TARGET_MIPS)
#elif defined(TARGET_SH4)
/* XXXXX */
#else
#error unsupported target CPU
#endif
Expand Down Expand Up @@ -1121,6 +1135,55 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
return 1;
}

#elif defined (TARGET_SH4)
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
int is_write, sigset_t *old_set,
void *puc)
{
TranslationBlock *tb;
int ret;

if (cpu_single_env)
env = cpu_single_env; /* XXX: find a correct solution for multithread */
#if defined(DEBUG_SIGNAL)
printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
pc, address, is_write, *(unsigned long *)old_set);
#endif
/* XXX: locking issue */
if (is_write && page_unprotect(h2g(address), pc, puc)) {
return 1;
}

/* see if it is an MMU fault */
ret = cpu_sh4_handle_mmu_fault(env, address, is_write, 1, 0);
if (ret < 0)
return 0; /* not an MMU fault */
if (ret == 0)
return 1; /* the MMU fault was handled without causing real CPU fault */

/* now we have a real cpu fault */
tb = tb_find_pc(pc);
if (tb) {
/* the PC is inside the translated code. It means that we have
a virtual CPU fault */
cpu_restore_state(tb, env, pc, puc);
}
if (ret == 1) {
#if 0
printf("PF exception: NIP=0x%08x error=0x%x %p\n",
env->nip, env->error_code, tb);
#endif
/* we restore the process signal mask as the sigreturn should
do it (XXX: use sigsetjmp) */
sigprocmask(SIG_SETMASK, old_set, NULL);
// do_raise_exception_err(env->exception_index, env->error_code);
} else {
/* activate soft MMU for this block */
cpu_resume_from_signal(env, puc);
}
/* never comes here */
return 1;
}
#else
#error unsupported target CPU
#endif
Expand Down
15 changes: 14 additions & 1 deletion dis-asm.h
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,23 @@ enum bfd_architecture
#define bfd_mach_z8002 2
bfd_arch_h8500, /* Hitachi H8/500 */
bfd_arch_sh, /* Hitachi SH */
#define bfd_mach_sh 0
#define bfd_mach_sh 1
#define bfd_mach_sh2 0x20
#define bfd_mach_sh_dsp 0x2d
#define bfd_mach_sh2a 0x2a
#define bfd_mach_sh2a_nofpu 0x2b
#define bfd_mach_sh2e 0x2e
#define bfd_mach_sh3 0x30
#define bfd_mach_sh3_nommu 0x31
#define bfd_mach_sh3_dsp 0x3d
#define bfd_mach_sh3e 0x3e
#define bfd_mach_sh4 0x40
#define bfd_mach_sh4_nofpu 0x41
#define bfd_mach_sh4_nommu_nofpu 0x42
#define bfd_mach_sh4a 0x4a
#define bfd_mach_sh4a_nofpu 0x4b
#define bfd_mach_sh4al_dsp 0x4d
#define bfd_mach_sh5 0x50
bfd_arch_alpha, /* Dec Alpha */
bfd_arch_arm, /* Advanced Risc Machines ARM */
#define bfd_mach_arm_2 1
Expand Down
5 changes: 4 additions & 1 deletion disas.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ generic_print_address (addr, info)
bfd_vma addr;
struct disassemble_info *info;
{
(*info->fprintf_func) (info->stream, "0x%llx", addr);
(*info->fprintf_func) (info->stream, "0x%llx", addr);
}

/* Just return the given address. */
Expand Down Expand Up @@ -194,6 +194,9 @@ void target_disas(FILE *out, target_ulong code, target_ulong size, int flags)
#endif
#elif defined(TARGET_M68K)
print_insn = print_insn_m68k;
#elif defined(TARGET_SH4)
disasm_info.mach = bfd_mach_sh4;
print_insn = print_insn_sh;
#else
fprintf(out, "0x" TARGET_FMT_lx
": Asm output not supported on this arch\n", code);
Expand Down
2 changes: 2 additions & 0 deletions exec-all.h
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,8 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr)
is_user = (env->psrs == 0);
#elif defined (TARGET_ARM)
is_user = ((env->uncached_cpsr & CPSR_M) == ARM_CPU_MODE_USR);
#elif defined (TARGET_SH4)
is_user = ((env->sr & SR_MD) == 0);
#else
#error unimplemented CPU
#endif
Expand Down
43 changes: 43 additions & 0 deletions gdbstub.c
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,45 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
env->PC = tswapl(*(uint32_t *)ptr);
ptr += 4;
}
#elif defined (TARGET_SH4)
static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
{
uint32_t *ptr = (uint32_t *)mem_buf;
int i;

#define SAVE(x) *ptr++=tswapl(x)
for (i = 0; i < 16; i++) SAVE(env->gregs[i]);
SAVE (env->pc);
SAVE (env->pr);
SAVE (env->gbr);
SAVE (env->vbr);
SAVE (env->mach);
SAVE (env->macl);
SAVE (env->sr);
SAVE (0); /* TICKS */
SAVE (0); /* STALLS */
SAVE (0); /* CYCLES */
SAVE (0); /* INSTS */
SAVE (0); /* PLR */

return ((uint8_t *)ptr - mem_buf);
}

static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
{
uint32_t *ptr = (uint32_t *)mem_buf;
int i;

#define LOAD(x) (x)=*ptr++;
for (i = 0; i < 16; i++) LOAD(env->gregs[i]);
LOAD (env->pc);
LOAD (env->pr);
LOAD (env->gbr);
LOAD (env->vbr);
LOAD (env->mach);
LOAD (env->macl);
LOAD (env->sr);
}
#else
static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
{
Expand Down Expand Up @@ -531,6 +570,8 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
env->npc = addr + 4;
#elif defined (TARGET_ARM)
env->regs[15] = addr;
#elif defined (TARGET_SH4)
env->pc = addr;
#endif
}
#ifdef CONFIG_USER_ONLY
Expand All @@ -551,6 +592,8 @@ static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
env->npc = addr + 4;
#elif defined (TARGET_ARM)
env->regs[15] = addr;
#elif defined (TARGET_SH4)
env->pc = addr;
#endif
}
cpu_single_step(env, 1);
Expand Down
24 changes: 24 additions & 0 deletions linux-user/elfload.c
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,30 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i

#endif /* TARGET_MIPS */

#ifdef TARGET_SH4

#define ELF_START_MMAP 0x80000000

#define elf_check_arch(x) ( (x) == EM_SH )

#define ELF_CLASS ELFCLASS32
#define ELF_DATA ELFDATA2LSB
#define ELF_ARCH EM_SH

#define ELF_PLAT_INIT(_r) /* XXXXX */

static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
{
/* Check other registers XXXXX */
regs->pc = infop->entry;
regs->regs[15] = infop->start_stack - 16 * 4;
}

#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096

#endif

#ifndef ELF_PLATFORM
#define ELF_PLATFORM (NULL)
#endif
Expand Down
41 changes: 41 additions & 0 deletions linux-user/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1387,6 +1387,38 @@ void cpu_loop(CPUMIPSState *env)
}
#endif

#ifdef TARGET_SH4
void cpu_loop (CPUState *env)
{
int trapnr, ret;
// target_siginfo_t info;

while (1) {
trapnr = cpu_sh4_exec (env);

switch (trapnr) {
case 0x160:
ret = do_syscall(env,
env->gregs[0x13],
env->gregs[0x14],
env->gregs[0x15],
env->gregs[0x16],
env->gregs[0x17],
env->gregs[0x10],
0);
env->gregs[0x10] = ret;
env->pc += 2;
break;
default:
printf ("Unhandled trap: 0x%x\n", trapnr);
cpu_dump_state(env, stderr, fprintf, 0);
exit (1);
}
process_pending_signals (env);
}
}
#endif

void usage(void)
{
printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003-2005 Fabrice Bellard\n"
Expand Down Expand Up @@ -1665,6 +1697,15 @@ int main(int argc, char **argv)
}
env->PC = regs->cp0_epc;
}
#elif defined(TARGET_SH4)
{
int i;

for(i = 0; i < 16; i++) {
env->gregs[i] = regs->regs[i];
}
env->pc = regs->pc;
}
#else
#error unsupported target CPU
#endif
Expand Down
Loading

0 comments on commit fdf9b3e

Please sign in to comment.