#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)
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()
//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;
}
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;