Commit e95c8d51c2a47d7ccb422f83446cb91a18f8f37d

Authored by bellard
1 parent 4971b827

full system SPARC emulation (Blue Swirl)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1087 c046a42c-6fe2-441c-8c8c-71466251a162
.cvsignore
@@ -12,3 +12,4 @@ qemu.1 @@ -12,3 +12,4 @@ qemu.1
12 qemu.pod 12 qemu.pod
13 sparc-user 13 sparc-user
14 qemu-img 14 qemu-img
  15 +sparc-softmmu
Changelog
@@ -17,6 +17,7 @@ version 0.6.1: @@ -17,6 +17,7 @@ version 0.6.1:
17 - Fixed Fedora Core 2 problems (now you can run qemu without any 17 - Fixed Fedora Core 2 problems (now you can run qemu without any
18 LD_ASSUME_KERNEL tricks on FC2) 18 LD_ASSUME_KERNEL tricks on FC2)
19 - DHCP fix for Windows (accept DHCPREQUEST alone) 19 - DHCP fix for Windows (accept DHCPREQUEST alone)
  20 + - SPARC system emulation (Blue Swirl)
20 21
21 version 0.6.0: 22 version 0.6.0:
22 23
Makefile.target
@@ -63,6 +63,26 @@ endif @@ -63,6 +63,26 @@ endif
63 endif # ARCH = amd64 63 endif # ARCH = amd64
64 64
65 endif # TARGET_ARCH = ppc 65 endif # TARGET_ARCH = ppc
  66 +
  67 +ifeq ($(TARGET_ARCH), sparc)
  68 +
  69 +ifeq ($(ARCH), ppc)
  70 +PROGS+=$(QEMU_SYSTEM)
  71 +endif
  72 +
  73 +ifeq ($(ARCH), i386)
  74 +ifdef CONFIG_SOFTMMU
  75 +PROGS+=$(QEMU_SYSTEM)
  76 +endif
  77 +endif # ARCH = i386
  78 +
  79 +ifeq ($(ARCH), amd64)
  80 +ifdef CONFIG_SOFTMMU
  81 +PROGS+=$(QEMU_SYSTEM)
  82 +endif
  83 +endif # ARCH = amd64
  84 +
  85 +endif # TARGET_ARCH = sparc
66 endif # !CONFIG_USER_ONLY 86 endif # !CONFIG_USER_ONLY
67 87
68 ifdef CONFIG_STATIC 88 ifdef CONFIG_STATIC
@@ -201,6 +221,10 @@ ifeq ($(TARGET_ARCH), ppc) @@ -201,6 +221,10 @@ ifeq ($(TARGET_ARCH), ppc)
201 LIBOBJS+= op_helper.o helper.o 221 LIBOBJS+= op_helper.o helper.o
202 endif 222 endif
203 223
  224 +ifeq ($(TARGET_ARCH), sparc)
  225 +LIBOBJS+= op_helper.o helper.o
  226 +endif
  227 +
204 # NOTE: the disassembler code is only needed for debugging 228 # NOTE: the disassembler code is only needed for debugging
205 LIBOBJS+=disas.o 229 LIBOBJS+=disas.o
206 ifeq ($(findstring i386, $(TARGET_ARCH) $(ARCH)),i386) 230 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
254 VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o 278 VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o
255 VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o 279 VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o
256 endif 280 endif
  281 +ifeq ($(TARGET_ARCH), sparc)
  282 +VL_OBJS+= sun4m.o tcx.o lance.o iommu.o sched.o m48t08.o magic-load.o
  283 +endif
257 ifdef CONFIG_GDBSTUB 284 ifdef CONFIG_GDBSTUB
258 VL_OBJS+=gdbstub.o 285 VL_OBJS+=gdbstub.o
259 endif 286 endif
@@ -325,7 +352,7 @@ op.o: op.c op_template.h @@ -325,7 +352,7 @@ op.o: op.c op_template.h
325 endif 352 endif
326 353
327 ifeq ($(TARGET_ARCH), sparc) 354 ifeq ($(TARGET_ARCH), sparc)
328 -op.o: op.c op_template.h 355 +op.o: op.c op_template.h op_mem.h
329 endif 356 endif
330 357
331 ifeq ($(TARGET_ARCH), ppc) 358 ifeq ($(TARGET_ARCH), ppc)
configure
@@ -27,7 +27,7 @@ ar="ar" @@ -27,7 +27,7 @@ ar="ar"
27 make="make" 27 make="make"
28 strip="strip" 28 strip="strip"
29 cpu=`uname -m` 29 cpu=`uname -m`
30 -target_list="i386-user i386 i386-softmmu arm-user sparc-user ppc-user ppc-softmmu" 30 +target_list="i386-user i386 i386-softmmu arm-user sparc-user ppc-user ppc-softmmu sparc-softmmu"
31 case "$cpu" in 31 case "$cpu" in
32 i386|i486|i586|i686|i86pc|BePC) 32 i386|i486|i586|i686|i86pc|BePC)
33 cpu="i386" 33 cpu="i386"
@@ -99,7 +99,7 @@ if [ "$bsd" = "yes" ] ; then @@ -99,7 +99,7 @@ if [ "$bsd" = "yes" ] ; then
99 if [ ! "$darwin" = "yes" ] ; then 99 if [ ! "$darwin" = "yes" ] ; then
100 make="gmake" 100 make="gmake"
101 fi 101 fi
102 - target_list="i386-softmmu ppc-softmmu" 102 + target_list="i386-softmmu ppc-softmmu sparc-softmmu"
103 fi 103 fi
104 104
105 # find source path 105 # find source path
@@ -160,7 +160,7 @@ ar="${cross_prefix}${ar}" @@ -160,7 +160,7 @@ ar="${cross_prefix}${ar}"
160 strip="${cross_prefix}${strip}" 160 strip="${cross_prefix}${strip}"
161 161
162 if test "$mingw32" = "yes" ; then 162 if test "$mingw32" = "yes" ; then
163 - target_list="i386-softmmu ppc-softmmu" 163 + target_list="i386-softmmu ppc-softmmu sparc-softmmu"
164 EXESUF=".exe" 164 EXESUF=".exe"
165 gdbstub="no" 165 gdbstub="no"
166 fi 166 fi
cpu-exec.c
@@ -208,6 +208,11 @@ int cpu_exec(CPUState *env1) @@ -208,6 +208,11 @@ int cpu_exec(CPUState *env1)
208 env->exception_next_eip, 0); 208 env->exception_next_eip, 0);
209 #elif defined(TARGET_PPC) 209 #elif defined(TARGET_PPC)
210 do_interrupt(env); 210 do_interrupt(env);
  211 +#elif defined(TARGET_SPARC)
  212 + do_interrupt(env->exception_index,
  213 + 0,
  214 + env->error_code,
  215 + env->exception_next_pc, 0);
