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)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sun, 24 Jan 2021 04:24:42 +0000 (04:24 +0000)
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 08801f99afeae0d05e8442cf3c103133f0379f8c..0a5fdd6752e881ae8f16ab97ebeae84b32616f1c 100644 (file)
 #include "base/types.hh"
 #include "cpu/static_inst_fwd.hh"
 
-namespace LittleEndianGuest {}
-
+//namespace LittleEndianGuest {}
+namespace BigEndianGuest {}
 namespace PowerISA
 {
 
 const ByteOrder GuestByteOrder = ByteOrder::little;
-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 91d080e3217ed6fe9eec026912c6331d43865bf7..d65295622753a0d414d9681df450e13ae82b9277 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>
 
@@ -68,7 +73,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);
@@ -96,7 +101,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;
             }
         }
@@ -378,6 +385,27 @@ TLB::translateAtomic(const 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);
@@ -397,6 +425,22 @@ TLB::translateAtomic(const 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{
@@ -420,6 +464,22 @@ TLB::translateAtomic(const 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 124d983b3ba0e47bdf0be85e29477beff479594a..9648ba308a830ed64dc0981239c5ab24b169f2d6 100644 (file)
@@ -250,9 +250,10 @@ ElfObject::determineArch()
               "recompile your binary.\n");
     } else if (emach == EM_PPC64 && eclass == ELFCLASS64) {
         arch = Power;
-        if (edata != ELFDATA2LSB) {
+        //if (edata != ELFDATA2LSB) {
+        if (edata != 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 {
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 8b420dae2a9538e286514f82d81a311debe2cb3b..f97562db17e58c12942351bdb83eff01fa9fb27f 100644 (file)
@@ -301,7 +301,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;
 }
 
@@ -319,7 +320,7 @@ Terminal::console_in()
     }
 
     DPRINTF(TerminalVerbose, "console_in: return: %#x\n", value);
-
+    //printf("console_in: return: 0x%lx\n", value);
     return value;
 }
 
@@ -355,6 +356,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 1ef4346eb5c0c6775505a2274da99069dd03f3d4..fbc1e55ffcd7c725b42dd77b4e7cbf6615318c2c 100644 (file)
@@ -76,6 +76,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
@@ -99,7 +103,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
@@ -109,7 +113,7 @@ Uart8250::read(PacketPtr pkt)
                     pkt->setRaw((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();
@@ -199,7 +203,7 @@ Uart8250::write(PacketPtr pkt)
         case 0x1:
             if (!(LCR & 0x80)) { // Intr Enable Register(IER)
                 IER = pkt->getRaw<uint8_t>();
-                if (UART_IER_THRI & IER & 0)
+                if (UART_IER_THRI & IER)
                 {
                     DPRINTF(Uart,
                             "IER: IER_THRI set, scheduling TX intrrupt\n");