Skip to content

Commit

Permalink
Updated documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
sysprogs committed Sep 2, 2012
1 parent 685c047 commit 22fc5db
Show file tree
Hide file tree
Showing 9 changed files with 256 additions and 226 deletions.
2 changes: 2 additions & 0 deletions GlobalSessionMonitor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ BOOL CALLBACK MSP430Proxy::GlobalSessionMonitor::CtrlHandler( DWORD dwType )
MutexLocker lck(g_SessionMonitor.m_Mutex);
if (g_SessionMonitor.pSession)
g_SessionMonitor.pSession->SendBreakInRequestAsync();
else
printf("No active session. To stop listening, press Ctrl+Break.\n");
return TRUE;
}
return FALSE;
Expand Down
129 changes: 88 additions & 41 deletions MSP430EEMTarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@ MAIN_SEGMENT_SIZE
using namespace GDBServerFoundation;
using namespace MSP430Proxy;

//Breakpoint cookie format:
//32 bits: [type : 4] [reserved : 12] [user_data : 16]
//For RAM breakpoints user_data contains the original insn
//For hardware breakpoints user_data contains the handle returned by EEM API

enum {kBpCookieTypeMask = 0xF0000000,
kBpCookieTypeHardware = 0x10000000,
kBpCookieTypeSoftwareFLASH = 0x20000000,
kBpCookieTypeSoftwareRAM = 0x30000000,
kBpCookieDataMask = 0x0000FFFF};

#define MAKE_BP_COOKIE(type, data) (((type) & kBpCookieTypeMask) | ((data) & kBpCookieDataMask))

