/* * Calls linux_debug_hook before the kernel dies. If KGDB is enabled, * then try to fall into the debugger */ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd, void *ptr) { struct die_args *args = (struct die_args *)ptr; struct pt_regs *regs = args->regs; int trap = (regs->cp0_cause & 0x7c) >> 2; /* Userpace events, ignore. */ if (user_mode(regs)) return NOTIFY_DONE; if (atomic_read(&kgdb_active) != -1) kgdb_nmicallback(smp_processor_id(), regs); if (kgdb_handle_exception(trap, compute_signal(trap), 0, regs)) return NOTIFY_DONE; if (atomic_read(&kgdb_setting_breakpoint)) if ((trap == 9) && (regs->cp0_epc == (unsigned long)breakinst)) regs->cp0_epc += 4; /* In SMP mode, __flush_cache_all does IPI */ local_irq_enable(); __flush_cache_all(); return NOTIFY_STOP; }
int btstack_main(int argc, const char * argv[]){ #ifdef TABLE_SIZE compute_signal(); #endif hci_register_sco_packet_handler(&sco_packet_handler); hci_discoverable_control(1); hci_ssp_set_io_capability(SSP_IO_CAPABILITY_DISPLAY_YES_NO); gap_set_local_name("BTstack HSP HS"); hsp_hs_init(rfcomm_channel_nr); hsp_hs_register_packet_handler(packet_handler); sdp_init(); memset((uint8_t *)hsp_service_buffer, 0, sizeof(hsp_service_buffer)); hsp_hs_create_service((uint8_t *)hsp_service_buffer, rfcomm_channel_nr, hsp_hs_service_name, 0); sdp_register_service_internal(NULL, (uint8_t *)hsp_service_buffer); // turn on! hci_power_control(HCI_POWER_ON); return 0; }
/* * Calls linux_debug_hook before the kernel dies. If KGDB is enabled, * then try to fall into the debugger */ static int kgdb_mips_notify(struct notifier_block *self, unsigned long cmd, void *ptr) { struct die_args *args = (struct die_args *)ptr; struct pt_regs *regs = args->regs; int trap = (regs->cp0_cause & 0x7c) >> 2; /* See if KGDB is interested. */ if (user_mode(regs)) /* Userpace events, ignore. */ return NOTIFY_DONE; kgdb_handle_exception(trap, compute_signal(trap), 0, regs); return NOTIFY_OK; }
/* * Set up exception handlers for tracing and breakpoints */ void handle_exception(struct pt_regs *regs) { int trap = (regs->cp0_cause & 0x7c) >> 2; if (fixup_exception(regs)) { return; } if (atomic_read(&debugger_active)) kgdb_nmihook(smp_processor_id(), regs); if (atomic_read(&kgdb_setting_breakpoint)) if ((trap == 9) && (regs->cp0_epc == (unsigned long)breakinst)) regs->cp0_epc += 4; kgdb_handle_exception(0, compute_signal(trap), 0, regs); /* In SMP mode, __flush_cache_all does IPI */ __flush_cache_all(); }
/* * This function does all command procesing for interfacing to gdb. */ void gdb_stub_handler(int exception_vector) { int sigval; int addr, length; char * ptr; #ifdef GDB_REMOTE_UDP gdb_udp_poll_start(); #endif /* GDB_REMOTE_UDP */ if(remote_debug) GDB_PRINTF("vector=%d, ps=0x%x, pc=0x%x\n", exception_vector, gdb_registers[PS], gdb_registers[PC]); /* reply to host that an exception has occurred */ sigval = compute_signal(exception_vector); remcomOutBuffer[0] = 'S'; remcomOutBuffer[1] = hexchars[sigval >> 4]; remcomOutBuffer[2] = hexchars[sigval % 16]; remcomOutBuffer[3] = 0; if(remote_debug) GDB_PRINTF("GDB send packet: %s\n", remcomOutBuffer); gdb_put_packet(remcomOutBuffer); while (1) { remcomOutBuffer[0] = 0; gdb_get_packet(remcomInBuffer); if(remote_debug) GDB_PRINTF("GDB reveive packet: %s\n", remcomInBuffer); switch (remcomInBuffer[0]) { case '?' : remcomOutBuffer[0] = 'S'; remcomOutBuffer[1] = hexchars[sigval >> 4]; remcomOutBuffer[2] = hexchars[sigval % 16]; remcomOutBuffer[3] = 0; break; case 'd' : remote_debug = !(remote_debug); /* toggle debug flag */ break; case 'g' : /* return the value of the CPU registers */ mem2hex((char*) gdb_registers, remcomOutBuffer, NUMREGBYTES, 0); break; case 'G' : /* set the value of the CPU registers - return OK */ hex2mem(&remcomInBuffer[1], (char*) gdb_registers, NUMREGBYTES, 0); gdb_strcpy(remcomOutBuffer,"OK"); break; /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */ case 'm' : /* TRY TO READ %x,%x. IF SUCCEED, SET PTR = 0 */ ptr = &remcomInBuffer[1]; if (hex2int(&ptr,&addr)) if (*(ptr++) == ',') if (hex2int(&ptr,&length)) { ptr = 0; mem_err = 0; mem2hex((char*) addr, remcomOutBuffer, length, 1); if (mem_err) { gdb_strcpy (remcomOutBuffer, "E03"); if(remote_debug) GDB_PRINTF("memory fault"); } } if (ptr) { gdb_strcpy(remcomOutBuffer,"E01"); if(remote_debug) GDB_PRINTF("malformed read memory command: %s",remcomInBuffer); } break; /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */ case 'M' : /* TRY TO READ '%x,%x:'. IF SUCCEED, SET PTR = 0 */ ptr = &remcomInBuffer[1]; if (hex2int(&ptr,&addr)) if (*(ptr++) == ',') if (hex2int(&ptr,&length)) if (*(ptr++) == ':') { mem_err = 0; hex2mem(ptr, (char*) addr, length, 1); if (mem_err) { gdb_strcpy (remcomOutBuffer, "E03"); if(remote_debug) GDB_PRINTF("memory fault"); } else { gdb_strcpy(remcomOutBuffer,"OK"); } ptr = 0; } if (ptr) { gdb_strcpy(remcomOutBuffer,"E02"); if(remote_debug) GDB_PRINTF("malformed write memory command: %s",remcomInBuffer); } break; /* cAA..AA Continue at address AA..AA(optional) */ /* sAA..AA Step one instruction from AA..AA(optional) */ case 'c' : case 's' : /* try to read optional parameter, pc unchanged if no parm */ ptr = &remcomInBuffer[1]; if (hex2int(&ptr,&addr)) gdb_registers[PC] = addr; /* set the trace bit if we're stepping */ if (remcomInBuffer[0] == 's') gdb_registers[PS] |= 0x100; else gdb_registers[PS] &= 0xfffffeff; #ifdef GDB_REMOTE_UDP gdb_udp_poll_stop(); #endif /* GDB_REMOTE_UDP */ return; // break; /* kill the program */ case 'k' : /* do nothing */ break; /* Z<type-1x>,<address-x>,<length-x> Add breakpoint */ case 'Z' : if(hex(remcomInBuffer[1]) != 0) { /* We support only software break points so far */ break; } ptr = &remcomInBuffer[2]; if (*(ptr++) == ',') if (hex2int(&ptr,&addr)) { if (*(ptr++) == ',') { if (hex2int(&ptr,&length)) { if(length != 1) { gdb_strcpy(remcomOutBuffer,"E02"); if(remote_debug) GDB_PRINTF("Breakpoint address length isn't equal to 1."); break; } ptr = 0; } } } if (ptr) { gdb_strcpy(remcomOutBuffer,"E01"); if(remote_debug) GDB_PRINTF("malformed add breakpoint command: %s",remcomInBuffer); } else { struct zbreak *z; /* check whether this break point already set */ z = zbreak_list_find(addr); if(z) { /* Repeated packet */ gdb_strcpy(remcomOutBuffer,"OK"); break; } /* get an free zbreak */ mem_err = 0; z = zbreak_new(addr); if(z == NULL) { gdb_strcpy(remcomOutBuffer,"E03"); if(remote_debug) GDB_PRINTF("new zbreak failed.\n"); break; } if (mem_err) { gdb_strcpy (remcomOutBuffer, "E03"); if(remote_debug) GDB_PRINTF("memory fault"); break; } gdb_strcpy(remcomOutBuffer, "OK"); } break; /* z<type-1x>,<address-x>,<length-x> Remove breakpoint */ /* zz Remove all breakpoints */ case 'z' : if(hex(remcomInBuffer[1]) == 'z') { /* remove all breakpoints */ while(valid_zbreak_list.next != &valid_zbreak_list) { zbreak_free(valid_zbreak_list.next); } gdb_strcpy(remcomOutBuffer, "OK"); break; } if(hex(remcomInBuffer[1]) != 0) { /* We support only software break points so far */ break; } ptr = &remcomInBuffer[2]; if (*(ptr++) == ',') if (hex2int(&ptr,&addr)) { if (*(ptr++) == ',') { if (hex2int(&ptr,&length)) { if(length != 1) { gdb_strcpy(remcomOutBuffer,"E02"); if(remote_debug) GDB_PRINTF("Breakpoint address length isn't equal to 1."); break; } ptr = 0; } } } if (ptr) { gdb_strcpy(remcomOutBuffer,"E01"); if(remote_debug) GDB_PRINTF("malformed remove breakpoint command: %s",remcomInBuffer); } else { struct zbreak *z; z = zbreak_list_find(addr); if(z == NULL) { gdb_strcpy(remcomOutBuffer,"E03"); if(remote_debug) GDB_PRINTF("Breakpoint no found.\n"); break; } /* free zbreak */ zbreak_free(z); gdb_strcpy(remcomOutBuffer,"OK"); } break; } /* switch */ /* reply to the request */ if(remote_debug) GDB_PRINTF("GDB send packet: %s\n", remcomOutBuffer); gdb_put_packet(remcomOutBuffer); } }