misc: Make the GDB register cache accessible in various sized chunks.
Not all ISAs have 64 bit sized registers, so it's not always very convenient to access the GDB register cache in 64 bit sized chunks. This change makes it accessible in 8, 16, 32, or 64 bit chunks. The MIPS and ARM implementations were working around that limitation by bundling and unbundling 32 bit values into 64 bit values. That code has been removed.
This commit is contained in:
parent
7540656fc5
commit
fe48c0a32b
7 changed files with 174 additions and 213 deletions
|
@ -1,4 +1,5 @@
|
||||||
/*
|
/*
|
||||||
|
* Copyright 2014 Google, Inc.
|
||||||
* Copyright (c) 2002-2005 The Regents of The University of Michigan
|
* Copyright (c) 2002-2005 The Regents of The University of Michigan
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
|
@ -145,7 +146,7 @@ using namespace std;
|
||||||
using namespace AlphaISA;
|
using namespace AlphaISA;
|
||||||
|
|
||||||
RemoteGDB::RemoteGDB(System *_system, ThreadContext *tc)
|
RemoteGDB::RemoteGDB(System *_system, ThreadContext *tc)
|
||||||
: BaseRemoteGDB(_system, tc, KGDB_NUMREGS)
|
: BaseRemoteGDB(_system, tc, KGDB_NUMREGS * sizeof(uint64_t))
|
||||||
{
|
{
|
||||||
memset(gdbregs.regs, 0, gdbregs.bytes());
|
memset(gdbregs.regs, 0, gdbregs.bytes());
|
||||||
}
|
}
|
||||||
|
@ -211,23 +212,20 @@ RemoteGDB::getregs()
|
||||||
{
|
{
|
||||||
memset(gdbregs.regs, 0, gdbregs.bytes());
|
memset(gdbregs.regs, 0, gdbregs.bytes());
|
||||||
|
|
||||||
gdbregs.regs[KGDB_REG_PC] = context->pcState().pc();
|
gdbregs.regs64[KGDB_REG_PC] = context->pcState().pc();
|
||||||
|
|
||||||
// @todo: Currently this is very Alpha specific.
|
// @todo: Currently this is very Alpha specific.
|
||||||
if (PcPAL(gdbregs.regs[KGDB_REG_PC])) {
|
if (PcPAL(gdbregs.regs64[KGDB_REG_PC])) {
|
||||||
for (int i = 0; i < NumIntArchRegs; ++i) {
|
for (int i = 0; i < NumIntArchRegs; ++i)
|
||||||
gdbregs.regs[i] = context->readIntReg(reg_redir[i]);
|
gdbregs.regs64[i] = context->readIntReg(reg_redir[i]);
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < NumIntArchRegs; ++i) {
|
for (int i = 0; i < NumIntArchRegs; ++i)
|
||||||
gdbregs.regs[i] = context->readIntReg(i);
|
gdbregs.regs64[i] = context->readIntReg(i);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef KGDB_FP_REGS
|
#ifdef KGDB_FP_REGS
|
||||||
for (int i = 0; i < NumFloatArchRegs; ++i) {
|
for (int i = 0; i < NumFloatArchRegs; ++i)
|
||||||
gdbregs.regs[i + KGDB_REG_F0] = context->readFloatRegBits(i);
|
gdbregs.regs64[i + KGDB_REG_F0] = context->readFloatRegBits(i);
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -239,22 +237,22 @@ void
|
||||||
RemoteGDB::setregs()
|
RemoteGDB::setregs()
|
||||||
{
|
{
|
||||||
// @todo: Currently this is very Alpha specific.
|
// @todo: Currently this is very Alpha specific.
|
||||||
if (PcPAL(gdbregs.regs[KGDB_REG_PC])) {
|
if (PcPAL(gdbregs.regs64[KGDB_REG_PC])) {
|
||||||
for (int i = 0; i < NumIntArchRegs; ++i) {
|
for (int i = 0; i < NumIntArchRegs; ++i) {
|
||||||
context->setIntReg(reg_redir[i], gdbregs.regs[i]);
|
context->setIntReg(reg_redir[i], gdbregs.regs64[i]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < NumIntArchRegs; ++i) {
|
for (int i = 0; i < NumIntArchRegs; ++i) {
|
||||||
context->setIntReg(i, gdbregs.regs[i]);
|
context->setIntReg(i, gdbregs.regs64[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef KGDB_FP_REGS
|
#ifdef KGDB_FP_REGS
|
||||||
for (int i = 0; i < NumFloatArchRegs; ++i) {
|
for (int i = 0; i < NumFloatArchRegs; ++i) {
|
||||||
context->setFloatRegBits(i, gdbregs.regs[i + KGDB_REG_F0]);
|
context->setFloatRegBits(i, gdbregs.regs64[i + KGDB_REG_F0]);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
context->pcState(gdbregs.regs[KGDB_REG_PC]);
|
context->pcState(gdbregs.regs64[KGDB_REG_PC]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/*
|
/*
|
||||||
|
* Copyright 2014 Google Inc.
|
||||||
* Copyright (c) 2010, 2013 ARM Limited
|
* Copyright (c) 2010, 2013 ARM Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
*
|
*
|
||||||
|
@ -160,7 +161,8 @@ using namespace std;
|
||||||
using namespace ArmISA;
|
using namespace ArmISA;
|
||||||
|
|
||||||
RemoteGDB::RemoteGDB(System *_system, ThreadContext *tc)
|
RemoteGDB::RemoteGDB(System *_system, ThreadContext *tc)
|
||||||
: BaseRemoteGDB(_system, tc, MAX_NUMREGS), notTakenBkpt(0), takenBkpt(0)
|
: BaseRemoteGDB(_system, tc, GDB_REG_BYTES),
|
||||||
|
notTakenBkpt(0), takenBkpt(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,62 +209,50 @@ RemoteGDB::getregs()
|
||||||
|
|
||||||
if (inAArch64(context)) { // AArch64
|
if (inAArch64(context)) { // AArch64
|
||||||
// x0-x31
|
// x0-x31
|
||||||
for (int i = 0; i < 32; ++i) {
|
for (int i = 0; i < 32; ++i)
|
||||||
gdbregs.regs[REG_X0 + i] = context->readIntReg(INTREG_X0 + i);
|
gdbregs.regs64[GDB64_X0 + i] = context->readIntReg(INTREG_X0 + i);
|
||||||
}
|
|
||||||
// pc
|
// pc
|
||||||
gdbregs.regs[REG_PC_64] = context->pcState().pc();
|
gdbregs.regs64[GDB64_PC] = context->pcState().pc();
|
||||||
// cpsr
|
// cpsr
|
||||||
gdbregs.regs[REG_CPSR_64] = context->readMiscRegNoEffect(MISCREG_CPSR);
|
gdbregs.regs64[GDB64_CPSR] =
|
||||||
|
context->readMiscRegNoEffect(MISCREG_CPSR);
|
||||||
// v0-v31
|
// v0-v31
|
||||||
for (int i = 0; i < 32; ++i) {
|
for (int i = 0; i < 128; i += 4) {
|
||||||
gdbregs.regs[REG_V0 + 2 * i] = static_cast<uint64_t>(
|
int gdboff = GDB64_V0_32 + i;
|
||||||
context->readFloatRegBits(i * 4 + 3)) << 32 |
|
gdbregs.regs32[gdboff + 0] = context->readFloatRegBits(i + 2);
|
||||||
context->readFloatRegBits(i * 4 + 2);
|
gdbregs.regs32[gdboff + 1] = context->readFloatRegBits(i + 3);
|
||||||
gdbregs.regs[REG_V0 + 2 * i + 1] = static_cast<uint64_t>(
|
gdbregs.regs32[gdboff + 2] = context->readFloatRegBits(i + 0);
|
||||||
context->readFloatRegBits(i * 4 + 1)) << 32 |
|
gdbregs.regs32[gdboff + 3] = context->readFloatRegBits(i + 1);
|
||||||
context->readFloatRegBits(i * 4 + 0);
|
|
||||||
}
|
}
|
||||||
} else { // AArch32
|
} else { // AArch32
|
||||||
// R0-R15 supervisor mode
|
// R0-R15 supervisor mode
|
||||||
// arm registers are 32 bits wide, gdb registers are 64 bits wide two
|
gdbregs.regs32[GDB32_R0 + 0] = context->readIntReg(INTREG_R0);
|
||||||
// arm registers are packed into one gdb register (little endian)
|
gdbregs.regs32[GDB32_R0 + 1] = context->readIntReg(INTREG_R1);
|
||||||
gdbregs.regs[REG_R0 + 0] = context->readIntReg(INTREG_R1) << 32 |
|
gdbregs.regs32[GDB32_R0 + 2] = context->readIntReg(INTREG_R2);
|
||||||
context->readIntReg(INTREG_R0);
|
gdbregs.regs32[GDB32_R0 + 3] = context->readIntReg(INTREG_R3);
|
||||||
gdbregs.regs[REG_R0 + 1] = context->readIntReg(INTREG_R3) << 32 |
|
gdbregs.regs32[GDB32_R0 + 4] = context->readIntReg(INTREG_R4);
|
||||||
context->readIntReg(INTREG_R2);
|
gdbregs.regs32[GDB32_R0 + 5] = context->readIntReg(INTREG_R5);
|
||||||
gdbregs.regs[REG_R0 + 2] = context->readIntReg(INTREG_R5) << 32 |
|
gdbregs.regs32[GDB32_R0 + 6] = context->readIntReg(INTREG_R6);
|
||||||
context->readIntReg(INTREG_R4);
|
gdbregs.regs32[GDB32_R0 + 7] = context->readIntReg(INTREG_R7);
|
||||||
gdbregs.regs[REG_R0 + 3] = context->readIntReg(INTREG_R7) << 32 |
|
gdbregs.regs32[GDB32_R0 + 8] = context->readIntReg(INTREG_R8);
|
||||||
context->readIntReg(INTREG_R6);
|
gdbregs.regs32[GDB32_R0 + 9] = context->readIntReg(INTREG_R9);
|
||||||
gdbregs.regs[REG_R0 + 4] = context->readIntReg(INTREG_R9) << 32 |
|
gdbregs.regs32[GDB32_R0 + 10] = context->readIntReg(INTREG_R10);
|
||||||
context->readIntReg(INTREG_R8);
|
gdbregs.regs32[GDB32_R0 + 11] = context->readIntReg(INTREG_R11);
|
||||||
gdbregs.regs[REG_R0 + 5] = context->readIntReg(INTREG_R11) << 32|
|
gdbregs.regs32[GDB32_R0 + 12] = context->readIntReg(INTREG_R12);
|
||||||
context->readIntReg(INTREG_R10);
|
gdbregs.regs32[GDB32_R0 + 13] = context->readIntReg(INTREG_SP);
|
||||||
gdbregs.regs[REG_R0 + 6] = context->readIntReg(INTREG_SP) << 32 |
|
gdbregs.regs32[GDB32_R0 + 14] = context->readIntReg(INTREG_LR);
|
||||||
context->readIntReg(INTREG_R12);
|
gdbregs.regs32[GDB32_R0 + 15] = context->pcState().pc();
|
||||||
gdbregs.regs[REG_R0 + 7] = context->pcState().pc() << 32 |
|
|
||||||
context->readIntReg(INTREG_LR);
|
|
||||||
|
|
||||||
// CPSR
|
// CPSR
|
||||||
gdbregs.regs[REG_CPSR] = context->readMiscRegNoEffect(MISCREG_CPSR);
|
gdbregs.regs32[GDB32_CPSR] = context->readMiscRegNoEffect(MISCREG_CPSR);
|
||||||
|
|
||||||
// vfpv3/neon floating point registers (32 double or 64 float)
|
// vfpv3/neon floating point registers (32 double or 64 float)
|
||||||
|
for (int i = 0; i < NumFloatV7ArchRegs; ++i)
|
||||||
gdbregs.regs[REG_F0] =
|
gdbregs.regs32[GDB32_F0 + i] = context->readFloatRegBits(i);
|
||||||
static_cast<uint64_t>(context->readFloatRegBits(0)) << 32 |
|
|
||||||
gdbregs.regs[REG_CPSR];
|
|
||||||
|
|
||||||
for (int i = 1; i < (NumFloatV7ArchRegs>>1); ++i) {
|
|
||||||
gdbregs.regs[i + REG_F0] =
|
|
||||||
static_cast<uint64_t>(context->readFloatRegBits(2*i)) << 32 |
|
|
||||||
context->readFloatRegBits(2*i-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// FPSCR
|
// FPSCR
|
||||||
gdbregs.regs[REG_FPSCR] = static_cast<uint64_t>(
|
gdbregs.regs32[GDB32_FPSCR] =
|
||||||
context->readMiscRegNoEffect(MISCREG_FPSCR)) << 32 |
|
context->readMiscRegNoEffect(MISCREG_FPSCR);
|
||||||
context->readFloatRegBits(NumFloatV7ArchRegs - 1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,63 +267,50 @@ RemoteGDB::setregs()
|
||||||
DPRINTF(GDBAcc, "setregs in remotegdb \n");
|
DPRINTF(GDBAcc, "setregs in remotegdb \n");
|
||||||
if (inAArch64(context)) { // AArch64
|
if (inAArch64(context)) { // AArch64
|
||||||
// x0-x31
|
// x0-x31
|
||||||
for (int i = 0; i < 32; ++i) {
|
for (int i = 0; i < 32; ++i)
|
||||||
context->setIntReg(INTREG_X0 + i, gdbregs.regs[REG_X0 + i]);
|
context->setIntReg(INTREG_X0 + i, gdbregs.regs64[GDB64_X0 + i]);
|
||||||
}
|
|
||||||
// pc
|
// pc
|
||||||
context->pcState(gdbregs.regs[REG_PC_64]);
|
context->pcState(gdbregs.regs64[GDB64_PC]);
|
||||||
// cpsr
|
// cpsr
|
||||||
context->setMiscRegNoEffect(MISCREG_CPSR, gdbregs.regs[REG_CPSR_64]);
|
context->setMiscRegNoEffect(MISCREG_CPSR, gdbregs.regs64[GDB64_CPSR]);
|
||||||
// v0-v31
|
// v0-v31
|
||||||
for (int i = 0; i < 32; ++i) {
|
for (int i = 0; i < 128; i += 4) {
|
||||||
context->setFloatRegBits(i * 4 + 3,
|
int gdboff = GDB64_V0_32 + i;
|
||||||
gdbregs.regs[REG_V0 + 2 * i] >> 32);
|
context->setFloatRegBits(i + 2, gdbregs.regs32[gdboff + 0]);
|
||||||
context->setFloatRegBits(i * 4 + 2,
|
context->setFloatRegBits(i + 3, gdbregs.regs32[gdboff + 1]);
|
||||||
gdbregs.regs[REG_V0 + 2 * i]);
|
context->setFloatRegBits(i + 0, gdbregs.regs32[gdboff + 2]);
|
||||||
context->setFloatRegBits(i * 4 + 1,
|
context->setFloatRegBits(i + 1, gdbregs.regs32[gdboff + 3]);
|
||||||
gdbregs.regs[REG_V0 + 2 * i + 1] >> 32);
|
|
||||||
context->setFloatRegBits(i * 4 + 0,
|
|
||||||
gdbregs.regs[REG_V0 + 2 * i + 1]);
|
|
||||||
}
|
}
|
||||||
} else { // AArch32
|
} else { // AArch32
|
||||||
// R0-R15 supervisor mode
|
// R0-R15 supervisor mode
|
||||||
// arm registers are 32 bits wide, gdb registers are 64 bits wide
|
// arm registers are 32 bits wide, gdb registers are 64 bits wide
|
||||||
// two arm registers are packed into one gdb register (little endian)
|
// two arm registers are packed into one gdb register (little endian)
|
||||||
context->setIntReg(INTREG_R0 , bits(gdbregs.regs[REG_R0 + 0], 31, 0));
|
context->setIntReg(INTREG_R0, gdbregs.regs32[GDB32_R0 + 0]);
|
||||||
context->setIntReg(INTREG_R1 , bits(gdbregs.regs[REG_R0 + 0], 63, 32));
|
context->setIntReg(INTREG_R1, gdbregs.regs32[GDB32_R0 + 1]);
|
||||||
context->setIntReg(INTREG_R2 , bits(gdbregs.regs[REG_R0 + 1], 31, 0));
|
context->setIntReg(INTREG_R2, gdbregs.regs32[GDB32_R0 + 2]);
|
||||||
context->setIntReg(INTREG_R3 , bits(gdbregs.regs[REG_R0 + 1], 63, 32));
|
context->setIntReg(INTREG_R3, gdbregs.regs32[GDB32_R0 + 3]);
|
||||||
context->setIntReg(INTREG_R4 , bits(gdbregs.regs[REG_R0 + 2], 31, 0));
|
context->setIntReg(INTREG_R4, gdbregs.regs32[GDB32_R0 + 4]);
|
||||||
context->setIntReg(INTREG_R5 , bits(gdbregs.regs[REG_R0 + 2], 63, 32));
|
context->setIntReg(INTREG_R5, gdbregs.regs32[GDB32_R0 + 5]);
|
||||||
context->setIntReg(INTREG_R6 , bits(gdbregs.regs[REG_R0 + 3], 31, 0));
|
context->setIntReg(INTREG_R6, gdbregs.regs32[GDB32_R0 + 6]);
|
||||||
context->setIntReg(INTREG_R7 , bits(gdbregs.regs[REG_R0 + 3], 63, 32));
|
context->setIntReg(INTREG_R7, gdbregs.regs32[GDB32_R0 + 7]);
|
||||||
context->setIntReg(INTREG_R8 , bits(gdbregs.regs[REG_R0 + 4], 31, 0));
|
context->setIntReg(INTREG_R8, gdbregs.regs32[GDB32_R0 + 8]);
|
||||||
context->setIntReg(INTREG_R9 , bits(gdbregs.regs[REG_R0 + 4], 63, 32));
|
context->setIntReg(INTREG_R9, gdbregs.regs32[GDB32_R0 + 9]);
|
||||||
context->setIntReg(INTREG_R10, bits(gdbregs.regs[REG_R0 + 5], 31, 0));
|
context->setIntReg(INTREG_R10, gdbregs.regs32[GDB32_R0 + 10]);
|
||||||
context->setIntReg(INTREG_R11, bits(gdbregs.regs[REG_R0 + 5], 63, 32));
|
context->setIntReg(INTREG_R11, gdbregs.regs32[GDB32_R0 + 11]);
|
||||||
context->setIntReg(INTREG_R12, bits(gdbregs.regs[REG_R0 + 6], 31, 0));
|
context->setIntReg(INTREG_R12, gdbregs.regs32[GDB32_R0 + 12]);
|
||||||
context->setIntReg(INTREG_SP , bits(gdbregs.regs[REG_R0 + 6], 63, 32));
|
context->setIntReg(INTREG_SP, gdbregs.regs32[GDB32_R0 + 13]);
|
||||||
context->setIntReg(INTREG_LR , bits(gdbregs.regs[REG_R0 + 7], 31, 0));
|
context->setIntReg(INTREG_LR, gdbregs.regs32[GDB32_R0 + 14]);
|
||||||
context->pcState(bits(gdbregs.regs[REG_R0 + 7], 63, 32));
|
context->pcState(gdbregs.regs32[GDB32_R0 + 7]);
|
||||||
|
|
||||||
//CPSR
|
//CPSR
|
||||||
context->setMiscRegNoEffect(MISCREG_CPSR, gdbregs.regs[REG_CPSR]);
|
context->setMiscRegNoEffect(MISCREG_CPSR, gdbregs.regs32[GDB32_CPSR]);
|
||||||
|
|
||||||
//vfpv3/neon floating point registers (32 double or 64 float)
|
//vfpv3/neon floating point registers (32 double or 64 float)
|
||||||
context->setFloatRegBits(0, gdbregs.regs[REG_F0]>>32);
|
for (int i = 0; i < NumFloatV7ArchRegs; ++i)
|
||||||
|
context->setFloatRegBits(i, gdbregs.regs32[GDB32_F0 + i]);
|
||||||
for (int i = 1; i < NumFloatV7ArchRegs; ++i) {
|
|
||||||
if (i%2) {
|
|
||||||
int j = (i+1)/2;
|
|
||||||
context->setFloatRegBits(i, bits(gdbregs.regs[j + REG_F0], 31, 0));
|
|
||||||
} else {
|
|
||||||
int j = i/2;
|
|
||||||
context->setFloatRegBits(i, gdbregs.regs[j + REG_F0]>>32);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//FPSCR
|
//FPSCR
|
||||||
context->setMiscReg(MISCREG_FPSCR, gdbregs.regs[REG_FPSCR]>>32);
|
context->setMiscReg(MISCREG_FPSCR, gdbregs.regs32[GDB32_FPSCR]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/*
|
/*
|
||||||
|
* Copyright 2014 Google, Inc.
|
||||||
* Copyright (c) 2013 ARM Limited
|
* Copyright (c) 2013 ARM Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
*
|
*
|
||||||
|
@ -45,6 +46,8 @@
|
||||||
#ifndef __ARCH_ARM_REMOTE_GDB_HH__
|
#ifndef __ARCH_ARM_REMOTE_GDB_HH__
|
||||||
#define __ARCH_ARM_REMOTE_GDB_HH__
|
#define __ARCH_ARM_REMOTE_GDB_HH__
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "base/remote_gdb.hh"
|
#include "base/remote_gdb.hh"
|
||||||
|
|
||||||
class System;
|
class System;
|
||||||
|
@ -54,21 +57,26 @@ namespace ArmISA
|
||||||
{
|
{
|
||||||
|
|
||||||
// AArch32 registers with vfpv3/neon
|
// AArch32 registers with vfpv3/neon
|
||||||
const int NUMREGS = 41; /* r0-r15, cpsr, d0-d31, fpscr */
|
enum {
|
||||||
const int REG_R0 = 0;
|
GDB32_R0 = 0,
|
||||||
const int REG_F0 = 8;
|
GDB32_CPSR = 16,
|
||||||
const int REG_CPSR = 8; /* bit 512 to bit 543 */
|
GDB32_F0 = 17,
|
||||||
const int REG_FPSCR = 40; /* bit 2592 to bit 2623 */
|
GDB32_FPSCR = 81,
|
||||||
|
GDB32_NUMREGS = 82
|
||||||
|
};
|
||||||
|
|
||||||
// AArch64 registers
|
// AArch64 registers
|
||||||
const int NUMREGS_64 = 98; // x0-x31, pc, cpsr (64-bit GPRs)
|
enum {
|
||||||
// v0-v31 (128-bit FPRs)
|
GDB64_X0 = 0,
|
||||||
const int REG_X0 = 0;
|
GDB64_PC = 32,
|
||||||
const int REG_PC_64 = 32;
|
GDB64_CPSR = 33,
|
||||||
const int REG_CPSR_64 = 33;
|
GDB64_V0 = 34,
|
||||||
const int REG_V0 = 34;
|
GDB64_V0_32 = 2 * GDB64_V0,
|
||||||
|
GDB64_NUMREGS = 98
|
||||||
|
};
|
||||||
|
|
||||||
const int MAX_NUMREGS = NUMREGS_64;
|
const int GDB_REG_BYTES = std::max(GDB64_NUMREGS * sizeof(uint64_t),
|
||||||
|
GDB32_NUMREGS * sizeof(uint32_t));
|
||||||
|
|
||||||
class RemoteGDB : public BaseRemoteGDB
|
class RemoteGDB : public BaseRemoteGDB
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/*
|
/*
|
||||||
|
* Copyright 2014 Google, Inc.
|
||||||
* Copyright (c) 2010 ARM Limited
|
* Copyright (c) 2010 ARM Limited
|
||||||
* All rights reserved
|
* All rights reserved
|
||||||
*
|
*
|
||||||
|
@ -148,7 +149,7 @@ using namespace std;
|
||||||
using namespace MipsISA;
|
using namespace MipsISA;
|
||||||
|
|
||||||
RemoteGDB::RemoteGDB(System *_system, ThreadContext *tc)
|
RemoteGDB::RemoteGDB(System *_system, ThreadContext *tc)
|
||||||
: BaseRemoteGDB(_system, tc, GdbNumRegs)
|
: BaseRemoteGDB(_system, tc, GdbNumRegs * sizeof(uint32_t))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,31 +182,26 @@ RemoteGDB::getregs()
|
||||||
// two MIPS registers are packed into one gdb register (little endian)
|
// two MIPS registers are packed into one gdb register (little endian)
|
||||||
|
|
||||||
// INTREG: R0~R31
|
// INTREG: R0~R31
|
||||||
for (int i = 0; i < GdbIntArchRegs; i++) {
|
for (int i = 0; i < GdbIntArchRegs; i++)
|
||||||
gdbregs.regs[i] = pack(
|
gdbregs.regs32[i] = context->readIntReg(i);
|
||||||
context->readIntReg(i * 2),
|
|
||||||
context->readIntReg(i * 2 + 1));
|
|
||||||
}
|
|
||||||
// SR, LO, HI, BADVADDR, CAUSE, PC
|
// SR, LO, HI, BADVADDR, CAUSE, PC
|
||||||
gdbregs.regs[GdbIntArchRegs + 0] = pack(
|
gdbregs.regs32[GdbIntArchRegs + 0] =
|
||||||
context->readMiscRegNoEffect(MISCREG_STATUS),
|
context->readMiscRegNoEffect(MISCREG_STATUS);
|
||||||
context->readIntReg(INTREG_LO));
|
gdbregs.regs32[GdbIntArchRegs + 1] = context->readIntReg(INTREG_LO);
|
||||||
gdbregs.regs[GdbIntArchRegs + 1] = pack(
|
gdbregs.regs32[GdbIntArchRegs + 2] = context->readIntReg(INTREG_HI);
|
||||||
context->readIntReg(INTREG_HI),
|
gdbregs.regs32[GdbIntArchRegs + 3] =
|
||||||
context->readMiscRegNoEffect(MISCREG_BADVADDR));
|
context->readMiscRegNoEffect(MISCREG_BADVADDR);
|
||||||
gdbregs.regs[GdbIntArchRegs + 2] = pack(
|
gdbregs.regs32[GdbIntArchRegs + 4] =
|
||||||
context->readMiscRegNoEffect(MISCREG_CAUSE),
|
context->readMiscRegNoEffect(MISCREG_CAUSE);
|
||||||
context->pcState().pc());
|
gdbregs.regs32[GdbIntArchRegs + 5] = context->pcState().pc();
|
||||||
// FLOATREG: F0~F31
|
// FLOATREG: F0~F31
|
||||||
for (int i = 0; i < GdbFloatArchRegs; i++) {
|
for (int i = 0; i < GdbFloatArchRegs; i++)
|
||||||
gdbregs.regs[GdbIntRegs + i] = pack(
|
gdbregs.regs32[GdbIntRegs + i] = context->readFloatRegBits(i);
|
||||||
context->readFloatRegBits(i * 2),
|
|
||||||
context->readFloatRegBits(i * 2 + 1));
|
|
||||||
}
|
|
||||||
// FCR, FIR
|
// FCR, FIR
|
||||||
gdbregs.regs[GdbIntRegs + GdbFloatArchRegs + 0] = pack(
|
gdbregs.regs32[GdbIntRegs + GdbFloatArchRegs + 0] =
|
||||||
context->readFloatRegBits(FLOATREG_FCCR),
|
context->readFloatRegBits(FLOATREG_FCCR);
|
||||||
context->readFloatRegBits(FLOATREG_FIR));
|
gdbregs.regs32[GdbIntRegs + GdbFloatArchRegs + 1] =
|
||||||
|
context->readFloatRegBits(FLOATREG_FIR);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -217,41 +213,27 @@ RemoteGDB::setregs()
|
||||||
{
|
{
|
||||||
DPRINTF(GDBAcc, "setregs in remotegdb \n");
|
DPRINTF(GDBAcc, "setregs in remotegdb \n");
|
||||||
|
|
||||||
// MIPS registers are 32 bits wide, gdb registers are 64 bits wide
|
|
||||||
// two MIPS registers are packed into one gdb register (little endian)
|
|
||||||
|
|
||||||
// INTREG: R0~R31
|
// INTREG: R0~R31
|
||||||
for (int i = 0; i < GdbIntArchRegs; i++) {
|
for (int i = 1; i < GdbIntArchRegs; i++)
|
||||||
if (i) context->setIntReg(i * 2,
|
context->setIntReg(i, gdbregs.regs32[i]);
|
||||||
unpackLo(gdbregs.regs[i]));
|
|
||||||
context->setIntReg(i * 2 + 1,
|
|
||||||
unpackHi(gdbregs.regs[i]));
|
|
||||||
}
|
|
||||||
// SR, LO, HI, BADVADDR, CAUSE, PC
|
// SR, LO, HI, BADVADDR, CAUSE, PC
|
||||||
context->setMiscRegNoEffect(MISCREG_STATUS,
|
context->setMiscRegNoEffect(MISCREG_STATUS,
|
||||||
unpackLo(gdbregs.regs[GdbIntArchRegs + 0]));
|
gdbregs.regs32[GdbIntArchRegs + 0]);
|
||||||
context->setIntReg(INTREG_LO,
|
context->setIntReg(INTREG_LO, gdbregs.regs32[GdbIntArchRegs + 1]);
|
||||||
unpackHi(gdbregs.regs[GdbIntArchRegs + 0]));
|
context->setIntReg(INTREG_HI, gdbregs.regs32[GdbIntArchRegs + 2]);
|
||||||
context->setIntReg(INTREG_HI,
|
|
||||||
unpackLo(gdbregs.regs[GdbIntArchRegs + 1]));
|
|
||||||
context->setMiscRegNoEffect(MISCREG_BADVADDR,
|
context->setMiscRegNoEffect(MISCREG_BADVADDR,
|
||||||
unpackHi(gdbregs.regs[GdbIntArchRegs + 1]));
|
gdbregs.regs32[GdbIntArchRegs + 3]);
|
||||||
context->setMiscRegNoEffect(MISCREG_CAUSE,
|
context->setMiscRegNoEffect(MISCREG_CAUSE,
|
||||||
unpackLo(gdbregs.regs[GdbIntArchRegs + 2]));
|
gdbregs.regs32[GdbIntArchRegs + 4]);
|
||||||
context->pcState(
|
context->pcState(gdbregs.regs32[GdbIntArchRegs + 5]);
|
||||||
unpackHi(gdbregs.regs[GdbIntArchRegs + 2]));
|
|
||||||
// FLOATREG: F0~F31
|
// FLOATREG: F0~F31
|
||||||
for (int i = 0; i < GdbFloatArchRegs; i++) {
|
for (int i = 0; i < GdbFloatArchRegs; i++)
|
||||||
context->setFloatRegBits(i * 2,
|
context->setFloatRegBits(i, gdbregs.regs32[GdbIntRegs + i]);
|
||||||
unpackLo(gdbregs.regs[GdbIntRegs + i]));
|
|
||||||
context->setFloatRegBits(i * 2 + 1,
|
|
||||||
unpackHi(gdbregs.regs[GdbIntRegs + i]));
|
|
||||||
}
|
|
||||||
// FCR, FIR
|
// FCR, FIR
|
||||||
context->setFloatRegBits(FLOATREG_FCCR,
|
context->setFloatRegBits(FLOATREG_FCCR,
|
||||||
unpackLo(gdbregs.regs[GdbIntRegs + GdbFloatArchRegs + 0]));
|
gdbregs.regs32[GdbIntRegs + GdbFloatArchRegs + 0]);
|
||||||
context->setFloatRegBits(FLOATREG_FIR,
|
context->setFloatRegBits(FLOATREG_FIR,
|
||||||
unpackHi(gdbregs.regs[GdbIntRegs + GdbFloatArchRegs + 0]));
|
gdbregs.regs32[GdbIntRegs + GdbFloatArchRegs + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/*
|
/*
|
||||||
|
* Copyright 2014 Google, Inc.
|
||||||
* Copyright (c) 2007 The Regents of The University of Michigan
|
* Copyright (c) 2007 The Regents of The University of Michigan
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
|
@ -42,11 +43,10 @@ namespace MipsISA
|
||||||
{
|
{
|
||||||
|
|
||||||
// The number of special regs depends on gdb.
|
// The number of special regs depends on gdb.
|
||||||
// Two 32-bit regs are packed into one 64-bit reg.
|
const int GdbIntArchRegs = NumIntArchRegs;
|
||||||
const int GdbIntArchRegs = NumIntArchRegs / 2;
|
const int GdbIntSpecialRegs = 6;
|
||||||
const int GdbIntSpecialRegs = 6 / 2;
|
const int GdbFloatArchRegs = NumFloatArchRegs;
|
||||||
const int GdbFloatArchRegs = NumFloatArchRegs / 2;
|
const int GdbFloatSpecialRegs = 2;
|
||||||
const int GdbFloatSpecialRegs = 2 / 2;
|
|
||||||
|
|
||||||
const int GdbIntRegs = GdbIntArchRegs + GdbIntSpecialRegs;
|
const int GdbIntRegs = GdbIntArchRegs + GdbIntSpecialRegs;
|
||||||
const int GdbFloatRegs = GdbFloatArchRegs + GdbFloatSpecialRegs;
|
const int GdbFloatRegs = GdbFloatArchRegs + GdbFloatSpecialRegs;
|
||||||
|
@ -69,23 +69,6 @@ namespace MipsISA
|
||||||
|
|
||||||
void clearSingleStep();
|
void clearSingleStep();
|
||||||
void setSingleStep();
|
void setSingleStep();
|
||||||
|
|
||||||
private:
|
|
||||||
uint64_t
|
|
||||||
pack(uint32_t lo, uint32_t hi)
|
|
||||||
{
|
|
||||||
return static_cast<uint64_t>(hi) << 32 | lo;
|
|
||||||
}
|
|
||||||
uint32_t
|
|
||||||
unpackLo(uint64_t val)
|
|
||||||
{
|
|
||||||
return bits(val, 31, 0);
|
|
||||||
}
|
|
||||||
uint32_t
|
|
||||||
unpackHi(uint64_t val)
|
|
||||||
{
|
|
||||||
return bits(val, 63, 32);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/*
|
/*
|
||||||
|
* Copyright 2014 Google, Inc.
|
||||||
* Copyright (c) 2002-2005 The Regents of The University of Michigan
|
* Copyright (c) 2002-2005 The Regents of The University of Michigan
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
|
@ -143,7 +144,7 @@ using namespace std;
|
||||||
using namespace SparcISA;
|
using namespace SparcISA;
|
||||||
|
|
||||||
RemoteGDB::RemoteGDB(System *_system, ThreadContext *c)
|
RemoteGDB::RemoteGDB(System *_system, ThreadContext *c)
|
||||||
: BaseRemoteGDB(_system, c, NumGDBRegs), nextBkpt(0)
|
: BaseRemoteGDB(_system, c, NumGDBRegs * sizeof(uint64_t)), nextBkpt(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
|
@ -185,34 +186,35 @@ RemoteGDB::getregs()
|
||||||
PSTATE pstate = context->readMiscReg(MISCREG_PSTATE);
|
PSTATE pstate = context->readMiscReg(MISCREG_PSTATE);
|
||||||
|
|
||||||
if (pstate.am) {
|
if (pstate.am) {
|
||||||
uint32_t *regs;
|
gdbregs.regs32[Reg32Pc] = htobe((uint32_t)pc.pc());
|
||||||
regs = (uint32_t*)gdbregs.regs;
|
gdbregs.regs32[Reg32Npc] = htobe((uint32_t)pc.npc());
|
||||||
regs[Reg32Pc] = htobe((uint32_t)pc.pc());
|
|
||||||
regs[Reg32Npc] = htobe((uint32_t)pc.npc());
|
|
||||||
for (int x = RegG0; x <= RegI0 + 7; x++)
|
for (int x = RegG0; x <= RegI0 + 7; x++)
|
||||||
regs[x] = htobe((uint32_t)context->readIntReg(x - RegG0));
|
gdbregs.regs32[x] = htobe((uint32_t)context->readIntReg(x - RegG0));
|
||||||
|
|
||||||
regs[Reg32Y] = htobe((uint32_t)context->readIntReg(NumIntArchRegs + 1));
|
gdbregs.regs32[Reg32Y] =
|
||||||
regs[Reg32Psr] = htobe((uint32_t)pstate);
|
htobe((uint32_t)context->readIntReg(NumIntArchRegs + 1));
|
||||||
regs[Reg32Fsr] = htobe((uint32_t)context->readMiscReg(MISCREG_FSR));
|
gdbregs.regs32[Reg32Psr] = htobe((uint32_t)pstate);
|
||||||
regs[Reg32Csr] = htobe((uint32_t)context->readIntReg(NumIntArchRegs + 2));
|
gdbregs.regs32[Reg32Fsr] =
|
||||||
|
htobe((uint32_t)context->readMiscReg(MISCREG_FSR));
|
||||||
|
gdbregs.regs32[Reg32Csr] =
|
||||||
|
htobe((uint32_t)context->readIntReg(NumIntArchRegs + 2));
|
||||||
} else {
|
} else {
|
||||||
gdbregs.regs[RegPc] = htobe(pc.pc());
|
gdbregs.regs64[RegPc] = htobe(pc.pc());
|
||||||
gdbregs.regs[RegNpc] = htobe(pc.npc());
|
gdbregs.regs64[RegNpc] = htobe(pc.npc());
|
||||||
for (int x = RegG0; x <= RegI0 + 7; x++)
|
for (int x = RegG0; x <= RegI0 + 7; x++)
|
||||||
gdbregs.regs[x] = htobe(context->readIntReg(x - RegG0));
|
gdbregs.regs64[x] = htobe(context->readIntReg(x - RegG0));
|
||||||
|
|
||||||
gdbregs.regs[RegFsr] = htobe(context->readMiscReg(MISCREG_FSR));
|
gdbregs.regs64[RegFsr] = htobe(context->readMiscReg(MISCREG_FSR));
|
||||||
gdbregs.regs[RegFprs] = htobe(context->readMiscReg(MISCREG_FPRS));
|
gdbregs.regs64[RegFprs] = htobe(context->readMiscReg(MISCREG_FPRS));
|
||||||
gdbregs.regs[RegY] = htobe(context->readIntReg(NumIntArchRegs + 1));
|
gdbregs.regs64[RegY] = htobe(context->readIntReg(NumIntArchRegs + 1));
|
||||||
gdbregs.regs[RegState] = htobe(
|
gdbregs.regs64[RegState] = htobe(
|
||||||
context->readMiscReg(MISCREG_CWP) |
|
context->readMiscReg(MISCREG_CWP) |
|
||||||
pstate << 8 |
|
pstate << 8 |
|
||||||
context->readMiscReg(MISCREG_ASI) << 24 |
|
context->readMiscReg(MISCREG_ASI) << 24 |
|
||||||
context->readIntReg(NumIntArchRegs + 2) << 32);
|
context->readIntReg(NumIntArchRegs + 2) << 32);
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINTF(GDBRead, "PC=%#x\n", gdbregs.regs[RegPc]);
|
DPRINTF(GDBRead, "PC=%#x\n", gdbregs.regs64[RegPc]);
|
||||||
|
|
||||||
// Floating point registers are left at 0 in netbsd
|
// Floating point registers are left at 0 in netbsd
|
||||||
// All registers other than the pc, npc and int regs
|
// All registers other than the pc, npc and int regs
|
||||||
|
@ -229,14 +231,14 @@ void
|
||||||
RemoteGDB::setregs()
|
RemoteGDB::setregs()
|
||||||
{
|
{
|
||||||
PCState pc;
|
PCState pc;
|
||||||
pc.pc(gdbregs.regs[RegPc]);
|
pc.pc(gdbregs.regs64[RegPc]);
|
||||||
pc.npc(gdbregs.regs[RegNpc]);
|
pc.npc(gdbregs.regs64[RegNpc]);
|
||||||
pc.nnpc(pc.npc() + sizeof(MachInst));
|
pc.nnpc(pc.npc() + sizeof(MachInst));
|
||||||
pc.upc(0);
|
pc.upc(0);
|
||||||
pc.nupc(1);
|
pc.nupc(1);
|
||||||
context->pcState(pc);
|
context->pcState(pc);
|
||||||
for (int x = RegG0; x <= RegI0 + 7; x++)
|
for (int x = RegG0; x <= RegI0 + 7; x++)
|
||||||
context->setIntReg(x - RegG0, gdbregs.regs[x]);
|
context->setIntReg(x - RegG0, gdbregs.regs64[x]);
|
||||||
// Only the integer registers, pc and npc are set in netbsd
|
// Only the integer registers, pc and npc are set in netbsd
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/*
|
/*
|
||||||
|
* Copyright 2014 Google, Inc.
|
||||||
* Copyright (c) 2002-2005 The Regents of The University of Michigan
|
* Copyright (c) 2002-2005 The Regents of The University of Michigan
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
|
@ -36,6 +37,7 @@
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "arch/types.hh"
|
#include "arch/types.hh"
|
||||||
|
#include "base/intmath.hh"
|
||||||
#include "base/pollevent.hh"
|
#include "base/pollevent.hh"
|
||||||
#include "base/socket.hh"
|
#include "base/socket.hh"
|
||||||
#include "cpu/pc_event.hh"
|
#include "cpu/pc_event.hh"
|
||||||
|
@ -136,16 +138,25 @@ class BaseRemoteGDB
|
||||||
class GdbRegCache
|
class GdbRegCache
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
GdbRegCache(size_t newSize) : regs(new uint64_t[newSize]), size(newSize)
|
GdbRegCache(size_t newSize) :
|
||||||
|
regs64(new uint64_t[divCeil(newSize, sizeof(uint64_t))]),
|
||||||
|
size(newSize)
|
||||||
{}
|
{}
|
||||||
~GdbRegCache()
|
~GdbRegCache()
|
||||||
{
|
{
|
||||||
delete [] regs;
|
delete [] regs64;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64_t * regs;
|
union {
|
||||||
|
uint64_t *regs64;
|
||||||
|
uint32_t *regs32;
|
||||||
|
uint16_t *regs16;
|
||||||
|
uint8_t *regs8;
|
||||||
|
void *regs;
|
||||||
|
};
|
||||||
|
// Size of cache in bytes.
|
||||||
size_t size;
|
size_t size;
|
||||||
size_t bytes() { return size * sizeof(uint64_t); }
|
size_t bytes() { return size; }
|
||||||
};
|
};
|
||||||
|
|
||||||
GdbRegCache gdbregs;
|
GdbRegCache gdbregs;
|
||||||
|
|
Loading…
Reference in a new issue