full system SPARC emulation (Blue Swirl)

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1087 c046a42c-6fe2-441c-8c8c-71466251a162
This commit is contained in:
bellard 2004-09-30 22:22:08 +00:00
parent 4971b827da
commit e95c8d51c2
14 changed files with 307 additions and 78 deletions

View File

@ -12,3 +12,4 @@ qemu.1
qemu.pod
sparc-user
qemu-img
sparc-softmmu

View File

@ -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:

View File

@ -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)

6
configure vendored
View File

@ -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

View File

@ -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;

View File

@ -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

6
exec.c
View File

@ -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 */

167
gdbstub.c
View File

@ -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(&registers[i]);
for(i = 36; i < 44; i++)
tswapls(&registers[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(&registers[i], env->gpr[i]);
registers[i] = tswapl(env->gpr[i]);
}
/* fill in fprs */
for (i = 0; i < 32; i++) {
to_le32(&registers[(i * 2) + 32], *((uint32_t *)&env->fpr[i]));
to_le32(&registers[(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(&registers[96], (uint32_t)env->nip/* - 4*/);
to_le32(&registers[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(&registers[98], tmp);
to_le32(&registers[99], env->lr);
to_le32(&registers[100], env->ctr);
to_le32(&registers[101], _load_xer(env));
to_le32(&registers[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(&registers[i]);
env->gpr[i] = tswapl(registers[i]);
}
/* fill in fprs */
for (i = 0; i < 32; i++) {
*((uint32_t *)&env->fpr[i]) = from_le32(&registers[(i * 2) + 32]);
*((uint32_t *)&env->fpr[i] + 1) = from_le32(&registers[(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(&registers[96]);
_store_msr(env, from_le32(&registers[97]));
registers[98] = from_le32(&registers[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(&registers[99]);
env->ctr = from_le32(&registers[100]);
_store_xer(env, from_le32(&registers[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

109
monitor.c
View File

@ -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);
}

View File

@ -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);

View File

@ -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

View File

@ -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;

15
vl.c
View File

@ -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);

22
vl.h
View File

@ -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"