diff options
Diffstat (limited to 'src/arch/power')
-rw-r--r-- | src/arch/power/remote_gdb.cc | 72 | ||||
-rw-r--r-- | src/arch/power/remote_gdb.hh | 50 |
2 files changed, 57 insertions, 65 deletions
diff --git a/src/arch/power/remote_gdb.cc b/src/arch/power/remote_gdb.cc index b8a1592b6..ef10efc18 100644 --- a/src/arch/power/remote_gdb.cc +++ b/src/arch/power/remote_gdb.cc @@ -1,4 +1,5 @@ /* + * Copyright 2015 LabWare * Copyright 2014 Google, Inc. * Copyright (c) 2010 ARM Limited * All rights reserved @@ -149,7 +150,7 @@ using namespace std; using namespace PowerISA; RemoteGDB::RemoteGDB(System *_system, ThreadContext *tc) - : BaseRemoteGDB(_system, tc, GDB_REG_BYTES) + : BaseRemoteGDB(_system, tc) { } @@ -171,67 +172,50 @@ RemoteGDB::acc(Addr va, size_t len) return context->getProcessPtr()->pTable->lookup(va, entry); } -/* - * Translate the kernel debugger register format into the GDB register - * format. - * - * The PowerPC ISA is quite flexible in what register sets may be present - * depending on the features implemented by the particular CPU; - * GDB addresses this by describing the format of how register contents - * are transferred on the wire, in XML files such as 'power-core.xml'. - * Ideally, we should be reading these files instead of hardcoding this - * information, but for now the following implementation is enough to - * serve as the RSP backend for the out-of-the-box, default GDB. - */ void -RemoteGDB::getregs() +RemoteGDB::PowerGdbRegCache::getRegs(ThreadContext *context) { - DPRINTF(GDBAcc, "getregs in remotegdb \n"); - memset(gdbregs.regs, 0, gdbregs.bytes()); + DPRINTF(GDBAcc, "getRegs in remotegdb \n"); // Default order on 32-bit PowerPC: // R0-R31 (32-bit each), F0-F31 (64-bit IEEE754 double), // PC, MSR, CR, LR, CTR, XER (32-bit each) - // INTREG: R0~R31 for (int i = 0; i < NumIntArchRegs; i++) - gdbregs.regs32[GdbFirstGPRIndex + i] = htobe((uint32_t)context->readIntReg(i)); + r.gpr[i] = htobe((uint32_t)context->readIntReg(i)); - // FLOATREG: F0~F31 for (int i = 0; i < NumFloatArchRegs; i++) - gdbregs.regs32[GdbFirstFPRIndex + i] = context->readFloatRegBits(i); - - // PC, MSR, CR, LR, CTR, XER - gdbregs.regs32[GdbPCIndex] = htobe((uint32_t)context->pcState().pc()); - gdbregs.regs32[GdbMSRIndex] = 0; // Is MSR modeled? - gdbregs.regs32[GdbCRIndex] = htobe((uint32_t)context->readIntReg(INTREG_CR)); - gdbregs.regs32[GdbLRIndex] = htobe((uint32_t)context->readIntReg(INTREG_LR)); - gdbregs.regs32[GdbCTRIndex] = htobe((uint32_t)context->readIntReg(INTREG_CTR)); - gdbregs.regs32[GdbXERIndex] = htobe((uint32_t)context->readIntReg(INTREG_XER)); + r.fpr[i] = context->readFloatRegBits(i); + + r.pc = htobe((uint32_t)context->pcState().pc()); + r.msr = 0; // Is MSR modeled? + r.cr = htobe((uint32_t)context->readIntReg(INTREG_CR)); + r.lr = htobe((uint32_t)context->readIntReg(INTREG_LR)); + r.ctr = htobe((uint32_t)context->readIntReg(INTREG_CTR)); + r.xer = htobe((uint32_t)context->readIntReg(INTREG_XER)); } -/* - * Translate the GDB register format into the kernel debugger register - * format. - */ void -RemoteGDB::setregs() +RemoteGDB::PowerGdbRegCache::setRegs(ThreadContext *context) const { - DPRINTF(GDBAcc, "setregs in remotegdb \n"); + DPRINTF(GDBAcc, "setRegs in remotegdb \n"); - // INTREG: R0~R31 for (int i = 0; i < NumIntArchRegs; i++) - context->setIntReg(i, betoh(gdbregs.regs32[GdbFirstGPRIndex + i])); + context->setIntReg(i, betoh(r.gpr[i])); - // FLOATREG: F0~F31 for (int i = 0; i < NumFloatArchRegs; i++) - context->setFloatRegBits(i, gdbregs.regs64[GdbFirstFPRIndex + i]); + context->setFloatRegBits(i, r.fpr[i]); - // PC, MSR, CR, LR, CTR, XER - context->pcState(betoh(gdbregs.regs32[GdbPCIndex])); + context->pcState(betoh(r.pc)); // Is MSR modeled? - context->setIntReg(INTREG_CR, betoh(gdbregs.regs32[GdbCRIndex])); - context->setIntReg(INTREG_LR, betoh(gdbregs.regs32[GdbLRIndex])); - context->setIntReg(INTREG_CTR, betoh(gdbregs.regs32[GdbCTRIndex])); - context->setIntReg(INTREG_XER, betoh(gdbregs.regs32[GdbXERIndex])); + context->setIntReg(INTREG_CR, betoh(r.cr)); + context->setIntReg(INTREG_LR, betoh(r.lr)); + context->setIntReg(INTREG_CTR, betoh(r.ctr)); + context->setIntReg(INTREG_XER, betoh(r.xer)); +} + +RemoteGDB::BaseGdbRegCache* +RemoteGDB::gdbRegs() { + return new PowerGdbRegCache(this); } + diff --git a/src/arch/power/remote_gdb.hh b/src/arch/power/remote_gdb.hh index aea75528e..e1c396266 100644 --- a/src/arch/power/remote_gdb.hh +++ b/src/arch/power/remote_gdb.hh @@ -1,4 +1,5 @@ /* + * Copyright (c) 2015 LabWare * Copyright (c) 2002-2005 The Regents of The University of Michigan * Copyright (c) 2007-2008 The Florida State University * Copyright (c) 2009 The University of Edinburgh @@ -30,6 +31,7 @@ * Authors: Nathan Binkert * Stephen Hines * Timothy M. Jones + * Boris Shingarov */ #ifndef __ARCH_POWER_REMOTE_GDB_HH__ @@ -42,32 +44,38 @@ namespace PowerISA { -const int GDB_REG_BYTES = - NumIntArchRegs * 4 + - NumFloatArchRegs * 8 + - 4 + /* PC */ - 4 + /* MSR */ - 4 + /* CR */ - 4 + /* LR */ - 4 + /* CTR */ - 4; /* XER */ -const int GdbFirstGPRIndex = 0; -const int GdbFirstFPRIndex = 16; -const int GdbPCIndex = 96; -const int GdbMSRIndex = 97; -const int GdbCRIndex = 98; -const int GdbLRIndex = 99; -const int GdbCTRIndex = 100; -const int GdbXERIndex = 101; class RemoteGDB : public BaseRemoteGDB { - public: - RemoteGDB(System *_system, ThreadContext *tc); protected: bool acc(Addr addr, size_t len); - void getregs(); - void setregs(); + + class PowerGdbRegCache : public BaseGdbRegCache + { + using BaseGdbRegCache::BaseGdbRegCache; + private: + struct { + uint32_t gpr[NumIntArchRegs]; + uint64_t fpr[NumFloatArchRegs]; + uint32_t pc; + uint32_t msr; + uint32_t cr; + uint32_t lr; + uint32_t ctr; + uint32_t xer; + } r; + public: + char *data() const { return (char *)&r; } + size_t size() const { return sizeof(r); } + void getRegs(ThreadContext*); + void setRegs(ThreadContext*) const; + const std::string name() const { return gdb->name() + ".PowerGdbRegCache"; } + }; + + + public: + RemoteGDB(System *_system, ThreadContext *tc); + BaseGdbRegCache *gdbRegs(); }; } // namespace PowerISA |