211 #endif 216 #endif
212 } 217 }
213 env->exception_index = -1; 218 env->exception_index = -1;
@@ -261,6 +266,14 @@ int cpu_exec(CPUState *env1) @@ -261,6 +266,14 @@ int cpu_exec(CPUState *env1)
261 env->interrupt_request &= ~CPU_INTERRUPT_TIMER; 266 env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
262 } 267 }
263 } 268 }
  269 +#elif defined(TARGET_SPARC)
  270 + if (interrupt_request & CPU_INTERRUPT_HARD) {
  271 + do_interrupt(0, 0, 0, 0, 0);
  272 + env->interrupt_request &= ~CPU_INTERRUPT_HARD;
  273 + } else if (interrupt_request & CPU_INTERRUPT_TIMER) {
  274 + //do_interrupt(0, 0, 0, 0, 0);
  275 + env->interrupt_request &= ~CPU_INTERRUPT_TIMER;
  276 + }
264 #endif 277 #endif
265 if (interrupt_request & CPU_INTERRUPT_EXITTB) { 278 if (interrupt_request & CPU_INTERRUPT_EXITTB) {
266 env->interrupt_request &= ~CPU_INTERRUPT_EXITTB; 279 env->interrupt_request &= ~CPU_INTERRUPT_EXITTB;
exec-all.h
@@ -56,6 +56,7 @@ struct TranslationBlock; @@ -56,6 +56,7 @@ struct TranslationBlock;
56 extern uint16_t gen_opc_buf[OPC_BUF_SIZE]; 56 extern uint16_t gen_opc_buf[OPC_BUF_SIZE];
57 extern uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE]; 57 extern uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE];
58 extern uint32_t gen_opc_pc[OPC_BUF_SIZE]; 58 extern uint32_t gen_opc_pc[OPC_BUF_SIZE];
  59 +extern uint32_t gen_opc_npc[OPC_BUF_SIZE];
59 extern uint8_t gen_opc_cc_op[OPC_BUF_SIZE]; 60 extern uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
60 extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE]; 61 extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
61 62
@@ -541,8 +542,7 @@ extern spinlock_t tb_lock; @@ -541,8 +542,7 @@ extern spinlock_t tb_lock;
541 542
542 extern int tb_invalidated_flag; 543 extern int tb_invalidated_flag;
543 544
544 -#if (defined(TARGET_I386) || defined(TARGET_PPC)) && \  
545 - !defined(CONFIG_USER_ONLY) 545 +#if !defined(CONFIG_USER_ONLY)
546 546
547 void tlb_fill(unsigned long addr, int is_write, int is_user, 547 void tlb_fill(unsigned long addr, int is_write, int is_user,
548 void *retaddr); 548 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)
585 is_user = ((env->hflags & HF_CPL_MASK) == 3); 585 is_user = ((env->hflags & HF_CPL_MASK) == 3);
586 #elif defined (TARGET_PPC) 586 #elif defined (TARGET_PPC)
587 is_user = msr_pr; 587 is_user = msr_pr;
  588 +#elif defined (TARGET_SPARC)
  589 + is_user = (env->psrs == 0);
