+}
+
+#elif defined (TARGET_PPC)
+static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
+{
+ uint32_t *registers = (uint32_t *)mem_buf, tmp;
+ int i;
+
+ /* fill in gprs */
+ for(i = 0; i < 32; i++) {
+ registers[i] = tswapl(env->gpr[i]);
+ }
+ /* fill in fprs */
+ for (i = 0; i < 32; i++) {
+ 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 */
+ registers[96] = tswapl(env->nip);
+ registers[97] = tswapl(do_load_msr(env));
+ tmp = 0;
+ for (i = 0; i < 8; i++)
+ tmp |= env->crf[i] << (32 - ((i + 1) * 4));
+ registers[98] = tswapl(tmp);
+ registers[99] = tswapl(env->lr);
+ registers[100] = tswapl(env->ctr);
+ registers[101] = tswapl(ppc_load_xer(env));
+ registers[102] = 0;
+
+ return 103 * 4;
+}
+
+static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
+{
+ uint32_t *registers = (uint32_t *)mem_buf;
+ int i;
+
+ /* fill in gprs */
+ for (i = 0; i < 32; i++) {
+ env->gpr[i] = tswapl(registers[i]);
+ }
+ /* fill in fprs */
+ for (i = 0; i < 32; i++) {
+ *((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 = tswapl(registers[96]);
+ do_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 = tswapl(registers[99]);
+ env->ctr = tswapl(registers[100]);
+ ppc_store_xer(env, tswapl(registers[101]));
+}
+#elif defined (TARGET_SPARC)
+static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
+{
+ target_ulong *registers = (target_ulong *)mem_buf;
+ int i;
+
+ /* fill in g0..g7 */
+ for(i = 0; i < 8; i++) {
+ registers[i] = tswapl(env->gregs[i]);
+ }
+ /* fill in register window */
+ for(i = 0; i < 24; i++) {
+ registers[i + 8] = tswapl(env->regwptr[i]);
+ }
+#ifndef TARGET_SPARC64
+ /* 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);
+ {
+ target_ulong tmp;
+
+ tmp = GET_PSR(env);
+ 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 * sizeof(target_ulong);
+#else
+ /* fill in fprs */
+ for (i = 0; i < 64; i += 2) {
+ uint64_t tmp;
+
+ tmp = ((uint64_t)*(uint32_t *)&env->fpr[i]) << 32;
+ tmp |= *(uint32_t *)&env->fpr[i + 1];
+ registers[i / 2 + 32] = tswap64(tmp);
+ }
+ registers[64] = tswapl(env->pc);
+ registers[65] = tswapl(env->npc);
+ registers[66] = tswapl(env->tstate[env->tl]);
+ registers[67] = tswapl(env->fsr);
+ registers[68] = tswapl(env->fprs);
+ registers[69] = tswapl(env->y);
+ return 70 * sizeof(target_ulong);
+#endif
+}
+
+static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
+{
+ target_ulong *registers = (target_ulong *)mem_buf;
+ 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 + 8]);
+ }
+#ifndef TARGET_SPARC64
+ /* 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]);
+ PUT_PSR(env, tswapl(registers[65]));
+ 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
+ for (i = 0; i < 64; i += 2) {
+ uint64_t tmp;
+
+ tmp = tswap64(registers[i / 2 + 32]);
+ *((uint32_t *)&env->fpr[i]) = tmp >> 32;
+ *((uint32_t *)&env->fpr[i + 1]) = tmp & 0xffffffff;
+ }
+ env->pc = tswapl(registers[64]);
+ env->npc = tswapl(registers[65]);
+ env->tstate[env->tl] = tswapl(registers[66]);
+ env->fsr = tswapl(registers[67]);
+ env->fprs = tswapl(registers[68]);
+ env->y = tswapl(registers[69]);
+#endif
+}
+#elif defined (TARGET_ARM)
+static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
+{
+ int i;
+ uint8_t *ptr;
+
+ ptr = mem_buf;
+ /* 16 core integer registers (4 bytes each). */
+ for (i = 0; i < 16; i++)
+ {
+ *(uint32_t *)ptr = tswapl(env->regs[i]);
+ ptr += 4;
+ }
+ /* 8 FPA registers (12 bytes each), FPS (4 bytes).
+ Not yet implemented. */
+ memset (ptr, 0, 8 * 12 + 4);
+ ptr += 8 * 12 + 4;
+ /* CPSR (4 bytes). */
+ *(uint32_t *)ptr = tswapl (cpsr_read(env));
+ ptr += 4;
+
+ return ptr - mem_buf;
+}
+
+static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
+{
+ int i;
+ uint8_t *ptr;
+
+ ptr = mem_buf;
+ /* Core integer registers. */
+ for (i = 0; i < 16; i++)
+ {
+ env->regs[i] = tswapl(*(uint32_t *)ptr);
+ ptr += 4;
+ }
+ /* Ignore FPA regs and scr. */
+ ptr += 8 * 12 + 4;
+ cpsr_write (env, tswapl(*(uint32_t *)ptr), 0xffffffff);
+}
+#elif defined (TARGET_M68K)
+static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
+{
+ int i;
+ uint8_t *ptr;
+ CPU_DoubleU u;
+
+ ptr = mem_buf;
+ /* D0-D7 */
+ for (i = 0; i < 8; i++) {
+ *(uint32_t *)ptr = tswapl(env->dregs[i]);
+ ptr += 4;
+ }
+ /* A0-A7 */
+ for (i = 0; i < 8; i++) {
+ *(uint32_t *)ptr = tswapl(env->aregs[i]);
+ ptr += 4;
+ }
+ *(uint32_t *)ptr = tswapl(env->sr);
+ ptr += 4;
+ *(uint32_t *)ptr = tswapl(env->pc);
+ ptr += 4;
+ /* F0-F7. The 68881/68040 have 12-bit extended precision registers.
+ ColdFire has 8-bit double precision registers. */
+ for (i = 0; i < 8; i++) {
+ u.d = env->fregs[i];
+ *(uint32_t *)ptr = tswap32(u.l.upper);
+ *(uint32_t *)ptr = tswap32(u.l.lower);
+ }
+ /* FP control regs (not implemented). */
+ memset (ptr, 0, 3 * 4);
+ ptr += 3 * 4;
+
+ return ptr - mem_buf;
+}
+
+static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
+{
+ int i;
+ uint8_t *ptr;
+ CPU_DoubleU u;
+
+ ptr = mem_buf;
+ /* D0-D7 */
+ for (i = 0; i < 8; i++) {
+ env->dregs[i] = tswapl(*(uint32_t *)ptr);
+ ptr += 4;
+ }
+ /* A0-A7 */
+ for (i = 0; i < 8; i++) {
+ env->aregs[i] = tswapl(*(uint32_t *)ptr);
+ ptr += 4;
+ }
+ env->sr = tswapl(*(uint32_t *)ptr);
+ ptr += 4;
+ env->pc = tswapl(*(uint32_t *)ptr);
+ ptr += 4;
+ /* F0-F7. The 68881/68040 have 12-bit extended precision registers.
+ ColdFire has 8-bit double precision registers. */
+ for (i = 0; i < 8; i++) {
+ u.l.upper = tswap32(*(uint32_t *)ptr);
+ u.l.lower = tswap32(*(uint32_t *)ptr);
+ env->fregs[i] = u.d;
+ }
+ /* FP control regs (not implemented). */
+ ptr += 3 * 4;
+}
+#elif defined (TARGET_MIPS)
+static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
+{
+ int i;
+ uint8_t *ptr;
+
+ ptr = mem_buf;
+ for (i = 0; i < 32; i++)
+ {
+ *(uint32_t *)ptr = tswapl(env->gpr[i]);
+ ptr += 4;
+ }
+
+ *(uint32_t *)ptr = tswapl(env->CP0_Status);
+ ptr += 4;
+
+ *(uint32_t *)ptr = tswapl(env->LO);
+ ptr += 4;
+
+ *(uint32_t *)ptr = tswapl(env->HI);
+ ptr += 4;
+
+ *(uint32_t *)ptr = tswapl(env->CP0_BadVAddr);
+ ptr += 4;
+
+ *(uint32_t *)ptr = tswapl(env->CP0_Cause);
+ ptr += 4;
+
+ *(uint32_t *)ptr = tswapl(env->PC);
+ ptr += 4;
+
+ if (env->CP0_Config1 & (1 << CP0C1_FP))
+ {
+ for (i = 0; i < 32; i++)
+ {
+ *(uint32_t *)ptr = tswapl(env->fpr[i].fs[FP_ENDIAN_IDX]);
+ ptr += 4;
+ }
+
+ *(uint32_t *)ptr = tswapl(env->fcr31);
+ ptr += 4;
+
+ *(uint32_t *)ptr = tswapl(env->fcr0);
+ ptr += 4;
+ }
+
+ /* 32 FP registers, fsr, fir, fp. Not yet implemented. */
+ /* what's 'fp' mean here? */
+
+ return ptr - mem_buf;
+}
+
+/* convert MIPS rounding mode in FCR31 to IEEE library */
+static unsigned int ieee_rm[] =
+ {
+ float_round_nearest_even,
+ float_round_to_zero,
+ float_round_up,
+ float_round_down
+ };
+#define RESTORE_ROUNDING_MODE \
+ set_float_rounding_mode(ieee_rm[env->fcr31 & 3], &env->fp_status)
+
+static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
+{
+ int i;
+ uint8_t *ptr;
+
+ ptr = mem_buf;
+ for (i = 0; i < 32; i++)
+ {
+ env->gpr[i] = tswapl(*(uint32_t *)ptr);
+ ptr += 4;
+ }
+
+ env->CP0_Status = tswapl(*(uint32_t *)ptr);
+ ptr += 4;
+
+ env->LO = tswapl(*(uint32_t *)ptr);
+ ptr += 4;
+
+ env->HI = tswapl(*(uint32_t *)ptr);
+ ptr += 4;
+
+ env->CP0_BadVAddr = tswapl(*(uint32_t *)ptr);
+ ptr += 4;
+
+ env->CP0_Cause = tswapl(*(uint32_t *)ptr);
+ ptr += 4;
+
+ env->PC = tswapl(*(uint32_t *)ptr);
+ ptr += 4;
+
+ if (env->CP0_Config1 & (1 << CP0C1_FP))
+ {
+ for (i = 0; i < 32; i++)
+ {
+ env->fpr[i].fs[FP_ENDIAN_IDX] = tswapl(*(uint32_t *)ptr);
+ ptr += 4;
+ }
+
+ env->fcr31 = tswapl(*(uint32_t *)ptr) & 0x0183FFFF;
+ ptr += 4;
+
+ env->fcr0 = tswapl(*(uint32_t *)ptr);
+ ptr += 4;
+
+ /* set rounding mode */
+ RESTORE_ROUNDING_MODE;
+
+#ifndef CONFIG_SOFTFLOAT
+ /* no floating point exception for native float */
+ SET_FP_ENABLE(env->fcr31, 0);
+#endif
+ }
+}
+#elif defined (TARGET_SH4)
+
+/* Hint: Use "set architecture sh4" in GDB to see fpu registers */
+
+static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
+{
+ uint32_t *ptr = (uint32_t *)mem_buf;
+ int i;
+
+#define SAVE(x) *ptr++=tswapl(x)
+ if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
+ for (i = 0; i < 8; i++) SAVE(env->gregs[i + 16]);
+ } else {
+ for (i = 0; i < 8; i++) SAVE(env->gregs[i]);
+ }
+ for (i = 8; i < 16; i++) SAVE(env->gregs[i]);
+ SAVE (env->pc);
+ SAVE (env->pr);
+ SAVE (env->gbr);
+ SAVE (env->vbr);
+ SAVE (env->mach);
+ SAVE (env->macl);
+ SAVE (env->sr);
+ SAVE (env->fpul);
+ SAVE (env->fpscr);
+ for (i = 0; i < 16; i++)
+ SAVE(env->fregs[i + ((env->fpscr & FPSCR_FR) ? 16 : 0)]);
+ SAVE (env->ssr);
+ SAVE (env->spc);
+ for (i = 0; i < 8; i++) SAVE(env->gregs[i]);
+ for (i = 0; i < 8; i++) SAVE(env->gregs[i + 16]);
+ return ((uint8_t *)ptr - mem_buf);
+}
+
+static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
+{
+ uint32_t *ptr = (uint32_t *)mem_buf;
+ int i;
+
+#define LOAD(x) (x)=*ptr++;
+ if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
+ for (i = 0; i < 8; i++) LOAD(env->gregs[i + 16]);
+ } else {
+ for (i = 0; i < 8; i++) LOAD(env->gregs[i]);
+ }
+ for (i = 8; i < 16; i++) LOAD(env->gregs[i]);
+ LOAD (env->pc);
+ LOAD (env->pr);
+ LOAD (env->gbr);
+ LOAD (env->vbr);
+ LOAD (env->mach);
+ LOAD (env->macl);
+ LOAD (env->sr);
+ LOAD (env->fpul);
+ LOAD (env->fpscr);
+ for (i = 0; i < 16; i++)
+ LOAD(env->fregs[i + ((env->fpscr & FPSCR_FR) ? 16 : 0)]);
+ LOAD (env->ssr);
+ LOAD (env->spc);
+ for (i = 0; i < 8; i++) LOAD(env->gregs[i]);
+ for (i = 0; i < 8; i++) LOAD(env->gregs[i + 16]);
+}
+#else
+static int cpu_gdb_read_registers(CPUState *env, uint8_t *mem_buf)
+{
+ return 0;
+}
+
+static void cpu_gdb_write_registers(CPUState *env, uint8_t *mem_buf, int size)
+{
+}
+
+#endif
+
+static int gdb_handle_packet(GDBState *s, CPUState *env, const char *line_buf)
+{
+ const char *p;
+ int ch, reg_size, type;
+ char buf[4096];
+ uint8_t mem_buf[2000];
+ uint32_t *registers;
+ target_ulong addr, len;
+
+#ifdef DEBUG_GDB
+ printf("command='%s'\n", line_buf);
+#endif
+ p = line_buf;
+ ch = *p++;
+ switch(ch) {
+ case '?':
+ /* TODO: Make this return the correct value for user-mode. */
+ snprintf(buf, sizeof(buf), "S%02x", SIGTRAP);
+ put_packet(s, buf);
+ break;
+ case 'c':
+ if (*p != '\0') {
+ addr = strtoull(p, (char **)&p, 16);
+#if defined(TARGET_I386)
+ env->eip = addr;
+#elif defined (TARGET_PPC)
+ env->nip = addr;
+#elif defined (TARGET_SPARC)
+ env->pc = addr;
+ env->npc = addr + 4;
+#elif defined (TARGET_ARM)
+ env->regs[15] = addr;
+#elif defined (TARGET_SH4)
+ env->pc = addr;
+#endif
+ }
+#ifdef CONFIG_USER_ONLY
+ s->running_state = 1;
+#else
+ vm_start();
+#endif
+ return RS_IDLE;
+ case 's':
+ if (*p != '\0') {