From bc0b6a7e99828d41607308d6311103f965d39ac0 Mon Sep 17 00:00:00 2001 From: Pratik Rajesh Sampat Date: Thu, 13 Jun 2019 11:30:16 +0530 Subject: [PATCH] arch-power: Add support for OPAL firmware Change-Id: I16d20224132ee6fc57ceeb88ecf99a1b2ab9d0d0 Signed-off-by: Pratik Rajesh Sampat --- src/arch/power/isa_traits.hh | 7 ++-- src/arch/power/linux/system.cc | 59 ++++++++++++++++++++++++++++++- src/arch/power/tlb.cc | 64 ++++++++++++++++++++++++++++++++-- src/base/loader/elf_object.cc | 5 +-- src/dev/power/g500.cc | 10 ++++-- src/dev/serial/terminal.cc | 8 +++-- src/dev/serial/uart8250.cc | 10 ++++-- 7 files changed, 147 insertions(+), 16 deletions(-) diff --git a/src/arch/power/isa_traits.hh b/src/arch/power/isa_traits.hh index 08801f99a..0a5fdd675 100644 --- a/src/arch/power/isa_traits.hh +++ b/src/arch/power/isa_traits.hh @@ -34,13 +34,14 @@ #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); diff --git a/src/arch/power/linux/system.cc b/src/arch/power/linux/system.cc index 1c4a11c7b..ed628d8dd 100644 --- a/src/arch/power/linux/system.cc +++ b/src/arch/power/linux/system.cc @@ -39,6 +39,13 @@ #include "arch/power/linux/system.hh" +#include +#include +#include +#include + +#include + #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(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 * diff --git a/src/arch/power/tlb.cc b/src/arch/power/tlb.cc index 91d080e32..d65295622 100644 --- a/src/arch/power/tlb.cc +++ b/src/arch/power/tlb.cc @@ -30,6 +30,11 @@ */ #include "arch/power/tlb.hh" +#include +#include +#include +#include + #include #include @@ -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(":") != string::npos) { + if (addr_str.find(":") != string::npos + || addr_str.find(":") != 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; 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); + } + 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; 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); + } + return NoFault; } diff --git a/src/base/loader/elf_object.cc b/src/base/loader/elf_object.cc index 124d983b3..9648ba308 100644 --- a/src/base/loader/elf_object.cc +++ b/src/base/loader/elf_object.cc @@ -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 { diff --git a/src/dev/power/g500.cc b/src/dev/power/g500.cc index 418b368c0..85cab7d3a 100644 --- a/src/dev/power/g500.cc +++ b/src/dev/power/g500.cc @@ -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 +} diff --git a/src/dev/serial/terminal.cc b/src/dev/serial/terminal.cc index 8b420dae2..f97562db1 100644 --- a/src/dev/serial/terminal.cc +++ b/src/dev/serial/terminal.cc @@ -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); diff --git a/src/dev/serial/uart8250.cc b/src/dev/serial/uart8250.cc index 1ef4346eb..fbc1e55ff 100644 --- a/src/dev/serial/uart8250.cc +++ b/src/dev/serial/uart8250.cc @@ -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 " + <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(); - if (UART_IER_THRI & IER & 0) + if (UART_IER_THRI & IER) { DPRINTF(Uart, "IER: IER_THRI set, scheduling TX intrrupt\n"); -- 2.30.2