Commit e95c8d51c2a47d7ccb422f83446cb91a18f8f37d
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
Showing
14 changed files
with
307 additions
and
78 deletions
.cvsignore
Changelog
Makefile.target
... | ... | @@ -63,6 +63,26 @@ endif |
63 | 63 | endif # ARCH = amd64 |
64 | 64 | |
65 | 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 | 86 | endif # !CONFIG_USER_ONLY |
67 | 87 | |
68 | 88 | ifdef CONFIG_STATIC |
... | ... | @@ -201,6 +221,10 @@ ifeq ($(TARGET_ARCH), ppc) |
201 | 221 | LIBOBJS+= op_helper.o helper.o |
202 | 222 | endif |
203 | 223 | |
224 | +ifeq ($(TARGET_ARCH), sparc) | |
225 | +LIBOBJS+= op_helper.o helper.o | |
226 | +endif | |
227 | + | |
204 | 228 | # NOTE: the disassembler code is only needed for debugging |
205 | 229 | LIBOBJS+=disas.o |
206 | 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 | 278 | VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o fdc.o m48t59.o |
255 | 279 | VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o adb.o openpic.o |
256 | 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 | 284 | ifdef CONFIG_GDBSTUB |
258 | 285 | VL_OBJS+=gdbstub.o |
259 | 286 | endif |
... | ... | @@ -325,7 +352,7 @@ op.o: op.c op_template.h |
325 | 352 | endif |
326 | 353 | |
327 | 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 | 356 | endif |
330 | 357 | |
331 | 358 | ifeq ($(TARGET_ARCH), ppc) | ... | ... |
configure
... | ... | @@ -27,7 +27,7 @@ ar="ar" |
27 | 27 | make="make" |
28 | 28 | strip="strip" |
29 | 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 | 31 | case "$cpu" in |
32 | 32 | i386|i486|i586|i686|i86pc|BePC) |
33 | 33 | cpu="i386" |
... | ... | @@ -99,7 +99,7 @@ if [ "$bsd" = "yes" ] ; then |
99 | 99 | if [ ! "$darwin" = "yes" ] ; then |
100 | 100 | make="gmake" |
101 | 101 | fi |
102 | - target_list="i386-softmmu ppc-softmmu" | |
102 | + target_list="i386-softmmu ppc-softmmu sparc-softmmu" | |
103 | 103 | fi |
104 | 104 | |
105 | 105 | # find source path |
... | ... | @@ -160,7 +160,7 @@ ar="${cross_prefix}${ar}" |
160 | 160 | strip="${cross_prefix}${strip}" |
161 | 161 | |
162 | 162 | if test "$mingw32" = "yes" ; then |
163 | - target_list="i386-softmmu ppc-softmmu" | |
163 | + target_list="i386-softmmu ppc-softmmu sparc-softmmu" | |
164 | 164 | EXESUF=".exe" |
165 | 165 | gdbstub="no" |
166 | 166 | fi | ... | ... |
cpu-exec.c
... | ... | @@ -208,6 +208,11 @@ int cpu_exec(CPUState *env1) |
208 | 208 | env->exception_next_eip, 0); |
209 | 209 | #elif defined(TARGET_PPC) |
210 | 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 | 216 | #endif |
212 | 217 | } |
213 | 218 | env->exception_index = -1; |
... | ... | @@ -261,6 +266,14 @@ int cpu_exec(CPUState *env1) |
261 | 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 | 277 | #endif |
265 | 278 | if (interrupt_request & CPU_INTERRUPT_EXITTB) { |
266 | 279 | env->interrupt_request &= ~CPU_INTERRUPT_EXITTB; | ... | ... |
exec-all.h
... | ... | @@ -56,6 +56,7 @@ struct TranslationBlock; |
56 | 56 | extern uint16_t gen_opc_buf[OPC_BUF_SIZE]; |
57 | 57 | extern uint32_t gen_opparam_buf[OPPARAM_BUF_SIZE]; |
58 | 58 | extern uint32_t gen_opc_pc[OPC_BUF_SIZE]; |
59 | +extern uint32_t gen_opc_npc[OPC_BUF_SIZE]; | |
59 | 60 | extern uint8_t gen_opc_cc_op[OPC_BUF_SIZE]; |
60 | 61 | extern uint8_t gen_opc_instr_start[OPC_BUF_SIZE]; |
61 | 62 | |
... | ... | @@ -541,8 +542,7 @@ extern spinlock_t tb_lock; |
541 | 542 | |
542 | 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 | 547 | void tlb_fill(unsigned long addr, int is_write, int is_user, |
548 | 548 | void *retaddr); |
... | ... | @@ -585,6 +585,8 @@ static inline target_ulong get_phys_addr_code(CPUState *env, target_ulong addr) |
585 | 585 | is_user = ((env->hflags & HF_CPL_MASK) == 3); |
586 | 586 | #elif defined (TARGET_PPC) |
587 | 587 | is_user = msr_pr; |
588 | +#elif defined (TARGET_SPARC) | |
589 | + is_user = (env->psrs == 0); | |
588 | 590 | #else |
589 | 591 | #error "Unimplemented !" |
590 | 592 | #endif | ... | ... |
exec.c
... | ... | @@ -1077,7 +1077,7 @@ static void breakpoint_invalidate(CPUState *env, target_ulong pc) |
1077 | 1077 | breakpoint is reached */ |
1078 | 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 | 1081 | int i; |
1082 | 1082 | |
1083 | 1083 | for(i = 0; i < env->nb_breakpoints; i++) { |
... | ... | @@ -1099,7 +1099,7 @@ int cpu_breakpoint_insert(CPUState *env, target_ulong pc) |
1099 | 1099 | /* remove a breakpoint */ |
1100 | 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 | 1103 | int i; |
1104 | 1104 | for(i = 0; i < env->nb_breakpoints; i++) { |
1105 | 1105 | if (env->breakpoints[i] == pc) |
... | ... | @@ -1122,7 +1122,7 @@ int cpu_breakpoint_remove(CPUState *env, target_ulong pc) |
1122 | 1122 | CPU loop after each instruction */ |
1123 | 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 | 1126 | if (env->singlestep_enabled != enabled) { |
1127 | 1127 | env->singlestep_enabled = enabled; |
1128 | 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 | 157 | |
158 | 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 | 160 | static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) |
169 | 161 | { |
162 | + uint32_t *registers = (uint32_t *)mem_buf; | |
170 | 163 | int i, fpus; |
171 | 164 | |
172 | 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 | 176 | /* XXX: convert floats */ |
184 | 177 | for(i = 0; i < 8; i++) { |
185 | 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 | 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(®isters[i]); | |
192 | + for(i = 36; i < 44; i++) | |
193 | + tswapls(®isters[i]); | |
196 | 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 | 202 | for(i = 0; i < 8; i++) { |
205 | 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 | 207 | #if defined(CONFIG_USER_ONLY) |
210 | 208 | #define LOAD_SEG(index, sreg)\ |
211 | 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 | 218 | } |
221 | 219 | |
222 | 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 | 221 | static uint32_t from_le32 (uint32_t *buf) |
233 | 222 | { |
234 | 223 | uint8_t *p = (uint8_t *)buf; |
... | ... | @@ -243,24 +232,24 @@ static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) |
243 | 232 | |
244 | 233 | /* fill in gprs */ |
245 | 234 | for(i = 0; i < 32; i++) { |
246 | - to_le32(®isters[i], env->gpr[i]); | |
235 | + registers[i] = tswapl(env->gpr[i]); | |
247 | 236 | } |
248 | 237 | /* fill in fprs */ |
249 | 238 | for (i = 0; i < 32; i++) { |
250 | - to_le32(®isters[(i * 2) + 32], *((uint32_t *)&env->fpr[i])); | |
251 | - to_le32(®isters[(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 | 242 | /* nip, msr, ccr, lnk, ctr, xer, mq */ |
254 | - to_le32(®isters[96], (uint32_t)env->nip/* - 4*/); | |
255 | - to_le32(®isters[97], _load_msr(env)); | |
243 | + registers[96] = tswapl(env->nip); | |
244 | + registers[97] = tswapl(_load_msr(env)); | |
256 | 245 | tmp = 0; |
257 | 246 | for (i = 0; i < 8; i++) |
258 | 247 | tmp |= env->crf[i] << (32 - ((i + 1) * 4)); |
259 | - to_le32(®isters[98], tmp); | |
260 | - to_le32(®isters[99], env->lr); | |
261 | - to_le32(®isters[100], env->ctr); | |
262 | - to_le32(®isters[101], _load_xer(env)); | |
263 | - to_le32(®isters[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 | 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 | 261 | |
273 | 262 | /* fill in gprs */ |
274 | 263 | for (i = 0; i < 32; i++) { |
275 | - env->gpr[i] = from_le32(®isters[i]); | |
264 | + env->gpr[i] = tswapl(registers[i]); | |
276 | 265 | } |
277 | 266 | /* fill in fprs */ |
278 | 267 | for (i = 0; i < 32; i++) { |
279 | - *((uint32_t *)&env->fpr[i]) = from_le32(®isters[(i * 2) + 32]); | |
280 | - *((uint32_t *)&env->fpr[i] + 1) = from_le32(®isters[(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 | 271 | /* nip, msr, ccr, lnk, ctr, xer, mq */ |
283 | - env->nip = from_le32(®isters[96]); | |
284 | - _store_msr(env, from_le32(®isters[97])); | |
285 | - registers[98] = from_le32(®isters[98]); | |
272 | + env->nip = tswapl(registers[96]); | |
273 | + _store_msr(env, tswapl(registers[97])); | |
274 | + registers[98] = tswapl(registers[98]); | |
286 | 275 | for (i = 0; i < 8; i++) |
287 | 276 | env->crf[i] = (registers[98] >> (32 - ((i + 1) * 4))) & 0xF; |
288 | - env->lr = from_le32(®isters[99]); | |
289 | - env->ctr = from_le32(®isters[100]); | |
290 | - _store_xer(env, from_le32(®isters[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 | 349 | #else |
293 | 350 | ... | ... |
monitor.c
... | ... | @@ -883,18 +883,18 @@ static jmp_buf expr_env; |
883 | 883 | typedef struct MonitorDef { |
884 | 884 | const char *name; |
885 | 885 | int offset; |
886 | - int (*get_value)(struct MonitorDef *md); | |
886 | + int (*get_value)(struct MonitorDef *md, int val); | |
887 | 887 | } MonitorDef; |
888 | 888 | |
889 | 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 | 892 | return cpu_single_env->eip + (long)cpu_single_env->segs[R_CS].base; |
893 | 893 | } |
894 | 894 | #endif |
895 | 895 | |
896 | 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 | 899 | unsigned int u; |
900 | 900 | int i; |
... | ... | @@ -906,7 +906,7 @@ static int monitor_get_ccr (struct MonitorDef *md) |
906 | 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 | 911 | return (cpu_single_env->msr[MSR_POW] << MSR_POW) | |
912 | 912 | (cpu_single_env->msr[MSR_ILE] << MSR_ILE) | |
... | ... | @@ -925,7 +925,7 @@ static int monitor_get_msr (struct MonitorDef *md) |
925 | 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 | 930 | return (cpu_single_env->xer[XER_SO] << XER_SO) | |
931 | 931 | (cpu_single_env->xer[XER_OV] << XER_OV) | |
... | ... | @@ -933,25 +933,38 @@ static int monitor_get_xer (struct MonitorDef *md) |
933 | 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 | 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 | 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 | 948 | return cpu_ppc_load_tbl(cpu_single_env); |
952 | 949 | } |
953 | 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 | 968 | static MonitorDef monitor_defs[] = { |
956 | 969 | #ifdef TARGET_I386 |
957 | 970 | |
... | ... | @@ -1037,6 +1050,78 @@ static MonitorDef monitor_defs[] = { |
1037 | 1050 | { "sr14", offsetof(CPUState, sr[14]) }, |
1038 | 1051 | { "sr15", offsetof(CPUState, sr[15]) }, |
1039 | 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 | 1125 | #endif |
1041 | 1126 | { NULL }, |
1042 | 1127 | }; |
... | ... | @@ -1054,7 +1139,7 @@ static int get_monitor_def(int *pval, const char *name) |
1054 | 1139 | for(md = monitor_defs; md->name != NULL; md++) { |
1055 | 1140 | if (compare_cmd(name, md->name)) { |
1056 | 1141 | if (md->get_value) { |
1057 | - *pval = md->get_value(md); | |
1142 | + *pval = md->get_value(md, md->offset); | |
1058 | 1143 | } else { |
1059 | 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 | 178 | rbp->bp_hlen = 6; |
179 | 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 | 184 | q = rbp->bp_vend; |
184 | 185 | memcpy(q, rfc1533_cookie, 4); | ... | ... |
softmmu_header.h
... | ... | @@ -55,6 +55,8 @@ |
55 | 55 | #define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3) |
56 | 56 | #elif defined (TARGET_PPC) |
57 | 57 | #define CPU_MEM_INDEX (msr_pr) |
58 | +#elif defined (TARGET_SPARC) | |
59 | +#define CPU_MEM_INDEX ((env->psrs) == 0) | |
58 | 60 | #endif |
59 | 61 | #define MMUSUFFIX _mmu |
60 | 62 | |
... | ... | @@ -64,6 +66,8 @@ |
64 | 66 | #define CPU_MEM_INDEX ((env->hflags & HF_CPL_MASK) == 3) |
65 | 67 | #elif defined (TARGET_PPC) |
66 | 68 | #define CPU_MEM_INDEX (msr_pr) |
69 | +#elif defined (TARGET_SPARC) | |
70 | +#define CPU_MEM_INDEX ((env->psrs) == 0) | |
67 | 71 | #endif |
68 | 72 | #define MMUSUFFIX _cmmu |
69 | 73 | ... | ... |
translate-all.c
... | ... | @@ -46,6 +46,8 @@ uint32_t gen_opc_pc[OPC_BUF_SIZE]; |
46 | 46 | uint8_t gen_opc_instr_start[OPC_BUF_SIZE]; |
47 | 47 | #if defined(TARGET_I386) |
48 | 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 | 51 | #endif |
50 | 52 | |
51 | 53 | int code_copy_enabled = 1; |
... | ... | @@ -208,6 +210,7 @@ int cpu_restore_state(TranslationBlock *tb, |
208 | 210 | #elif defined(TARGET_SPARC) |
209 | 211 | /* XXX: restore npc too */ |
210 | 212 | env->pc = gen_opc_pc[j]; |
213 | + env->npc = gen_opc_npc[j]; | |
211 | 214 | #elif defined(TARGET_PPC) |
212 | 215 | { |
213 | 216 | int type; | ... | ... |
vl.c
... | ... | @@ -710,7 +710,7 @@ static void qemu_run_timers(QEMUTimer **ptimer_head, int64_t current_time) |
710 | 710 | |
711 | 711 | for(;;) { |
712 | 712 | ts = *ptimer_head; |
713 | - if (ts->expire_time > current_time) | |
713 | + if (!ts || ts->expire_time > current_time) | |
714 | 714 | break; |
715 | 715 | /* remove timer from the list before calling the callback */ |
716 | 716 | *ptimer_head = ts->next; |
... | ... | @@ -2166,6 +2166,15 @@ int cpu_load(QEMUFile *f, void *opaque, int version_id) |
2166 | 2166 | { |
2167 | 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 | 2178 | #else |
2170 | 2179 | |
2171 | 2180 | #warning No CPU save/restore functions |
... | ... | @@ -3336,6 +3345,10 @@ int main(int argc, char **argv) |
3336 | 3345 | ppc_init(ram_size, vga_ram_size, boot_device, |
3337 | 3346 | ds, fd_filename, snapshot, |
3338 | 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 | 3352 | #endif |
3340 | 3353 | |
3341 | 3354 | gui_timer = qemu_new_timer(rt_clock, gui_update, NULL); | ... | ... |
vl.h
... | ... | @@ -664,6 +664,28 @@ extern CPUWriteMemoryFunc *PPC_io_write[]; |
664 | 664 | extern CPUReadMemoryFunc *PPC_io_read[]; |
665 | 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 | 689 | /* NVRAM helpers */ |
668 | 690 | #include "hw/m48t59.h" |
669 | 691 | ... | ... |