summaryrefslogtreecommitdiff
path: root/src/arch/arm
diff options
context:
space:
mode:
authorGabe Black <gabeblack@google.com>2014-12-05 01:44:24 -0800
committerGabe Black <gabeblack@google.com>2014-12-05 01:44:24 -0800
commitfe48c0a32bf749358eeb95e748f9fc2247cc5480 (patch)
tree25e64817703c264bf09fa884db7eb187927870f7 /src/arch/arm
parent7540656fc5b8ce0cafb54f41b913a7e81cbfb4b3 (diff)
downloadgem5-fe48c0a32bf749358eeb95e748f9fc2247cc5480.tar.xz
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.
Diffstat (limited to 'src/arch/arm')
-rw-r--r--src/arch/arm/remote_gdb.cc153
-rw-r--r--src/arch/arm/remote_gdb.hh32
2 files changed, 85 insertions, 100 deletions
diff --git a/src/arch/arm/remote_gdb.cc b/src/arch/arm/remote_gdb.cc
index 86dd5a725..fce060311 100644
--- a/src/arch/arm/remote_gdb.cc
+++ b/src/arch/arm/remote_gdb.cc
@@ -1,4 +1,5 @@
/*
+ * Copyright 2014 Google Inc.
* Copyright (c) 2010, 2013 ARM Limited
* All rights reserved
*
@@ -160,7 +161,8 @@ using namespace std;
using namespace ArmISA;
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
// x0-x31
- for (int i = 0; i < 32; ++i) {
- gdbregs.regs[REG_X0 + i] = context->readIntReg(INTREG_X0 + i);
- }
+ for (int i = 0; i < 32; ++i)
+ gdbregs.regs64[GDB64_X0 + i] = context->readIntReg(INTREG_X0 + i);
// pc
- gdbregs.regs[REG_PC_64] = context->pcState().pc();
+ gdbregs.regs64[GDB64_PC] = context->pcState().pc();
// cpsr
- gdbregs.regs[REG_CPSR_64] = context->readMiscRegNoEffect(MISCREG_CPSR);
+ gdbregs.regs64[GDB64_CPSR] =
+ context->readMiscRegNoEffect(MISCREG_CPSR);
// v0-v31
- for (int i = 0; i < 32; ++i) {
- gdbregs.regs[REG_V0 + 2 * i] = static_cast<uint64_t>(
- context->readFloatRegBits(i * 4 + 3)) << 32 |
- context->readFloatRegBits(i * 4 + 2);
- gdbregs.regs[REG_V0 + 2 * i + 1] = static_cast<uint64_t>(
- context->readFloatRegBits(i * 4 + 1)) << 32 |
- context->readFloatRegBits(i * 4 + 0);
+ for (int i = 0; i < 128; i += 4) {
+ int gdboff = GDB64_V0_32 + i;
+ gdbregs.regs32[gdboff + 0] = context->readFloatRegBits(i + 2);
+ gdbregs.regs32[gdboff + 1] = context->readFloatRegBits(i + 3);
+ gdbregs.regs32[gdboff + 2] = context->readFloatRegBits(i + 0);
+ gdbregs.regs32[gdboff + 3] = context->readFloatRegBits(i + 1);
}
} else { // AArch32
// R0-R15 supervisor mode
- // arm registers are 32 bits wide, gdb registers are 64 bits wide two
- // arm registers are packed into one gdb register (little endian)
- gdbregs.regs[REG_R0 + 0] = context->readIntReg(INTREG_R1) << 32 |
- context->readIntReg(INTREG_R0);
- gdbregs.regs[REG_R0 + 1] = context->readIntReg(INTREG_R3) << 32 |
- context->readIntReg(INTREG_R2);
- gdbregs.regs[REG_R0 + 2] = context->readIntReg(INTREG_R5) << 32 |
- context->readIntReg(INTREG_R4);
- gdbregs.regs[REG_R0 + 3] = context->readIntReg(INTREG_R7) << 32 |
- context->readIntReg(INTREG_R6);
- gdbregs.regs[REG_R0 + 4] = context->readIntReg(INTREG_R9) << 32 |
- context->readIntReg(INTREG_R8);
- gdbregs.regs[REG_R0 + 5] = context->readIntReg(INTREG_R11) << 32|
- context->readIntReg(INTREG_R10);
- gdbregs.regs[REG_R0 + 6] = context->readIntReg(INTREG_SP) << 32 |
- context->readIntReg(INTREG_R12);
- gdbregs.regs[REG_R0 + 7] = context->pcState().pc() << 32 |
- context->readIntReg(INTREG_LR);
+ gdbregs.regs32[GDB32_R0 + 0] = context->readIntReg(INTREG_R0);
+ gdbregs.regs32[GDB32_R0 + 1] = context->readIntReg(INTREG_R1);
+ gdbregs.regs32[GDB32_R0 + 2] = context->readIntReg(INTREG_R2);
+ gdbregs.regs32[GDB32_R0 + 3] = context->readIntReg(INTREG_R3);
+ gdbregs.regs32[GDB32_R0 + 4] = context->readIntReg(INTREG_R4);
+ gdbregs.regs32[GDB32_R0 + 5] = context->readIntReg(INTREG_R5);
+ gdbregs.regs32[GDB32_R0 + 6] = context->readIntReg(INTREG_R6);
+ gdbregs.regs32[GDB32_R0 + 7] = context->readIntReg(INTREG_R7);
+ gdbregs.regs32[GDB32_R0 + 8] = context->readIntReg(INTREG_R8);
+ gdbregs.regs32[GDB32_R0 + 9] = context->readIntReg(INTREG_R9);
+ gdbregs.regs32[GDB32_R0 + 10] = context->readIntReg(INTREG_R10);
+ gdbregs.regs32[GDB32_R0 + 11] = context->readIntReg(INTREG_R11);
+ gdbregs.regs32[GDB32_R0 + 12] = context->readIntReg(INTREG_R12);
+ gdbregs.regs32[GDB32_R0 + 13] = context->readIntReg(INTREG_SP);
+ gdbregs.regs32[GDB32_R0 + 14] = context->readIntReg(INTREG_LR);
+ gdbregs.regs32[GDB32_R0 + 15] = context->pcState().pc();
// 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)
-
- gdbregs.regs[REG_F0] =
- 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);
- }
+ for (int i = 0; i < NumFloatV7ArchRegs; ++i)
+ gdbregs.regs32[GDB32_F0 + i] = context->readFloatRegBits(i);
// FPSCR
- gdbregs.regs[REG_FPSCR] = static_cast<uint64_t>(
- context->readMiscRegNoEffect(MISCREG_FPSCR)) << 32 |
- context->readFloatRegBits(NumFloatV7ArchRegs - 1);
+ gdbregs.regs32[GDB32_FPSCR] =
+ context->readMiscRegNoEffect(MISCREG_FPSCR);
}
}
@@ -277,63 +267,50 @@ RemoteGDB::setregs()
DPRINTF(GDBAcc, "setregs in remotegdb \n");
if (inAArch64(context)) { // AArch64
// x0-x31
- for (int i = 0; i < 32; ++i) {
- context->setIntReg(INTREG_X0 + i, gdbregs.regs[REG_X0 + i]);
- }
+ for (int i = 0; i < 32; ++i)
+ context->setIntReg(INTREG_X0 + i, gdbregs.regs64[GDB64_X0 + i]);
// pc
- context->pcState(gdbregs.regs[REG_PC_64]);
+ context->pcState(gdbregs.regs64[GDB64_PC]);
// cpsr
- context->setMiscRegNoEffect(MISCREG_CPSR, gdbregs.regs[REG_CPSR_64]);
+ context->setMiscRegNoEffect(MISCREG_CPSR, gdbregs.regs64[GDB64_CPSR]);
// v0-v31
- for (int i = 0; i < 32; ++i) {
- context->setFloatRegBits(i * 4 + 3,
- gdbregs.regs[REG_V0 + 2 * i] >> 32);
- context->setFloatRegBits(i * 4 + 2,
- gdbregs.regs[REG_V0 + 2 * i]);
- context->setFloatRegBits(i * 4 + 1,
- gdbregs.regs[REG_V0 + 2 * i + 1] >> 32);
- context->setFloatRegBits(i * 4 + 0,
- gdbregs.regs[REG_V0 + 2 * i + 1]);
+ for (int i = 0; i < 128; i += 4) {
+ int gdboff = GDB64_V0_32 + i;
+ context->setFloatRegBits(i + 2, gdbregs.regs32[gdboff + 0]);
+ context->setFloatRegBits(i + 3, gdbregs.regs32[gdboff + 1]);
+ context->setFloatRegBits(i + 0, gdbregs.regs32[gdboff + 2]);
+ context->setFloatRegBits(i + 1, gdbregs.regs32[gdboff + 3]);
}
} else { // AArch32
// R0-R15 supervisor mode
// arm registers are 32 bits wide, gdb registers are 64 bits wide
// 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_R1 , bits(gdbregs.regs[REG_R0 + 0], 63, 32));
- context->setIntReg(INTREG_R2 , bits(gdbregs.regs[REG_R0 + 1], 31, 0));
- context->setIntReg(INTREG_R3 , bits(gdbregs.regs[REG_R0 + 1], 63, 32));
- context->setIntReg(INTREG_R4 , bits(gdbregs.regs[REG_R0 + 2], 31, 0));
- context->setIntReg(INTREG_R5 , bits(gdbregs.regs[REG_R0 + 2], 63, 32));
- context->setIntReg(INTREG_R6 , bits(gdbregs.regs[REG_R0 + 3], 31, 0));
- context->setIntReg(INTREG_R7 , bits(gdbregs.regs[REG_R0 + 3], 63, 32));
- context->setIntReg(INTREG_R8 , bits(gdbregs.regs[REG_R0 + 4], 31, 0));
- context->setIntReg(INTREG_R9 , bits(gdbregs.regs[REG_R0 + 4], 63, 32));
- context->setIntReg(INTREG_R10, bits(gdbregs.regs[REG_R0 + 5], 31, 0));
- context->setIntReg(INTREG_R11, bits(gdbregs.regs[REG_R0 + 5], 63, 32));
- context->setIntReg(INTREG_R12, bits(gdbregs.regs[REG_R0 + 6], 31, 0));
- context->setIntReg(INTREG_SP , bits(gdbregs.regs[REG_R0 + 6], 63, 32));
- context->setIntReg(INTREG_LR , bits(gdbregs.regs[REG_R0 + 7], 31, 0));
- context->pcState(bits(gdbregs.regs[REG_R0 + 7], 63, 32));
+ context->setIntReg(INTREG_R0, gdbregs.regs32[GDB32_R0 + 0]);
+ context->setIntReg(INTREG_R1, gdbregs.regs32[GDB32_R0 + 1]);
+ context->setIntReg(INTREG_R2, gdbregs.regs32[GDB32_R0 + 2]);
+ context->setIntReg(INTREG_R3, gdbregs.regs32[GDB32_R0 + 3]);
+ context->setIntReg(INTREG_R4, gdbregs.regs32[GDB32_R0 + 4]);
+ context->setIntReg(INTREG_R5, gdbregs.regs32[GDB32_R0 + 5]);
+ context->setIntReg(INTREG_R6, gdbregs.regs32[GDB32_R0 + 6]);
+ context->setIntReg(INTREG_R7, gdbregs.regs32[GDB32_R0 + 7]);
+ context->setIntReg(INTREG_R8, gdbregs.regs32[GDB32_R0 + 8]);
+ context->setIntReg(INTREG_R9, gdbregs.regs32[GDB32_R0 + 9]);
+ context->setIntReg(INTREG_R10, gdbregs.regs32[GDB32_R0 + 10]);
+ context->setIntReg(INTREG_R11, gdbregs.regs32[GDB32_R0 + 11]);
+ context->setIntReg(INTREG_R12, gdbregs.regs32[GDB32_R0 + 12]);
+ context->setIntReg(INTREG_SP, gdbregs.regs32[GDB32_R0 + 13]);
+ context->setIntReg(INTREG_LR, gdbregs.regs32[GDB32_R0 + 14]);
+ context->pcState(gdbregs.regs32[GDB32_R0 + 7]);
//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)
- context->setFloatRegBits(0, gdbregs.regs[REG_F0]>>32);
-
- 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);
- }
- }
+ for (int i = 0; i < NumFloatV7ArchRegs; ++i)
+ context->setFloatRegBits(i, gdbregs.regs32[GDB32_F0 + i]);
//FPSCR
- context->setMiscReg(MISCREG_FPSCR, gdbregs.regs[REG_FPSCR]>>32);
+ context->setMiscReg(MISCREG_FPSCR, gdbregs.regs32[GDB32_FPSCR]);
}
}
diff --git a/src/arch/arm/remote_gdb.hh b/src/arch/arm/remote_gdb.hh
index a6b2b9d35..423ba9d02 100644
--- a/src/arch/arm/remote_gdb.hh
+++ b/src/arch/arm/remote_gdb.hh
@@ -1,4 +1,5 @@
/*
+ * Copyright 2014 Google, Inc.
* Copyright (c) 2013 ARM Limited
* All rights reserved
*
@@ -45,6 +46,8 @@
#ifndef __ARCH_ARM_REMOTE_GDB_HH__
#define __ARCH_ARM_REMOTE_GDB_HH__
+#include <algorithm>
+
#include "base/remote_gdb.hh"
class System;
@@ -54,21 +57,26 @@ namespace ArmISA
{
// AArch32 registers with vfpv3/neon
-const int NUMREGS = 41; /* r0-r15, cpsr, d0-d31, fpscr */
-const int REG_R0 = 0;
-const int REG_F0 = 8;
-const int REG_CPSR = 8; /* bit 512 to bit 543 */
-const int REG_FPSCR = 40; /* bit 2592 to bit 2623 */
+enum {
+ GDB32_R0 = 0,
+ GDB32_CPSR = 16,
+ GDB32_F0 = 17,
+ GDB32_FPSCR = 81,
+ GDB32_NUMREGS = 82
+};
// AArch64 registers
-const int NUMREGS_64 = 98; // x0-x31, pc, cpsr (64-bit GPRs)
- // v0-v31 (128-bit FPRs)
-const int REG_X0 = 0;
-const int REG_PC_64 = 32;
-const int REG_CPSR_64 = 33;
-const int REG_V0 = 34;
+enum {
+ GDB64_X0 = 0,
+ GDB64_PC = 32,
+ GDB64_CPSR = 33,
+ GDB64_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
{