3 #include <bzscore/assert.h>
4 #include <MSP430_Debug.h>
6 using namespace MSP430Proxy;
9 : m_FlashStart(flashStart)
10 , m_FlashEnd(flashEnd)
11 , m_FlashSize(flashEnd - flashStart + 1)
12 , m_BreakInstruction(breakInstruction)
13 , m_bInstantCleanup(instantCleanup)
15 ASSERT(!(m_FlashSize & 1));
16 size_t segmentCount = (m_FlashSize + MAIN_SEGMENT_SIZE - 1) / MAIN_SEGMENT_SIZE;
17 m_Segments.resize(segmentCount);
22 TranslatedAddr addr = TranslateAddress(rawAddr);
26 return m_Segments[addr.Segment].SetBreakpoint(addr.Offset);
29 MSP430Proxy::SoftwareBreakpointManager::TranslatedAddr MSP430Proxy::SoftwareBreakpointManager::TranslateAddress(
unsigned addr )
31 TranslatedAddr result;
36 if (addr < m_FlashStart)
39 unsigned flashOff = addr - m_FlashStart;
40 if (flashOff >= m_FlashSize)
52 TranslatedAddr addr = TranslateAddress(rawAddr);
56 return m_Segments[addr.Segment].RemoveBreakpoint(addr.Offset);
59 bool MSP430Proxy::SoftwareBreakpointManager::SegmentRecord::SetBreakpoint(
unsigned offset )
61 switch(BpState[offset / 2])
63 case BreakpointActive:
64 case BreakpointPending:
66 case BreakpointInactive:
67 InactiveBreakpointCount--;
68 BpState[offset / 2] = BreakpointActive;
71 PendingBreakpointCount++;
72 BpState[offset / 2] = BreakpointPending;
79 bool MSP430Proxy::SoftwareBreakpointManager::SegmentRecord::RemoveBreakpoint(
unsigned offset )
81 switch(BpState[offset / 2])
83 case BreakpointActive:
84 InactiveBreakpointCount++;
85 BpState[offset / 2] = BreakpointInactive;
87 case BreakpointPending:
88 PendingBreakpointCount--;
89 BpState[offset / 2] = NoBreakpoint;
91 case BreakpointInactive:
101 for (
size_t i = 0; i < m_Segments.size(); i++)
103 if (!m_Segments[i].PendingBreakpointCount)
105 if (!m_bInstantCleanup || !m_Segments[i].InactiveBreakpointCount)
110 unsigned short data[MAIN_SEGMENT_SIZE / 2], data2[MAIN_SEGMENT_SIZE / 2];
111 if (MSP430_Read_Memory(segBase, (
char *)data,
sizeof(data)) != STATUS_OK)
114 bool eraseNeeded =
false;
116 for (
size_t j = 0; j < MAIN_SEGMENT_SIZE / 2; j++)
118 switch(m_Segments[i].BpState[j])
120 case BreakpointInactive:
121 m_Segments[i].BpState[j] = NoBreakpoint;
122 data[j] = m_Segments[i].OriginalInstructions[j];
125 case BreakpointPending:
126 m_Segments[i].BpState[j] = BreakpointActive;
127 m_Segments[i].OriginalInstructions[j] = data[j];
129 if ((data[j] & m_BreakInstruction) != m_BreakInstruction)
132 data[j] = m_BreakInstruction;
141 if (MSP430_Erase(ERASE_MAIN, segBase,
sizeof(data)) != STATUS_OK)
145 if (MSP430_Write_Memory(segBase, (
char *)data,
sizeof(data)) != STATUS_OK)
148 if (MSP430_Read_Memory(segBase, (
char *)data2,
sizeof(data2)) != STATUS_OK)
151 if (memcmp(data, data2,
sizeof(data)))
164 m_Segments[i].PendingBreakpointCount = 0;
165 m_Segments[i].InactiveBreakpointCount = 0;
173 TranslatedAddr addr = TranslateAddress(rawAddr);
177 return (
BreakpointState)m_Segments[addr.Segment].BpState[addr.Offset / 2];
182 TranslatedAddr addr = TranslateAddress(rawAddr);
186 switch (m_Segments[addr.Segment].BpState[addr.Offset / 2])
188 case BreakpointActive:
189 case BreakpointInactive:
190 *pInsn = m_Segments[addr.Segment].OriginalInstructions[addr.Offset / 2];
200 if (addr < m_FlashStart)
202 unsigned delta = m_FlashStart - addr;
209 pBlock = ((
char *)pBlock + delta);
212 int bufferOffsetInFlash = addr - m_FlashStart;
214 size_t indexInBlock = 0;
215 for (
size_t seg = bufferOffsetInFlash /
MAIN_SEGMENT_SIZE; seg < m_Segments.size(); seg++)
223 while (i < MAIN_SEGMENT_SIZE)
225 if (indexInBlock >= length)
228 switch(m_Segments[seg].BpState[i / 2])
230 case BreakpointActive:
231 case BreakpointInactive:
233 ((
char *)pBlock)[indexInBlock] = ((
char *)m_Segments[seg].OriginalInstructions)[i];
235 ((
char *)m_Segments[seg].OriginalInstructions)[i] = ((
char *)pBlock)[indexInBlock];