Pouya Fotouhi has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/23401 )

Change subject: dev: Adding GPU as a PCI device
......................................................................

dev: Adding GPU as a PCI device

Adds a new pci device to model GPU. This patch only adds the base
structures.

Change-Id: I0ca032cd130e33f1211e94b742041b673843c2d9
---
M configs/fs/system/system.py
A src/dev/gpu/Gpu.py
A src/dev/gpu/SConscript
A src/dev/gpu/gpu_ctrl.cc
A src/dev/gpu/gpu_ctrl.hh
M src/dev/pci/device.hh
M src/dev/x86/SouthBridge.py
7 files changed, 512 insertions(+), 3 deletions(-)



diff --git a/configs/fs/system/system.py b/configs/fs/system/system.py
index ef374ab..570e69e 100644
--- a/configs/fs/system/system.py
+++ b/configs/fs/system/system.py
@@ -91,7 +91,7 @@
         self.createCPU()

         # Create the GPU
-        if self._opts.dgpu or self._opts.apu :
+        if self._opts.dgpu or self._opts.apu:
             self.createGPU()

         # Create the memory heirarchy for the system.
@@ -268,7 +268,7 @@
         self.pc.south_bridge.ide.disks = [disk0, disk2]

     def createDMADevices(self):
-        if self._opts.dgpu or self._opts.apu :
+        if self._opts.dgpu or self._opts.apu:
             # Set up the HSA packet processor
             hsapp_gpu_map_paddr = int(Addr(self._opts.mem_size))
             gpu_hsapp = HSAPacketProcessor(pioAddr=hsapp_gpu_map_paddr,
@@ -319,7 +319,7 @@
             cpu.dtb.walker.port = self.ruby._cpu_ports[i].slave


-        if self._opts.dgpu or self._opts.apu :
+        if self._opts.dgpu or self._opts.apu:
             gpu_port_idx = len(self.ruby._cpu_ports) \
                            - self._opts.num_compute_units \
                            - self._opts.num_sqc \
@@ -358,6 +358,8 @@
             cpu.interrupts[0].int_slave = self.ruby._cpu_ports[i].master

     def initFS(self):
+
+
         self.pc = Pc()

         # North Bridge
@@ -373,6 +375,11 @@
             self._dma_ports = [self.pc.south_bridge.ide.dma]
self.pc.attachIO(self.iobus, [port for port in self._dma_ports])

+        if self._opts.dgpu:
+            # add GPU to southbridge
+            self.pc.south_bridge.attachGPU(self.iobus,
+                             [port.dma for port in self._dma_ports])
+
         self.intrctrl = IntrControl()

         ###############################################
diff --git a/src/dev/gpu/Gpu.py b/src/dev/gpu/Gpu.py
new file mode 100644
index 0000000..76f9978
--- /dev/null
+++ b/src/dev/gpu/Gpu.py
@@ -0,0 +1,69 @@
+# Copyright (c) 2019 Advanced Micro Devices, Inc.
+# All rights reserved.
+#
+# For use for simulation and test purposes only
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# Author: Pouya Fotouhi
+
+from m5.SimObject import SimObject
+from m5.params import *
+from m5.objects.PciDevice import PciDevice
+
+
+class GPUController(PciDevice):
+    type = 'GPUController'
+    cxx_header = "dev/gpu/gpu_ctrl.hh"
+
+    # IDs for AMD Vega 10
+    VendorID = 0x1002
+    DeviceID = 0x6863
+    Command = 0x3
+    Status = 0x0280
+    Revision = 0x0
+    ClassCode = 0x03
+    SubClassCode = 0x00
+    ProgIF = 0x00
+    BAR0 = 0x0000000c
+    BAR1 = 0x00000010
+    BAR2 = 0x0000000c
+    BAR3 = 0x00000020
+    BAR4 = 0x00000001
+    BAR5 = 0x81000000
+    InterruptLine = 14
+    InterruptPin =2
+    BAR0Size = '16GB'
+    BAR1Size = '0'
+    BAR2Size = '2MB'
+    BAR3Size = '0'
+    BAR4Size = '256B'
+    BAR5Size = '512kB'
+    ExpansionROM = 0
+
+    RomBin = Param.String("/proj/radl_tools/fs/bios_Marvel_Vega10",
+                          "ROM binary dumped from hardware")
diff --git a/src/dev/gpu/SConscript b/src/dev/gpu/SConscript
new file mode 100644
index 0000000..8485a5f
--- /dev/null
+++ b/src/dev/gpu/SConscript
@@ -0,0 +1,46 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2019 Advanced Micro Devices, Inc.
+# All rights reserved.
+#
+# For use for simulation and test purposes only
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# 1. Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# 3. Neither the name of the copyright holder nor the names of its
+# contributors may be used to endorse or promote products derived from this
+# software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Pouya Fotouhi
+
+Import('*')
+
+if env['TARGET_ISA'] == 'null':
+    Return()
+
+# Controllers
+SimObject('Gpu.py')
+
+Source('gpu_ctrl.cc')
+
+DebugFlag('GPUCtrl')
diff --git a/src/dev/gpu/gpu_ctrl.cc b/src/dev/gpu/gpu_ctrl.cc
new file mode 100644
index 0000000..8c07f8d
--- /dev/null
+++ b/src/dev/gpu/gpu_ctrl.cc
@@ -0,0 +1,254 @@
+/*
+ * Copyright (c) 2019 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * For use for simulation and test purposes only
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Pouya Fotouhi
+ */
+
+#include "dev/gpu/gpu_ctrl.hh"
+
+#include <string>
+
+#include "cpu/intr_control.hh"
+#include "debug/GPUCtrl.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
+#include "params/GPUController.hh"
+#include "sim/byteswap.hh"
+
+// clang complains about std::set being overloaded with Packet::set if
+// we open up the entire namespace std
+using std::string;
+
+GPUController::GPUController(Params *p)
+    : PciDevice(p), romBin(0)
+{
+    // Loading the rom binary dumped from hardware.
+    romBin.open (p->RomBin, std::ios::binary);
+    romBin.read(rom.data(), ROMSize);
+    romBin.close();
+}
+
+void
+GPUController::readROM(PacketPtr pkt)
+{
+    Addr rom_offset = pkt->getAddr() & (ROMSize - 1);
+    uint64_t rom_data;
+    memcpy(&rom_data, rom.data() + rom_offset, pkt->getSize());
+
+    switch (pkt->getSize()) {
+      case sizeof(uint8_t):
+        pkt->setLE<uint8_t>((uint8_t)rom_data);
+        break;
+      case sizeof(uint16_t):
+        pkt->setLE<uint16_t>((uint16_t)rom_data);
+        break;
+      case sizeof(uint32_t):
+        pkt->setLE<uint32_t>((uint32_t)rom_data);
+        break;
+      case sizeof(uint64_t):
+        pkt->setLE<uint64_t>(rom_data);
+        break;
+      default:
+        panic("invalid access size for GPU ROM!\n");
+    }
+    DPRINTF(GPUCtrl, "Read from addr %#x on ROM offset %#x data: %#x\n",
+            pkt->getAddr(), rom_offset, rom_data);
+}
+
+AddrRangeList
+GPUController::getAddrRanges() const
+{
+    AddrRangeList ranges = PciDevice::getAddrRanges();
+
+    if (config.expansionROM)
+        ranges.push_back(RangeSize(config.expansionROM, ROMSize));
+    else
+        ranges.push_back(RangeSize(VGA_ROM_DEFAULT, ROMSize));
+    return ranges;
+}
+
+Tick
+GPUController::readConfig(PacketPtr pkt)
+{
+    int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
+    DPRINTF(GPUCtrl, "Read Config: from offset: %#x size: %#x
+            data: %#x\n", offset, pkt->getSize(), config.data[offset]);
+    return PciDevice::readConfig(pkt);
+}
+
+Tick
+GPUController::writeConfig(PacketPtr pkt)
+{
+    int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
+    uint32_t data;
+    if (pkt->getSize() == 1)
+        data = pkt->getLE<uint8_t>();
+    else if (pkt->getSize() == 2)
+        data = pkt->getLE<uint16_t>();
+    else
+        data = pkt->getLE<uint32_t>();
+
+    DPRINTF(GPUCtrl, "Write Config: from offset: %#x size: %#x
+            data: %#x\n", offset, pkt->getSize(), data);
+    return PciDevice::writeConfig(pkt);
+}
+
+
+void
+GPUController::dispatchAccess(PacketPtr pkt, bool read)
+{
+    uint32_t data;
+    if (pkt->getSize() == 1)
+        data = pkt->getLE<uint8_t>();
+    else if (pkt->getSize() == 2)
+        data = pkt->getLE<uint16_t>();
+    else if (pkt->getSize() == 4)
+        data = pkt->getLE<uint32_t>();
+    else
+        data = pkt->getLE<uint64_t>();
+
+    DPRINTF(GPUCtrl, "%s from addr %#x size: %#x data: %#x\n",
+            read ? "Read" : "Write", pkt->getAddr(), pkt->getSize(),
+                data);
+    pkt->makeAtomicResponse();
+}
+
+void
+GPUController::readFrame(PacketPtr pkt, Addr offset) {
+    DPRINTF(GPUCtrl, "Read frame\n");
+    // @TODO This should turn into an option later.
+    // Only read from the trace during the initialization of driver.
+    if (true) {
+//        fromTrace(pkt, offset);
+    }
+//    else
+        // Real functionality
+}
+
+
+void
+GPUController::readDoorbell(PacketPtr pkt, Addr offset) {
+    DPRINTF(GPUCtrl, "Read doorbell\n");
+    // @TODO This should turn into an option later.
+    // Only read from the trace during the initialization of driver.
+    if (true) {
+//        fromTrace(pkt, offset);
+    }
+//    else
+        // Real functionality
+}
+
+
+void
+GPUController::readMmio(PacketPtr pkt, Addr offset) {
+    DPRINTF(GPUCtrl, "Read MMIO\n");
+    // @TODO This should turn into an option later.
+    // Only read from the trace during the initialization of driver.
+    if (true) {
+//        fromTrace(pkt, offset);
+    }
+//    else
+        // Real functionality
+}
+
+
+
+Tick
+GPUController::read(PacketPtr pkt)
+{
+    if (isROM(pkt->getAddr()))
+        readROM(pkt);
+    else {
+        int barnum = getBAR(pkt->getAddr());
+        Addr offset = pkt->getAddr() - BARAddrs[barnum];
+        switch (barnum) {
+          case 0:
+              readFrame(pkt, offset);
+              break;
+          case 2:
+              readDoorbell(pkt, offset);
+              break;
+          case 5:
+              readMmio(pkt, offset);
+              break;
+          default:
+            panic("Request with address out of mapped range!");
+        }
+    }
+    dispatchAccess(pkt, true);
+    return pioDelay;
+}
+
+Tick
+GPUController::write(PacketPtr pkt)
+{
+
+    uint64_t data;
+    if (pkt->getSize() == 1)
+        data = pkt->getLE<uint8_t>();
+    else if (pkt->getSize() == 2)
+        data = pkt->getLE<uint16_t>();
+    else if (pkt->getSize() == 4)
+        data = pkt->getLE<uint32_t>();
+    else
+        data = pkt->getLE<uint64_t>();
+
+ // Record only if there is non-zero value, or a value to be overwritten.
+    // Reads return 0 by default.
+    if (data || regs.find(pkt->getAddr()) != regs.end())
+        regs[pkt->getAddr()] = data;
+
+    dispatchAccess(pkt, false);
+    return pioDelay;
+}
+
+void
+GPUController::serialize(CheckpointOut &cp) const
+{
+    // Serialize the PciDevice base class
+    PciDevice::serialize(cp);
+}
+
+void
+GPUController::unserialize(CheckpointIn &cp)
+{
+    // Unserialize the PciDevice base class
+    PciDevice::unserialize(cp);
+
+}
+
+GPUController *
+GPUControllerParams::create()
+{
+    return new GPUController(this);
+}
+
diff --git a/src/dev/gpu/gpu_ctrl.hh b/src/dev/gpu/gpu_ctrl.hh
new file mode 100644
index 0000000..dee06ea
--- /dev/null
+++ b/src/dev/gpu/gpu_ctrl.hh
@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2019 Advanced Micro Devices, Inc.
+ * All rights reserved.
+ *
+ * For use for simulation and test purposes only
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the copyright holder nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Author: Pouya Fotouhi
+ */
+
+/**
+ * Simple PCI GPU controller.
+*/
+
+#ifndef __DEV_GPU_CTRL_HH__
+#define __DEV_GPU_CTRL_HH__
+
+#include <fstream>
+#include <iostream>
+#include <list>
+#include <map>
+#include <sstream>
+#include <tuple>
+#include <vector>
+
+#include "base/bitunion.hh"
+#include "dev/io_device.hh"
+#include "dev/pci/device.hh"
+#include "params/GPUController.hh"
+
+// By default (no expansion enabled), kernel expects the vga ROM at 0xc0000.
+constexpr uint32_t VGA_ROM_DEFAULT = 0xc0000;
+constexpr uint32_t ROMSize = 0x20000;        // 128kB
+
+
+/**
+ * Device model for an AMD GPU
+ */
+class GPUController : public PciDevice
+{
+  private:
+
+    /** Registers used in device specific PCI configuration */
+    // ADD IF NEEDED.
+
+    // Internal management variables
+    // ADD IF NEEDED.
+
+    void dispatchAccess(PacketPtr pkt, bool read);
+
+    // Separate functions for each memory region
+    void readFrame(PacketPtr pkt, Addr offset);
+    void readDoorbell(PacketPtr pkt, Addr offset);
+    void readMmio(PacketPtr pkt, Addr offset);
+
+    // ROM
+    void readROM(PacketPtr pkt);
+
+    /**
+     * Does the given address lie within the space mapped by ROM
+     * expansion register?
+     */
+    bool
+    isROM(Addr addr) const
+    {
+        if (config.expansionROM)
+            return config.expansionROM <= addr &&
+                   addr < config.expansionROM + ROMSize;
+        else
+ return VGA_ROM_DEFAULT <= addr && addr < VGA_ROM_DEFAULT + ROMSize;
+    }
+
+    std::array<char, ROMSize> rom;
+    std::ifstream romBin;
+
+    std::map<uint32_t, uint64_t> regs;
+
+
+  public:
+    typedef GPUControllerParams Params;
+    const Params *params() const { return (const Params *)_params; }
+    GPUController(Params *p);
+
+    // We need this later on.
+    void intrPost();
+
+    Tick writeConfig(PacketPtr pkt) override;
+    Tick readConfig(PacketPtr pkt) override;
+
+    Tick read(PacketPtr pkt) override;
+    Tick write(PacketPtr pkt) override;
+
+    AddrRangeList getAddrRanges() const override;
+
+    void serialize(CheckpointOut &cp) const override;
+    void unserialize(CheckpointIn &cp) override;
+};
+#endif // __DEV_GPU_CTRL_HH__
diff --git a/src/dev/pci/device.hh b/src/dev/pci/device.hh
index d154526..23d91fb 100644
--- a/src/dev/pci/device.hh
+++ b/src/dev/pci/device.hh
@@ -115,6 +115,8 @@
     /** Whether the BARs are really hardwired legacy IO locations. */
     bool legacyIO[6];

+    bool isROM(Addr addr);
+
     /**
      * Does the given BAR represent 32 lower bits of a 64-bit address?
      */
diff --git a/src/dev/x86/SouthBridge.py b/src/dev/x86/SouthBridge.py
index 80b432d..cce71f4 100644
--- a/src/dev/x86/SouthBridge.py
+++ b/src/dev/x86/SouthBridge.py
@@ -35,6 +35,7 @@
 from m5.objects.I8254 import I8254
 from m5.objects.I8259 import I8259
 from m5.objects.Ide import IdeController
+from m5.objects.Gpu import GPUController
 from m5.objects.PcSpeaker import PcSpeaker
 from m5.SimObject import SimObject

@@ -85,6 +86,13 @@
     ide.InterruptPin = 1
     ide.LegacyIOBase = x86IOAddress(0)

+    def attachGPU(self, bus, dma_ports):
+        self.gpu = GPUController(pci_func=0, pci_dev=8, pci_bus=0)
+        self.gpu.pio = bus.master
+        if dma_ports.count(self.gpu.dma) == 0:
+                self.gpu.dma = bus.slave
+
+
     def attachIO(self, bus, dma_ports):
         # Route interrupt signals
         self.pic1.output = self.io_apic.inputs[0]

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/23401
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-Change-Id: I0ca032cd130e33f1211e94b742041b673843c2d9
Gerrit-Change-Number: 23401
Gerrit-PatchSet: 1
Gerrit-Owner: Pouya Fotouhi <pfoto...@ucdavis.edu>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to