Skip to content

Commit

Permalink
Lots of debugging and bringup on ARM memory debug. Still working on f…
Browse files Browse the repository at this point in the history
…iguring things out.
  • Loading branch information
azonenberg committed May 8, 2018
1 parent 0d6755d commit 031216b
Show file tree
Hide file tree
Showing 7 changed files with 204 additions and 71 deletions.
25 changes: 21 additions & 4 deletions ARMCortexA9.cpp
Expand Up @@ -70,20 +70,37 @@ ARMCortexA9::ARMCortexA9(ARMDebugMemAccessPort* ap, uint32_t address, ARMDebugPe
//Print it out
PrintIDRegister(did);

//DBGDSMCR turn off MMU

//TODO: Write to DBGDRCR to halt the CPU (C11.11.17)

//TODO: Write to DBGDSCCR to force write-through cache (C11.11.19)

//DBGDEVID[3:0] 2226

//Read DBGDSCR to get status stuff (TODO: make struct) for this
//uint32_t foo = ReadRegisterByIndex(DBGDSCR_EXT);
//LogDebug("foo = %x\n", foo);
//uint32_t dbgdscr = ReadRegisterByIndex(DBGDSCR_EXT);
//LogDebug("DBGDSCR = %x\n", dbgdscr);

//Pins of interest are MIO bank 1, pins 50/51

//Read PSS_IDCODE
//uint32_t pss_idcode = ReadMemory(0xF8000530);
//uint32_t pss_idcode = m_ap->ReadWord(0xF8000530);
//LogDebug("pss_idcode = %08x\n", pss_idcode);

//MIO LED @ MIO7
//MIO inputs at MIO50, 51
//GPIO controller is at 0xe0000000
//Read DIRM to see what
//Read DATA_RO?

//Read L0_SEL

//

//Read the PC and dump the instruction at that address
//uint32_t pc = SampleProgramCounter();
uint32_t pc = SampleProgramCounter();
LogDebug("PC = %08x\n", pc);
//uint32_t value = ReadMemory(0xE0000000);//m_ap->ReadWord(0x80000000); //ReadMemory(0xFC000000);

//LogDebug(" value = %08x\n", value);
Expand Down
1 change: 1 addition & 0 deletions ARMCortexA9.h
Expand Up @@ -249,6 +249,7 @@ class ARMCortexA9 : public DebuggableDevice
DBGLAR = 1004,
DBGLSR = 1005,
DBGAUTHSTATUS = 1006,
DBGDEVID = 1010
};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down
2 changes: 2 additions & 0 deletions ARMDebugAccessPort.h
Expand Up @@ -85,6 +85,8 @@ class ARMDebugAccessPort
ARMDebugAccessPort(ARMDebugPort* dp, uint8_t apnum, ARMDebugPortIDRegister id);
virtual ~ARMDebugAccessPort();

virtual void Initialize() =0;

enum dap_type
{
DAP_JTAG = 0,
Expand Down
82 changes: 50 additions & 32 deletions ARMDebugMemAccessPort.cpp
Expand Up @@ -63,14 +63,21 @@ ARMDebugMemAccessPort::ARMDebugMemAccessPort(ARMDebugPort* dp, uint8_t apnum, AR
"Invalid DAP type",
"");
}
}

