arch-power: Cleanup console snooping
authorSandipan Das <sandipan@linux.ibm.com>
Wed, 22 Apr 2020 07:55:39 +0000 (13:25 +0530)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 24 Jan 2021 04:25:25 +0000 (04:25 +0000)
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 <sandipan@linux.ibm.com>
src/arch/power/tlb.cc
src/arch/power/tlb.hh

index b5c0ddc9e1ff4bd4251c49c996492b1cfb851730..e1c18a9de0161efc3b2aa80325b3fb5e69382667 100644 (file)
@@ -86,7 +86,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)
@@ -95,31 +217,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("<log_store>:") != string::npos
-                || addr_str.find("<log_store.isra.1>:") != 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()
@@ -410,36 +508,9 @@ TLB::translateAtomic(const 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; i<len; i++){
-                    read =  (char)rwalk->readPhysMem((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; i<len; i++){
-                    read =  (char)rwalk->readPhysMem((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;
             }
@@ -449,36 +520,8 @@ TLB::translateAtomic(const 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; i<len; i++){
-                    read =  (char)rwalk->readPhysMem((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; i<len; i++){
-                    read =  (char)rwalk->readPhysMem((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;
 
index 463843403754564e7ca84f92e55641e27ff8f2f5..c1cdb078e1cab34073e19e909b1586b6d3377648 100644 (file)
@@ -101,7 +101,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()
     {
@@ -166,6 +166,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