Skip to content

Commit

Permalink
Continued work on STM32 support. Fixed lots of bugs.
Browse files Browse the repository at this point in the history
  • Loading branch information
azonenberg committed Jul 17, 2018
1 parent 29186dd commit 3ceae70
Show file tree
Hide file tree
Showing 9 changed files with 179 additions and 58 deletions.
2 changes: 1 addition & 1 deletion ARMCoreSightDevice.cpp
Expand Up @@ -59,7 +59,7 @@ string ARMCoreSightDevice::GetDescription()
switch(m_idreg.partnum)
{
case 0x003:
return "Cortex-M3/M4 Data Watchpoint/Trace";
return "Cortex-M4 Flash Patch/Breakpoint";
case 0x00c:
return "Cortex-M4 System Control Space";
case 0x906:
Expand Down
10 changes: 8 additions & 2 deletions ARMCortexM4.cpp
Expand Up @@ -49,8 +49,7 @@ using namespace std;
ARMCortexM4::ARMCortexM4(ARMDebugMemAccessPort* ap, uint32_t address, ARMDebugPeripheralIDRegisterBits idreg)
: ARMv7MProcessor(ap, address, idreg)
{
LogTrace("Found ARM Cortex-M4 at %08x, probing...\n", address);
LogIndenter li;
//LogTrace("Found ARM Cortex-M4 at %08x, probing...\n", address);

/*
//DBGDSMCR turn off MMU
Expand All @@ -75,6 +74,13 @@ void ARMCortexM4::PrintInfo()
{
LogVerbose("%s\n", GetDescription().c_str());
LogIndenter li;

if(HaltedDueToUnrecoverableException())
LogVerbose("Core is halted due to unrecoverable exception\n");

//LogTrace("asdf\n");


/*
PrintIDRegister(m_deviceID);
Expand Down
33 changes: 26 additions & 7 deletions ARMDebugMemAccessPort.cpp
Expand Up @@ -35,7 +35,6 @@

#include "jtaghal.h"
#include "ARMAPBDevice.h"
#include "ARMCortexA9.h"
#include "ARMDebugPort.h"
#include "ARMDebugAccessPort.h"
#include "ARMDebugMemAccessPort.h"
Expand Down Expand Up @@ -207,8 +206,6 @@ void ARMDebugMemAccessPort::LoadROMTable(uint32_t baseAddress)
uint32_t entry = ReadWord(baseAddress + i*4);
if(entry == 0)
break;
LogTrace("i=%d, entry=%08x\n", i, entry);
LogIndenter li;

//If we hit 959 and it's not a terminator, something is wrong - should not be this many entries
if(i == 959)
Expand Down Expand Up @@ -238,17 +235,18 @@ void ARMDebugMemAccessPort::LoadROMTable(uint32_t baseAddress)

//Walk this table entry
uint32_t compid_raw[4];
for(int i=0; i<4; i++)
compid_raw[i] = ReadWord(address + 0xff0 + 4*i);
for(int j=0; j<4; j++)
compid_raw[j] = ReadWord(address + 0xff0 + 4*j);
uint32_t compid =
((compid_raw[3] & 0xff) << 24) |
((compid_raw[2] & 0xff) << 16) |
((compid_raw[1] & 0xff) << 8) |
(compid_raw[0] & 0xff);

LogTrace("address = %08x\n", address);
LogTrace("ID registers = %08x %08x %08x %08x\n", compid_raw[0], compid_raw[1], compid_raw[2], compid_raw[3]);
LogIndenter li;

//Look up the peripheral ID
//Look up peripheral ID
uint64_t periphid_raw[8];
for(int i=0; i<4; i++)
periphid_raw[i] = ReadWord(address + 0xfe0 + 4*i);
Expand All @@ -264,6 +262,18 @@ void ARMDebugMemAccessPort::LoadROMTable(uint32_t baseAddress)
(periphid_raw[2] << 16) |
(periphid_raw[1] << 8) |
(periphid_raw[0] << 0);

//Debug prints
if(i > 0)
{
for(int j=0; j<12; j++)
{
uint32_t base = address + 0xfd0 + 4*j;
uint32_t val = ReadWord(base);
LogTrace("0x%08x => 0x%08x\n", base, val);
}
}

/*{
LogTrace("Peripheral ID:\n");
LogIndenter li;
Expand Down Expand Up @@ -376,6 +386,15 @@ void ARMDebugMemAccessPort::ProcessDebugBlock(uint32_t base_address, uint32_t id
//Handle fully supported devices first, then just make a generic CoreSight device for the rest
switch(reg.bits.partnum)
{
//Cortex-M4 SCS
case 0x00c:
{
ARMCortexM4* cortex = new ARMCortexM4(this, base_address, reg.bits);
m_dp->AddTarget(cortex);
m_debugDevices.push_back(cortex);
}
break;

//Cortex-A9
case 0xC09:
{
Expand Down
3 changes: 0 additions & 3 deletions ARMDebugPort.cpp
Expand Up @@ -462,12 +462,9 @@ uint32_t ARMDebugPort::APRegisterRead(uint8_t ap, ApReg addr)
DebugAbort();
ClearStatusRegisterErrors();

//

throw JtagExceptionWrapper(
"Failed to read AP register",
"");
exit(1);
}

return data_out;
Expand Down
38 changes: 28 additions & 10 deletions ARMv7MProcessor.cpp
Expand Up @@ -49,7 +49,7 @@ using namespace std;
ARMv7MProcessor::ARMv7MProcessor(ARMDebugMemAccessPort* ap, uint32_t address, ARMDebugPeripheralIDRegisterBits idreg)
: ARMAPBDevice(ap, address, idreg)
{
LogTrace("Found ARMv7-M processor at %08x, probing...\n", address);
//LogTrace("Found ARMv7-M processor at %08x, probing...\n", address);

/*
//Read the Debug ID register and extract flags
Expand Down Expand Up @@ -140,29 +140,47 @@ uint32_t ARMv7MProcessor::ReadMemory(uint32_t addr)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Debugging

/**
@brief Checks if the CPU is halted due to a fatal error
*/
bool ARMv7MProcessor::HaltedDueToUnrecoverableException()
{
uint32_t dhcsr = ReadRegisterByIndex(DHCSR);
if( (dhcsr >> 19) & 1)
return true;
return false;
}

uint32_t ARMv7MProcessor::ReadCPURegister(ARM_V7M_CPU_REGISTERS reg)
{
//TODO
return 0;
}

/**
@brief Halts the CPU and enters debug state
See ARMv7M-A/R arch ref manual XXX
See ARMv7-M arch manual C1-6
*/
void ARMv7MProcessor::EnterDebugState()
{
/*
//Request a halt by writing to DBGDRCR.HRQ
LogTrace("Halting CPU to enter debug state...\n");
LogIndenter li;
WriteRegisterByIndex(DBGDRCR, 0x00000001);

//Poll DBGDSCR.HALTED until it gets to 1
//Set C_DEBUGEN and C_HALT on consecutive writes
//TODO: can we do both at once?
WriteRegisterByIndex(DHCSR, 0xa05f0001);
WriteRegisterByIndex(DHCSR, 0xa05f0003);

//Poll DHCSR.S_HALT until the CPU stops
while(true)
{
uint32_t v = ReadRegisterByIndex(DBGDSCR_EXT);
LogTrace("DBGDSCR = %08x\n", v);
if(v & 1)
uint32_t dhcsr = ReadRegisterByIndex(DHCSR);
if(dhcsr & 0x00010000)
break;
LogTrace("DHCSR = %08x\n", dhcsr);
usleep(1000);
}
*/
}

void ARMv7MProcessor::ExitDebugState()
Expand Down
74 changes: 72 additions & 2 deletions ARMv7MProcessor.h
Expand Up @@ -55,9 +55,72 @@ class ARMv7MProcessor : public DebuggableDevice
// Registers

//register numbers, multiply by 4 to get address
enum ARM_V7M_DEBUG_REGISTERS
enum ARM_V7M_SCS_REGISTERS
{
//DBGDIDR = 0,
ACTLR = 0x0002, //Auxiliary Control Register
STCSR = 0x0004, //SysTick Control/Status Register
STRVR = 0x0005, //SysTick Reload Value Register
STCVR = 0x0006, //SysTick Current Value Register
STCR = 0x0007, //SysTick Calibration Value Register
CPUID = 0x0340, //CPU identifier
ICSR = 0x0341, //Interrupt Control and State Register
VTOR = 0x0342, //Vector Table Offset Register
AIRCR = 0x0343, //Application Interrupt and Reset Control Register
SCR = 0x0344, //System Control Register
CCR = 0x0345, //Configuration and Control Register
SHPR1 = 0x0346, //System Handler Priority Register 1
SHPR2 = 0x0347, //System Handler Priority Register 2
SHPR3 = 0x0348, //System Handler Priority Register 3
SHCSR = 0x0349, //System Handler Control and State Register
CFSR = 0x034a, //Configurable Fault Status Register
HFSR = 0x034b, //Hard Fault Status Register
DFSR = 0x034c, //Debug Fault Status Register
MMFAR = 0x034d, //MemManage Address Register
BFAR = 0x034e, //BusFault Address Register
AFSR = 0x034f, //Auxiliary Fault Status Register
ID_PFR0 = 0x0350, //Processor Feature Register 0
ID_PFR1 = 0x0351, //Processor Feature Register 1
ID_DFR0 = 0x0352, //Debug Features Register 0
ID_AFR0 = 0x0353, //Auxiliary Features Register 0
ID_MMFR0 = 0x0354, //Memory Model Features Register 0
ID_MMFR1 = 0x0355, //Memory Model Features Register 1
ID_MMFR2 = 0x0356, //Memory Model Features Register 2
ID_MMFR3 = 0x0357, //Memory Model Features Register 3
ID_ISAR0 = 0x0358, //Instruction Set Attributes Register 0
ID_ISAR1 = 0x0359, //Instruction Set Attributes Register 1
ID_ISAR2 = 0x035a, //Instruction Set Attributes Register 2
ID_ISAR3 = 0x035b, //Instruction Set Attributes Register 3
ID_ISAR4 = 0x035c, //Instruction Set Attributes Register 4
CPACR = 0x0362, //Coprocessor Access Control Register
DHCSR = 0x037c, //Debug Halting Control/Status Register
DCRSR = 0x037d, //Debug Core Register Selector
DEMCR = 0x037f, //Debug Exception Monitor Control Register
STIR = 0x03c0 //Software Triggered Interrupt Register
};

//register numbers for DCRSR
enum ARM_V7M_CPU_REGISTERS
{
R0 = 0,
R1 = 1,
R2 = 2,
R3 = 3,
R4 = 4,
R5 = 5,
R6 = 6,
R7 = 7,
R8 = 8,
R9 = 9,
R10 = 10,
R11 = 11,
R12 = 12,
SP = 13, //current stack pointer
LR = 14, //link register
DBGRA = 15, //debug return address
XPSR = 16, //flags etc
MSP = 17, //main SP
PSP = 18, //process SP
CTRL = 20 //{CONTROL, FAULTMASK, BASEPRI, PRIMASK}
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand All @@ -66,11 +129,18 @@ class ARMv7MProcessor : public DebuggableDevice
virtual std::string GetDescription() =0;
virtual void PrintInfo() =0;

bool HaltedDueToUnrecoverableException();

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Memory access via the default (AHB) MEM-AP

virtual uint32_t ReadMemory(uint32_t addr);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// CPU register access

uint32_t ReadCPURegister(ARM_V7M_CPU_REGISTERS reg);

protected:
//void PrintIDRegister(ARMv7MDebugIDRegister did);

Expand Down
5 changes: 5 additions & 0 deletions LockableDevice.h
Expand Up @@ -135,6 +135,11 @@ class LockableDevice
*/
virtual UncertainBoolean IsDeviceReadLocked() =0;

/**
@brief Prints detailed information regarding the state of the read lock
*/
virtual void PrintLockProbeDetails() =0;

/**
@brief Sets a global read-protection lock on the entire device.
Expand Down
71 changes: 38 additions & 33 deletions STM32Device.cpp
Expand Up @@ -67,6 +67,39 @@ STM32Device::STM32Device(
//uint32_t id = m_dap->ReadMemory(0xe0042000);
//LogDebug("id = %08x\n", id);

//TODO: How portable are these addresses?
m_flashSfrBase = 0x40023C00;
m_flashMemoryBase = 0x08000000;
m_sramMemoryBase = 0x20000000;

//Look up size of flash memory
try
{
m_flashKB = m_dap->ReadMemory(0x1fff7a20) >> 16; //F_ID, flash size in kbytes
}
catch(const JtagException& e)
{
//If we fail, set flash size to zero so we don't try doing anything with it
m_flashKB = 0;

if(!IsDeviceReadLocked().GetValue())
LogWarning("STM32Device: Unable to read flash memory size even though read protection doesn't seem to be set\n");

else
LogNotice("STM32Device: Cannot determine flash size because read protection is set\n");
}

//Look up RAM size (TODO can we get this from descriptors somehow?)
switch(devid)
{
case STM32F411E:
m_ramKB = 128;
break;

default:
m_ramKB = 0;
}

//Check read lock status
m_locksProbed = false;
STM32Device::ProbeLocksNondestructive();
Expand Down Expand Up @@ -115,39 +148,6 @@ STM32Device::STM32Device(
else
LogNotice("STM32Device: Cannot determine serial number because read protection is set\n");
}

//Look up size of flash memory
try
{
m_flashKB = m_dap->ReadMemory(0x1fff7a20) >> 16; //F_ID, flash size in kbytes
}
catch(const JtagException& e)
{
//If we fail, set flash size to zero so we don't try doing anything with it
m_flashKB = 0;

if(!IsDeviceReadLocked().GetValue())
LogWarning("STM32Device: Unable to read flash memory size even though read protection doesn't seem to be set\n");

else
LogNotice("STM32Device: Cannot determine flash size because read protection is set\n");
}

//TODO: How portable are these addresses?
m_flashSfrBase = 0x40023C00;
m_flashMemoryBase = 0x08000000;
m_sramMemoryBase = 0x20000000;

//Look up RAM size (TODO can we get this from descriptors somehow?)
switch(devid)
{
case STM32F411E:
m_ramKB = 128;
break;

default:
m_ramKB = 0;
}
}

/**
Expand Down Expand Up @@ -236,6 +236,11 @@ bool STM32Device::IsProgrammed()
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Lock bit access

void STM32Device::PrintLockProbeDetails()
{

}

void STM32Device::ProbeLocksNondestructive()
{
//Don't poke more than once
Expand Down
1 change: 1 addition & 0 deletions STM32Device.h
Expand Up @@ -108,6 +108,7 @@ class STM32Device
virtual UncertainBoolean IsDeviceReadLocked();
virtual void SetReadLock();
virtual void ClearReadLock();
virtual void PrintLockProbeDetails();

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Helpers for chain manipulation
Expand Down

0 comments on commit 3ceae70

Please sign in to comment.