Commit 6da41eafc40c543c581d8b585a906691beca43b0
1 parent
0124311e
added CPU callbacks
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@493 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
103 additions
and
37 deletions
gdbstub.c
... | ... | @@ -248,6 +248,23 @@ static int put_packet(char *buf) |
248 | 248 | return 0; |
249 | 249 | } |
250 | 250 | |
251 | + /* better than nothing for SOFTMMU : we use physical addresses */ | |
252 | +#ifdef CONFIG_SOFTMMU | |
253 | +static int memory_rw(uint8_t *buf, uint32_t addr, int len, int is_write) | |
254 | +{ | |
255 | + uint8_t *ptr; | |
256 | + | |
257 | + if (addr >= phys_ram_size || | |
258 | + ((int64_t)addr + len > phys_ram_size)) | |
259 | + return -1; | |
260 | + ptr = phys_ram_base + addr; | |
261 | + if (is_write) | |
262 | + memcpy(ptr, buf, len); | |
263 | + else | |
264 | + memcpy(buf, ptr, len); | |
265 | + return 0; | |
266 | +} | |
267 | +#else | |
251 | 268 | static int memory_rw(uint8_t *buf, uint32_t addr, int len, int is_write) |
252 | 269 | { |
253 | 270 | int l, flags; |
... | ... | @@ -276,13 +293,91 @@ static int memory_rw(uint8_t *buf, uint32_t addr, int len, int is_write) |
276 | 293 | } |
277 | 294 | return 0; |
278 | 295 | } |
296 | +#endif | |
297 | + | |
298 | +#if defined(TARGET_I386) | |
299 | + | |
300 | +static void to_le32(uint8_t *p, int v) | |
301 | +{ | |
302 | + p[0] = v; | |
303 | + p[1] = v >> 8; | |
304 | + p[2] = v >> 16; | |
305 | + p[3] = v >> 24; | |
306 | +} | |
307 | + | |
308 | +static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) | |
309 | +{ | |
310 | + int i, fpus; | |
311 | + | |
312 | + for(i = 0; i < 8; i++) { | |
313 | + to_le32(mem_buf + i * 4, env->regs[i]); | |
314 | + } | |
315 | + to_le32(mem_buf + 8 * 4, env->eip); | |
316 | + to_le32(mem_buf + 9 * 4, env->eflags); | |
317 | + to_le32(mem_buf + 10 * 4, env->segs[R_CS].selector); | |
318 | + to_le32(mem_buf + 11 * 4, env->segs[R_SS].selector); | |
319 | + to_le32(mem_buf + 12 * 4, env->segs[R_DS].selector); | |
320 | + to_le32(mem_buf + 13 * 4, env->segs[R_ES].selector); | |
321 | + to_le32(mem_buf + 14 * 4, env->segs[R_FS].selector); | |
322 | + to_le32(mem_buf + 15 * 4, env->segs[R_GS].selector); | |
323 | + /* XXX: convert floats */ | |
324 | + for(i = 0; i < 8; i++) { | |
325 | + memcpy(mem_buf + 16 * 4 + i * 10, &env->fpregs[i], 10); | |
326 | + } | |
327 | + to_le32(mem_buf + 36 * 4, env->fpuc); | |
328 | + fpus = (env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11; | |
329 | + to_le32(mem_buf + 37 * 4, fpus); | |
330 | + to_le32(mem_buf + 38 * 4, 0); /* XXX: convert tags */ | |
331 | + to_le32(mem_buf + 39 * 4, 0); /* fiseg */ | |
332 | + to_le32(mem_buf + 40 * 4, 0); /* fioff */ | |
333 | + to_le32(mem_buf + 41 * 4, 0); /* foseg */ | |
334 | + to_le32(mem_buf + 42 * 4, 0); /* fooff */ | |
335 | + to_le32(mem_buf + 43 * 4, 0); /* fop */ | |
336 | + return 44 * 4; | |
337 | +} | |
338 | + | |
339 | +static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) | |
340 | +{ | |
341 | + uint32_t *registers = (uint32_t *)mem_buf; | |
342 | + int i; | |
343 | + | |
344 | + for(i = 0; i < 8; i++) { | |
345 | + env->regs[i] = tswapl(registers[i]); | |
346 | + } | |
347 | + env->eip = registers[8]; | |
348 | + env->eflags = registers[9]; | |
349 | +#if defined(CONFIG_USER_ONLY) | |
350 | +#define LOAD_SEG(index, sreg)\ | |
351 | + if (tswapl(registers[index]) != env->segs[sreg].selector)\ | |
352 | + cpu_x86_load_seg(env, sreg, tswapl(registers[index])); | |
353 | + LOAD_SEG(10, R_CS); | |
354 | + LOAD_SEG(11, R_SS); | |
355 | + LOAD_SEG(12, R_DS); | |
356 | + LOAD_SEG(13, R_ES); | |
357 | + LOAD_SEG(14, R_FS); | |
358 | + LOAD_SEG(15, R_GS); | |
359 | +#endif | |
360 | +} | |
361 | + | |
362 | +#else | |
363 | + | |
364 | +static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf) | |
365 | +{ | |
366 | + return 0; | |
367 | +} | |
368 | + | |
369 | +static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size) | |
370 | +{ | |
371 | +} | |
372 | + | |
373 | +#endif | |
279 | 374 | |
280 | 375 | /* port = 0 means default port */ |
281 | 376 | int cpu_gdbstub(void *opaque, int (*main_loop)(void *opaque), int port) |
282 | 377 | { |
283 | 378 | CPUState *env; |
284 | 379 | const char *p; |
285 | - int ret, ch, nb_regs, i, type; | |
380 | + int ret, ch, reg_size, type; | |
286 | 381 | char buf[4096]; |
287 | 382 | uint8_t mem_buf[2000]; |
288 | 383 | uint32_t *registers; |
... | ... | @@ -339,47 +434,16 @@ int cpu_gdbstub(void *opaque, int (*main_loop)(void *opaque), int port) |
339 | 434 | break; |
340 | 435 | case 'g': |
341 | 436 | env = cpu_gdbstub_get_env(opaque); |
342 | - registers = (void *)mem_buf; | |
343 | -#if defined(TARGET_I386) | |
344 | - for(i = 0; i < 8; i++) { | |
345 | - registers[i] = tswapl(env->regs[i]); | |
346 | - } | |
347 | - registers[8] = env->eip; | |
348 | - registers[9] = env->eflags; | |
349 | - registers[10] = env->segs[R_CS].selector; | |
350 | - registers[11] = env->segs[R_SS].selector; | |
351 | - registers[12] = env->segs[R_DS].selector; | |
352 | - registers[13] = env->segs[R_ES].selector; | |
353 | - registers[14] = env->segs[R_FS].selector; | |
354 | - registers[15] = env->segs[R_GS].selector; | |
355 | - nb_regs = 16; | |
356 | -#endif | |
357 | - memtohex(buf, (const uint8_t *)registers, | |
358 | - sizeof(registers[0]) * nb_regs); | |
437 | + reg_size = cpu_gdb_read_registers(env, mem_buf); | |
438 | + memtohex(buf, mem_buf, reg_size); | |
359 | 439 | put_packet(buf); |
360 | 440 | break; |
361 | 441 | case 'G': |
362 | 442 | env = cpu_gdbstub_get_env(opaque); |
363 | 443 | registers = (void *)mem_buf; |
364 | -#if defined(TARGET_I386) | |
365 | - hextomem((uint8_t *)registers, p, 16 * 4); | |
366 | - for(i = 0; i < 8; i++) { | |
367 | - env->regs[i] = tswapl(registers[i]); | |
368 | - } | |
369 | - env->eip = registers[8]; | |
370 | - env->eflags = registers[9]; | |
371 | -#if defined(CONFIG_USER_ONLY) | |
372 | -#define LOAD_SEG(index, sreg)\ | |
373 | - if (tswapl(registers[index]) != env->segs[sreg].selector)\ | |
374 | - cpu_x86_load_seg(env, sreg, tswapl(registers[index])); | |
375 | - LOAD_SEG(10, R_CS); | |
376 | - LOAD_SEG(11, R_SS); | |
377 | - LOAD_SEG(12, R_DS); | |
378 | - LOAD_SEG(13, R_ES); | |
379 | - LOAD_SEG(14, R_FS); | |
380 | - LOAD_SEG(15, R_GS); | |
381 | -#endif | |
382 | -#endif | |
444 | + len = strlen(p) / 2; | |
445 | + hextomem((uint8_t *)registers, p, len); | |
446 | + cpu_gdb_write_registers(env, mem_buf, len); | |
383 | 447 | put_packet("OK"); |
384 | 448 | break; |
385 | 449 | case 'm': |
... | ... | @@ -445,6 +509,8 @@ int cpu_gdbstub(void *opaque, int (*main_loop)(void *opaque), int port) |
445 | 509 | put_packet("OK"); |
446 | 510 | } else if (!strncmp(p, "TStart", 6)) { |
447 | 511 | /* start log (gdb 'tstart' command) */ |
512 | + env = cpu_gdbstub_get_env(opaque); | |
513 | + tb_flush(env); | |
448 | 514 | cpu_set_log(CPU_LOG_ALL); |
449 | 515 | put_packet("OK"); |
450 | 516 | } else if (!strncmp(p, "TStop", 5)) { | ... | ... |