From 7266f752eef3f22b4ddbcc7604d631d25f84db0e Mon Sep 17 00:00:00 2001 From: Sandipan Das Date: Wed, 22 Apr 2020 13:25:39 +0530 Subject: [PATCH] arch-power: Cleanup console snooping This removes hard-coded physical addressess references used for console snooping of both the kernel and skiboot. Change-Id: I08475b819cc437e333801ff549bb963941fe1868 Signed-off-by: Sandipan Das --- src/arch/power/tlb.cc | 215 +++++++++++++++++++++++++----------------- src/arch/power/tlb.hh | 10 +- 2 files changed, 138 insertions(+), 87 deletions(-) diff --git a/src/arch/power/tlb.cc b/src/arch/power/tlb.cc index c7c5d82e0..f19271b08 100644 --- a/src/arch/power/tlb.cc +++ b/src/arch/power/tlb.cc @@ -92,7 +92,129 @@ SystemCallInterrupt::invoke(ThreadContext * tc, const StaticInstPtr &inst = #define MODE2MASK(X) (1 << (X)) -//uint64_t printk_debug; +void +TLB::initConsoleSnoop(void) +{ + int nameStart, addrLen; + string symName, symHexAddr; + ifstream in; + string line; + + /* Find console snoop point for kernel */ + in.open("dist/m5/system/binaries/objdump_vmlinux"); + if (!in.is_open()) { + panic("Could not find kernel objdump"); + } + + while (getline(in, line)) { + /* Find ".log_store" and the first call to ".memcpy" inside it */ + nameStart = line.find("<.log_store>:"); + + /* Sometimes, optimizations introduce ISRA symbols */ + if (nameStart == string::npos) { + nameStart = line.find("<.log_store.isra.1>:"); + } + + if (nameStart != string::npos) { + while (getline(in, line)) { + if (line.find("<.memcpy>") != string::npos && + (*(line.rbegin())) != ':') { + addrLen = line.find(":"); + istringstream hexconv(line.substr(0, addrLen)); + hexconv >> hex >> kernConsoleSnoopAddr; + + /* Use previous instruction and remove quadrant bits */ + kernConsoleSnoopAddr -= 4; + kernConsoleSnoopAddr &= (-1ULL >> 2); + break; + } + } + } + } + + in.close(); + + if (!kernConsoleSnoopAddr) { + panic("Could not determine kernel console snooping address"); + } + + /* Find console snoop point for skiboot */ + in.open("dist/m5/system/binaries/objdump_skiboot"); + if (!in.is_open()) { + panic("Could not find skiboot objdump"); + } + + while (getline(in, line)) { + /* Find ".console_write" and the first call to ".write" inside it */ + nameStart = line.find("<.console_write>:"); + + if (nameStart != string::npos) { + addrLen = line.find(":"); + istringstream hexconv(line.substr(0, addrLen)); + hexconv >> hex >> opalConsoleSnoopAddr; + + /* Add OPAL load offset */ + opalConsoleSnoopAddr += 0x30000000ULL; + break; + } + } + + inform("Snooping kernel console at 0x%016lx", kernConsoleSnoopAddr); + inform("Snooping skiboot console at 0x%016lx", opalConsoleSnoopAddr); + + in.close(); + if (!opalConsoleSnoopAddr) { + panic("Could not determine skiboot console snooping address"); + } +} + +void +TLB::trySnoopKernConsole(uint64_t paddr, ThreadContext *tc) +{ + uint64_t addr; + int len, i; + char *buf; + + if (paddr != kernConsoleSnoopAddr) { + return; + } + + len = (int) tc->readIntReg(5); + buf = new char[len + 1]; + addr = (uint64_t) tc->readIntReg(4) & (-1ULL >> 4); + + for (i = 0; i < len; i++) { + buf[i] = (char) rwalk->readPhysMem(addr + i, 8); + } + + buf[i] = '\0'; + printf("%lu [KERN LOG] %s\n", curTick(), buf); + delete buf; +} + +void +TLB::trySnoopOpalConsole(uint64_t paddr, ThreadContext *tc) +{ + uint64_t addr; + int len, i; + char *buf; + + if (paddr != opalConsoleSnoopAddr) { + return; + } + + len = (int) tc->readIntReg(5); + buf = new char[len + 1]; + addr = (uint64_t) tc->readIntReg(4) & (-1ULL >> 4); + + for (i = 0; i < len; i++) { + buf[i] = (char) rwalk->readPhysMem(addr + i, 8); + } + + buf[i] = '\0'; + printf("%lu [OPAL LOG] %s\n", curTick(), buf); + delete buf; +} TLB::TLB(const Params *p) : BaseTLB(p), size(p->size), nlu(0) @@ -101,31 +223,7 @@ TLB::TLB(const Params *p) memset(table, 0, sizeof(PowerISA::PTE[size])); smallPages = 0; rwalk = p->walker; - ifstream stream; - stream.open("dist/m5/system/binaries/objdump_vmlinux"); - string addr_str; - bool flag = false; - while (getline(stream, addr_str)) { - if (!flag){ - if (addr_str.find(":") != string::npos - || addr_str.find(":") != string::npos - || addr_str.find("<.log_store>:") != string::npos) { - flag = true; - } - } - else{ - if (addr_str.find("memcpy") != string::npos){ - break; - } - } - } - addr_str = addr_str.substr(1,15); // Extract the address - addr_str.insert (0, 1, '0'); // Prepend with `0` instead of `c` - istringstream converter(addr_str); - uint64_t value; - converter >> hex >> value; - value-=4; // Need the previous inst - this->printk_debug = value; + initConsoleSnoop(); } TLB::~TLB() @@ -428,36 +526,9 @@ TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode) //printf("MSR: %lx\n",(uint64_t)msr); Fault fault = rwalk->start(tc,req, mode); paddr = req->getPaddr(); - if (paddr == printk_debug){ - int len = (int)tc->readIntReg(5); - char buf[len]; - int i; - char read; - for (i=0; ireadPhysMem((tc->readIntReg(4) - & 0x0fffffffffffffff)+ i, 8); - buf[i] = read; - } - buf[i] = '\0'; - //DPRINTF(TLB, "[KERN LOG] %s\n",buf); - std::printf("%lu [KERN LOG] %s\n",curTick(),buf); - std::fflush(stdout); - } - if (paddr == 0x30012fd4){ - int len = (int)tc->readIntReg(5); - char buf[len]; - int i; - char read; - for (i=0; ireadPhysMem((tc->readIntReg(4) - & 0x0fffffffffffffff)+ i, 8); - buf[i] = read; - } - buf[i] = '\0'; - //DPRINTF(TLB, "[KERN LOG] %s\n",buf); - std::printf("%lu [OPAL LOG] %s\n",curTick(),buf); - std::fflush(stdout); - } + + trySnoopKernConsole(paddr, tc); + trySnoopOpalConsole(paddr, tc); return fault; } @@ -467,36 +538,8 @@ TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode) DPRINTF(TLB, "Translated %#x -> %#x.\n", vaddr, paddr); req->setPaddr(paddr); - if (paddr == printk_debug){ - int len = (int)tc->readIntReg(5); - int i; - char buf[len]; - char read; - for (i=0; ireadPhysMem((tc->readIntReg(4) - & 0x0fffffffffffffff)+ i, 8); - buf[i] = read; - } - buf[i] = '\0'; - //DPRINTF(TLB, "[KERN LOG] %s\n",buf); - std::printf("%lu [KERN LOG] %s\n",curTick(),buf); - std::fflush(stdout); - } - if (paddr == 0x30012fd4){ - int len = (int)tc->readIntReg(5); - char buf[len]; - int i; - char read; - for (i=0; ireadPhysMem((tc->readIntReg(4) - & 0x0fffffffffffffff)+ i, 8); - buf[i] = read; - } - buf[i] = '\0'; - //DPRINTF(TLB, "[KERN LOG] %s\n",buf); - std::printf("%lu [OPAL LOG] %s\n",curTick(),buf); - std::fflush(stdout); - } + trySnoopKernConsole(paddr, tc); + trySnoopOpalConsole(paddr, tc); return NoFault; diff --git a/src/arch/power/tlb.hh b/src/arch/power/tlb.hh index 2d3119e85..c79bb5389 100644 --- a/src/arch/power/tlb.hh +++ b/src/arch/power/tlb.hh @@ -107,7 +107,7 @@ class TLB : public BaseTLB PowerISA::PTE *table; // the Page Table int size; // TLB Size int nlu; // not last used entry (for replacement) - uint64_t printk_debug; // Address to probe for the debug; + void nextnlu() { @@ -181,6 +181,14 @@ class TLB : public BaseTLB void regStats() override; BaseMasterPort *getMasterPort() override; + + private: + uint64_t kernConsoleSnoopAddr; + uint64_t opalConsoleSnoopAddr; + + void initConsoleSnoop(); + void trySnoopKernConsole(uint64_t paddr, ThreadContext *tc); + void trySnoopOpalConsole(uint64_t paddr, ThreadContext *tc); }; } // namespace PowerISA -- 2.30.2