Skip to content

Commit 0310d43

Browse files
committed
Initial ARM Flash/Patch/Breakpoint unit support
1 parent 4b27604 commit 0310d43

File tree

8 files changed

+345
-168
lines changed

8 files changed

+345
-168
lines changed

ARMCortexM4.cpp

Lines changed: 2 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,7 @@ using namespace std;
4949
ARMCortexM4::ARMCortexM4(DebuggerInterface* iface, ARMDebugMemAccessPort* ap, uint32_t address, ARMDebugPeripheralIDRegisterBits idreg)
5050
: ARMv7MProcessor(iface, ap, address, idreg)
5151
{
52-
//LogTrace("Found ARM Cortex-M4 at %08x, probing...\n", address);
5352

54-
/*
55-
//DBGDSMCR turn off MMU
56-
57-
//TODO: Write to DBGDRCR to halt the CPU (C11.11.17)
58-
59-
//TODO: Write to DBGDSCCR to force write-through cache (C11.11.19)
60-
61-
//DBGDEVID[3:0] 2226
62-
*/
6353
}
6454

6555
ARMCortexM4::~ARMCortexM4()
@@ -78,61 +68,8 @@ void ARMCortexM4::PrintInfo()
7868
if(HaltedDueToUnrecoverableException())
7969
LogVerbose("Core is halted due to unrecoverable exception\n");
8070

81-
//LogTrace("asdf\n");
82-
83-
84-
/*
85-
PrintIDRegister(m_deviceID);
86-
87-
//Read DBGDSCR to get status stuff (TODO: make struct) for this
88-
//uint32_t dbgdscr = ReadRegisterByIndex(DBGDSCR_EXT);
89-
//LogDebug("DBGDSCR = %x\n", dbgdscr);
90-
91-
//Pins of interest are MIO bank 1, pins 50/51
92-
93-
//Read MCTRL
94-
95-
//Read PSS_IDCODE from the zynq
96-
//uint32_t pss_idcode = ReadMemory(0xF8000530);
97-
//LogDebug("pss_idcode = %08x\n", pss_idcode);
98-
99-
//Read MCTRL
100-
uint32_t mctrl = ReadMemory(0xF8007080);
101-
LogDebug("mctrl = %08x\n", mctrl);
102-
103-
//Set MIO7 (MIO LED) to output
104-
m_ap->GetDebugPort()->WriteMemory(0xf800071c, 0x00000600); //sclr.MIO_PIN_07
105-
m_ap->GetDebugPort()->WriteMemory(0xe000a204, 0x00000080); //gpio.XGPIOPS_DIRM_OFFSET
106-
m_ap->GetDebugPort()->WriteMemory(0xe000a208, 0x00000080); //gpio.XGPIOPS_OUTEN_OFFSET
107-
for(int i=0; i<10; i++)
108-
{
109-
LogDebug("toggle\n");
110-
m_ap->GetDebugPort()->WriteMemory(0xe000a040, 0x00000080); //gpio.XGPIOPS_DATA_OFFSET
111-
usleep(500 * 1000);
112-
m_ap->GetDebugPort()->WriteMemory(0xe000a040, 0x00000000); //gpio.XGPIOPS_DATA_OFFSET
113-
usleep(500 * 1000);
114-
}
115-
116-
//MIO LED @ MIO7
117-
//MIO inputs at MIO50, 51
118-
//GPIO controller is at 0xe000a000
119-
//Input data (DATA_RO) is at +0x60 - 6c
120-
//
121-
122-
//Read L0_SEL
123-
*/
124-
//Read the PC and dump the instruction at that address
125-
//uint32_t pc = SampleProgramCounter();
126-
//LogVerbose("PC = %08x\n", pc);
127-
128-
//DEBUG
129-
//EnterDebugState();
130-
131-
/*
132-
//uint32_t value = ReadMemory(0xE0000000);//m_ap->ReadWord(0x80000000); //ReadMemory(0xFC000000);
133-
134-
//LogDebug(" value = %08x\n", value);
135-
*/
71+
if(m_fpb)
72+
m_fpb->PrintInfo();
13673
}
13774

