#ifndef __ASM_GDB_STUB_H
 #define __ASM_GDB_STUB_H
 
+#undef GDBSTUB_DEBUG_IO
 #undef GDBSTUB_DEBUG_PROTOCOL
 
 #include <asm/ptrace.h>
 extern void debug_to_serial(const char *p, int n);
 extern void console_set_baud(unsigned baud);
 
+#ifdef GDBSTUB_DEBUG_IO
+#define gdbstub_io(FMT,...) gdbstub_printk(FMT, ##__VA_ARGS__)
+#else
+#define gdbstub_io(FMT,...) ({ 0; })
+#endif
+
 #ifdef GDBSTUB_DEBUG_PROTOCOL
 #define gdbstub_proto(FMT,...) gdbstub_printk(FMT,##__VA_ARGS__)
 #else
 
                return -EINTR;
        }
        else if (st & (UART_LSR_FE|UART_LSR_OE|UART_LSR_PE)) {
-               gdbstub_proto("### GDB Rx Error (st=%02x) ###\n",st);
+               gdbstub_io("### GDB Rx Error (st=%02x) ###\n",st);
                return -EIO;
        }
        else {
-               gdbstub_proto("### GDB Rx %02x (st=%02x) ###\n",ch,st);
+               gdbstub_io("### GDB Rx %02x (st=%02x) ###\n",ch,st);
                *_ch = ch & 0x7f;
                return 0;
        }
 
 
 } /* end gdbstub_get_mmu_state() */
 
+/*
+ * handle general query commands of the form 'qXXXXX'
+ */
+static void gdbstub_handle_query(void)
+{
+       if (strcmp(input_buffer, "qAttached") == 0) {
+               /* return current thread ID */
+               sprintf(output_buffer, "1");
+               return;
+       }
+
+       if (strcmp(input_buffer, "qC") == 0) {
+               /* return current thread ID */
+               sprintf(output_buffer, "QC 0");
+               return;
+       }
+
+       if (strcmp(input_buffer, "qOffsets") == 0) {
+               /* return relocation offset of text and data segments */
+               sprintf(output_buffer, "Text=0;Data=0;Bss=0");
+               return;
+       }
+
+       if (strcmp(input_buffer, "qSymbol::") == 0) {
+               sprintf(output_buffer, "OK");
+               return;
+       }
+
+       if (strcmp(input_buffer, "qSupported") == 0) {
+               /* query of supported features */
+               sprintf(output_buffer, "PacketSize=%u;ReverseContinue-;ReverseStep-",
+                       sizeof(input_buffer));
+               return;
+       }
+
+       gdbstub_strcpy(output_buffer,"E01");
+}
+
 /*****************************************************************************/
 /*
  * handle event interception and GDB remote protocol processing
                case 'k' :
                        goto done;      /* just continue */
 
+                       /* detach */
+               case 'D':
+                       gdbstub_strcpy(output_buffer, "OK");
+                       break;
 
                        /* reset the whole machine (FIXME: system dependent) */
                case 'r':
                        __debug_status.dcr |= DCR_SE;
                        goto done;
 
+                       /* extended command */
+               case 'v':
+                       if (strcmp(input_buffer, "vCont?") == 0) {
+                               output_buffer[0] = 0;
+                               break;
+                       }
+                       goto unsupported_cmd;
+
                        /* set baud rate (bBB) */
                case 'b':
                        ptr = &input_buffer[1];
                        gdbstub_strcpy(output_buffer,"OK");
                        break;
 
+                       /* Thread-setting packet */
+               case 'H':
+                       gdbstub_strcpy(output_buffer, "OK");
+                       break;
+
+               case 'q':
+                       gdbstub_handle_query();
+                       break;
+
                default:
+               unsupported_cmd:
                        gdbstub_proto("### GDB Unsupported Cmd '%s'\n",input_buffer);
+                       gdbstub_strcpy(output_buffer,"E01");
                        break;
                }