588 #else 590 #else
589 #error "Unimplemented !" 591 #error "Unimplemented !"
590 #endif 592 #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)
1077 breakpoint is reached */ 1077 breakpoint is reached */
1078 int cpu_breakpoint_insert(CPUState *env, target_ulong pc) 1078 int cpu_breakpoint_insert(CPUState *env, target_ulong pc)
1079 { 1079 {
1080 -#if defined(TARGET_I386) || defined(TARGET_PPC) 1080 +#if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_SPARC)
1081 int i; 1081 int i;
1082 1082
1083 for(i = 0; i < env->nb_breakpoints; i++) { 1083 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)
1099 /* remove a breakpoint */ 1099 /* remove a breakpoint */
1100 int cpu_breakpoint_remove(CPUState *env, target_ulong pc) 1100 int cpu_breakpoint_remove(CPUState *env, target_ulong pc)
1101 { 1101 {
1102 -#if defined(TARGET_I386) || defined(TARGET_PPC) 1102 +#if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_SPARC)
1103 int i; 1103 int i;
1104 for(i = 0; i < env->nb_breakpoints; i++) { 1104 for(i = 0; i < env->nb_breakpoints; i++) {
1105 if (env->breakpoints[i] == pc) 1105 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)
1122 CPU loop after each instruction */ 1122 CPU loop after each instruction */
1123 void cpu_single_step(CPUState *env, int enabled) 1123 void cpu_single_step(CPUState *env, int enabled)
1124 { 1124 {
1125 -#if defined(TARGET_I386) || defined(TARGET_PPC) 1125 +#if defined(TARGET_I386) || defined(TARGET_PPC) || defined(TARGET_SPARC)
1126 if (env->singlestep_enabled != enabled) { 1126 if (env->singlestep_enabled != enabled) {
1127 env->singlestep_enabled = enabled; 1127 env->singlestep_enabled = enabled;
1128 /* must flush all the translated code to avoid inconsistancies */ 1128 /* must flush all the translated code to avoid inconsistancies */
gdbstub.c
@@ -157,42 +157,40 @@ static int put_packet(GDBState *s, char *buf) @@ -157,42 +157,40 @@ static int put_packet(GDBState *s, char *buf)
157 157
158 #if defined(TARGET_I386) 158 #if defined(TARGET_I386)
159 159
160 -static void to_le32(uint8_t *p, int v)  
161 -{  
162 - p[0] = v;  
163 - p[1] = v >> 8;  
164 - p[2] = v >> 16;  
165 - p[3] = v >> 24;  
166 -}  
167 -  
168 static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) 160 static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
169 { 161 {
  162 + uint32_t *registers = (uint32_t *)mem_buf;
170 int i, fpus; 163 int i, fpus;
171 164
172 for(i = 0; i < 8; i++) { 165 for(i = 0; i < 8; i++) {
173 - to_le32(mem_buf + i * 4, env->regs[i]); 166 + registers[i] = env->regs[i];
174 } 167 }
175 - to_le32(mem_buf + 8 * 4, env->eip);  
176 - to_le32(mem_buf + 9 * 4, env->eflags);  
177 - to_le32(mem_buf + 10 * 4, env->segs[R_CS].selector);  
178 - to_le32(mem_buf + 11 * 4, env->segs[R_SS].selector);  
179 - to_le32(mem_buf + 12 * 4, env->segs[R_DS].selector);  
180 - to_le32(mem_buf + 13 * 4, env->segs[R_ES].selector);  
181 - to_le32(mem_buf + 14 * 4, env->segs[R_FS].selector);  
182 - to_le32(mem_buf + 15 * 4, env->segs[R_GS].selector); 168 + registers[8] = env->eip;
  169 + registers[9] = env->eflags;
  170 + registers[10] = env->segs[R_CS].selector;
  171 + registers[11] = env->segs[R_SS].selector;
  172 + registers[12] = env->segs[R_DS].selector;
  173 + registers[13] = env->segs[R_ES].selector;
  174 + registers[14] = env->segs[R_FS].selector;
  175 + registers[15] = env->segs[R_GS].selector;
183 /* XXX: convert floats */ 176 /* XXX: convert floats */
184 for(i = 0; i < 8; i++) { 177 for(i = 0; i < 8; i++) {
185 memcpy(mem_buf + 16 * 4 + i * 10, &env->fpregs[i], 10); 178 memcpy(mem_buf + 16 * 4 + i * 10, &env->fpregs[i], 10);
186 } 179 }
187 - to_le32(mem_buf + 36 * 4, env->fpuc); 180 + registers[36] = env->fpuc;
188 fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; 181 fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11;
189 - to_le32(mem_buf + 37 * 4, fpus);  
190 - to_le32(mem_buf + 38 * 4, 0); /* XXX: convert tags */  
191 - to_le32(mem_buf + 39 * 4, 0); /* fiseg */  
192 - to_le32(mem_buf + 40 * 4, 0); /* fioff */  
193 - to_le32(mem_buf + 41 * 4, 0); /* foseg */  
194 - to_le32(mem_buf + 42 * 4, 0); /* fooff */  
195 - to_le32(mem_buf + 43 * 4, 0); /* fop */ 182 + registers[37] = fpus;
  183 + registers[38] = 0; /* XXX: convert tags */
  184 + registers[39] = 0; /* fiseg */
  185 + registers[40] = 0; /* fioff */
  186 + registers[41] = 0; /* foseg */
  187 + registers[42] = 0; /* fooff */
  188 + registers[43] = 0; /* fop */
  189 +
  190 + for(i = 0; i < 16; i++)
  191 + tswapls(&registers[i]);
  192 + for(i = 36; i < 44; i++)
  193 + tswapls(&registers[i]);
196 return 44 * 4; 194 return 44 * 4;
197 } 195 }
198 196
@@ -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)
204 for(i = 0; i < 8; i++) { 202 for(i = 0; i < 8; i++) {
205 env->regs[i] = tswapl(registers[i]); 203 env->regs[i] = tswapl(registers[i]);
206 } 204 }
207 - env->eip = registers[8];  
208 - env->eflags = registers[9]; 205 + env->eip = tswapl(registers[8]);
  206 + env->eflags = tswapl(registers[9]);
209 #if defined(CONFIG_USER_ONLY) 207 #if defined(CONFIG_USER_ONLY)
210 #define LOAD_SEG(index, sreg)\ 208 #define LOAD_SEG(index, sreg)\
211 if (tswapl(registers[index]) != env->segs[sreg].selector)\ 209 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)
220 } 218 }
221 219
222 #elif defined (TARGET_PPC) 220 #elif defined (TARGET_PPC)
223 -static void to_le32(uint32_t *buf, uint32_t v)  
224 -{  
225 - uint8_t *p = (uint8_t *)buf;  
226 - p[3] = v;  
227 - p[2] = v >> 8;  
228 - p[1] = v >> 16;  
229 - p[0] = v >> 24;  
230 -}  
231 -  
232 static uint32_t from_le32 (uint32_t *buf) 221 static uint32_t from_le32 (uint32_t *buf)
233 { 222 {
234 uint8_t *p = (uint8_t *)buf; 223 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)
243 232
244 /* fill in gprs */ 233 /* fill in gprs */
245 for(i = 0; i < 32; i++) { 234 for(i = 0; i < 32; i++) {
246 - to_le32(&registers[i], env->gpr[i]); 235 + registers[i] = tswapl(env->gpr[i]);
247 } 236 }
248 /* fill in fprs */ 237 /* fill in fprs */
249 for (i = 0; i < 32; i++) { 238 for (i = 0; i < 32; i++) {
250 - to_le32(&registers[(i * 2) + 32], *((uint32_t *)&env->fpr[i]));  
251 - to_le32(&registers[(i * 2) + 33], *((uint32_t *)&env->fpr[i] + 1)); 239 + registers[(i * 2) + 32] = tswapl(*((uint32_t *)&env->fpr[i]));
  240 + registers[(i * 2) + 33] = tswapl(*((uint32_t *)&env->fpr[i] + 1));
252 } 241 }
253 /* nip, msr, ccr, lnk, ctr, xer, mq */ 242 /* nip, msr, ccr, lnk, ctr, xer, mq */
254 - to_le32(&registers[96], (uint32_t)env->nip/* - 4*/);  
255 - to_le32(&registers[97], _load_msr(env)); 243 + registers[96] = tswapl(env->nip);
  244 + registers[97] = tswapl(_load_msr(env));
256 tmp = 0; 245 tmp = 0;
257 for (i = 0; i < 8; i++) 246 for (i = 0; i < 8; i++)
258 tmp |= env->crf[i] << (32 - ((i + 1) * 4)); 247 tmp |= env->crf[i] << (32 - ((i + 1) * 4));
259 - to_le32(&registers[98], tmp);  
260 - to_le32(&registers[99], env->lr);  
261 - to_le32(&registers[100], env->ctr);  
262 - to_le32(&registers[101], _load_xer(env));  
263 - to_le32(&registers[102], 0); 248 + registers[98] = tswapl(tmp);
  249 + registers[99] = tswapl(env->lr);
  250 + registers[100] = tswapl(env->ctr);
  251 + registers[101] = tswapl(_load_xer(env));
  252 + registers[102] = 0;
264 253
265 return 103 * 4; 254 return 103 * 4;
266 } 255 }
@@ -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)
272 261
273 /* fill in gprs */ 262 /* fill in gprs */
274 for (i = 0; i < 32; i++) { 263 for (i = 0; i < 32; i++) {
275 - env->gpr[i] = from_le32(&registers[i]); 264 + env->gpr[i] = tswapl(registers[i]);
276 } 265 }
277 /* fill in fprs */ 266 /* fill in fprs */
278 for (i = 0; i < 32; i++) { 267 for (i = 0; i < 32; i++) {
279 - *((uint32_t *)&env->fpr[i]) = from_le32(&registers[(i * 2) + 32]);  
280 - *((uint32_t *)&env->fpr[i] + 1) = from_le32(&registers[(i * 2) + 33]); 268 + *((uint32_t *)&env->fpr[i]) = tswapl(registers[(i * 2) + 32]);
  269 + *((uint32_t *)&env->fpr[i] + 1) = tswapl(registers[(i * 2) + 33]);
281 } 270 }
282 /* nip, msr, ccr, lnk, ctr, xer, mq */ 271 /* nip, msr, ccr, lnk, ctr, xer, mq */
283 - env->nip = from_le32(&registers[96]);  
284 - _store_msr(env, from_le32(&registers[97]));  
285 - registers[98] = from_le32(&registers[98]); 272 + env->nip = tswapl(registers[96]);
  273 + _store_msr(env, tswapl(registers[97]));
  274 + registers[98] = tswapl(registers[98]);
286 for (i = 0; i < 8; i++) 275 for (i = 0; i < 8; i++)
287 env->crf[i] = (registers[98] >> (32 - ((i + 1) * 4))) & 0xF; 276 env->crf[i] = (registers[98] >> (32 - ((i + 1) * 4))) & 0xF;
288 - env->lr = from_le32(&registers[99]);  
289 - env->ctr = from_le32(&registers[100]);  
290 - _store_xer(env, from_le32(&registers[101])); 277 + env->lr = tswapl(registers[99]);
  278 + env->ctr = tswapl(registers[100]);
  279 + _store_xer(env, tswapl(registers[101]));
  280 +}
  281 +#elif defined (TARGET_SPARC)
  282 +static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
  283 +{
  284 + uint32_t *registers = (uint32_t *)mem_buf, tmp;
  285 + int i;
  286 +
  287 + /* fill in g0..g7 */
  288 + for(i = 0; i < 7; i++) {
  289 + registers[i] = tswapl(env->gregs[i]);
  290 + }
  291 + /* fill in register window */
  292 + for(i = 0; i < 24; i++) {
  293 + registers[i + 8] = tswapl(env->regwptr[i]);
  294 + }
  295 + /* fill in fprs */
  296 + for (i = 0; i < 32; i++) {
  297 + registers[i + 32] = tswapl(*((uint32_t *)&env->fpr[i]));
  298 + }
  299 + /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
  300 + registers[64] = tswapl(env->y);
  301 + tmp = (0<<28) | (4<<24) | env->psr \
  302 + | (env->psrs? PSR_S : 0) \
  303 + | (env->psrs? PSR_PS : 0) \
  304 + | (env->psret? PSR_ET : 0) \
  305 + | env->cwp;
  306 + registers[65] = tswapl(tmp);
  307 + registers[66] = tswapl(env->wim);
  308 + registers[67] = tswapl(env->tbr);
  309 + registers[68] = tswapl(env->pc);
  310 + registers[69] = tswapl(env->npc);
  311 + registers[70] = tswapl(env->fsr);
  312 + registers[71] = 0; /* csr */
  313 + registers[72] = 0;
  314 +
  315 + return 73 * 4;
  316 +}
  317 +
  318 +static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
  319 +{
  320 + uint32_t *registers = (uint32_t *)mem_buf, tmp;
  321 + int i;
  322 +
  323 + /* fill in g0..g7 */
  324 + for(i = 0; i < 7; i++) {
  325 + env->gregs[i] = tswapl(registers[i]);
  326 + }
  327 + /* fill in register window */
  328 + for(i = 0; i < 24; i++) {
  329 + env->regwptr[i] = tswapl(registers[i]);
  330 + }
  331 + /* fill in fprs */
  332 + for (i = 0; i < 32; i++) {
  333 + *((uint32_t *)&env->fpr[i]) = tswapl(registers[i + 32]);
  334 + }
  335 + /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
  336 + env->y = tswapl(registers[64]);
  337 + tmp = tswapl(registers[65]);
  338 + env->psr = tmp & ~PSR_ICC;
  339 + env->psrs = (tmp & PSR_S)? 1 : 0;
  340 + env->psrps = (tmp & PSR_PS)? 1 : 0;
  341 + env->psret = (tmp & PSR_ET)? 1 : 0;
  342 + env->cwp = (tmp & PSR_CWP);
  343 + env->wim = tswapl(registers[66]);
  344 + env->tbr = tswapl(registers[67]);
  345 + env->pc = tswapl(registers[68]);
  346 + env->npc = tswapl(registers[69]);
  347 + env->fsr = tswapl(registers[70]);
291 } 348 }
292 #else 349 #else
293 350
monitor.c
@@ -883,18 +883,18 @@ static jmp_buf expr_env; @@ -883,18 +883,18 @@ static jmp_buf expr_env;
883 typedef struct MonitorDef { 883 typedef struct MonitorDef {
884 const char *name; 884 const char *name;
885 int offset; 885 int offset;
886 - int (*get_value)(struct MonitorDef *md); 886 + int (*get_value)(struct MonitorDef *md, int val);
887 } MonitorDef; 887 } MonitorDef;
888 888
889 #if defined(TARGET_I386) 889 #if defined(TARGET_I386)
890 -static int monitor_get_pc (struct MonitorDef *md) 890 +static int monitor_get_pc (struct MonitorDef *md, int val)
891 { 891 {
892 return cpu_single_env->eip + (long)cpu_single_env->segs[R_CS].base; 892 return cpu_single_env->eip + (long)cpu_single_env->segs[R_CS].base;
893 } 893 }
894 #endif 894 #endif
895 895
896 #if defined(TARGET_PPC) 896 #if defined(TARGET_PPC)
897 -static int monitor_get_ccr (struct MonitorDef *md) 897 +static int monitor_get_ccr (struct MonitorDef *md, int val)
898 { 898 {
899 unsigned int u; 899 unsigned int u;
900 int i; 900 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)
906 return u; 906 return u;
907 } 907 }
908 908
909 -static int monitor_get_msr (struct MonitorDef *md) 909 +static int monitor_get_msr (struct MonitorDef *md, int val)
910 { 910 {
911 return (cpu_single_env->msr[MSR_POW] << MSR_POW) | 911 return (cpu_single_env->msr[MSR_POW] << MSR_POW) |
912 (cpu_single_env->msr[MSR_ILE] << MSR_ILE) | 912 (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)
925 (cpu_single_env->msr[MSR_LE] << MSR_LE); 925 (cpu_single_env->msr[MSR_LE] << MSR_LE);
926 } 926 }
927 927
928 -static int monitor_get_xer (struct MonitorDef *md) 928 +static int monitor_get_xer (struct MonitorDef *md, int val)
929 { 929 {
930 return (cpu_single_env->xer[XER_SO] << XER_SO) | 930 return (cpu_single_env->xer[XER_SO] << XER_SO) |
931 (cpu_single_env->xer[XER_OV] << XER_OV) | 931 (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)
933 (cpu_single_env->xer[XER_BC] << XER_BC); 933 (cpu_single_env->xer[XER_BC] << XER_BC);
934 } 934 }
935 935
936 -uint32_t cpu_ppc_load_decr (CPUState *env);  
937 -static int monitor_get_decr (struct MonitorDef *md) 936 +static int monitor_get_decr (struct MonitorDef *md, int val)
938 { 937 {
939 return cpu_ppc_load_decr(cpu_single_env); 938 return cpu_ppc_load_decr(cpu_single_env);
940 } 939 }
941 940
942 -uint32_t cpu_ppc_load_tbu (CPUState *env);  
943 -static int monitor_get_tbu (struct MonitorDef *md) 941 +static int monitor_get_tbu (struct MonitorDef *md, int val)
944 { 942 {
945 return cpu_ppc_load_tbu(cpu_single_env); 943 return cpu_ppc_load_tbu(cpu_single_env);
946 } 944 }
947 945
948 -uint32_t cpu_ppc_load_tbl (CPUState *env);  
949 -static int monitor_get_tbl (struct MonitorDef *md) 946 +static int monitor_get_tbl (struct MonitorDef *md, int val)
950 { 947 {
951 return cpu_ppc_load_tbl(cpu_single_env); 948 return cpu_ppc_load_tbl(cpu_single_env);
952 } 949 }
953 #endif 950 #endif
954 951
  952 +#if defined(TARGET_SPARC)
  953 +static int monitor_get_psr (struct MonitorDef *md, int val)
  954 +{
  955 + return (0<<28) | (4<<24) | cpu_single_env->psr \
  956 + | (cpu_single_env->psrs? PSR_S : 0) \
  957 + | (cpu_single_env->psrs? PSR_PS : 0) \
  958 + | (cpu_single_env->psret? PSR_ET : 0) \
  959 + | cpu_single_env->cwp;
  960 +}
  961 +
  962 +static int monitor_get_reg(struct MonitorDef *md, int val)
  963 +{
  964 + return cpu_single_env->regwptr[val];
  965 +}
  966 +#endif
  967 +