void ARMDebugMemAccessPort::Initialize()
{
//If we're enabled, try to load the ROM (if any)
ARMDebugMemAPControlStatusWord csw = GetStatusRegister();
if(csw.bits.enable)
{
LogDebug("Searching for debug ROMs in AP %d (%s)...\n", m_apnum, (m_daptype == DAP_AHB) ? "AHB" : "APB");
LogIndenter li;
FindRootRomTable();
if(m_hasDebugRom)
LoadROMTable(m_debugBaseAddress);
else
LogDebug("No debug ROM found\n");
}

//Looks like the AHB DAP for Zynq is used for main system memory access
Expand All @@ -96,18 +103,20 @@ bool ARMDebugMemAccessPort::IsEnabled()
void ARMDebugMemAccessPort::PrintStatusRegister()
{
ARMDebugMemAPControlStatusWord csw = GetStatusRegister();
LogDebug(" Status register for AP %u:\n", m_apnum);
LogIndenter li;
LogDebug("Status register for AP %u:\n", m_apnum);
LogIndenter li2;
if(csw.bits.size >= ACCESS_INVALID)
LogDebug(" Size : UNDEFINED\n");
LogDebug("Size : UNDEFINED\n");
else
LogDebug(" Size : %s\n", g_cswLenNames[csw.bits.size]);
LogDebug(" Auto inc : %u\n", csw.bits.auto_increment);
LogDebug(" Enable : %u\n", csw.bits.enable);
LogDebug(" Busy : %u\n", csw.bits.busy);
LogDebug(" Mode : %u\n", csw.bits.mode);
LogDebug(" Secure debug : %u\n", csw.bits.secure_priv_debug);
LogDebug(" Bus protection: %u\n", csw.bits.bus_protect);
LogDebug(" Debug SW : %u\n", csw.bits.debug_sw_enable);
LogDebug("Size : %s\n", g_cswLenNames[csw.bits.size]);
LogDebug("Auto inc : %u\n", csw.bits.auto_increment);
LogDebug("Enable : %u\n", csw.bits.enable);
LogDebug("Busy : %u\n", csw.bits.busy);
LogDebug("Mode : %u\n", csw.bits.mode);
LogDebug("Secure debug : %u\n", csw.bits.secure_priv_debug);
LogDebug("Bus protection : %u\n", csw.bits.bus_protect);
LogDebug("Nonsecure transfer : %u\n", csw.bits.nonsecure_transfer);
}

string ARMDebugMemAccessPort::GetDescription()
Expand All @@ -134,11 +143,13 @@ uint32_t ARMDebugMemAccessPort::ReadWord(uint32_t addr)
return m_dp->APRegisterRead(m_apnum, ARMDebugPort::REG_MEM_DRW);
}

void ARMDebugMemAccessPort::WriteWord(uint32_t /*addr*/, uint32_t /*value*/)
void ARMDebugMemAccessPort::WriteWord(uint32_t addr, uint32_t value)
{
throw JtagExceptionWrapper(
"WriteWord() not yet implemented",
"");
//Write the address
m_dp->APRegisterWrite(m_apnum, ARMDebugPort::REG_MEM_TAR, addr);

//Write data
m_dp->APRegisterWrite(m_apnum, ARMDebugPort::REG_MEM_DRW, value);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -177,6 +188,9 @@ void ARMDebugMemAccessPort::FindRootRomTable()

void ARMDebugMemAccessPort::LoadROMTable(uint32_t baseAddress)
{
LogDebug("Loading ROM table at address %08x\n", baseAddress);
LogIndenter li;

//Read ROM table entries until we get to an invalid one
for(int i=0; i<960; i++)
{
Expand Down Expand Up @@ -247,8 +261,11 @@ void ARMDebugMemAccessPort::LoadROMTable(uint32_t baseAddress)

//Additional ROM table
case CLASS_ROMTABLE:
//LogDebug("Found extra ROM table at 0x%08x, loading\n", address);
LoadROMTable(address);
{
LogDebug("Found extra ROM table at 0x%08x, loading\n", address);
LogIndenter li;
LoadROMTable(address);
}
break;

//Don't know what to do with anything else
Expand Down Expand Up @@ -298,9 +315,10 @@ void ARMDebugMemAccessPort::ProcessDebugBlock(uint32_t base_address)
"");
}

//unsigned int blockcount = (1 << reg.bits.log_4k_blocks);
//LogDebug("Found debug component at %08x (rev/mod/step %u/%u/%u, %u 4KB pages)\n",
// base_address, reg.bits.revnum, reg.bits.cust_mod, reg.bits.revand, blockcount);
unsigned int blockcount = (1 << reg.bits.log_4k_blocks);
LogDebug("Found debug component at %08x (rev/mod/step %u/%u/%u, %u 4KB pages)\n",
base_address, reg.bits.revnum, reg.bits.cust_mod, reg.bits.revand, blockcount);
LogIndenter li;

//Check IDCODE for Xilinx
if( (reg.bits.jep106_cont == 0x00) && (reg.bits.jep106_id == 0x49) )
Expand All @@ -310,12 +328,12 @@ void ARMDebugMemAccessPort::ProcessDebugBlock(uint32_t base_address)
//See Xilinx UG585 page 729 table 28-5
if(reg.bits.partnum == 0x001)
{
//LogDebug(" Xilinx Fabric Trace Monitor\n");
LogDebug("Xilinx Fabric Trace Monitor\n");
}

//unknown, skip it
else
LogWarning(" Unknown Xilinx device (part number 0x%x)\n", reg.bits.partnum);
LogWarning("Unknown Xilinx device (part number 0x%x)\n", reg.bits.partnum);

}

