summaryrefslogtreecommitdiffstats
path: root/utils/bcmregtool/main.cpp
diff options
context:
space:
mode:
authorEvan Lojewski <github@meklort.com>2019-02-26 21:19:19 -0700
committerEvan Lojewski <github@meklort.com>2019-02-26 21:19:19 -0700
commitffe607d0c2c0b8c3f58d8855cef2b50aa538ca19 (patch)
tree94d4e2244a3ab10350dd10cdab23edf63f5301ab /utils/bcmregtool/main.cpp
parentb2d7a5130948de4037ee0e6d9937052c0039484b (diff)
downloadbcm5719-ortega-ffe607d0c2c0b8c3f58d8855cef2b50aa538ca19.tar.gz
bcm5719-ortega-ffe607d0c2c0b8c3f58d8855cef2b50aa538ca19.zip
Update bcmregtool to print out the symbol name when reporting the context and a number of other changes
Diffstat (limited to 'utils/bcmregtool/main.cpp')
-rw-r--r--utils/bcmregtool/main.cpp218
1 files changed, 194 insertions, 24 deletions
diff --git a/utils/bcmregtool/main.cpp b/utils/bcmregtool/main.cpp
index 558f843..082fe0b 100644
--- a/utils/bcmregtool/main.cpp
+++ b/utils/bcmregtool/main.cpp
@@ -66,9 +66,16 @@
#include <iostream>
#include <bcm5719_GEN.h>
+#include <elfio/elfio.hpp>
+
+#include "../NVRam/bcm5719_NVM.h"
+
using namespace std;
+using namespace ELFIO;
using optparse::OptionParser;
+elfio gELFIOReader;
+
const char* regnames[32] = {
"$zero", /* Zero register - always 0 */
"$at", /* Assembler register */
@@ -82,6 +89,42 @@ const char* regnames[32] = {
"$ra", /* return address */
};
+const string symbol_for_address(uint32_t address, uint32_t &offset)
+{
+ Elf_Half sec_num = gELFIOReader.sections.size();
+
+ for ( int i = 0; i < sec_num; ++i ) {
+ section* psec = gELFIOReader.sections[i];
+ // Check section type
+ if ( psec->get_type() == SHT_SYMTAB ) {
+ const symbol_section_accessor symbols( gELFIOReader, psec );
+ for ( unsigned int j = 0; j < symbols.get_symbols_num(); ++j ) {
+ std::string name;
+ Elf64_Addr value;
+ Elf_Xword size;
+ unsigned char bind;
+ unsigned char type;
+ Elf_Half section_index;
+ unsigned char other;
+
+ // Read symbol properties
+ symbols.get_symbol( j, name, value, size, bind,
+ type, section_index, other );
+
+
+ if(value <= address &&
+ value + size > address)
+ {
+ offset = address - value;
+ return name;
+ }
+ }
+ }
+ }
+
+ return string("unknown");
+}
+
void print_context(void)
{
uint32_t r[32];
@@ -125,23 +168,102 @@ void print_context(void)
r[31] = DEVICE.RxRiscRegister31.r32;
printf("==== Context ===\n");
- printf(" pc: 0x%08X opcode: 0x%08X\n", pc, opcode);
+ uint32_t sym_offset = 0;
+ string symbol = symbol_for_address(pc, sym_offset);
+ printf(" pc: 0x%08X (%s+%d) opcode: 0x%08X \n", pc, symbol.c_str(), sym_offset, opcode);
int numCols = 4;
int offset = 32 / numCols;
for(int i = 0; i < ARRAY_ELEMENTS(r)/4; i++)
{
for(int j = 0; j < numCols; j++)
{
- printf("%5s: 0x%08X ", regnames[i + j*offset], r[i + j*offset]);
+ printf("$%d(%5s): 0x%08X ", i + j*offset, regnames[i + j*offset], r[i + j*offset]);
}
printf("\n");
}
}
+void writeMemory(uint32_t rxAddr, uint32_t value)
+{
+ cout << "Updating " << std::hex << rxAddr << " to " << std::hex << value << endl;
+ // Halt.
+ RegDEVICERxRiscMode_t mode;
+ mode.r32 = 0;
+ mode.bits.Halt = 1;
+ DEVICE.RxRiscMode = mode;
+
+ DEVICE.RxRiscMode.print();
+
+ // Save old state that we will clobber so we can restore it afterwards.
+ uint32_t oldIP = DEVICE.RxRiscProgramCounter.r32;
+ uint32_t oldT6 = DEVICE.RxRiscRegister14.r32;
+ uint32_t oldT7 = DEVICE.RxRiscRegister15.r32;
+
+ // Check that the instructions we are expecting to use are correct. This will
+ // break if the ROM is different.
+ DEVICE.RxRiscProgramCounter.r32 = 0x40000038;
+
+
+ cout << "PC is now " << (uint32_t)DEVICE.RxRiscProgramCounter.r32 << endl;
+ uint32_t iw = DEVICE.RxRiscCurrentInstruction.r32;
+ if (iw != 0xADCF0000)
+ { // sw $t7, 0($t6)
+ fprintf(stderr, "cannot set RX word via forced store because the device has an unknown ROM (got 0x%08X)\n", iw);
+ return;
+ }
+
+ DEVICE.RxRiscRegister14.r32 = rxAddr;
+ DEVICE.RxRiscRegister15.r32 = value;
+
+ mode.bits.SingleStep = 1;
+ DEVICE.RxRiscMode = mode;
+
+ // Don't remove this, it creates a small delay which seems to sometimes be
+ // necessary.
+ uint32_t pc = DEVICE.RxRiscProgramCounter.r32;
+ if (pc != 0x4000003C)
+ {
+ fprintf(stderr, " bad2 0x%08x\n", pc);
+ }
+
+ // Restore.
+ DEVICE.RxRiscRegister15.r32 = oldT7;
+ DEVICE.RxRiscRegister14.r32 = oldT6;
+ DEVICE.RxRiscProgramCounter.r32 = oldIP;
+
+ mode.bits.SingleStep = 0;
+ DEVICE.RxRiscMode = mode;
+}
+
+void step(void)
+{
+ uint32_t oldPC = DEVICE.RxRiscProgramCounter.r32;
+
+ RegDEVICERxRiscMode_t mode;
+ mode.r32 = 0;
+ mode.bits.SingleStep = 1;
+ mode.bits.Halt = 1;
+ DEVICE.RxRiscMode = mode;
+
+ // Force a re-load of the next word.
+ uint32_t newPC = DEVICE.RxRiscProgramCounter.r32;
+
+ if(oldPC +4 != newPC)
+ {
+ // branched. Re-read PC to re-read opcode
+ DEVICE.RxRiscProgramCounter.r32 = DEVICE.RxRiscProgramCounter.r32;
+ }
+}
+
int main(int argc, char const *argv[])
{
OptionParser parser = OptionParser().description("BCM Register Utility");
+ parser.add_option("--elf")
+ .dest("debugfile")
+ .metavar("DEBUG_FILE")
+ .help("Elf file used for improved context decoding.");
+
parser.add_option("-f", "--function")
.dest("function")
.type("int")
@@ -149,19 +271,27 @@ int main(int argc, char const *argv[])
.metavar("FUNCTION")
.help("Read registers from the specified pci function.");
-
- parser.add_option("-r", "--reset")
- .dest("reset")
- .set_default("0")
- .action("store_true")
- .help("Issue a device reset request.");
-
parser.add_option("-s", "--step")
.dest("step")
.set_default("0")
.action("store_true")
.help("Single step the CPU.");
+ parser.add_option("-t", "--stepto")
+ .dest("stepto")
+ .metavar("ADDR")
+ .help("Single step the CPU.");
+
+ parser.add_option("--halt")
+ .dest("halt")
+ .set_default("0")
+ .action("store_true")
+ .help("Halt the CPU.");
+
+ parser.add_option("-pc", "--pc")
+ .dest("pc")
+ .help("Force the PC to the specified value.");
+
parser.add_option("-c", "--context")
.dest("context")
.set_default("0")
@@ -197,26 +327,64 @@ int main(int argc, char const *argv[])
exit(-1);
}
+ if(options.is_set("debugfile"))
+ {
+ if(!gELFIOReader.load(options["debugfile"]))
+ {
+ cerr << "Unablt to read elf file " << options["debugfile"] << endl;
+ exit(-1);
+ }
+ }
+
+ if(options.get("step"))
+ {
+ do {
+ cout << "Stepping...\n";
+ step();
+ print_context();
+
+ } while(DEVICE.RxRiscProgramCounter.r32 > 0x40000000);
+ exit(0);
+ }
+
+ if(options.is_set("stepto"))
+ {
+ uint32_t addr = stoi(options["stepto"], nullptr, 0);
+ do {
+ cout << "Stepping...\n";
+
+ step();
+ print_context();
+
+ } while(DEVICE.RxRiscProgramCounter.r32 != addr);
+ exit(0);
+
+ }
+
- if(options.get("reset"))
+
+ if(options.get("halt"))
{
- cout << "Resetting...\n";
+ cout << "Halting...\n";
RegDEVICERxRiscMode_t mode;
mode.r32 = 0;
- mode.bits.Reset = 1;
+ mode.bits.Halt = 1;
DEVICE.RxRiscMode = mode;
+
+ print_context();
exit(0);
}
- if(options.get("step"))
+ if(options.is_set("pc"))
{
- cout << "Stepping...\n";
+ uint32_t pc = stoi(options["pc"], nullptr, 0);
+ cout << "Updating PC to " << std::hex << pc << endl;
RegDEVICERxRiscMode_t mode;
mode.r32 = 0;
- mode.bits.SingleStep = 1;
mode.bits.Halt = 1;
DEVICE.RxRiscMode = mode;
+ DEVICE.RxRiscProgramCounter.r32 = pc;
print_context();
exit(0);
}
@@ -232,6 +400,7 @@ int main(int argc, char const *argv[])
cout << "Running...\n";
RegDEVICERxRiscMode_t mode;
mode.r32 = 0; // Ensure single-step and halt are cleared
+ mode.bits.EnableInstructionCache = 1;
DEVICE.RxRiscMode = mode;
exit(0);
}
@@ -240,21 +409,17 @@ int main(int argc, char const *argv[])
{
uint8_t phy = MII_getPhy();
printf("MII Phy: %d\n", phy);
- printf("MII Control: 0x%04X\n", MII_readRegister(phy, REG_MII_CONTROL));
- printf("MII Status: 0x%04X\n", MII_readRegister(phy, REG_MII_STATUS));
- printf("MII PHY ID[high]: 0x%04X\n", MII_readRegister(phy, REG_MII_PHY_ID_HIGH));
- printf("MII PHY ID[low]: 0x%04X\n", MII_readRegister(phy, REG_MII_PHY_ID_LOW));
-
- MII_selectBlock(0, 0x8010);
- printf("0x1A (0x8010): 0x%04X\n", MII_readRegister(0, (mii_reg_t)0x1A));
- MII_selectBlock(0, 0);
-
+ printf("MII Control: 0x%04X\n", MII_readRegister(phy, (mii_reg_t)REG_MII_CONTROL));
+ printf("MII Status: 0x%04X\n", MII_readRegister(phy, (mii_reg_t)REG_MII_STATUS));
+ printf("MII PHY ID[high]: 0x%04X\n", MII_readRegister(phy, (mii_reg_t)REG_MII_PHY_ID_HIGH));
+ printf("MII PHY ID[low]: 0x%04X\n", MII_readRegister(phy, (mii_reg_t)REG_MII_PHY_ID_LOW));
exit(0);
}
if(options.get("info"))
{
+ printf("Gen DataSig: 0x%08X\n", (uint32_t)GEN.GenDataSig.r32);
printf("Firmware Ver: 0x%08X\n", (uint32_t)GEN.GenFwVersion.r32);
printf("Chip Id: 0x%08X\n", (uint32_t)DEVICE.ChipId.r32);
printf("Vendor ID: 0x%04X Device ID: 0x%04X\n", (uint16_t)DEVICE.PciVendorDeviceId.bits.VendorID, (uint16_t)DEVICE.PciVendorDeviceId.bits.DeviceID);
@@ -275,6 +440,9 @@ int main(int argc, char const *argv[])
uint64_t serial = (((uint64_t)(DEVICE.PciSerialNumberHigh.r32)) << 32) | DEVICE.PciSerialNumberLow.r32;
printf("Serial Number: 0x%016lX\n", serial);
+ uint64_t genmac = (((uint64_t)(GEN.GenMacAddrHighMbox.r32)) << 32) | GEN.GenMacAddrLowMbox.r32;
+ printf("GEN Mac Addr: 0x%016lX\n", genmac);
+
printf("\n");
printf("Power Budget[0]: 0x%08X\n", (uint32_t)DEVICE.PciPowerBudget0.r32);
@@ -336,6 +504,8 @@ int main(int argc, char const *argv[])
printf("LedControl: 0x%08X\n", (uint32_t)DEVICE.LedControl.r32);
printf("GrcModeControl: 0x%08X\n", (uint32_t)DEVICE.GrcModeControl.r32);
+ DEVICE.GrcModeControl.bits.NVRAMWriteEnable = 1;
+ DEVICE.GrcModeControl.print();
printf("GphyControlStatus: 0x%08X\n", (uint32_t)DEVICE.GphyControlStatus.r32);
printf("TopLevelMiscellaneousControl1: 0x%08X\n", (uint32_t)DEVICE.TopLevelMiscellaneousControl1.r32);
printf("MiscellaneousLocalControl: 0x%08X\n", (uint32_t)DEVICE.MiscellaneousLocalControl.r32);
OpenPOWER on IntegriCloud