955 static MonitorDef monitor_defs[] = { 968 static MonitorDef monitor_defs[] = {
956 #ifdef TARGET_I386 969 #ifdef TARGET_I386
957 970
@@ -1037,6 +1050,78 @@ static MonitorDef monitor_defs[] = { @@ -1037,6 +1050,78 @@ static MonitorDef monitor_defs[] = {
1037 { "sr14", offsetof(CPUState, sr[14]) }, 1050 { "sr14", offsetof(CPUState, sr[14]) },
1038 { "sr15", offsetof(CPUState, sr[15]) }, 1051 { "sr15", offsetof(CPUState, sr[15]) },
1039 /* Too lazy to put BATs and SPRs ... */ 1052 /* Too lazy to put BATs and SPRs ... */
  1053 +#elif defined(TARGET_SPARC)
  1054 + { "g0", offsetof(CPUState, gregs[0]) },
  1055 + { "g1", offsetof(CPUState, gregs[1]) },
  1056 + { "g2", offsetof(CPUState, gregs[2]) },
  1057 + { "g3", offsetof(CPUState, gregs[3]) },
  1058 + { "g4", offsetof(CPUState, gregs[4]) },
  1059 + { "g5", offsetof(CPUState, gregs[5]) },
  1060 + { "g6", offsetof(CPUState, gregs[6]) },
  1061 + { "g7", offsetof(CPUState, gregs[7]) },
  1062 + { "o0", 0, monitor_get_reg },
  1063 + { "o1", 1, monitor_get_reg },
  1064 + { "o2", 2, monitor_get_reg },
  1065 + { "o3", 3, monitor_get_reg },
  1066 + { "o4", 4, monitor_get_reg },
  1067 + { "o5", 5, monitor_get_reg },
  1068 + { "o6", 6, monitor_get_reg },
  1069 + { "o7", 7, monitor_get_reg },
  1070 + { "l0", 8, monitor_get_reg },
  1071 + { "l1", 9, monitor_get_reg },
  1072 + { "l2", 10, monitor_get_reg },
  1073 + { "l3", 11, monitor_get_reg },
  1074 + { "l4", 12, monitor_get_reg },
  1075 + { "l5", 13, monitor_get_reg },
  1076 + { "l6", 14, monitor_get_reg },
  1077 + { "l7", 15, monitor_get_reg },
  1078 + { "i0", 16, monitor_get_reg },
  1079 + { "i1", 17, monitor_get_reg },
  1080 + { "i2", 18, monitor_get_reg },
  1081 + { "i3", 19, monitor_get_reg },
  1082 + { "i4", 20, monitor_get_reg },
  1083 + { "i5", 21, monitor_get_reg },
  1084 + { "i6", 22, monitor_get_reg },
  1085 + { "i7", 23, monitor_get_reg },
  1086 + { "pc", offsetof(CPUState, pc) },
  1087 + { "npc", offsetof(CPUState, npc) },
  1088 + { "y", offsetof(CPUState, y) },
  1089 + { "psr", 0, &monitor_get_psr, },
  1090 + { "wim", offsetof(CPUState, wim) },
  1091 + { "tbr", offsetof(CPUState, tbr) },
  1092 + { "fsr", offsetof(CPUState, fsr) },
  1093 + { "f0", offsetof(CPUState, fpr[0]) },
  1094 + { "f1", offsetof(CPUState, fpr[1]) },
  1095 + { "f2", offsetof(CPUState, fpr[2]) },
  1096 + { "f3", offsetof(CPUState, fpr[3]) },
  1097 + { "f4", offsetof(CPUState, fpr[4]) },
  1098 + { "f5", offsetof(CPUState, fpr[5]) },
  1099 + { "f6", offsetof(CPUState, fpr[6]) },
  1100 + { "f7", offsetof(CPUState, fpr[7]) },
  1101 + { "f8", offsetof(CPUState, fpr[8]) },
  1102 + { "f9", offsetof(CPUState, fpr[9]) },
  1103 + { "f10", offsetof(CPUState, fpr[10]) },
  1104 + { "f11", offsetof(CPUState, fpr[11]) },
  1105 + { "f12", offsetof(CPUState, fpr[12]) },
  1106 + { "f13", offsetof(CPUState, fpr[13]) },
  1107 + { "f14", offsetof(CPUState, fpr[14]) },
  1108 + { "f15", offsetof(CPUState, fpr[15]) },
  1109 + { "f16", offsetof(CPUState, fpr[16]) },
  1110 + { "f17", offsetof(CPUState, fpr[17]) },
  1111 + { "f18", offsetof(CPUState, fpr[18]) },
  1112 + { "f19", offsetof(CPUState, fpr[19]) },
  1113 + { "f20", offsetof(CPUState, fpr[20]) },
  1114 + { "f21", offsetof(CPUState, fpr[21]) },
  1115 + { "f22", offsetof(CPUState, fpr[22]) },
  1116 + { "f23", offsetof(CPUState, fpr[23]) },
  1117 + { "f24", offsetof(CPUState, fpr[24]) },
  1118 + { "f25", offsetof(CPUState, fpr[25]) },
  1119 + { "f26", offsetof(CPUState, fpr[26]) },
  1120 + { "f27", offsetof(CPUState, fpr[27]) },
  1121 + { "f28", offsetof(CPUState, fpr[28]) },
  1122 + { "f29", offsetof(CPUState, fpr[29]) },
  1123 + { "f30", offsetof(CPUState, fpr[30]) },
  1124 + { "f31", offsetof(CPUState, fpr[31]) },
1040 #endif 1125 #endif
1041 { NULL }, 1126 { NULL },
1042 }; 1127 };
@@ -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)
1054 for(md = monitor_defs; md->name != NULL; md++) { 1139 for(md = monitor_defs; md->name != NULL; md++) {
1055 if (compare_cmd(name, md->name)) { 1140 if (compare_cmd(name, md->name)) {
1056 if (md->get_value) { 1141 if (md->get_value) {
1057 - *pval = md->get_value(md); 1142 + *pval = md->get_value(md, md->offset);
1058 } else { 1143 } else {
1059 *pval = *(uint32_t *)((uint8_t *)cpu_single_env + md->offset); 1144 *pval = *(uint32_t *)((uint8_t *)cpu_single_env + md->offset);
1060 } 1145 }
slirp/bootp.c
@@ -178,7 +178,8 @@ static void bootp_reply(struct bootp_t *bp) @@ -178,7 +178,8 @@ static void bootp_reply(struct bootp_t *bp)
178 rbp->bp_hlen = 6; 178 rbp->bp_hlen = 6;
179 memcpy(rbp->bp_hwaddr, bp->bp_hwaddr, 6); 179 memcpy(rbp->bp_hwaddr, bp->bp_hwaddr, 6);
180 180
181 - rbp->bp_yiaddr = daddr.sin_addr; /* IP address */ 181 + rbp->bp_yiaddr = daddr.sin_addr; /* Client IP address */
  182 + rbp->bp_siaddr = saddr.sin_addr; /* Server IP address */
182 183
183 q = rbp->bp_vend; 184 q = rbp->bp_vend;
184 memcpy(q, rfc1533_cookie, 4); 185 memcpy(q, rfc1533_cookie, 4);
softmmu_header.h
@@ -55,6 +55,8 @@ @@ -55,6 +55,8 @@
55 #define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3) 55 #define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)
56 #elif defined (TARGET_PPC) 56 #elif defined (TARGET_PPC)
57 #define CPU_MEM_INDEX (msr_pr) 57 #define CPU_MEM_INDEX (msr_pr)
  58 +#elif defined (TARGET_SPARC)
  59 +#define CPU_MEM_INDEX ((env->psrs) == 0)
58 #endif 60 #endif
59 #define MMUSUFFIX _mmu 61 #define MMUSUFFIX _mmu
60 62
@@ -64,6 +66,8 @@ @@ -64,6 +66,8 @@
64 #define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3) 66 #define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3)
65 #elif defined (TARGET_PPC) 67 #elif defined (TARGET_PPC)
66 #define CPU_MEM_INDEX (msr_pr) 68 #define CPU_MEM_INDEX (msr_pr)
  69 +#elif defined (TARGET_SPARC)
  70 +#define CPU_MEM_INDEX ((env->psrs) == 0)
67 #endif 71 #endif
68 #define MMUSUFFIX _cmmu 72 #define MMUSUFFIX _cmmu
69 73
translate-all.c
@@ -46,6 +46,8 @@ uint32_t gen_opc_pc[OPC_BUF_SIZE]; @@ -46,6 +46,8 @@ uint32_t gen_opc_pc[OPC_BUF_SIZE];
46 uint8_t gen_opc_instr_start[OPC_BUF_SIZE]; 46 uint8_t gen_opc_instr_start[OPC_BUF_SIZE];
47 #if defined(TARGET_I386) 47 #if defined(TARGET_I386)
48 uint8_t gen_opc_cc_op[OPC_BUF_SIZE]; 48 uint8_t gen_opc_cc_op[OPC_BUF_SIZE];
  49 +#elif defined(TARGET_SPARC)
  50 +uint32_t gen_opc_npc[OPC_BUF_SIZE];
49 #endif 51 #endif
50 52
51 int code_copy_enabled = 1; 53 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,
208 #elif defined(TARGET_SPARC) 210 #elif defined(TARGET_SPARC)
209 /* XXX: restore npc too */ 211 /* XXX: restore npc too */
210 env->pc = gen_opc_pc[j]; 212 env->pc = gen_opc_pc[j];
  213 + env->npc = gen_opc_npc[j];
211 #elif defined(TARGET_PPC) 214 #elif defined(TARGET_PPC)
212 { 215 {
213 int type; 216 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)
710 710
711 for(;;) { 711 for(;;) {
712 ts = *ptimer_head; 712 ts = *ptimer_head;
713 - if (ts->expire_time > current_time) 713 + if (!ts || ts->expire_time > current_time)
714 break; 714 break;
715 /* remove timer from the list before calling the callback */ 715 /* remove timer from the list before calling the callback */
716 *ptimer_head = ts->next; 716 *ptimer_head = ts->next;
@@ -2166,6 +2166,15 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) @@ -2166,6 +2166,15 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id)
2166 { 2166 {
2167 return 0; 2167 return 0;
2168 } 2168 }
  2169 +#elif defined(TARGET_SPARC)
  2170 +void cpu_save(QEMUFile *f, void *opaque)
  2171 +{
  2172 +}
  2173 +
  2174 +int cpu_load(QEMUFile *f, void *opaque, int version_id)
  2175 +{
  2176 + return 0;
  2177 +}
2169 #else 2178 #else
2170 2179
2171 #warning No CPU save/restore functions 2180 #warning No CPU save/restore functions
@@ -3336,6 +3345,10 @@ int main(int argc, char **argv) @@ -3336,6 +3345,10 @@ int main(int argc, char **argv)
3336 ppc_init(ram_size, vga_ram_size, boot_device, 3345 ppc_init(ram_size, vga_ram_size, boot_device,
3337 ds, fd_filename, snapshot, 3346 ds, fd_filename, snapshot,
3338 kernel_filename, kernel_cmdline, initrd_filename); 3347 kernel_filename, kernel_cmdline, initrd_filename);
  3348 +#elif defined(TARGET_SPARC)
  3349 + sun4m_init(ram_size, vga_ram_size, boot_device,
  3350 + ds, fd_filename, snapshot,
  3351 + kernel_filename, kernel_cmdline, initrd_filename);
3339 #endif 3352 #endif
3340 3353
3341 gui_timer = qemu_new_timer(rt_clock, gui_update, NULL); 3354 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[];
664 extern CPUReadMemoryFunc *PPC_io_read[]; 664 extern CPUReadMemoryFunc *PPC_io_read[];
665 extern int prep_enabled; 665 extern int prep_enabled;
666 666
  667 +/* sun4m.c */
  668 +void sun4m_init(int ram_size, int vga_ram_size, int boot_device,
  669 + DisplayState *ds, const char **fd_filename, int snapshot,
  670 + const char *kernel_filename, const char *kernel_cmdline,
  671 + const char *initrd_filename);
  672 +
  673 +/* iommu.c */
  674 +void iommu_init();
  675 +uint32_t iommu_translate(uint32_t addr);
  676 +
  677 +/* lance.c */
  678 +void lance_init(NetDriverState *nd, int irq);
  679 +
  680 +/* tcx.c */
  681 +void tcx_init(DisplayState *ds);
  682 +
  683 +/* sched.c */
  684 +void sched_init();
  685 +
  686 +/* magic-load.c */
  687 +void magic_init(const char *kfn, int kloadaddr);
  688 +
667 /* NVRAM helpers */ 689 /* NVRAM helpers */
668 #include "hw/m48t59.h" 690 #include "hw/m48t59.h"
669 691