Expand All @@ -325,37 +343,37 @@ void ARMDebugMemAccessPort::ProcessDebugBlock(uint32_t base_address)
switch(reg.bits.partnum)
{
case 0x906:
//LogDebug(" CoreSight Cross Trigger Interface\n");
LogDebug("CoreSight Cross Trigger Interface\n");
break;

case 0x907:
//LogDebug(" CoreSight Embedded Trace Buffer\n");
LogDebug("CoreSight Embedded Trace Buffer\n");
break;

case 0x908:
//LogDebug(" CoreSight Trace Funnel\n");
LogDebug("CoreSight Trace Funnel\n");
break;

case 0x912:
//LogDebug(" CoreSight Trace Port Interface Unit\n");
LogDebug("CoreSight Trace Port Interface Unit\n");
break;

//ID is 913, not 914. CoreSight Components TRM is wrong.
//See ARM #TAC650738
case 0x913:
//LogDebug(" CoreSight Instrumentation Trace Macrocell\n");
LogDebug("CoreSight Instrumentation Trace Macrocell\n");
break;

case 0x914:
//LogDebug(" CoreSight Serial Wire Output\n");
LogDebug("CoreSight Serial Wire Output\n");
break;

case 0x950:
//LogDebug(" Cortex-A9 Program Trace Macrocell\n");
LogDebug("Cortex-A9 Program Trace Macrocell\n");
break;

case 0x9A0:
//LogDebug(" Cortex-A9 Performance Monitoring Unit\n");
LogDebug("Cortex-A9 Performance Monitoring Unit\n");
break;

case 0xC09:
Expand All @@ -367,21 +385,21 @@ void ARMDebugMemAccessPort::ProcessDebugBlock(uint32_t base_address)
break;

default:
LogWarning(" Unknown ARM device (part number 0x%x)\n", reg.bits.partnum);
LogWarning("Unknown ARM device (part number 0x%x)\n", reg.bits.partnum);
break;
}
}

//Check IDCODE for Switchcore (?)
else if( (reg.bits.jep106_cont == 0x03) && (reg.bits.jep106_id == 0x09) )
{
//LogWarning(" Unknown Switchcore device (part number 0x%x)\n", reg.bits.partnum);
//LogWarning("Unknown Switchcore device (part number 0x%x)\n", reg.bits.partnum);
}

//Unknown vendor
else
{
LogWarning(" Unknown device (JEP106 %u:%x, part number 0x%x)\n",
LogWarning("Unknown device (JEP106 %u:%x, part number 0x%x)\n",
reg.bits.jep106_cont, reg.bits.jep106_id, reg.bits.partnum);
}
}
12 changes: 9 additions & 3 deletions ARMDebugMemAccessPort.h
Expand Up @@ -70,10 +70,13 @@ union ARMDebugMemAPControlStatusWord
unsigned int secure_priv_debug:1;

///Bus access protection (implementation defined)
unsigned int bus_protect:7;
unsigned int bus_protect:6;

///Debug software access enable (implementation defined)
unsigned int debug_sw_enable:1;
///Secure transfer (high=nonsecure)
unsigned int nonsecure_transfer:1;

//Reserved, should be zero
unsigned int reserved_zero_3 : 1;

} __attribute__ ((packed)) bits;

Expand All @@ -97,6 +100,9 @@ class ARMDebugMemAccessPort : public ARMDebugAccessPort
ARMDebugMemAccessPort(ARMDebugPort* dp, uint8_t apnum, ARMDebugPortIDRegister id);
virtual ~ARMDebugMemAccessPort();

//Called after all other Mem-APs are up
virtual void Initialize();

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Memory access

Expand Down

0 comments on commit 031216b

Please sign in to comment.