enum MSP430_MSG
{
WMX_SINGLESTEP = WM_USER + 1,
Expand All @@ -28,6 +41,8 @@ bool MSP430Proxy::MSP430EEMTarget::Initialize(const GlobalSettings &settings)
if (m_pBreakpointManager)
return false;

m_BreakpointPolicy = settings.SoftBreakPolicy;

MESSAGE_ID msgs = {0,};
msgs.uiMsgIdSingleStep = WMX_SINGLESTEP;
msgs.uiMsgIdBreakpoint = WMX_BREKAPOINT;
Expand All @@ -42,19 +57,25 @@ bool MSP430Proxy::MSP430EEMTarget::Initialize(const GlobalSettings &settings)

m_bEEMInitialized = true;

BpParameter_t bkpt;
memset(&bkpt, 0, sizeof(bkpt));

bkpt.bpMode = BP_COMPLEX;
bkpt.lAddrVal = settings.BreakpointInstruction;
bkpt.bpType = BP_MDB;
bkpt.bpAccess = BP_FETCH;
bkpt.bpAction = BP_BRK;
bkpt.bpOperat = BP_EQUAL;
bkpt.bpCondition = BP_NO_COND;
bkpt.lMask = 0xffff;
if (MSP430_EEM_SetBreakpoint(&m_SoftwareBreakpointWrapperHandle, &bkpt) != STATUS_OK)
REPORT_AND_RETURN("Cannot create a MDB breakpoint for handling software breakpoints", false);
if (m_BreakpointPolicy != HardwareOnly)
{
BpParameter_t bkpt;
memset(&bkpt, 0, sizeof(bkpt));

bkpt.bpMode = BP_COMPLEX;
bkpt.lAddrVal = settings.BreakpointInstruction;
bkpt.bpType = BP_MDB;
bkpt.bpAccess = BP_FETCH;
bkpt.bpAction = BP_BRK;
bkpt.bpOperat = BP_EQUAL;
bkpt.bpCondition = BP_NO_COND;
bkpt.lMask = 0xffff;
if (MSP430_EEM_SetBreakpoint(&m_SoftwareBreakpointWrapperHandle, &bkpt) != STATUS_OK)
REPORT_AND_RETURN("Cannot create a MDB breakpoint for handling software breakpoints", false);
m_HardwareBreakpointsUsed++;
}
else
m_SoftwareBreakpointWrapperHandle = -1;

m_pBreakpointManager = new SoftwareBreakpointManager(m_DeviceInfo.mainStart, m_DeviceInfo.mainEnd, settings.BreakpointInstruction, settings.InstantBreakpointCleanup);

Expand All @@ -65,11 +86,14 @@ MSP430Proxy::MSP430EEMTarget::~MSP430EEMTarget()
{
delete m_pBreakpointManager;

BpParameter_t bkpt;
memset(&bkpt, 0, sizeof(bkpt));
bkpt.bpMode = BP_CLEAR;
if (m_SoftwareBreakpointWrapperHandle != -1)
{
BpParameter_t bkpt;
memset(&bkpt, 0, sizeof(bkpt));
bkpt.bpMode = BP_CLEAR;

MSP430_EEM_SetBreakpoint(&m_SoftwareBreakpointWrapperHandle, &bkpt);
MSP430_EEM_SetBreakpoint(&m_SoftwareBreakpointWrapperHandle, &bkpt);
}

if (m_bEEMInitialized)
MSP430_EEM_Close();
Expand Down Expand Up @@ -152,25 +176,59 @@ bool MSP430Proxy::MSP430EEMTarget::WaitForJTAGEvent()

GDBServerFoundation::GDBStatus MSP430Proxy::MSP430EEMTarget::CreateBreakpoint( BreakpointType type, ULONGLONG Address, unsigned kind, OUT INT_PTR *pCookie )
{
BpParameter_t bkpt;
memset(&bkpt, 0, sizeof(bkpt));
switch(type)
{
case bptSoftwareBreakpoint:
return DoCreateCodeBreakpoint(false, Address, pCookie);
switch(m_BreakpointPolicy)
{
case HardwareOnly:
return DoCreateCodeBreakpoint(true, Address, pCookie);
case HardwareThenSoftware:
return DoCreateCodeBreakpoint((m_HardwareBreakpointsUsed < m_DeviceInfo.nBreakpoints), Address, pCookie);
case SoftwareOnly:
default:
return DoCreateCodeBreakpoint(false, Address, pCookie);
}
case bptHardwareBreakpoint:
return DoCreateCodeBreakpoint(true, Address, pCookie);
if (m_BreakpointPolicy == HardwareThenSoftware && m_bFLASHCommandsUsed)
return DoCreateCodeBreakpoint((m_HardwareBreakpointsUsed < m_DeviceInfo.nBreakpoints), Address, pCookie);
else
return DoCreateCodeBreakpoint(true, Address, pCookie);
case bptAccessWatchpoint:
case bptWriteWatchpoint:
case bptReadWatchpoint:
break;
default:
return kGDBNotSupported;
}

//TODO: support memory breakpoints
BpParameter_t bkpt;
memset(&bkpt, 0, sizeof(bkpt));
bkpt.bpMode = BP_COMPLEX;
bkpt.lAddrVal = (ULONG)Address;
bkpt.bpType = BP_MAB;
switch(type)
{
case bptAccessWatchpoint:
bkpt.bpAccess = BP_NO_FETCH;
break;
case bptReadWatchpoint:
bkpt.bpAccess = BP_READ;
break;
case bptWriteWatchpoint:
bkpt.bpAccess = BP_WRITE;
break;
}
bkpt.bpAction = BP_BRK;
bkpt.bpOperat = BP_EQUAL;
bkpt.bpCondition = BP_NO_COND;
bkpt.lMask = 0xffff;

WORD bpHandle = 0;
if (MSP430_EEM_SetBreakpoint(&bpHandle, &bkpt) != STATUS_OK)
REPORT_AND_RETURN("Cannot set an EEM breakpoint", kGDBUnknownError);

*pCookie = bpHandle;
*pCookie = MAKE_BP_COOKIE(kBpCookieTypeHardware, bpHandle);

return kGDBSuccess;
}
Expand All @@ -182,6 +240,9 @@ GDBServerFoundation::GDBStatus MSP430Proxy::MSP430EEMTarget::RemoveBreakpoint( B
case bptSoftwareBreakpoint:
return DoRemoveCodeBreakpoint(false, Address, Cookie);
case bptHardwareBreakpoint:
case bptReadWatchpoint:
case bptWriteWatchpoint:
case bptAccessWatchpoint:
return DoRemoveCodeBreakpoint(true, Address, Cookie);
default:
return kGDBNotSupported;
Expand Down Expand Up @@ -246,19 +307,6 @@ GDBServerFoundation::GDBStatus MSP430Proxy::MSP430EEMTarget::WriteTargetMemory(
return kGDBSuccess;
}

//Breakpoint cookie format:
//32 bits: [type : 4] [reserved : 12] [user_data : 16]
//For RAM breakpoints user_data contains the original insn
//For hardware breakpoints user_data contains the handle returned by EEM API

enum {kBpCookieTypeMask = 0xF0000000,
kBpCookieTypeHardware = 0x10000000,
kBpCookieTypeSoftwareFLASH = 0x20000000,
kBpCookieTypeSoftwareRAM = 0x30000000,
kBpCookieDataMask = 0x0000FFFF};

#define MAKE_BP_COOKIE(type, data) (((type) & kBpCookieTypeMask) | ((data) & kBpCookieDataMask))

GDBServerFoundation::GDBStatus MSP430Proxy::MSP430EEMTarget::DoCreateCodeBreakpoint( bool hardware, ULONGLONG Address, INT_PTR *pCookie )
{
if (hardware)
Expand All @@ -274,6 +322,8 @@ GDBServerFoundation::GDBStatus MSP430Proxy::MSP430EEMTarget::DoCreateCodeBreakpo
if (MSP430_EEM_SetBreakpoint(&bpHandle, &bkpt) != STATUS_OK)
REPORT_AND_RETURN("Cannot set an EEM breakpoint", kGDBUnknownError);

m_HardwareBreakpointsUsed++;

C_ASSERT(sizeof(bpHandle) == 2);
*pCookie = MAKE_BP_COOKIE(kBpCookieTypeHardware, bpHandle);

Expand Down Expand Up @@ -315,9 +365,8 @@ GDBServerFoundation::GDBStatus MSP430Proxy::MSP430EEMTarget::DoCreateCodeBreakpo

GDBServerFoundation::GDBStatus MSP430Proxy::MSP430EEMTarget::DoRemoveCodeBreakpoint( bool hardware, ULONGLONG Address, INT_PTR Cookie )
{
if (hardware)
if ((Cookie & kBpCookieTypeMask) == kBpCookieTypeHardware)
{
ASSERT((Cookie & kBpCookieTypeMask) == kBpCookieTypeHardware);
BpParameter_t bkpt;
memset(&bkpt, 0, sizeof(bkpt));
bkpt.bpMode = BP_CLEAR;
Expand All @@ -326,13 +375,11 @@ GDBServerFoundation::GDBStatus MSP430Proxy::MSP430EEMTarget::DoRemoveCodeBreakpo

if (MSP430_EEM_SetBreakpoint(&bpHandle, &bkpt) != STATUS_OK)
REPORT_AND_RETURN("Cannot remove an EEM breakpoint", kGDBUnknownError);
m_HardwareBreakpointsUsed--;
return kGDBSuccess;
}
else
{
if ((Cookie & kBpCookieTypeMask) == kBpCookieTypeHardware)
return DoRemoveCodeBreakpoint(true, Address, Cookie);

if (!IsFLASHAddress(Address))
{
ASSERT((Cookie & kBpCookieTypeMask) == kBpCookieTypeSoftwareRAM);
Expand Down
6 changes: 6 additions & 0 deletions MSP430EEMTarget.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "MSP430Target.h"
#include <bzscore/sync.h>
#include <set>
#include "settings.h"

namespace MSP430Proxy
{
Expand All @@ -20,6 +21,8 @@ namespace MSP430Proxy
SoftwareBreakpointManager *m_pBreakpointManager;
RUN_MODES_t m_LastResumeMode;

unsigned m_HardwareBreakpointsUsed;

//! If the last resume operation was resuming from a breakpoint, this field contains its address. If not, it contains -1
LONG m_BreakpointAddrOfLastResumeOp;

Expand Down Expand Up @@ -53,6 +56,7 @@ namespace MSP430Proxy

RAMBreakpointDatabase m_RAMBreakpoints;
unsigned short m_BreakpointInstruction;
BreakpointPolicy m_BreakpointPolicy;

protected:
virtual bool DoResumeTarget(RUN_MODES_t mode) override;
Expand All @@ -70,6 +74,8 @@ namespace MSP430Proxy
, m_LastResumeMode(RUN_TO_BREAKPOINT)
, m_BreakpointAddrOfLastResumeOp(-1)
, m_BreakpointInstruction(0) //Will be updated in Initialize()
, m_HardwareBreakpointsUsed(0)
, m_BreakpointPolicy(HardwareThenSoftware)
{
}

Expand Down
18 changes: 15 additions & 3 deletions MSP430Target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ bool MSP430Proxy::MSP430GDBTarget::Initialize(const GlobalSettings &settings)
if (MSP430_Reset(ALL_RESETS, FALSE, FALSE) != STATUS_OK)
REPORT_AND_RETURN("Cannot reset the MSP430 device", false);

if (settings.AutoErase)
{
printf("Erasing FLASH...\n");
if (MSP430_Erase(ERASE_MAIN, m_DeviceInfo.mainStart, m_DeviceInfo.mainEnd - m_DeviceInfo.mainStart) != STATUS_OK)
printf("Warning: cannot erase FLASH: %s\n", GetLastMSP430Error());
else
m_bFLASHErased = true;
}

m_DeviceInfo.string[__countof(m_DeviceInfo.string) - 1] = 0;
printf("Found an %s device with %d hardware breakpoints.\n", m_DeviceInfo.string, m_DeviceInfo.nBreakpoints);

Expand Down Expand Up @@ -138,7 +147,7 @@ GDBServerFoundation::GDBStatus MSP430GDBTarget::SendBreakInRequestAsync()
return kGDBSuccess;
}

GDBServerFoundation::GDBStatus MSP430GDBTarget::ReadFrameRelatedRegisters( int threadID, TargetRegisterValues &registers )
GDBServerFoundation::GDBStatus MSP430GDBTarget::ReadFrameRelatedRegisters( int threadID, RegisterSetContainer &registers )
{
LONG rawRegs[16] = {0,};
if (MSP430_Read_Registers(rawRegs, MASKREG(PC) | MASKREG(SP)) != STATUS_OK)
Expand All @@ -150,7 +159,7 @@ GDBServerFoundation::GDBStatus MSP430GDBTarget::ReadFrameRelatedRegisters( int t
return kGDBSuccess;
}

GDBServerFoundation::GDBStatus MSP430GDBTarget::ReadTargetRegisters( int threadID, TargetRegisterValues &registers )
GDBServerFoundation::GDBStatus MSP430GDBTarget::ReadTargetRegisters( int threadID, RegisterSetContainer &registers )
{
LONG rawRegs[16] = {0,};
if (MSP430_Read_Registers(rawRegs, ALL_REGS) != STATUS_OK)
Expand All @@ -162,7 +171,7 @@ GDBServerFoundation::GDBStatus MSP430GDBTarget::ReadTargetRegisters( int threadI
return kGDBSuccess;
}

GDBServerFoundation::GDBStatus MSP430GDBTarget::WriteTargetRegisters( int threadID, const TargetRegisterValues &registers )
GDBServerFoundation::GDBStatus MSP430GDBTarget::WriteTargetRegisters( int threadID, const RegisterSetContainer &registers )
{
LONG rawRegs[16] = {0,};
int mask = 0;
Expand Down Expand Up @@ -259,6 +268,7 @@ GDBServerFoundation::GDBStatus MSP430GDBTarget::RemoveBreakpoint( BreakpointType

GDBServerFoundation::GDBStatus MSP430Proxy::MSP430GDBTarget::EraseFLASH( ULONGLONG addr, size_t length )
{
m_bFLASHCommandsUsed = true;
if (MSP430_Erase(ERASE_MAIN, (LONG)addr, length) != STATUS_OK)
REPORT_AND_RETURN("Cannot erase FLASH memory", kGDBUnknownError);
m_bFLASHErased = true;
Expand All @@ -267,13 +277,15 @@ GDBServerFoundation::GDBStatus MSP430Proxy::MSP430GDBTarget::EraseFLASH( ULONGLO

GDBServerFoundation::GDBStatus MSP430Proxy::MSP430GDBTarget::WriteFLASH( ULONGLONG addr, const void *pBuffer, size_t length )
{
m_bFLASHCommandsUsed = true;
if (MSP430_Write_Memory((LONG)addr, (char *)pBuffer, length) != STATUS_OK)
REPORT_AND_RETURN("Cannot program FLASH memory", kGDBUnknownError);
return kGDBSuccess;
}

GDBServerFoundation::GDBStatus MSP430Proxy::MSP430GDBTarget::CommitFLASHWrite()
{
m_bFLASHCommandsUsed = true;
return kGDBSuccess;
}

Expand Down
9 changes: 5 additions & 4 deletions MSP430Target.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ namespace MSP430Proxy
bool m_bFLASHErased;

protected:
bool m_BreakInPending;
bool m_BreakInPending, m_bFLASHCommandsUsed;

protected:
virtual bool WaitForJTAGEvent();
Expand All @@ -39,6 +39,7 @@ namespace MSP430Proxy
, m_bValid(false)
, m_BreakInPending(false)
, m_bFLASHErased(false)
, m_bFLASHCommandsUsed(false)
{
}

Expand All @@ -57,9 +58,9 @@ namespace MSP430Proxy
}

public: //Register accessing API
virtual GDBStatus ReadFrameRelatedRegisters(int threadID, TargetRegisterValues &registers);
virtual GDBStatus ReadTargetRegisters(int threadID, TargetRegisterValues &registers);
virtual GDBStatus WriteTargetRegisters(int threadID, const TargetRegisterValues &registers);
virtual GDBStatus ReadFrameRelatedRegisters(int threadID, RegisterSetContainer &registers);
virtual GDBStatus ReadTargetRegisters(int threadID, RegisterSetContainer &registers);
virtual GDBStatus WriteTargetRegisters(int threadID, const RegisterSetContainer &registers);

public: //Memory accessing API
virtual GDBStatus ReadTargetMemory(ULONGLONG Address, void *pBuffer, size_t *pSizeInBytes);
Expand Down
Loading

0 comments on commit 22fc5db

Please sign in to comment.