126d125
< #include "base/kgdb.h"
141,142c140
< vector<RemoteGDB *> debuggers;
< int current_debugger = -1;
---
> vector<BaseRemoteGDB *> debuggers;
146a145
> static int current_debugger = -1;
148c147
< RemoteGDB *gdb = debuggers[current_debugger];
---
> BaseRemoteGDB *gdb = debuggers[current_debugger];
152c151
< gdb->trap(ALPHA_KENTRY_IF);
---
> gdb->trap(SIGILL);
172c171
< GDBListener::GDBListener(RemoteGDB *g, int p)
---
> GDBListener::GDBListener(BaseRemoteGDB *g, int p)
232,242c231
< ///////////////////////////////////////////////////////////
< //
< //
< //
< int digit2i(char);
< char i2digit(int);
< void mem2hex(void *, const void *, int);
< const char *hex2mem(void *, const char *, int);
< Addr hex2i(const char **);
<
< RemoteGDB::Event::Event(RemoteGDB *g, int fd, int e)
---
> BaseRemoteGDB::Event::Event(BaseRemoteGDB *g, int fd, int e)
247c236
< RemoteGDB::Event::process(int revent)
---
> BaseRemoteGDB::Event::process(int revent)
250c239
< gdb->trap(ALPHA_KENTRY_IF);
---
> gdb->trap(SIGILL);
255c244
< RemoteGDB::RemoteGDB(System *_system, ThreadContext *c)
---
> BaseRemoteGDB::BaseRemoteGDB(System *_system, ThreadContext *c, size_t cacheSize)
258c247,248
< system(_system), pmem(_system->physmem), context(c)
---
> system(_system), pmem(_system->physmem), context(c),
> gdbregs(cacheSize)
260c250
< memset(gdbregs, 0, sizeof(gdbregs));
---
> memset(gdbregs.regs, 0, gdbregs.size);
263c253
< RemoteGDB::~RemoteGDB()
---
> BaseRemoteGDB::~BaseRemoteGDB()
270c260
< RemoteGDB::name()
---
> BaseRemoteGDB::name()
276c266
< RemoteGDB::isattached()
---
> BaseRemoteGDB::isattached()
280c270
< RemoteGDB::attach(int f)
---
> BaseRemoteGDB::attach(int f)
292c282
< RemoteGDB::detach()
---
> BaseRemoteGDB::detach()
303c293
< gdb_command(char cmd)
---
> BaseRemoteGDB::gdb_command(char cmd)
306,336c296,326
< case KGDB_SIGNAL: return "KGDB_SIGNAL";
< case KGDB_SET_BAUD: return "KGDB_SET_BAUD";
< case KGDB_SET_BREAK: return "KGDB_SET_BREAK";
< case KGDB_CONT: return "KGDB_CONT";
< case KGDB_ASYNC_CONT: return "KGDB_ASYNC_CONT";
< case KGDB_DEBUG: return "KGDB_DEBUG";
< case KGDB_DETACH: return "KGDB_DETACH";
< case KGDB_REG_R: return "KGDB_REG_R";
< case KGDB_REG_W: return "KGDB_REG_W";
< case KGDB_SET_THREAD: return "KGDB_SET_THREAD";
< case KGDB_CYCLE_STEP: return "KGDB_CYCLE_STEP";
< case KGDB_SIG_CYCLE_STEP: return "KGDB_SIG_CYCLE_STEP";
< case KGDB_KILL: return "KGDB_KILL";
< case KGDB_MEM_W: return "KGDB_MEM_W";
< case KGDB_MEM_R: return "KGDB_MEM_R";
< case KGDB_SET_REG: return "KGDB_SET_REG";
< case KGDB_READ_REG: return "KGDB_READ_REG";
< case KGDB_QUERY_VAR: return "KGDB_QUERY_VAR";
< case KGDB_SET_VAR: return "KGDB_SET_VAR";
< case KGDB_RESET: return "KGDB_RESET";
< case KGDB_STEP: return "KGDB_STEP";
< case KGDB_ASYNC_STEP: return "KGDB_ASYNC_STEP";
< case KGDB_THREAD_ALIVE: return "KGDB_THREAD_ALIVE";
< case KGDB_TARGET_EXIT: return "KGDB_TARGET_EXIT";
< case KGDB_BINARY_DLOAD: return "KGDB_BINARY_DLOAD";
< case KGDB_CLR_HW_BKPT: return "KGDB_CLR_HW_BKPT";
< case KGDB_SET_HW_BKPT: return "KGDB_SET_HW_BKPT";
< case KGDB_START: return "KGDB_START";
< case KGDB_END: return "KGDB_END";
< case KGDB_GOODP: return "KGDB_GOODP";
< case KGDB_BADP: return "KGDB_BADP";
---
> case GDBSignal: return "KGDB_SIGNAL";
> case GDBSetBaud: return "KGDB_SET_BAUD";
> case GDBSetBreak: return "KGDB_SET_BREAK";
> case GDBCont: return "KGDB_CONT";
> case GDBAsyncCont: return "KGDB_ASYNC_CONT";
> case GDBDebug: return "KGDB_DEBUG";
> case GDBDetach: return "KGDB_DETACH";
> case GDBRegR: return "KGDB_REG_R";
> case GDBRegW: return "KGDB_REG_W";
> case GDBSetThread: return "KGDB_SET_THREAD";
> case GDBCycleStep: return "KGDB_CYCLE_STEP";
> case GDBSigCycleStep: return "KGDB_SIG_CYCLE_STEP";
> case GDBKill: return "KGDB_KILL";
> case GDBMemW: return "KGDB_MEM_W";
> case GDBMemR: return "KGDB_MEM_R";
> case GDBSetReg: return "KGDB_SET_REG";
> case GDBReadReg: return "KGDB_READ_REG";
> case GDBQueryVar: return "KGDB_QUERY_VAR";
> case GDBSetVar: return "KGDB_SET_VAR";
> case GDBReset: return "KGDB_RESET";
> case GDBStep: return "KGDB_STEP";
> case GDBAsyncStep: return "KGDB_ASYNC_STEP";
> case GDBThreadAlive: return "KGDB_THREAD_ALIVE";
> case GDBTargetExit: return "KGDB_TARGET_EXIT";
> case GDBBinaryDload: return "KGDB_BINARY_DLOAD";
> case GDBClrHwBkpt: return "KGDB_CLR_HW_BKPT";
> case GDBSetHwBkpt: return "KGDB_SET_HW_BKPT";
> case GDBStart: return "KGDB_START";
> case GDBEnd: return "KGDB_END";
> case GDBGoodP: return "KGDB_GOODP";
> case GDBBadP: return "KGDB_BADP";
341,540d330
< ///////////////////////////////////////////////////////////
< // RemoteGDB::acc
< //
< // Determine if the mapping at va..(va+len) is valid.
< //
< bool
< RemoteGDB::acc(Addr va, size_t len)
< {
< Addr last_va;
<
< va = TheISA::TruncPage(va);
< last_va = TheISA::RoundPage(va + len);
<
< do {
< if (TheISA::IsK0Seg(va)) {
< if (va < (TheISA::K0SegBase + pmem->size())) {
< DPRINTF(GDBAcc, "acc: Mapping is valid K0SEG <= "
< "%#x < K0SEG + size\n", va);
< return true;
< } else {
< DPRINTF(GDBAcc, "acc: Mapping invalid %#x > K0SEG + size\n",
< va);
< return false;
< }
< }
<
< /**
< * This code says that all accesses to palcode (instruction and data)
< * are valid since there isn't a va->pa mapping because palcode is
< * accessed physically. At some point this should probably be cleaned up
< * but there is no easy way to do it.
< */
<
< if (AlphaISA::PcPAL(va) || va < 0x10000)
< return true;
<
< Addr ptbr = context->readMiscReg(AlphaISA::IPR_PALtemp20);
< TheISA::PageTableEntry pte = TheISA::kernel_pte_lookup(context->getPhysPort(), ptbr, va);
< if (!pte.valid()) {
< DPRINTF(GDBAcc, "acc: %#x pte is invalid\n", va);
< return false;
< }
< va += TheISA::PageBytes;
< } while (va < last_va);
<
< DPRINTF(GDBAcc, "acc: %#x mapping is valid\n", va);
< return true;
< }
<
< ///////////////////////////////////////////////////////////
< // RemoteGDB::signal
< //
< // Translate a trap number into a Unix-compatible signal number.
< // (GDB only understands Unix signal numbers.)
< //
< int
< RemoteGDB::signal(int type)
< {
< switch (type) {
< case ALPHA_KENTRY_INT:
< return (SIGTRAP);
<
< case ALPHA_KENTRY_UNA:
< return (SIGBUS);
<
< case ALPHA_KENTRY_ARITH:
< return (SIGFPE);
<
< case ALPHA_KENTRY_IF:
< return (SIGILL);
<
< case ALPHA_KENTRY_MM:
< return (SIGSEGV);
<
< default:
< panic("unknown signal type");
< return 0;
< }
< }
<
< ///////////////////////////////////////////////////////////
< // RemoteGDB::getregs
< //
< // Translate the kernel debugger register format into
< // the GDB register format.
< void
< RemoteGDB::getregs()
< {
< memset(gdbregs, 0, sizeof(gdbregs));
<
< gdbregs[KGDB_REG_PC] = context->readPC();
<
< // @todo: Currently this is very Alpha specific.
< if (AlphaISA::PcPAL(gdbregs[KGDB_REG_PC])) {
< for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
< gdbregs[i] = context->readIntReg(AlphaISA::reg_redir[i]);
< }
< } else {
< for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
< gdbregs[i] = context->readIntReg(i);
< }
< }
<
< #ifdef KGDB_FP_REGS
< for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) {
< gdbregs[i + KGDB_REG_F0] = context->readFloatRegBits(i);
< }
< #endif
< }
<
< ///////////////////////////////////////////////////////////
< // RemoteGDB::setregs
< //
< // Translate the GDB register format into the kernel
< // debugger register format.
< //
< void
< RemoteGDB::setregs()
< {
< // @todo: Currently this is very Alpha specific.
< if (AlphaISA::PcPAL(gdbregs[KGDB_REG_PC])) {
< for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
< context->setIntReg(AlphaISA::reg_redir[i], gdbregs[i]);
< }
< } else {
< for (int i = 0; i < TheISA::NumIntArchRegs; ++i) {
< context->setIntReg(i, gdbregs[i]);
< }
< }
<
< #ifdef KGDB_FP_REGS
< for (int i = 0; i < TheISA::NumFloatArchRegs; ++i) {
< context->setFloatRegBits(i, gdbregs[i + KGDB_REG_F0]);
< }
< #endif
< context->setPC(gdbregs[KGDB_REG_PC]);
< }
<
< void
< RemoteGDB::setTempBreakpoint(TempBreakpoint &bkpt, Addr addr)
< {
< DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n", addr);
<
< bkpt.address = addr;
< insertHardBreak(addr, 4);
< }
<
< void
< RemoteGDB::clearTempBreakpoint(TempBreakpoint &bkpt)
< {
< DPRINTF(GDBMisc, "setTempBreakpoint: addr=%#x\n",
< bkpt.address);
<
<
< removeHardBreak(bkpt.address, 4);
< bkpt.address = 0;
< }
<
< void
< RemoteGDB::clearSingleStep()
< {
< DPRINTF(GDBMisc, "clearSingleStep bt_addr=%#x nt_addr=%#x\n",
< takenBkpt.address, notTakenBkpt.address);
<
< if (takenBkpt.address != 0)
< clearTempBreakpoint(takenBkpt);
<
< if (notTakenBkpt.address != 0)
< clearTempBreakpoint(notTakenBkpt);
< }
<
< void
< RemoteGDB::setSingleStep()
< {
< Addr pc = context->readPC();
< Addr npc, bpc;
< bool set_bt = false;
<
< npc = pc + sizeof(MachInst);
<
< // User was stopped at pc, e.g. the instruction at pc was not
< // executed.
< MachInst inst = read<MachInst>(pc);
< StaticInstPtr si(inst);
< if (si->hasBranchTarget(pc, context, bpc)) {
< // Don't bother setting a breakpoint on the taken branch if it
< // is the same as the next pc
< if (bpc != npc)
< set_bt = true;
< }
<
< DPRINTF(GDBMisc, "setSingleStep bt_addr=%#x nt_addr=%#x\n",
< takenBkpt.address, notTakenBkpt.address);
<
< setTempBreakpoint(notTakenBkpt, npc);
<
< if (set_bt)
< setTempBreakpoint(takenBkpt, bpc);
< }
<
546c336
< RemoteGDB::getbyte()
---
> BaseRemoteGDB::getbyte()
554c344
< RemoteGDB::putbyte(uint8_t b)
---
> BaseRemoteGDB::putbyte(uint8_t b)
561c351
< RemoteGDB::send(const char *bp)
---
> BaseRemoteGDB::send(const char *bp)
570c360,362
< putbyte(KGDB_START);
---
> //Start sending a packet
> putbyte(GDBStart);
> //Send the contents, and also keep a check sum.
575c367,369
< putbyte(KGDB_END);
---
> //Send the ending character.
> putbyte(GDBEnd);
> //Sent the checksum.
578c372,374
< } while ((c = getbyte() & 0x7f) == KGDB_BADP);
---
> //Try transmitting over and over again until the other end doesn't send an
> //error back.
> } while ((c = getbyte() & 0x7f) == GDBBadP);
583c379
< RemoteGDB::recv(char *bp, int maxlen)
---
> BaseRemoteGDB::recv(char *bp, int maxlen)
592c388,389
< while ((c = getbyte()) != KGDB_START)
---
> //Find the beginning of a packet
> while ((c = getbyte()) != GDBStart)
595c392,394
< while ((c = getbyte()) != KGDB_END && len < maxlen) {
---
> //Read until you find the end of the data in the packet, and keep
> //track of the check sum.
> while ((c = getbyte()) != GDBEnd && len < maxlen) {
600a400,401
>
> //Mask the check sum, and terminate the command string.
603a405
> //If the command was too long, report an error.
605c407
< putbyte(KGDB_BADP);
---
> putbyte(GDBBadP);
608a411
> //Bring in the checksum. If the check sum matches, csum will be 0.
611a415
> //If the check sum was correct
613c417,418
< putbyte(KGDB_GOODP);
---
> //Report that the packet was received correctly
> putbyte(GDBGoodP);
623c428,429
< putbyte(KGDB_BADP);
---
> //Otherwise, report that there was a mistake.
> putbyte(GDBBadP);
633c439
< RemoteGDB::read(Addr vaddr, size_t size, char *data)
---
> BaseRemoteGDB::read(Addr vaddr, size_t size, char *data)
665c471
< RemoteGDB::write(Addr vaddr, size_t size, const char *data)
---
> BaseRemoteGDB::write(Addr vaddr, size_t size, const char *data)
688,691d493
< #ifdef IMB
< alpha_pal_imb();
< #endif
<
695,696c497
<
< PCEventQueue *RemoteGDB::getPcEventQueue()
---
> PCEventQueue *BaseRemoteGDB::getPcEventQueue()
701,702c502
<
< RemoteGDB::HardBreakpoint::HardBreakpoint(RemoteGDB *_gdb, Addr pc)
---
> BaseRemoteGDB::HardBreakpoint::HardBreakpoint(BaseRemoteGDB *_gdb, Addr pc)
710c510
< RemoteGDB::HardBreakpoint::process(ThreadContext *tc)
---
> BaseRemoteGDB::HardBreakpoint::process(ThreadContext *tc)
715c515
< gdb->trap(ALPHA_KENTRY_INT);
---
> gdb->trap(SIGTRAP);
719c519
< RemoteGDB::insertSoftBreak(Addr addr, size_t len)
---
> BaseRemoteGDB::insertSoftBreak(Addr addr, size_t len)
721c521
< if (len != sizeof(MachInst))
---
> if (len != sizeof(TheISA::MachInst))
728c528
< RemoteGDB::removeSoftBreak(Addr addr, size_t len)
---
> BaseRemoteGDB::removeSoftBreak(Addr addr, size_t len)
737c537
< RemoteGDB::insertHardBreak(Addr addr, size_t len)
---
> BaseRemoteGDB::insertHardBreak(Addr addr, size_t len)
754c554
< RemoteGDB::removeHardBreak(Addr addr, size_t len)
---
> BaseRemoteGDB::removeHardBreak(Addr addr, size_t len)
775c575
< break_type(char c)
---
> BaseRemoteGDB::break_type(char c)
793c593
< RemoteGDB::trap(int type)
---
> BaseRemoteGDB::trap(int type)
797,798c597,598
< char data[KGDB_BUFLEN + 1];
< char buffer[sizeof(gdbregs) * 2 + 256];
---
> char data[GDBPacketBufLen + 1];
> char buffer[gdbregs.size * 2 + 256];
826c626
< snprintf((char *)buffer, sizeof(buffer), "S%02x", signal(type));
---
> snprintf((char *)buffer, sizeof(buffer), "S%02x", type);
840c640
< case KGDB_SIGNAL:
---
> case GDBSignal:
844c644,645
< snprintf((char *)buffer, sizeof(buffer), "S%02x", signal(type));
---
> snprintf((char *)buffer, sizeof(buffer),
> "S%02x", type);
848,849c649,650
< case KGDB_REG_R:
< if (2 * sizeof(gdbregs) > sizeof(buffer))
---
> case GDBRegR:
> if (2 * gdbregs.size > sizeof(buffer))
852c653
< mem2hex(buffer, gdbregs, sizeof(gdbregs));
---
> mem2hex(buffer, gdbregs.regs, gdbregs.size);
856,857c657,658
< case KGDB_REG_W:
< p = hex2mem(gdbregs, p, sizeof(gdbregs));
---
> case GDBRegW:
> p = hex2mem(gdbregs.regs, p, gdbregs.size);
867c668
< case KGDB_SET_REG:
---
> case GDBSetReg:
878c679
< gdbregs[val] = hex2i(&p);
---
> gdbregs.regs[val] = hex2i(&p);
885c686
< case KGDB_MEM_R:
---
> case GDBMemR:
917c718
< case KGDB_MEM_W:
---
> case GDBMemW:
947c748
< case KGDB_SET_THREAD:
---
> case GDBSetThread:
956,957c757,758
< case KGDB_DETACH:
< case KGDB_KILL:
---
> case GDBDetach:
> case GDBKill:
963c764
< case KGDB_ASYNC_CONT:
---
> case GDBAsyncCont:
973c774
< case KGDB_CONT:
---
> case GDBCont:
982c783
< case KGDB_ASYNC_STEP:
---
> case GDBAsyncStep:
992c793
< case KGDB_STEP:
---
> case GDBStep:
1001c802
< case KGDB_CLR_HW_BKPT:
---
> case GDBClrHwBkpt:
1033c834
< case KGDB_SET_HW_BKPT:
---
> case GDBSetHwBkpt:
1065c866
< case KGDB_QUERY_VAR:
---
> case GDBQueryVar:
1073,1083c874,884
< case KGDB_SET_BAUD:
< case KGDB_SET_BREAK:
< case KGDB_DEBUG:
< case KGDB_CYCLE_STEP:
< case KGDB_SIG_CYCLE_STEP:
< case KGDB_READ_REG:
< case KGDB_SET_VAR:
< case KGDB_RESET:
< case KGDB_THREAD_ALIVE:
< case KGDB_TARGET_EXIT:
< case KGDB_BINARY_DLOAD:
---
> case GDBSetBaud:
> case GDBSetBreak:
> case GDBDebug:
> case GDBCycleStep:
> case GDBSigCycleStep:
> case GDBReadReg:
> case GDBSetVar:
> case GDBReset:
> case GDBThreadAlive:
> case GDBTargetExit:
> case GDBBinaryDload:
1109c910
< digit2i(char c)
---
> BaseRemoteGDB::digit2i(char c)
1124c925
< i2digit(int n)
---
> BaseRemoteGDB::i2digit(int n)
1131c932
< mem2hex(void *vdst, const void *vsrc, int len)
---
> BaseRemoteGDB::mem2hex(void *vdst, const void *vsrc, int len)
1148c949
< hex2mem(void *vdst, const char *src, int maxlen)
---
> BaseRemoteGDB::hex2mem(void *vdst, const char *src, int maxlen)
1169c970
< hex2i(const char **srcp)
---
> BaseRemoteGDB::hex2i(const char **srcp)