arch-power: Add support for OPAL firmware
authorPratik Rajesh Sampat <prasampa@in.ibm.com>
Thu, 13 Jun 2019 06:00:16 +0000 (11:30 +0530)
committerSandipan Das <sandipan@linux.ibm.com>
Tue, 20 Aug 2019 06:43:55 +0000 (12:13 +0530)
Change-Id: I16d20224132ee6fc57ceeb88ecf99a1b2ab9d0d0
Signed-off-by: Pratik Rajesh Sampat <prasampa@in.ibm.com>
src/arch/power/isa_traits.hh
src/arch/power/linux/system.cc
src/arch/power/tlb.cc
src/base/loader/elf_object.cc
src/dev/power/g500.cc
src/dev/serial/terminal.cc
src/dev/serial/uart8250.cc

index 4f84ac34f864b77fa3c0401cce26d5ff7c986f39..46c62efe48ac5db960317ab1b54214db0dcd7508 100644 (file)
 #include "base/types.hh"
 #include "cpu/static_inst_fwd.hh"
 
-namespace LittleEndianGuest {}
-
+//namespace LittleEndianGuest {}
+namespace BigEndianGuest {}
 namespace PowerISA
 {
 
-using namespace LittleEndianGuest;
+//using namespace LittleEndianGuest;
+using namespace BigEndianGuest;
 
 StaticInstPtr decodeInst(ExtMachInst);
 
index 1c4a11c7bb45c3aa042342828ff05679a8215254..ed628d8dd0d39f8dc7d04b6b38b0360829c5e704 100644 (file)
 
 #include "arch/power/linux/system.hh"
 
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <cstring>
+
 #include "arch/vtophys.hh"
 #include "base/loader/dtb_object.hh"
 #include "base/loader/object_file.hh"
@@ -75,7 +82,7 @@ LinuxPowerSystem::initState()
     bool kernel_has_fdt_support =
         kernelSymtab->findAddress("unflatten_device_tree", addr);
     bool dtb_file_specified = params()->dtb_filename != "";
-
+    kernel_has_fdt_support = true;
     if (kernel_has_fdt_support && dtb_file_specified) {
         // Kernel supports flattened device tree and dtb file specified.
         // Using Device Tree Blob to describe system configuration.
@@ -105,6 +112,56 @@ LinuxPowerSystem::initState()
         dtb_file->loadSections(physProxy);
         delete dtb_file;
     }
+    if (kernel){
+        inform("Loading kernel: %s at address %#x\n",params()->kernel,
+                        0x20000000);
+        kernel->setTextBase(0x20000000);
+        kernel->loadSections(physProxy);
+
+    }
+    if (!params()->skiboot.empty()){
+        inform("Loading skiboot: %s at address %#x\n",params()->skiboot,
+                        0x0);
+        ObjectFile *skiboot_file = createObjectFile(params()->skiboot,true);
+        if (!skiboot_file){
+                fatal("Could not load skiboot\n");
+        }
+        skiboot_file->setTextBase(0x0);
+        skiboot_file->loadSections(physProxy);
+    }
+    if (!params()->initramfs.empty()){
+        inform("Loading initramfs: %s at address %#x\n",params()->initramfs,
+                        0x28000000);
+        int fd = open(params()->initramfs.c_str(), O_RDONLY);
+        if (fd < 0){
+                fatal("Couldn't open %s file\n",params()->initramfs);
+        }
+        off_t off = lseek(fd, 0, SEEK_END);
+        fatal_if(off < 0,
+                "Failed to determine size of the object file %s\n",
+                params()->initramfs);
+        auto len = static_cast<size_t>(off);
+
+        uint8_t *buffer = (uint8_t *)malloc(len + 1);
+        if (!buffer){
+                fatal("Malloc failed\n");
+        }
+        lseek(fd,0,SEEK_SET);
+        int sz = read(fd, buffer, len);
+        if (sz != len){
+                fatal("Reading the initramfs file"
+                        "failed len :: %d read :: %d\n",len,sz);
+        }
+        //buffer[len+1] = '\0';
+        //const uint8_t *blob = (uint8_t *)malloc(len + 1);
+        //strncpy()
+        // load the file in memory
+        //physProxy.memsetBlob(0x28000000,(const uint8_t *)buffer,len);
+        physProxy.writeBlobPhys(0x28000000, 0, buffer,len);
+        close(fd);
+
+
+    }
 }
 
 LinuxPowerSystem *
