Line 17... |
Line 17... |
"Description:\n"
|
"Description:\n"
|
" Get breakpoints list or add/remove breakpoint with specified\n"
|
" Get breakpoints list or add/remove breakpoint with specified\n"
|
" flags.\n"
|
" flags.\n"
|
"Response:\n"
|
"Response:\n"
|
" List of lists [[iii]*] if breakpoint list was requested, where:\n"
|
" List of lists [[iii]*] if breakpoint list was requested, where:\n"
|
" i - uint64_t address value\n"
|
" i|s - uint64_t address value or 'string' symbol name\n"
|
" i - uint32_t instruction value\n"
|
" i - uint32_t instruction value\n"
|
" i - uint64_t Breakpoint flags: hardware,...\n"
|
" i - uint64_t Breakpoint flags: hardware,...\n"
|
" Nil in a case of add/rm breakpoint\n"
|
" Nil in a case of add/rm breakpoint\n"
|
"Usage:\n"
|
"Usage:\n"
|
" br"
|
" br"
|
" br add <addr>\n"
|
" br add <addr>\n"
|
" br rm <addr>\n"
|
" br rm <addr>\n"
|
|
" br rm 'symbol_name'\n"
|
" br add <addr> hw\n"
|
" br add <addr> hw\n"
|
"Example:\n"
|
"Example:\n"
|
" br add 0x10000000\n"
|
" br add 0x10000000\n"
|
" br add 0x00020040 hw\n"
|
" br add 0x00020040 hw\n"
|
" br rm 0x10000000\n");
|
" br add 'func1'\n"
|
|
" br rm 0x10000000\n"
|
|
" br rm 'func1'\n");
|
|
|
AttributeType lstServ;
|
AttributeType lstServ;
|
RISCV_get_services_with_iface(IFACE_SOURCE_CODE, &lstServ);
|
RISCV_get_services_with_iface(IFACE_SOURCE_CODE, &lstServ);
|
isrc_ = 0;
|
isrc_ = 0;
|
if (lstServ.size() != 0) {
|
if (lstServ.size() != 0) {
|
Line 66... |
Line 69... |
uint64_t flags = 0;
|
uint64_t flags = 0;
|
if (args->size() == 4 && (*args)[3].is_equal("hw")) {
|
if (args->size() == 4 && (*args)[3].is_equal("hw")) {
|
flags |= BreakFlag_HW;
|
flags |= BreakFlag_HW;
|
}
|
}
|
|
|
Reg64Type instr;
|
DsuMapType *pdsu = info_->getpDsu();
|
uint64_t addr = (*args)[2].to_uint64();
|
|
tap_->read(addr, 4, instr.buf);
|
|
isrc_->registerBreakpoint(addr, instr.buf32[0], flags);
|
|
|
|
instr.buf32[0] = 0x00100073; // EBREAK instruction
|
Reg64Type braddr;
|
|
Reg64Type brinstr;
|
|
AttributeType &bpadr = (*args)[2];
|
|
if (bpadr.is_integer()) {
|
|
braddr.val = bpadr.to_uint64();
|
|
} else if (bpadr.is_string()) {
|
|
if (isrc_->symbol2Address(bpadr.to_string(), &braddr.val) < 0) {
|
|
generateError(res, "Symbol not found");
|
|
return;
|
|
}
|
|
} else {
|
|
generateError(res, "Wrong command format");
|
|
return;
|
|
}
|
|
|
if ((*args)[1].is_equal("add")) {
|
if ((*args)[1].is_equal("add")) {
|
tap_->write(addr, 4, instr.buf);
|
brinstr.val = 0;
|
|
tap_->read(braddr.val, 4, brinstr.buf);
|
|
|
|
isrc_->registerBreakpoint(braddr.val, flags, brinstr.val);
|
|
if (flags & BreakFlag_HW) {
|
|
uint64_t dsuaddr =
|
|
reinterpret_cast<uint64_t>(&pdsu->udbg.v.add_breakpoint);
|
|
tap_->write(dsuaddr, 8, braddr.buf);
|
|
} else {
|
|
if ((brinstr.val & 0x3) == 0x3) {
|
|
brinstr.buf32[0] = 0x00100073; // EBREAK instruction
|
|
} else {
|
|
brinstr.buf16[0] = 0x9002; // C.EBREAK instruction
|
|
}
|
|
tap_->write(braddr.val, 4, brinstr.buf);
|
|
}
|
return;
|
return;
|
}
|
}
|
|
|
if ((*args)[1].is_equal("rm")) {
|
if ((*args)[1].is_equal("rm")) {
|
if (!isrc_->unregisterBreakpoint(addr, instr.buf32, &flags)) {
|
isrc_->unregisterBreakpoint(braddr.val, &flags, &brinstr.val);
|
tap_->write(addr, 4, instr.buf);
|
if (flags & BreakFlag_HW) {
|
|
uint64_t dsuaddr =
|
|
reinterpret_cast<uint64_t>(&pdsu->udbg.v.remove_breakpoint);
|
|
tap_->write(dsuaddr, 8, braddr.buf);
|
|
} else {
|
|
tap_->write(braddr.val, 4, brinstr.buf);
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
} // namespace debugger
|
} // namespace debugger
|