提交 e95c8d51 编写于 作者: B bellard

full system SPARC emulation (Blue Swirl)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1087 c046a42c-6fe2-441c-8c8c-71466251a162
上级 4971b827
...@@ -12,3 +12,4 @@ qemu.1 ...@@ -12,3 +12,4 @@ qemu.1
qemu.pod qemu.pod
sparc-user sparc-user
qemu-img qemu-img
sparc-softmmu
...@@ -17,6 +17,7 @@ version 0.6.1: ...@@ -17,6 +17,7 @@ version 0.6.1:
- Fixed Fedora Core 2 problems (now you can run qemu without any - Fixed Fedora Core 2 problems (now you can run qemu without any
LD_ASSUME_KERNEL tricks on FC2) LD_ASSUME_KERNEL tricks on FC2)
- DHCP fix for Windows (accept DHCPREQUEST alone) - DHCP fix for Windows (accept DHCPREQUEST alone)
- SPARC system emulation (Blue Swirl)
version 0.6.0: version 0.6.0:
......
...@@ -63,6 +63,26 @@ endif ...@@ -63,6 +63,26 @@ endif
endif # ARCH = amd64 endif # ARCH = amd64
endif # TARGET_ARCH = ppc 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 endif # !CONFIG_USER_ONLY
ifdef CONFIG_STATIC ifdef CONFIG_STATIC
...@@ -201,6 +221,10 @@ ifeq ($(TARGET_ARCH), ppc) ...@@ -201,6 +221,10 @@ ifeq ($(TARGET_ARCH), ppc)
LIBOBJS+= op_helper.o helper.o LIBOBJS+= op_helper.o helper.o
endif endif
ifeq ($(TARGET_ARCH), sparc)
LIBOBJS+= op_helper.o helper.o
endif
# NOTE: the disassembler code is only needed for debugging # NOTE: the disassembler code is only needed for debugging
LIBOBJS+=disas.o LIBOBJS+=disas.o
ifeq ($(findstring i386, $(TARGET_ARCH) $(ARCH)),i386) 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 ...@@ -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+= 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 VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o
endif 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 ifdef CONFIG_GDBSTUB
VL_OBJS+=gdbstub.o VL_OBJS+=gdbstub.o
endif endif
...@@ -325,7 +352,7 @@ op.o: op.c op_template.h ...@@ -325,7 +352,7 @@ op.o: op.c op_template.h
endif endif
ifeq ($(TARGET_ARCH), sparc) ifeq ($(TARGET_ARCH), sparc)
op.o: op.c op_template.h op.o: op.c op_template.h op_mem.h
endif endif
ifeq ($(TARGET_ARCH), ppc) ifeq ($(TARGET_ARCH), ppc)
......
...@@ -27,7 +27,7 @@ ar="ar" ...@@ -27,7 +27,7 @@ ar="ar"
make="make" make="make"
strip="strip" strip="strip"
cpu=`uname -m` 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 case "$cpu" in
i386|i486|i586|i686|i86pc|BePC) i386|i486|i586|i686|i86pc|BePC)
cpu="i386" cpu="i386"
...@@ -99,7 +99,7 @@ if [ "$bsd" = "yes" ] ; then ...@@ -99,7 +99,7 @@ if [ "$bsd" = "yes" ] ; then
if [ ! "$darwin" = "yes" ] ; then if [ ! "$darwin" = "yes" ] ; then
make="gmake" make="gmake"
fi fi
target_list="i386-softmmu ppc-softmmu" target_list="i386-softmmu ppc-softmmu sparc-softmmu"
fi fi
# find source path # find source path
...@@ -160,7 +160,7 @@ ar="${cross_prefix}${ar}" ...@@ -160,7 +160,7 @@ ar="${cross_prefix}${ar}"
strip="${cross_prefix}${strip}" strip="${cross_prefix}${strip}"
if test "$mingw32" = "yes" ; then if test "$mingw32" = "yes" ; then
target_list="i386-softmmu ppc-softmmu" target_list="i386-softmmu ppc-softmmu sparc-softmmu"
EXESUF=".exe" EXESUF=".exe"
gdbstub="no" gdbstub="no"
fi fi
......
...@@ -208,6 +208,11 @@ int cpu_exec(CPUState *env1) ...@@ -208,6 +208,11 @@ int cpu_exec(CPUState *env1)
env->exception_next_eip, 0); env->exception_next_eip, 0);
#elif defined(TARGET_PPC) #elif defined(TARGET_PPC)
do_interrupt(env); do_interrupt(env);
#elif defined(TARGET_SPARC)
do_interrupt(env->exception_index,
0,
env->error_code,
env->exception_next_pc, 0);
#endif #endif
} }
env->exception_index = -1; env->exception_index = -1;
...@@ -261,6 +266,14 @@ int cpu_exec(CPUState *env1) ...@@ -261,6 +266,14 @@ int cpu_exec(CPUState *env1)
env->interrupt_request &= ~CPU_INTERRUPT_TIMER; 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 #endif
if (interrupt_request & CPU_INTERRUPT_EXITTB) { if (interrupt_request & CPU_INTERRUPT_EXITTB) {
env->interrupt_request &= ~CPU_INTERRUPT_EXITTB; env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
......
...@@ -56,6 +56,7 @@ struct TranslationBlock; ...@@ -56,6 +56,7 @@ struct TranslationBlock;
extern uint16_t gen_opc_buf[OPC_BUF_SIZE]; extern uint16_t gen_opc_buf[OPC_BUF_SIZE];
extern uint32_t gen_opparam_buf[OPPARAM_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_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_cc_op[OPC_BUF_SIZE];
extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE]; extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
...@@ -541,8 +542,7 @@ extern spinlock_t tb_lock; ...@@ -541,8 +542,7 @@ extern spinlock_t tb_lock;
extern int tb_invalidated_flag; extern int tb_invalidated_flag;
#if (defined(TARGET_I386) || defined(TARGET_PPC)) && \ #if !defined(CONFIG_USER_ONLY)
!defined(CONFIG_USER_ONLY)
void tlb_fill(unsigned long addr, int is_write, int is_user, void tlb_fill(unsigned long addr, int is_write, int is_user,
void *retaddr); void *retaddr);
...@@ -585,6 +585,8 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr) ...@@ -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); is_user = ((env->hflags & HF_CPL_MASK) == 3);
#elif defined (TARGET_PPC) #elif defined (TARGET_PPC)
is_user = msr_pr; is_user = msr_pr;
#elif defined (TARGET_SPARC)
is_user = (env->psrs == 0);
#else #else
#error "Unimplemented !" #error "Unimplemented !"
#endif #endif
......
...@@ -1077,7 +1077,7 @@ static void breakpoint_invalidate(CPUState *env, target_ulong pc) ...@@ -1077,7 +1077,7 @@ static void breakpoint_invalidate(CPUState *env, target_ulong pc)
breakpoint is reached */ breakpoint is reached */
int cpu_breakpoint_insert(CPUState *env, target_ulong pc) 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; int i;
for(i = 0; i < env->nb_breakpoints; i++) { for(i = 0; i < env->nb_breakpoints; i++) {
...@@ -1099,7 +1099,7 @@ int cpu_breakpoint_insert(CPUState *env, target_ulong pc) ...@@ -1099,7 +1099,7 @@ int cpu_breakpoint_insert(CPUState *env, target_ulong pc)
/* remove a breakpoint */ /* remove a breakpoint */
int cpu_breakpoint_remove(CPUState *env, target_ulong pc) 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; int i;
for(i = 0; i < env->nb_breakpoints; i++) { for(i = 0; i < env->nb_breakpoints; i++) {
if (env->breakpoints[i] == pc) if (env->breakpoints[i] == pc)
...@@ -1122,7 +1122,7 @@ int cpu_breakpoint_remove(CPUState *env, target_ulong pc) ...@@ -1122,7 +1122,7 @@ int cpu_breakpoint_remove(CPUState *env, target_ulong pc)
CPU loop after each instruction */ CPU loop after each instruction */
void cpu_single_step(CPUState *env, int enabled) 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) { if (env->singlestep_enabled != enabled) {
env->singlestep_enabled = enabled; env->singlestep_enabled = enabled;
/* must flush all the translated code to avoid inconsistancies */ /* must flush all the translated code to avoid inconsistancies */
......
...@@ -157,42 +157,40 @@ static int put_packet(GDBState *s, char *buf) ...@@ -157,42 +157,40 @@ static int put_packet(GDBState *s, char *buf)
#if defined(TARGET_I386) #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) static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
{ {
uint32_t *registers = (uint32_t *)mem_buf;
int i, fpus; int i, fpus;
for(i = 0; i < 8; i++) { 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); registers[8] = env->eip;
to_le32(mem_buf + 9 * 4, env->eflags); registers[9] = env->eflags;
to_le32(mem_buf + 10 * 4, env->segs[R_CS].selector); registers[10] = env->segs[R_CS].selector;
to_le32(mem_buf + 11 * 4, env->segs[R_SS].selector); registers[11] = env->segs[R_SS].selector;
to_le32(mem_buf + 12 * 4, env->segs[R_DS].selector); registers[12] = env->segs[R_DS].selector;
to_le32(mem_buf + 13 * 4, env->segs[R_ES].selector); registers[13] = env->segs[R_ES].selector;
to_le32(mem_buf + 14 * 4, env->segs[R_FS].selector); registers[14] = env->segs[R_FS].selector;
to_le32(mem_buf + 15 * 4, env->segs[R_GS].selector); registers[15] = env->segs[R_GS].selector;
/* XXX: convert floats */ /* XXX: convert floats */
for(i = 0; i < 8; i++) { for(i = 0; i < 8; i++) {
memcpy(mem_buf + 16 * 4 + i * 10, &env->fpregs[i], 10); 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; fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
to_le32(mem_buf + 37 * 4, fpus); registers[37] = fpus;
to_le32(mem_buf + 38 * 4, 0); /* XXX: convert tags */ registers[38] = 0; /* XXX: convert tags */
to_le32(mem_buf + 39 * 4, 0); /* fiseg */ registers[39] = 0; /* fiseg */
to_le32(mem_buf + 40 * 4, 0); /* fioff */ registers[40] = 0; /* fioff */
to_le32(mem_buf + 41 * 4, 0); /* foseg */ registers[41] = 0; /* foseg */
to_le32(mem_buf + 42 * 4, 0); /* fooff */ registers[42] = 0; /* fooff */
to_le32(mem_buf + 43 * 4, 0); /* fop */ registers[43] = 0; /* fop */
for(i = 0; i < 16; i++)
tswapls(&registers[i]);
for(i = 36; i < 44; i++)
tswapls(&registers[i]);
return 44 * 4; return 44 * 4;
} }
...@@ -204,8 +202,8 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) ...@@ -204,8 +202,8 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
for(i = 0; i < 8; i++) { for(i = 0; i < 8; i++) {
env->regs[i] = tswapl(registers[i]); env->regs[i] = tswapl(registers[i]);
} }
env->eip = registers[8]; env->eip = tswapl(registers[8]);
env->eflags = registers[9]; env->eflags = tswapl(registers[9]);
#if defined(CONFIG_USER_ONLY) #if defined(CONFIG_USER_ONLY)
#define LOAD_SEG(index, sreg)\ #define LOAD_SEG(index, sreg)\
if (tswapl(registers[index]) != env->segs[sreg].selector)\ 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) ...@@ -220,15 +218,6 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
} }
#elif defined (TARGET_PPC) #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) static uint32_t from_le32 (uint32_t *buf)
{ {
uint8_t *p = (uint8_t *)buf; uint8_t *p = (uint8_t *)buf;
...@@ -243,24 +232,24 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) ...@@ -243,24 +232,24 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
/* fill in gprs */ /* fill in gprs */
for(i = 0; i < 32; i++) { for(i = 0; i < 32; i++) {
to_le32(&registers[i], env->gpr[i]); registers[i] = tswapl(env->gpr[i]);
} }
/* fill in fprs */ /* fill in fprs */
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
to_le32(&registers[(i * 2) + 32], *((uint32_t *)&env->fpr[i])); registers[(i * 2) + 32] = tswapl(*((uint32_t *)&env->fpr[i]));
to_le32(&registers[(i * 2) + 33], *((uint32_t *)&env->fpr[i] + 1)); registers[(i * 2) + 33] = tswapl(*((uint32_t *)&env->fpr[i] + 1));
} }
/* nip, msr, ccr, lnk, ctr, xer, mq */ /* nip, msr, ccr, lnk, ctr, xer, mq */
to_le32(&registers[96], (uint32_t)env->nip/* - 4*/); registers[96] = tswapl(env->nip);
to_le32(&registers[97], _load_msr(env)); registers[97] = tswapl(_load_msr(env));
tmp = 0; tmp = 0;
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
tmp |= env->crf[i] << (32 - ((i + 1) * 4)); tmp |= env->crf[i] << (32 - ((i + 1) * 4));
to_le32(&registers[98], tmp); registers[98] = tswapl(tmp);
to_le32(&registers[99], env->lr); registers[99] = tswapl(env->lr);
to_le32(&registers[100], env->ctr); registers[100] = tswapl(env->ctr);
to_le32(&registers[101], _load_xer(env)); registers[101] = tswapl(_load_xer(env));
to_le32(&registers[102], 0); registers[102] = 0;
return 103 * 4; return 103 * 4;
} }
...@@ -272,22 +261,90 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) ...@@ -272,22 +261,90 @@ static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
/* fill in gprs */ /* fill in gprs */
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
env->gpr[i] = from_le32(&registers[i]); env->gpr[i] = tswapl(registers[i]);
} }
/* fill in fprs */ /* fill in fprs */
for (i = 0; i < 32; i++) { for (i = 0; i < 32; i++) {
*((uint32_t *)&env->fpr[i]) = from_le32(&registers[(i * 2) + 32]); *((uint32_t *)&env->fpr[i]) = tswapl(registers[(i * 2) + 32]);
*((uint32_t *)&env->fpr[i] + 1) = from_le32(&registers[(i * 2) + 33]); *((uint32_t *)&env->fpr[i] + 1) = tswapl(registers[(i * 2) + 33]);
} }
/* nip, msr, ccr, lnk, ctr, xer, mq */ /* nip, msr, ccr, lnk, ctr, xer, mq */
env->nip = from_le32(&registers[96]); env->nip = tswapl(registers[96]);
_store_msr(env, from_le32(&registers[97])); _store_msr(env, tswapl(registers[97]));
registers[98] = from_le32(&registers[98]); registers[98] = tswapl(registers[98]);
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
env->crf[i] = (registers[98] >> (32 - ((i + 1) * 4))) & 0xF; env->crf[i] = (registers[98] >> (32 - ((i + 1) * 4))) & 0xF;
env->lr = from_le32(&registers[99]); env->lr = tswapl(registers[99]);
env->ctr = from_le32(&registers[100]); env->ctr = tswapl(registers[100]);
_store_xer(env, from_le32(&registers[101])); _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 #else
......
...@@ -883,18 +883,18 @@ static jmp_buf expr_env; ...@@ -883,18 +883,18 @@ static jmp_buf expr_env;
typedef struct MonitorDef { typedef struct MonitorDef {
const char *name; const char *name;
int offset; int offset;
int (*get_value)(struct MonitorDef *md); int (*get_value)(struct MonitorDef *md, int val);
} MonitorDef; } MonitorDef;
#if defined(TARGET_I386) #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; return cpu_single_env->eip + (long)cpu_single_env->segs[R_CS].base;
} }
#endif #endif
#if defined(TARGET_PPC) #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; unsigned int u;
int i; int i;
...@@ -906,7 +906,7 @@ static int monitor_get_ccr (struct MonitorDef *md) ...@@ -906,7 +906,7 @@ static int monitor_get_ccr (struct MonitorDef *md)
return u; 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) | return (cpu_single_env->msr[MSR_POW] << MSR_POW) |
(cpu_single_env->msr[MSR_ILE] << MSR_ILE) | (cpu_single_env->msr[MSR_ILE] << MSR_ILE) |
...@@ -925,7 +925,7 @@ static int monitor_get_msr (struct MonitorDef *md) ...@@ -925,7 +925,7 @@ static int monitor_get_msr (struct MonitorDef *md)
(cpu_single_env->msr[MSR_LE] << MSR_LE); (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) | return (cpu_single_env->xer[XER_SO] << XER_SO) |
(cpu_single_env->xer[XER_OV] << XER_OV) | (cpu_single_env->xer[XER_OV] << XER_OV) |
...@@ -933,25 +933,38 @@ static int monitor_get_xer (struct MonitorDef *md) ...@@ -933,25 +933,38 @@ static int monitor_get_xer (struct MonitorDef *md)
(cpu_single_env->xer[XER_BC] << XER_BC); (cpu_single_env->xer[XER_BC] << XER_BC);
} }
uint32_t cpu_ppc_load_decr (CPUState *env); static int monitor_get_decr (struct MonitorDef *md, int val)
static int monitor_get_decr (struct MonitorDef *md)
{ {
return cpu_ppc_load_decr(cpu_single_env); return cpu_ppc_load_decr(cpu_single_env);
} }
uint32_t cpu_ppc_load_tbu (CPUState *env); static int monitor_get_tbu (struct MonitorDef *md, int val)
static int monitor_get_tbu (struct MonitorDef *md)
{ {
return cpu_ppc_load_tbu(cpu_single_env); return cpu_ppc_load_tbu(cpu_single_env);
} }
uint32_t cpu_ppc_load_tbl (CPUState *env); static int monitor_get_tbl (struct MonitorDef *md, int val)
static int monitor_get_tbl (struct MonitorDef *md)
{ {
return cpu_ppc_load_tbl(cpu_single_env); return cpu_ppc_load_tbl(cpu_single_env);
} }
#endif #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[] = { static MonitorDef monitor_defs[] = {
#ifdef TARGET_I386 #ifdef TARGET_I386
...@@ -1037,6 +1050,78 @@ static MonitorDef monitor_defs[] = { ...@@ -1037,6 +1050,78 @@ static MonitorDef monitor_defs[] = {
{ "sr14", offsetof(CPUState, sr[14]) }, { "sr14", offsetof(CPUState, sr[14]) },
{ "sr15", offsetof(CPUState, sr[15]) }, { "sr15", offsetof(CPUState, sr[15]) },
/* Too lazy to put BATs and SPRs ... */ /* 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 #endif
{ NULL }, { NULL },
}; };
...@@ -1054,7 +1139,7 @@ static int get_monitor_def(int *pval, const char *name) ...@@ -1054,7 +1139,7 @@ static int get_monitor_def(int *pval, const char *name)
for(md = monitor_defs; md->name != NULL; md++) { for(md = monitor_defs; md->name != NULL; md++) {
if (compare_cmd(name, md->name)) { if (compare_cmd(name, md->name)) {
if (md->get_value) { if (md->get_value) {
*pval = md->get_value(md); *pval = md->get_value(md, md->offset);
} else { } else {
*pval = *(uint32_t *)((uint8_t *)cpu_single_env + md->offset); *pval = *(uint32_t *)((uint8_t *)cpu_single_env + md->offset);
} }
......
...@@ -178,7 +178,8 @@ static void bootp_reply(struct bootp_t *bp) ...@@ -178,7 +178,8 @@ static void bootp_reply(struct bootp_t *bp)
rbp->bp_hlen = 6; rbp->bp_hlen = 6;
memcpy(rbp->bp_hwaddr, bp->bp_hwaddr, 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; q = rbp->bp_vend;
memcpy(q, rfc1533_cookie, 4); memcpy(q, rfc1533_cookie, 4);
......
...@@ -55,6 +55,8 @@ ...@@ -55,6 +55,8 @@
#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3) #define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)
#elif defined (TARGET_PPC) #elif defined (TARGET_PPC)
#define CPU_MEM_INDEX (msr_pr) #define CPU_MEM_INDEX (msr_pr)
#elif defined (TARGET_SPARC)
#define CPU_MEM_INDEX ((env->psrs) == 0)
#endif #endif
#define MMUSUFFIX _mmu #define MMUSUFFIX _mmu
...@@ -64,6 +66,8 @@ ...@@ -64,6 +66,8 @@
#define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3) #define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)
#elif defined (TARGET_PPC) #elif defined (TARGET_PPC)
#define CPU_MEM_INDEX (msr_pr) #define CPU_MEM_INDEX (msr_pr)
#elif defined (TARGET_SPARC)
#define CPU_MEM_INDEX ((env->psrs) == 0)
#endif #endif
#define MMUSUFFIX _cmmu #define MMUSUFFIX _cmmu
......
...@@ -46,6 +46,8 @@ uint32_t gen_opc_pc[OPC_BUF_SIZE]; ...@@ -46,6 +46,8 @@ uint32_t gen_opc_pc[OPC_BUF_SIZE];
uint8_t gen_opc_instr_start[OPC_BUF_SIZE]; uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
#if defined(TARGET_I386) #if defined(TARGET_I386)
uint8_t gen_opc_cc_op[OPC_BUF_SIZE]; uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
#elif defined(TARGET_SPARC)
uint32_t gen_opc_npc[OPC_BUF_SIZE];
#endif #endif
int code_copy_enabled = 1; int code_copy_enabled = 1;
...@@ -208,6 +210,7 @@ int cpu_restore_state(TranslationBlock *tb, ...@@ -208,6 +210,7 @@ int cpu_restore_state(TranslationBlock *tb,
#elif defined(TARGET_SPARC) #elif defined(TARGET_SPARC)
/* XXX: restore npc too */ /* XXX: restore npc too */
env->pc = gen_opc_pc[j]; env->pc = gen_opc_pc[j];
env->npc = gen_opc_npc[j];
#elif defined(TARGET_PPC) #elif defined(TARGET_PPC)
{ {
int type; int type;
......
...@@ -710,7 +710,7 @@ static void qemu_run_timers(QEMUTimer **ptimer_head, int64_t current_time) ...@@ -710,7 +710,7 @@ static void qemu_run_timers(QEMUTimer **ptimer_head, int64_t current_time)
for(;;) { for(;;) {
ts = *ptimer_head; ts = *ptimer_head;
if (ts->expire_time > current_time) if (!ts || ts->expire_time > current_time)
break; break;
/* remove timer from the list before calling the callback */ /* remove timer from the list before calling the callback */
*ptimer_head = ts->next; *ptimer_head = ts->next;
...@@ -2162,6 +2162,15 @@ void cpu_save(QEMUFile *f, void *opaque) ...@@ -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) int cpu_load(QEMUFile *f, void *opaque, int version_id)
{ {
return 0; return 0;
...@@ -3336,6 +3345,10 @@ int main(int argc, char **argv) ...@@ -3336,6 +3345,10 @@ int main(int argc, char **argv)
ppc_init(ram_size, vga_ram_size, boot_device, ppc_init(ram_size, vga_ram_size, boot_device,
ds, fd_filename, snapshot, ds, fd_filename, snapshot,
kernel_filename, kernel_cmdline, initrd_filename); 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 #endif
gui_timer = qemu_new_timer(rt_clock, gui_update, NULL); gui_timer = qemu_new_timer(rt_clock, gui_update, NULL);
......
...@@ -664,6 +664,28 @@ extern CPUWriteMemoryFunc *PPC_io_write[]; ...@@ -664,6 +664,28 @@ extern CPUWriteMemoryFunc *PPC_io_write[];
extern CPUReadMemoryFunc *PPC_io_read[]; extern CPUReadMemoryFunc *PPC_io_read[];
extern int prep_enabled; 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 */ /* NVRAM helpers */
#include "hw/m48t59.h" #include "hw/m48t59.h"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册