index 6a01ff7954acf572d6cc7e769a88334cd2062748..612a2babc9cdfd3efecf5f66563b8ae2543f8577 100644 (file)
  */
 #include "arch/power/tlb.hh"
 
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
 #include <string>
 #include <vector>
 
@@ -74,7 +79,7 @@ SystemCallInterrupt::invoke(ThreadContext * tc, const StaticInstPtr &inst =
       PowerInterrupt::updateSRR1(tc);
       PowerInterrupt::updateMsr(tc);
       tc->pcState(SystemCallPCSet);
-      std::printf("System call number = %lu\n", tc->readIntReg(0));
+      //std::printf("System call number = %lu\n", tc->readIntReg(0));
       if (tc->readIntReg(0) == 4){
         stdout_buf_length = (int)tc->readIntReg(5);
         stdout_buf_addr = tc->readIntReg(4);
@@ -102,7 +107,9 @@ TLB::TLB(const Params *p)
     bool flag = false;
     while (getline(stream, addr_str)) {
         if (!flag){
-            if (addr_str.find("<log_store>:") != string::npos) {
+            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;
             }
         }
@@ -396,6 +403,27 @@ TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode)
         }
         Msr msr = tc->readIntReg(INTREG_MSR);
         if (mode == Execute){
+                //0x20000000
+           /* if (vaddr == 0x30005214){
+                int fd = open("device_tree.dtb", O_CREAT | O_WRONLY,0644);
+                //uint64_t i;
+                int index = 0;
+                //uint64_t start_addr = (uint64_t)tc->readIntReg(3);
+                std::printf("r3(device tree start) 0x%016lx\n",
+                                tc->readIntReg(4));
+                uint64_t start_addr = (uint64_t)tc->readIntReg(4); //- 0x1000;
+                uint8_t buf[10745];
+                for (index=0; index<10745; index++){
+                    buf[index] = (uint8_t)rwalk->readPhysMem(
+                                        start_addr + index,8);
+                    if (index < 8){
+                            std::printf("buf[0x%016lx] = %02x\n",
+                            start_addr + index,(unsigned int)buf[index]);
+                    }
+                }
+                int len = write(fd,buf,10745);
+                std::printf("Written to the device_tree.dtb :: len %d\n",len);
+            }*/
             if (msr.ir){
                 //printf("MSR: %lx\n",(uint64_t)msr);
                 Fault fault = rwalk->start(tc,req, mode);
@@ -415,6 +443,22 @@ TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode)
                   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);
+                }
+
                 return fault;
             }
             else{
@@ -438,6 +482,22 @@ TLB::translateAtomic(RequestPtr req, ThreadContext *tc, Mode mode)
                   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);
+                }
+
                 return NoFault;
 
             }
index 8e1e065a549fb6813f8e610162545bb3a2ef5815..b7ff9b9ad86f035523657ccb2a84df74aa13a449 100644 (file)
@@ -121,9 +121,10 @@ ElfObject::tryFile(const std::string &fname, size_t len, uint8_t *data,
     } else if (ehdr.e_machine == EM_PPC64 &&
                ehdr.e_ident[EI_CLASS] == ELFCLASS64) {
         arch = Power;
-        if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB) {
+        //if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB) {
+        if (ehdr.e_ident[EI_DATA] != ELFDATA2MSB) {
             fatal("The binary you're trying to load is compiled for "
-                  "big endian Power.\ngem5 only supports little "
+                  "little endian Power.\ngem5 only supports big "
                   "endian Power. Please recompile your binary.\n");
         }
     } else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) {
index 418b368c0634913b42097a5307b93598979a7779..85cab7d3a37a0a50cb24be488711ef8138ef66d4 100644 (file)
@@ -12,14 +12,18 @@ G500::G500(const Params *p)
 void
 G500::postConsoleInt()
 {
-    warn_once("Don't know what interrupt to post for console.\n");
+    //warn_once("Don't know what interrupt to post for console.\n");
+    cout<<"Post console intr\n";
+    this->intrctrl->post(2,0);
     //panic("Need implementation\n");
 }
 
 void
 G500::clearConsoleInt()
 {
-    warn_once("Don't know what interrupt to clear for console.\n");
+    //warn_once("Don't know what interrupt to clear for console.\n");
+    //cout<<"Clear console intr\n";
+    this->intrctrl->clear(2,0);
     //panic("Need implementation\n");
 }
 
@@ -68,4 +72,4 @@ G500 *
 G500Params::create()
 {
     return new G500(this);
-}
\ No newline at end of file
+}
index bc8c14c531f94709f1ed1c2ad83d011570ec8390..1dc239802c2cbf2d91d9ace9446843d4bc3c6e35 100644 (file)
@@ -276,7 +276,8 @@ Terminal::readData()
 
     DPRINTF(TerminalVerbose, "in: \'%c\' %#02x more: %d\n",
             isprint(c) ? c : ' ', c, !rxbuf.empty());
