From e95c8d51c2a47d7ccb422f83446cb91a18f8f37d Mon Sep 17 00:00:00 2001 From: bellard Date: Thu, 30 Sep 2004 22:22:08 +0000 Subject: [PATCH] full system SPARC emulation (Blue Swirl) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1087 c046a42c-6fe2-441c-8c8c-71466251a162 --- .cvsignore | 1 + Changelog | 1 + Makefile.target | 29 +++++++- configure | 6 +- cpu-exec.c | 13 ++++ exec-all.h | 6 +- exec.c | 6 +- gdbstub.c | 167 +++++++++++++++++++++++++++++++---------------- monitor.c | 109 +++++++++++++++++++++++++++---- slirp/bootp.c | 3 +- softmmu_header.h | 4 ++ translate-all.c | 3 + vl.c | 15 ++++- vl.h | 22 +++++++ 14 files changed, 307 insertions(+), 78 deletions(-) diff --git a/.cvsignore b/.cvsignore index 9fad653e3d..bca4882388 100644 --- a/.cvsignore +++ b/.cvsignore @@ -12,3 +12,4 @@ qemu.1 qemu.pod sparc-user qemu-img +sparc-softmmu diff --git a/Changelog b/Changelog index bf8efc5bdf..8bbe6d95f7 100644 --- a/Changelog +++ b/Changelog @@ -17,6 +17,7 @@ version 0.6.1: - Fixed Fedora Core 2 problems (now you can run qemu without any LD_ASSUME_KERNEL tricks on FC2) - DHCP fix for Windows (accept DHCPREQUEST alone) + - SPARC system emulation (Blue Swirl) version 0.6.0: diff --git a/Makefile.target b/Makefile.target index 28585c7e94..ff07be844f 100644 --- a/Makefile.target +++ b/Makefile.target @@ -63,6 +63,26 @@ endif endif # ARCH = amd64 endif # TARGET_ARCH = ppc + +ifeq ($(TARGET_ARCH), sparc) + +ifeq ($(ARCH), ppc) +PROGS+=$(QEMU_SYSTEM) +endif + +ifeq ($(ARCH), i386) +ifdef CONFIG_SOFTMMU +PROGS+=$(QEMU_SYSTEM) +endif +endif # ARCH = i386 + +ifeq ($(ARCH), amd64) +ifdef CONFIG_SOFTMMU +PROGS+=$(QEMU_SYSTEM) +endif +endif # ARCH = amd64 + +endif # TARGET_ARCH = sparc endif # !CONFIG_USER_ONLY ifdef CONFIG_STATIC @@ -201,6 +221,10 @@ ifeq ($(TARGET_ARCH), ppc) LIBOBJS+= op_helper.o helper.o endif +ifeq ($(TARGET_ARCH), sparc) +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) @@ -254,6 +278,9 @@ VL_OBJS+= ppc.o ide.o ne2000.o pckbd.o vga.o sb16.o dma.o oss.o VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o endif +ifeq ($(TARGET_ARCH), sparc) +VL_OBJS+= sun4m.o tcx.o lance.o iommu.o sched.o m48t08.o magic-load.o +endif ifdef CONFIG_GDBSTUB VL_OBJS+=gdbstub.o endif @@ -325,7 +352,7 @@ op.o: op.c op_template.h endif ifeq ($(TARGET_ARCH), sparc) -op.o: op.c op_template.h +op.o: op.c op_template.h op_mem.h endif ifeq ($(TARGET_ARCH), ppc) diff --git a/configure b/configure index 54f1a9fbdd..5d7eed688f 100755 --- a/configure +++ b/configure @@ -27,7 +27,7 @@ ar="ar" make="make" strip="strip" cpu=`uname -m` -target_list="i386-user i386 i386-softmmu arm-user sparc-user ppc-user ppc-softmmu" +target_list="i386-user i386 i386-softmmu arm-user sparc-user ppc-user ppc-softmmu sparc-softmmu" case "$cpu" in i386|i486|i586|i686|i86pc|BePC) cpu="i386" @@ -99,7 +99,7 @@ if [ "$bsd" = "yes" ] ; then if [ ! "$darwin" = "yes" ] ; then make="gmake" fi - target_list="i386-softmmu ppc-softmmu" + target_list="i386-softmmu ppc-softmmu sparc-softmmu" fi # find source path @@ -160,7 +160,7 @@ ar="${cross_prefix}${ar}" strip="${cross_prefix}${strip}" if test "$mingw32" = "yes" ; then - target_list="i386-softmmu ppc-softmmu" + target_list="i386-softmmu ppc-softmmu sparc-softmmu" EXESUF=".exe" gdbstub="no" fi diff --git a/cpu-exec.c b/cpu-exec.c index 053c0cc5dd..930bd7bd8e 100644 --- a/cpu-exec.c +++ b/cpu-exec.c @@ -208,6 +208,11 @@ int cpu_exec(CPUState *env1) env->exception_next_eip, 0); #elif defined(TARGET_PPC) do_interrupt(env); +#elif defined(TARGET_SPARC) + do_interrupt(env->exception_index, + 0, + env->error_code, + env->exception_next_pc, 0); #endif } env->exception_index = -1; @@ -261,6 +266,14 @@ int cpu_exec(CPUState *env1) env->interrupt_request &= ~CPU_INTERRUPT_TIMER; } } +#elif defined(TARGET_SPARC) + if (interrupt_request & CPU_INTERRUPT_HARD) { + do_interrupt(0, 0, 0, 0, 0); + env->interrupt_request &= ~CPU_INTERRUPT_HARD; + } else if (interrupt_request & CPU_INTERRUPT_TIMER) { + //do_interrupt(0, 0, 0, 0, 0); + env->interrupt_request &= ~CPU_INTERRUPT_TIMER; + } #endif if (interrupt_request & CPU_INTERRUPT_EXITTB) { env->interrupt_request &= ~CPU_INTERRUPT_EXITTB; diff --git a/exec-all.h b/exec-all.h index b6853a1af6..2e886e07c8 100644 --- a/exec-all.h +++ b/exec-all.h @@ -56,6 +56,7 @@ struct TranslationBlock; extern uint16_t gen_opc_buf[OPC_BUF_SIZE]; extern uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE]; extern uint32_t gen_opc_pc[OPC_BUF_SIZE]; +extern uint32_t gen_opc_npc[OPC_BUF_SIZE]; extern uint8_t gen_opc_cc_op[OPC_BUF_SIZE]; extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE]; @@ -541,8 +542,7 @@ extern spinlock_t tb_lock; extern int tb_invalidated_flag; -#if (defined(TARGET_I386) || defined(TARGET_PPC)) && \ - !defined(CONFIG_USER_ONLY) +#if !defined(CONFIG_USER_ONLY) void tlb_fill(unsigned long addr, int is_write, int is_user, void *retaddr); @@ -585,6 +585,8 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr) is_user = ((env->hflags & HF_CPL_MASK) == 3); #elif defined (TARGET_PPC) is_user = msr_pr; +#elif defined (TARGET_SPARC) + is_user = (env->psrs == 0); #else #error "Unimplemented !" #endif diff --git a/exec.c b/exec.c index c33661bc49..f266bb970d 100644 --- a/exec.c +++ b/exec.c @@ -1077,7 +1077,7 @@ static void breakpoint_invalidate(CPUState *env, target_ulong pc) breakpoint is reached */ int cpu_breakpoint_insert(CPUState *env, target_ulong pc) { -#if defined(TARGET_I386) || defined(TARGET_PPC) +#if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_SPARC) int i; for(i = 0; i < env->nb_breakpoints; i++) { @@ -1099,7 +1099,7 @@ int cpu_breakpoint_insert(CPUState *env, target_ulong pc) /* remove a breakpoint */ int cpu_breakpoint_remove(CPUState *env, target_ulong pc) { -#if defined(TARGET_I386) || defined(TARGET_PPC) +#if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_SPARC) int i; for(i = 0; i < env->nb_breakpoints; i++) { if (env->breakpoints[i] == pc) @@ -1122,7 +1122,7 @@ int cpu_breakpoint_remove(CPUState *env, target_ulong pc) CPU loop after each instruction */ void cpu_single_step(CPUState *env, int enabled) { -#if defined(TARGET_I386) || defined(TARGET_PPC) +#if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_SPARC) if (env->singlestep_enabled != enabled) { env->singlestep_enabled = enabled; /* must flush all the translated code to avoid inconsistancies */ diff --git a/gdbstub.c b/gdbstub.c index 19623102de..e15216a590 100644 --- a/gdbstub.c +++ b/gdbstub.c @@ -157,42 +157,40 @@ static int put_packet(GDBState *s, char *buf) #if defined(TARGET_I386) -static void to_le32(uint8_t *p, int v) -{ - p[0] = v; - p[1] = v >> 8; - p[2] = v >> 16; - p[3] = v >> 24; -} - static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) { + uint32_t *registers = (uint32_t *)mem_buf; int i, fpus; for(i = 0; i < 8; i++) { - to_le32(mem_buf + i * 4, env->regs[i]); + registers[i] = env->regs[i]; } - to_le32(mem_buf + 8 * 4, env->eip); - to_le32(mem_buf + 9 * 4, env->eflags); - to_le32(mem_buf + 10 * 4, env->segs[R_CS].selector); - to_le32(mem_buf + 11 * 4, env->segs[R_SS].selector); - to_le32(mem_buf + 12 * 4, env->segs[R_DS].selector); - to_le32(mem_buf + 13 * 4, env->segs[R_ES].selector); - to_le32(mem_buf + 14 * 4, env->segs[R_FS].selector); - to_le32(mem_buf + 15 * 4, env->segs[R_GS].selector); + registers[8] = env->eip; + registers[9] = env->eflags; + registers[10] = env->segs[R_CS].selector; + registers[11] = env->segs[R_SS].selector; + registers[12] = env->segs[R_DS].selector; + registers[13] = env->segs[R_ES].selector; + registers[14] = env->segs[R_FS].selector; + registers[15] = env->segs[R_GS].selector; /* XXX: convert floats */ for(i = 0; i < 8; i++) { memcpy(mem_buf + 16 * 4 + i * 10, &env->fpregs[i], 10); } - to_le32(mem_buf + 36 * 4, env->fpuc); + registers[36] = env->fpuc; fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; - to_le32(mem_buf + 37 * 4, fpus); - to_le32(mem_buf + 38 * 4, 0); /* XXX: convert tags */ - to_le32(mem_buf + 39 * 4, 0); /* fiseg */ - to_le32(mem_buf + 40 * 4, 0); /* fioff */ - to_le32(mem_buf + 41 * 4, 0); /* foseg */ - to_le32(mem_buf + 42 * 4, 0); /* fooff */ - to_le32(mem_buf + 43 * 4, 0); /* fop */ + registers[37] = fpus; + registers[38] = 0; /* XXX: convert tags */ + registers[39] = 0; /* fiseg */ + registers[40] = 0; /* fioff */ + registers[41] = 0; /* foseg */ + registers[42] = 0; /* fooff */ + registers[43] = 0; /* fop */ + + for(i = 0; i < 16; i++) + tswapls(®isters[i]); + for(i = 36; i < 44; i++) + tswapls(®isters[i]); return 44 * 4; } @@ -204,8 +202,8 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) for(i = 0; i < 8; i++) { env->regs[i] = tswapl(registers[i]); } - env->eip = registers[8]; - env->eflags = registers[9]; + env->eip = tswapl(registers[8]); + env->eflags = tswapl(registers[9]); #if defined(CONFIG_USER_ONLY) #define LOAD_SEG(index, sreg)\ if (tswapl(registers[index]) != env->segs[sreg].selector)\ @@ -220,15 +218,6 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) } #elif defined (TARGET_PPC) -static void to_le32(uint32_t *buf, uint32_t v) -{ - uint8_t *p = (uint8_t *)buf; - p[3] = v; - p[2] = v >> 8; - p[1] = v >> 16; - p[0] = v >> 24; -} - static uint32_t from_le32 (uint32_t *buf) { uint8_t *p = (uint8_t *)buf; @@ -243,24 +232,24 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) /* fill in gprs */ for(i = 0; i < 32; i++) { - to_le32(®isters[i], env->gpr[i]); + registers[i] = tswapl(env->gpr[i]); } /* fill in fprs */ for (i = 0; i < 32; i++) { - to_le32(®isters[(i * 2) + 32], *((uint32_t *)&env->fpr[i])); - to_le32(®isters[(i * 2) + 33], *((uint32_t *)&env->fpr[i] + 1)); + registers[(i * 2) + 32] = tswapl(*((uint32_t *)&env->fpr[i])); + registers[(i * 2) + 33] = tswapl(*((uint32_t *)&env->fpr[i] + 1)); } /* nip, msr, ccr, lnk, ctr, xer, mq */ - to_le32(®isters[96], (uint32_t)env->nip/* - 4*/); - to_le32(®isters[97], _load_msr(env)); + registers[96] = tswapl(env->nip); + registers[97] = tswapl(_load_msr(env)); tmp = 0; for (i = 0; i < 8; i++) tmp |= env->crf[i] << (32 - ((i + 1) * 4)); - to_le32(®isters[98], tmp); - to_le32(®isters[99], env->lr); - to_le32(®isters[100], env->ctr); - to_le32(®isters[101], _load_xer(env)); - to_le32(®isters[102], 0); + registers[98] = tswapl(tmp); + registers[99] = tswapl(env->lr); + registers[100] = tswapl(env->ctr); + registers[101] = tswapl(_load_xer(env)); + registers[102] = 0; return 103 * 4; } @@ -272,22 +261,90 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) /* fill in gprs */ for (i = 0; i < 32; i++) { - env->gpr[i] = from_le32(®isters[i]); + env->gpr[i] = tswapl(registers[i]); } /* fill in fprs */ for (i = 0; i < 32; i++) { - *((uint32_t *)&env->fpr[i]) = from_le32(®isters[(i * 2) + 32]); - *((uint32_t *)&env->fpr[i] + 1) = from_le32(®isters[(i * 2) + 33]); + *((uint32_t *)&env->fpr[i]) = tswapl(registers[(i * 2) + 32]); + *((uint32_t *)&env->fpr[i] + 1) = tswapl(registers[(i * 2) + 33]); } /* nip, msr, ccr, lnk, ctr, xer, mq */ - env->nip = from_le32(®isters[96]); - _store_msr(env, from_le32(®isters[97])); - registers[98] = from_le32(®isters[98]); + env->nip = tswapl(registers[96]); + _store_msr(env, tswapl(registers[97])); + registers[98] = tswapl(registers[98]); for (i = 0; i < 8; i++) env->crf[i] = (registers[98] >> (32 - ((i + 1) * 4))) & 0xF; - env->lr = from_le32(®isters[99]); - env->ctr = from_le32(®isters[100]); - _store_xer(env, from_le32(®isters[101])); + env->lr = tswapl(registers[99]); + env->ctr = tswapl(registers[100]); + _store_xer(env, tswapl(registers[101])); +} +#elif defined (TARGET_SPARC) +static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) +{ + uint32_t *registers = (uint32_t *)mem_buf, tmp; + int i; + + /* fill in g0..g7 */ + for(i = 0; i < 7; i++) { + registers[i] = tswapl(env->gregs[i]); + } + /* fill in register window */ + for(i = 0; i < 24; i++) { + registers[i + 8] = tswapl(env->regwptr[i]); + } + /* fill in fprs */ + for (i = 0; i < 32; i++) { + registers[i + 32] = tswapl(*((uint32_t *)&env->fpr[i])); + } + /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ + registers[64] = tswapl(env->y); + tmp = (0<<28) | (4<<24) | env->psr \ + | (env->psrs? PSR_S : 0) \ + | (env->psrs? PSR_PS : 0) \ + | (env->psret? PSR_ET : 0) \ + | env->cwp; + registers[65] = tswapl(tmp); + registers[66] = tswapl(env->wim); + registers[67] = tswapl(env->tbr); + registers[68] = tswapl(env->pc); + registers[69] = tswapl(env->npc); + registers[70] = tswapl(env->fsr); + registers[71] = 0; /* csr */ + registers[72] = 0; + + return 73 * 4; +} + +static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) +{ + uint32_t *registers = (uint32_t *)mem_buf, tmp; + int i; + + /* fill in g0..g7 */ + for(i = 0; i < 7; i++) { + env->gregs[i] = tswapl(registers[i]); + } + /* fill in register window */ + for(i = 0; i < 24; i++) { + env->regwptr[i] = tswapl(registers[i]); + } + /* fill in fprs */ + for (i = 0; i < 32; i++) { + *((uint32_t *)&env->fpr[i]) = tswapl(registers[i + 32]); + } + /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */ + env->y = tswapl(registers[64]); + tmp = tswapl(registers[65]); + env->psr = tmp & ~PSR_ICC; + env->psrs = (tmp & PSR_S)? 1 : 0; + env->psrps = (tmp & PSR_PS)? 1 : 0; + env->psret = (tmp & PSR_ET)? 1 : 0; + env->cwp = (tmp & PSR_CWP); + env->wim = tswapl(registers[66]); + env->tbr = tswapl(registers[67]); + env->pc = tswapl(registers[68]); + env->npc = tswapl(registers[69]); + env->fsr = tswapl(registers[70]); } #else diff --git a/monitor.c b/monitor.c index ad0f315867..15b54d3e71 100644 --- a/monitor.c +++ b/monitor.c @@ -883,18 +883,18 @@ static jmp_buf expr_env; typedef struct MonitorDef { const char *name; int offset; - int (*get_value)(struct MonitorDef *md); + int (*get_value)(struct MonitorDef *md, int val); } MonitorDef; #if defined(TARGET_I386) -static int monitor_get_pc (struct MonitorDef *md) +static int monitor_get_pc (struct MonitorDef *md, int val) { return cpu_single_env->eip + (long)cpu_single_env->segs[R_CS].base; } #endif #if defined(TARGET_PPC) -static int monitor_get_ccr (struct MonitorDef *md) +static int monitor_get_ccr (struct MonitorDef *md, int val) { unsigned int u; int i; @@ -906,7 +906,7 @@ static int monitor_get_ccr (struct MonitorDef *md) return u; } -static int monitor_get_msr (struct MonitorDef *md) +static int monitor_get_msr (struct MonitorDef *md, int val) { return (cpu_single_env->msr[MSR_POW] << MSR_POW) | (cpu_single_env->msr[MSR_ILE] << MSR_ILE) | @@ -925,7 +925,7 @@ static int monitor_get_msr (struct MonitorDef *md) (cpu_single_env->msr[MSR_LE] << MSR_LE); } -static int monitor_get_xer (struct MonitorDef *md) +static int monitor_get_xer (struct MonitorDef *md, int val) { return (cpu_single_env->xer[XER_SO] << XER_SO) | (cpu_single_env->xer[XER_OV] << XER_OV) | @@ -933,25 +933,38 @@ static int monitor_get_xer (struct MonitorDef *md) (cpu_single_env->xer[XER_BC] << XER_BC); } -uint32_t cpu_ppc_load_decr (CPUState *env); -static int monitor_get_decr (struct MonitorDef *md) +static int monitor_get_decr (struct MonitorDef *md, int val) { return cpu_ppc_load_decr(cpu_single_env); } -uint32_t cpu_ppc_load_tbu (CPUState *env); -static int monitor_get_tbu (struct MonitorDef *md) +static int monitor_get_tbu (struct MonitorDef *md, int val) { return cpu_ppc_load_tbu(cpu_single_env); } -uint32_t cpu_ppc_load_tbl (CPUState *env); -static int monitor_get_tbl (struct MonitorDef *md) +static int monitor_get_tbl (struct MonitorDef *md, int val) { return cpu_ppc_load_tbl(cpu_single_env); } #endif +#if defined(TARGET_SPARC) +static int monitor_get_psr (struct MonitorDef *md, int val) +{ + return (0<<28) | (4<<24) | cpu_single_env->psr \ + | (cpu_single_env->psrs? PSR_S : 0) \ + | (cpu_single_env->psrs? PSR_PS : 0) \ + | (cpu_single_env->psret? PSR_ET : 0) \ + | cpu_single_env->cwp; +} + +static int monitor_get_reg(struct MonitorDef *md, int val) +{ + return cpu_single_env->regwptr[val]; +} +#endif + static MonitorDef monitor_defs[] = { #ifdef TARGET_I386 @@ -1037,6 +1050,78 @@ static MonitorDef monitor_defs[] = { { "sr14", offsetof(CPUState, sr[14]) }, { "sr15", offsetof(CPUState, sr[15]) }, /* Too lazy to put BATs and SPRs ... */ +#elif defined(TARGET_SPARC) + { "g0", offsetof(CPUState, gregs[0]) }, + { "g1", offsetof(CPUState, gregs[1]) }, + { "g2", offsetof(CPUState, gregs[2]) }, + { "g3", offsetof(CPUState, gregs[3]) }, + { "g4", offsetof(CPUState, gregs[4]) }, + { "g5", offsetof(CPUState, gregs[5]) }, + { "g6", offsetof(CPUState, gregs[6]) }, + { "g7", offsetof(CPUState, gregs[7]) }, + { "o0", 0, monitor_get_reg }, + { "o1", 1, monitor_get_reg }, + { "o2", 2, monitor_get_reg }, + { "o3", 3, monitor_get_reg }, + { "o4", 4, monitor_get_reg }, + { "o5", 5, monitor_get_reg }, + { "o6", 6, monitor_get_reg }, + { "o7", 7, monitor_get_reg }, + { "l0", 8, monitor_get_reg }, + { "l1", 9, monitor_get_reg }, + { "l2", 10, monitor_get_reg }, + { "l3", 11, monitor_get_reg }, + { "l4", 12, monitor_get_reg }, + { "l5", 13, monitor_get_reg }, + { "l6", 14, monitor_get_reg }, + { "l7", 15, monitor_get_reg }, + { "i0", 16, monitor_get_reg }, + { "i1", 17, monitor_get_reg }, + { "i2", 18, monitor_get_reg }, + { "i3", 19, monitor_get_reg }, + { "i4", 20, monitor_get_reg }, + { "i5", 21, monitor_get_reg }, + { "i6", 22, monitor_get_reg }, + { "i7", 23, monitor_get_reg }, + { "pc", offsetof(CPUState, pc) }, + { "npc", offsetof(CPUState, npc) }, + { "y", offsetof(CPUState, y) }, + { "psr", 0, &monitor_get_psr, }, + { "wim", offsetof(CPUState, wim) }, + { "tbr", offsetof(CPUState, tbr) }, + { "fsr", offsetof(CPUState, fsr) }, + { "f0", offsetof(CPUState, fpr[0]) }, + { "f1", offsetof(CPUState, fpr[1]) }, + { "f2", offsetof(CPUState, fpr[2]) }, + { "f3", offsetof(CPUState, fpr[3]) }, + { "f4", offsetof(CPUState, fpr[4]) }, + { "f5", offsetof(CPUState, fpr[5]) }, + { "f6", offsetof(CPUState, fpr[6]) }, + { "f7", offsetof(CPUState, fpr[7]) }, + { "f8", offsetof(CPUState, fpr[8]) }, + { "f9", offsetof(CPUState, fpr[9]) }, + { "f10", offsetof(CPUState, fpr[10]) }, + { "f11", offsetof(CPUState, fpr[11]) }, + { "f12", offsetof(CPUState, fpr[12]) }, + { "f13", offsetof(CPUState, fpr[13]) }, + { "f14", offsetof(CPUState, fpr[14]) }, + { "f15", offsetof(CPUState, fpr[15]) }, + { "f16", offsetof(CPUState, fpr[16]) }, + { "f17", offsetof(CPUState, fpr[17]) }, + { "f18", offsetof(CPUState, fpr[18]) }, + { "f19", offsetof(CPUState, fpr[19]) }, + { "f20", offsetof(CPUState, fpr[20]) }, + { "f21", offsetof(CPUState, fpr[21]) }, + { "f22", offsetof(CPUState, fpr[22]) }, + { "f23", offsetof(CPUState, fpr[23]) }, + { "f24", offsetof(CPUState, fpr[24]) }, + { "f25", offsetof(CPUState, fpr[25]) }, + { "f26", offsetof(CPUState, fpr[26]) }, + { "f27", offsetof(CPUState, fpr[27]) }, + { "f28", offsetof(CPUState, fpr[28]) }, + { "f29", offsetof(CPUState, fpr[29]) }, + { "f30", offsetof(CPUState, fpr[30]) }, + { "f31", offsetof(CPUState, fpr[31]) }, #endif { NULL }, }; @@ -1054,7 +1139,7 @@ static int get_monitor_def(int *pval, const char *name) for(md = monitor_defs; md->name != NULL; md++) { if (compare_cmd(name, md->name)) { if (md->get_value) { - *pval = md->get_value(md); + *pval = md->get_value(md, md->offset); } else { *pval = *(uint32_t *)((uint8_t *)cpu_single_env + md->offset); } diff --git a/slirp/bootp.c b/slirp/bootp.c index 8ae68af466..3924c10725 100644 --- a/slirp/bootp.c +++ b/slirp/bootp.c @@ -178,7 +178,8 @@ static void bootp_reply(struct bootp_t *bp) rbp->bp_hlen = 6; memcpy(rbp->bp_hwaddr, bp->bp_hwaddr, 6); - rbp->bp_yiaddr = daddr.sin_addr; /* IP address */ + rbp->bp_yiaddr = daddr.sin_addr; /* Client IP address */ + rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */ q = rbp->bp_vend; memcpy(q, rfc1533_cookie, 4); diff --git a/softmmu_header.h b/softmmu_header.h index 0bbc3681cc..074d090ba2 100644 --- a/softmmu_header.h +++ b/softmmu_header.h @@ -55,6 +55,8 @@ #define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3) #elif defined (TARGET_PPC) #define CPU_MEM_INDEX (msr_pr) +#elif defined (TARGET_SPARC) +#define CPU_MEM_INDEX ((env->psrs) == 0) #endif #define MMUSUFFIX _mmu @@ -64,6 +66,8 @@ #define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3) #elif defined (TARGET_PPC) #define CPU_MEM_INDEX (msr_pr) +#elif defined (TARGET_SPARC) +#define CPU_MEM_INDEX ((env->psrs) == 0) #endif #define MMUSUFFIX _cmmu diff --git a/translate-all.c b/translate-all.c index be3039c2c9..1fbed41340 100644 --- a/translate-all.c +++ b/translate-all.c @@ -46,6 +46,8 @@ uint32_t gen_opc_pc[OPC_BUF_SIZE]; uint8_t gen_opc_instr_start[OPC_BUF_SIZE]; #if defined(TARGET_I386) uint8_t gen_opc_cc_op[OPC_BUF_SIZE]; +#elif defined(TARGET_SPARC) +uint32_t gen_opc_npc[OPC_BUF_SIZE]; #endif int code_copy_enabled = 1; @@ -208,6 +210,7 @@ int cpu_restore_state(TranslationBlock *tb, #elif defined(TARGET_SPARC) /* XXX: restore npc too */ env->pc = gen_opc_pc[j]; + env->npc = gen_opc_npc[j]; #elif defined(TARGET_PPC) { int type; diff --git a/vl.c b/vl.c index 02edc7deb5..22b14128fb 100644 --- a/vl.c +++ b/vl.c @@ -710,7 +710,7 @@ static void qemu_run_timers(QEMUTimer **ptimer_head, int64_t current_time) for(;;) { ts = *ptimer_head; - if (ts->expire_time > current_time) + if (!ts || ts->expire_time > current_time) break; /* remove timer from the list before calling the callback */ *ptimer_head = ts->next; @@ -2162,6 +2162,15 @@ void cpu_save(QEMUFile *f, void *opaque) { } +int cpu_load(QEMUFile *f, void *opaque, int version_id) +{ + return 0; +} +#elif defined(TARGET_SPARC) +void cpu_save(QEMUFile *f, void *opaque) +{ +} + int cpu_load(QEMUFile *f, void *opaque, int version_id) { return 0; @@ -3336,6 +3345,10 @@ int main(int argc, char **argv) ppc_init(ram_size, vga_ram_size, boot_device, ds, fd_filename, snapshot, kernel_filename, kernel_cmdline, initrd_filename); +#elif defined(TARGET_SPARC) + sun4m_init(ram_size, vga_ram_size, boot_device, + ds, fd_filename, snapshot, + kernel_filename, kernel_cmdline, initrd_filename); #endif gui_timer = qemu_new_timer(rt_clock, gui_update, NULL); diff --git a/vl.h b/vl.h index 4cfe9c0053..8151613a9a 100644 --- a/vl.h +++ b/vl.h @@ -664,6 +664,28 @@ extern CPUWriteMemoryFunc *PPC_io_write[]; extern CPUReadMemoryFunc *PPC_io_read[]; extern int prep_enabled; +/* sun4m.c */ +void sun4m_init(int ram_size, int vga_ram_size, int boot_device, + DisplayState *ds, const char **fd_filename, int snapshot, + const char *kernel_filename, const char *kernel_cmdline, + const char *initrd_filename); + +/* iommu.c */ +void iommu_init(); +uint32_t iommu_translate(uint32_t addr); + +/* lance.c */ +void lance_init(NetDriverState *nd, int irq); + +/* tcx.c */ +void tcx_init(DisplayState *ds); + +/* sched.c */ +void sched_init(); + +/* magic-load.c */ +void magic_init(const char *kfn, int kloadaddr); + /* NVRAM helpers */ #include "hw/m48t59.h"