13875
string ARMCortexM4::GetDescription()

ARMDebugMemAccessPort.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,32 @@ void ARMDebugMemAccessPort::ProcessDebugBlock(uint32_t base_address, uint32_t id
403403
//Handle fully supported devices first, then just make a generic CoreSight device for the rest
404404
switch(reg.bits.partnum)
405405
{
406+
//Cortex-M4 FPB
407+
case 0x003:
408+
{
409+
//Find the CPU it goes to
410+
ARMv7MProcessor* cpu = NULL;
411+
for(size_t i=m_debugDevices.size() - 1; ; i--)
412+
{
413+
cpu = dynamic_cast<ARMv7MProcessor*>(m_debugDevices[i]);
414+
if(cpu)
415+
break;
416+
if(i == 0)
417+
break;
418+
}
419+
420+
if(!cpu)
421+
{
422+
LogError("Found Cortex-M4 Flash Patch/Breakpoint unit but unable to match it to a CPU core");
423+
return;
424+
}
425+
426+
//Create the FPB unit and attach it to the CPU (rather than having it show up as a separate device)
427+
ARMFlashPatchBreakpoint* fpb = new ARMFlashPatchBreakpoint(cpu, this, base_address, reg.bits);
428+
cpu->AddFlashPatchUnit(fpb);
429+
};
430+
break;
431+
406432
//Cortex-M4 SCS
407433
case 0x00c:
408434
{

ARMFlashPatchBreakpoint.cpp

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
/***********************************************************************************************************************
2+
* *
3+
* ANTIKERNEL v0.1 *
4+
* *
5+
* Copyright (c) 2012-2018 Andrew D. Zonenberg *
6+
* All rights reserved. *
7+
* *
8+
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the *
9+
* following conditions are met: *
10+
* *
11+
* * Redistributions of source code must retain the above copyright notice, this list of conditions, and the *
12+
* following disclaimer. *
13+
* *
14+
* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the *
15+
* following disclaimer in the documentation and/or other materials provided with the distribution. *
16+
* *
17+
* * Neither the name of the author nor the names of any contributors may be used to endorse or promote products *
18+
* derived from this software without specific prior written permission. *
19+
* *
20+
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
21+
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
22+
* THE AUTHORS BE HELD LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
23+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR *
24+
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
25+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
26+
* POSSIBILITY OF SUCH DAMAGE. *
27+
* *
28+
***********************************************************************************************************************/
29+
30+
/**
31+
@file
32+
@author Andrew D. Zonenberg
33+
@brief ARM Cortex-M Flash Patch/Breakpoint
34+
*/
35+
#include "jtaghal.h"
36+
#include "ARMAPBDevice.h"
37+
#include "ARMFlashPatchBreakpoint.h"
38+
39+
using namespace std;
40+
41+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
42+
// Construction / destruction
43+
44+
ARMFlashPatchBreakpoint::ARMFlashPatchBreakpoint(
45+
ARMv7MProcessor* cpu,
46+
ARMDebugMemAccessPort* ap,
47+
uint32_t address,
48+
ARMDebugPeripheralIDRegisterBits idreg)
49+
: ARMCoreSightDevice(ap, address, idreg)
50+
, m_cpu(cpu)
51+
{
52+
//Assume RAM is at 0x20000000 for now.
53+
//TODO: is this always true for Cortex-M's?
54+
m_sramBase = 0x20000000;
55+
56+
//Read the control register to get read-only config
57+
uint32_t ctrl = ReadRegisterByIndex(FP_CTRL);
58+
m_literalComparators = (ctrl >> 8) & 0xf;
59+
m_codeComparators = ( (ctrl >> 4) & 0xf ) | ( (ctrl >> 8) & 0xf0 );
60+
61+
//Read the remap register to see if we can remap or just to breakpoints
62+
uint32_t remap = ReadRegisterByIndex(FP_REMAP);
63+
m_canRemap = false;
64+
if(remap & 0x20000000)
65+
m_canRemap = true;
66+
67+
//Pull volatile config
68+
ProbeStatusRegisters();
69+
}
70+
71+
ARMFlashPatchBreakpoint::~ARMFlashPatchBreakpoint()
72+
{
73+
}
74+
75+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
76+
// Pretty printing
77+
78+
void ARMFlashPatchBreakpoint::ProbeStatusRegisters()
79+
{
80+
uint32_t ctrl = ReadRegisterByIndex(FP_CTRL);
81+
m_enabled = (ctrl & 1) ? true : false;
82+
83+
uint32_t remap = ReadRegisterByIndex(FP_REMAP);
84+
m_tableBase = (remap & 0x1FFFFFE0) | m_sramBase;
85+
}
86+
87+
void ARMFlashPatchBreakpoint::PrintInfo()
88+
{
89+
ProbeStatusRegisters();
90+
91+
//Heading
92+
LogNotice("%s rev %d.%d.%d\n",
93+
GetDescription().c_str(),
94+
m_idreg.revnum, m_idreg.cust_mod, m_idreg.revand);
95+
LogIndenter li;
96+
97+
//LogNotice("Attached to CPU: %s\n", m_cpu->GetDescription().c_str());
98+
99+
//Summary
100+
if(m_enabled)
101+
LogNotice("FPB enabled\n");
102+
else
103+
LogNotice("FPB disabled\n");
104+
105+
if(m_canRemap)
106+
{
107+
LogNotice("Remap supported\n");
108+
LogNotice("Remap table is at 0x%08x\n", m_tableBase);
109+
}
110+
else
111+
LogNotice("Remap not supported, breakpoints only\n");
112+
113+
//Code
114+
LogNotice("%d code comparators\n", m_codeComparators);
115+
for(uint32_t i=0; i<m_codeComparators; i++)
116+
{
117+
LogIndenter li2;
118+
}
119+
120+
//Literals
121+
LogNotice("%d literal comparators\n", m_literalComparators);
122+
}
123+
124+
string ARMFlashPatchBreakpoint::GetDescription()
125+
{
126+
switch(m_idreg.partnum)
127+
{
128+
case 0x003:
129+
return "Cortex-M4 Flash Patch/Breakpoint";
130+
131+
default:
132+
LogWarning("Unknown ARM FPB device (part number 0x%x)\n", m_idreg.partnum);
133+
return "unknown FPB device";
134+
}
135+
}
136+
137+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
138+
// Fun commands that actually do stuff
139+
140+
void ARMFlashPatchBreakpoint::Enable()
141+
{
142+
uint32_t ctrl = ReadRegisterByIndex(FP_CTRL);
143+
ctrl |= 1; //set ENABLE
144+
ctrl |= 2; //must also set KEY for writes to take effect
145+
WriteRegisterByIndex(FP_CTRL, ctrl);
146+
147+
m_enabled = true;
148+
}
149+
150+
void ARMFlashPatchBreakpoint::Disable()
151+
{
152+
uint32_t ctrl = ReadRegisterByIndex(FP_CTRL);
153+
ctrl &= ~1; //clear ENABLE
154+
ctrl |= 2; //must also set KEY for writes to take effect
155+
WriteRegisterByIndex(FP_CTRL, ctrl);
156+
157+
m_enabled = false;
158+
}
159+
160+
void ARMFlashPatchBreakpoint::SetRemapTableBase(uint32_t base)
161+
{
162+
//TODO: Sanity check that address is within SRAM region
163+
164+
//Align to 8 word boundary
165+
base &= 0x1FFFFFE0;
166+
WriteRegisterByIndex(FP_REMAP, base);
167+
168+
//Save the actual address including SRAM offset
169+
m_tableBase = base | m_sramBase;
170+
}
171+
172+
void ARMFlashPatchBreakpoint::RemapFlashWord(uint32_t slot, uint32_t flashAddress, uint32_t newValue)
173+
{
174+
if(flashAddress & 3)
175+
{
176+
LogWarning("ARM FPB requres word-aligned address\n");
177+
return;
178+
}
179+
180+
//Write the patched data to the remap table
181+
m_ap->WriteWord(m_tableBase + slot*4, newValue);
182+
183+
//Write to FP_COMPx to enable the comparator. Mask off unused address bits.
184+
flashAddress &= 0x1ffffffc;
185+
WriteRegisterByIndex(GetCodeComparatorIndex(slot), flashAddress | 1);
186+
}

ARMFlashPatchBreakpoint.h

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/***********************************************************************************************************************
2+
* *
3+
* ANTIKERNEL v0.1 *
4+
* *
5+
* Copyright (c) 2012-2018 Andrew D. Zonenberg *
6+
* All rights reserved. *
7+
* *
8+
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the *
9+
* following conditions are met: *
10+
* *
11+
* * Redistributions of source code must retain the above copyright notice, this list of conditions, and the *
12+
* following disclaimer. *
13+
* *
14+
* * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the *
15+
* following disclaimer in the documentation and/or other materials provided with the distribution. *
16+
* *
17+
* * Neither the name of the author nor the names of any contributors may be used to endorse or promote products *
18+
* derived from this software without specific prior written permission. *
19+
* *
20+
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
21+
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL *
22+
* THE AUTHORS BE HELD LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES *
23+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR *
24+
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT *
25+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
26+
* POSSIBILITY OF SUCH DAMAGE. *
27+
* *
28+
***********************************************************************************************************************/
29+
30+
/**
31+
@file
32+
@author Andrew D. Zonenberg
33+
@brief ARMv7-M Flash Patch/Breakpoint Unit
34+
*/
35+
#ifndef ARMFlashPatchBreakpoint_h
36+
#define ARMFlashPatchBreakpoint_h
37+
38+
class ARMv7MProcessor;
39+
40+
class ARMFlashPatchBreakpoint : public ARMCoreSightDevice
41+
{
42+
public:
43+
ARMFlashPatchBreakpoint(
44+
ARMv7MProcessor* cpu,
45+
ARMDebugMemAccessPort* ap,
46+
uint32_t address,
47+
ARMDebugPeripheralIDRegisterBits idreg);
48+
virtual ~ARMFlashPatchBreakpoint();
49+
50+
virtual std::string GetDescription();
51+
virtual void PrintInfo();
52+
53+
enum FpbRegisters
54+
{
55+
FP_CTRL = 0,
56+
FP_REMAP = 1,
57+
FP_COMP0 = 2 //plus comparator number
58+
};
59+
60+
uint32_t GetCodeComparatorIndex(uint32_t i)
61+
{ return FP_COMP0 + i; }
62+
63+
uint32_t GetLiteralComparatorIndex(uint32_t i)
64+
{ return FP_COMP0 + m_codeComparators + i; }
65+
66+
uint32_t GetCodeComparatorCount()
67+
{ return m_codeComparators; }
68+
69+
uint32_t GetLiteralComparatorCount()
70+
{ return m_literalComparators; }
71+
72+
void Enable();
73+
void Disable();
74+
75+
void SetRemapTableBase(uint32_t base);
76+
void RemapFlashWord(uint32_t slot, uint32_t flashAddress, uint32_t newValue);
77+
//TODO: literal comparator support
78+
79+
protected:
80+
ARMv7MProcessor* m_cpu;
81+
82+
uint32_t m_codeComparators;
83+
uint32_t m_literalComparators;
84+
bool m_enabled;
85+
bool m_canRemap;
86+
uint32_t m_tableBase;
87+
uint32_t m_sramBase;
88+
89+
void ProbeStatusRegisters();
90+
};
91+
92+
#endif

0 commit comments

Comments
 (0)