-
+    //printf("------Read: \'%c\' %#02x more: %d\n",
+    //        isprint(c) ? c : ' ', c, !rxbuf.empty());
     return c;
 }
 
@@ -294,7 +295,7 @@ Terminal::console_in()
     }
 
     DPRINTF(TerminalVerbose, "console_in: return: %#x\n", value);
-
+    //printf("console_in: return: 0x%lx\n", value);
     return value;
 }
 
@@ -330,6 +331,9 @@ Terminal::writeData(uint8_t c)
     if (outfile)
         outfile->stream()->put((char)c);
 
+    //printf("-------Written out: \'%c\' %#02x\n",
+    //        isprint(c) ? c : ' ', (int)c);
+
     DPRINTF(TerminalVerbose, "out: \'%c\' %#02x\n",
             isprint(c) ? c : ' ', (int)c);
 
index 5bb6d50d2bafb617b823fbd5a63f7b1d52140157..7f449dff2d21c1b1768c26d4cec8b5bec2e758c7 100644 (file)
@@ -80,6 +80,10 @@ Uart8250::scheduleIntr(Event *event)
     static const Tick interval = 225 * SimClock::Int::ns;
     DPRINTF(Uart, "Scheduling IER interrupt for %s, at cycle %lld\n",
             event->name(), curTick() + interval);
+    cout << "Scheduling IER interrupt for "
+         <<event->name()<< " at cycle" << curTick() + interval <<"\n";
+    //if (event->name().compare("TX.wrapped_function_event") == 0)
+    //  return;
     if (!event->scheduled())
         schedule(event, curTick() + interval);
     else
@@ -103,7 +107,7 @@ Uart8250::read(PacketPtr pkt)
     Addr daddr = pkt->getAddr() - pioAddr;
 
     DPRINTF(Uart, " read register %#x\n", daddr);
-
+    printf("read address 0x%lx\n", daddr);
     switch (daddr) {
         case 0x0:
             if (!(LCR & 0x80)) { // read byte
@@ -113,7 +117,7 @@ Uart8250::read(PacketPtr pkt)
                     pkt->set((uint8_t)0);
                     // A limited amount of these are ok.
                     DPRINTF(Uart, "empty read of RX register\n");
-                    printf("empty read of Rx register\n");
+                    //printf("empty read of Rx register\n");
                 }
                 status &= ~RX_INT;
                 platform->clearConsoleInt();
@@ -133,10 +137,13 @@ Uart8250::read(PacketPtr pkt)
             break;
         case 0x2: // Intr Identification Register (IIR)
             DPRINTF(Uart, "IIR Read, status = %#x\n", (uint32_t)status);
-            printf("IIR Read, status = %#x\n", (uint32_t)status);
-            if (status & RX_INT) /* Rx data interrupt has a higher priority */
-                pkt->set(IIR_RXID);
+            //printf("IIR Read, status = %#x\n", (uint32_t)status);
+            if (status & RX_INT){ /* Rx data interrupt has a higher priority */
+              //printf("RX data interrupt detected\n");
+              pkt->set(IIR_RXID);
+            }
             else if (status & TX_INT) {
+                //printf("Tx data interrupt detected\n");
                 pkt->set(IIR_TXID);
                 //Tx interrupts are cleared on IIR reads
                 status &= ~TX_INT;
@@ -202,7 +209,7 @@ Uart8250::write(PacketPtr pkt)
         case 0x1:
             if (!(LCR & 0x80)) { // Intr Enable Register(IER)
                 IER = pkt->get<uint8_t>();
-                if (UART_IER_THRI & IER & 0)
+                if (UART_IER_THRI & IER)
                 {
                     DPRINTF(Uart, "IER: IER_THRI set, scheduling TX intrrupt\n");
                     if (curTick() - lastTxInt > 225 * SimClock::Int::ns) {