dev: Added new LupIO-RTC device

This device supplies the computer system with the simulated time by
retrieving the current tick number and converting to seconds, then
returning that time in ISO 8601 format. It is implemented as a
BasicPioDevice and is read-only.

The following are the specifications regarding the LupIO-RTC:
https://gitlab.com/luplab/lupio/lupio-specs/-/blob/main/lupio-rtc.md

Change-Id: Ic99291e5c862e728dac90b15ca818d42f25cbbee
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/53026
Maintainer: Bobby Bruce <bbruce@ucdavis.edu>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
diff --git a/src/dev/lupio/LupioRTC.py b/src/dev/lupio/LupioRTC.py
new file mode 100644
index 0000000..8392e65
--- /dev/null
+++ b/src/dev/lupio/LupioRTC.py
@@ -0,0 +1,35 @@
+# Copyright (c) 2021 The Regents of the University of California
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# 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;
+# neither the name of the copyright holders 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
+# OWNER 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.
+
+from m5.objects.Device import BasicPioDevice
+from m5.params import Param
+
+class LupioRTC(BasicPioDevice):
+    type = 'LupioRTC'
+    cxx_class='gem5::LupioRTC'
+    cxx_header = 'dev/lupio/lupio_rtc.hh'
+    time = Param.Time('01/01/2020', "Initial system time to use")
+    pio_size = Param.Addr(0x1000, "PIO Size")
diff --git a/src/dev/lupio/SConscript b/src/dev/lupio/SConscript
new file mode 100644
index 0000000..30fbbe0
--- /dev/null
+++ b/src/dev/lupio/SConscript
@@ -0,0 +1,33 @@
+# Copyright (c) 2021 The Regents of the University of California
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# 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;
+# neither the name of the copyright holders 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
+# OWNER 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.
+
+Import('*')
+
+SimObject('LupioRTC.py', tags='riscv isa')
+
+DebugFlag('LupioRTC')
+
+Source('lupio_rtc.cc', tags='riscv isa')
diff --git a/src/dev/lupio/lupio_rtc.cc b/src/dev/lupio/lupio_rtc.cc
new file mode 100644
index 0000000..b372815
--- /dev/null
+++ b/src/dev/lupio/lupio_rtc.cc
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 2021 The Regents of the University of California
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * 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;
+ * neither the name of the copyright holders 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
+ * OWNER 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.
+ */
+
+#include "dev/lupio/lupio_rtc.hh"
+
+#include "base/time.hh"
+#include "debug/LupioRTC.hh"
+#include "mem/packet_access.hh"
+#include "params/LupioRTC.hh"
+
+namespace gem5
+{
+
+LupioRTC::LupioRTC(const Params &params) :
+    BasicPioDevice(params, params.pio_size),
+    time(params.time)
+{
+    start = mktime(&time);
+}
+
+uint8_t
+LupioRTC::lupioRTCRead(uint8_t addr)
+{
+    uint8_t r = 0;
+    uint32_t time_sec;
+    time_t total_time;
+
+    /**
+     * Get simulated time in seconds
+     */
+    time_sec = (curTick() / sim_clock::as_int::s);
+    total_time = (time_t) time_sec + start;
+
+    /**
+     * Transform into broken-down time representation
+     */
+    gmtime_r(&total_time, &time);
+
+    switch (addr) {
+        case LUPIO_RTC_SECD:
+            r = time.tm_sec;                 /* 0-60 (for leap seconds) */
+            break;
+        case LUPIO_RTC_MINT:
+            r = time.tm_min;                 /* 0-59 */
+            break;
+        case LUPIO_RTC_HOUR:
+            r = time.tm_hour;                /* 0-23 */
+            break;
+        case LUPIO_RTC_DYMO:
+            r = time.tm_mday;                /* 1-31 */
+            break;
+        case LUPIO_RTC_MNTH:
+            r = time.tm_mon + 1;             /* 1-12 */
+            break;
+        case LUPIO_RTC_YEAR:
+            r = (time.tm_year + 1900) % 100; /* 0-99 */
+            break;
+        case LUPIO_RTC_CENT:
+            r = (time.tm_year + 1900) / 100; /* 0-99 */
+            break;
+        case LUPIO_RTC_DYWK:
+            r = 1 + (time.tm_wday + 6) % 7;  /* 1-7 (Monday is 1) */
+            break;
+        case LUPIO_RTC_DYYR:
+            r = time.tm_yday + 1;            /* 1-366 (for leap years) */
+            break;
+    }
+    return r;
+}
+
+Tick
+LupioRTC::read(PacketPtr pkt)
+{
+    bool is_atomic = pkt->isAtomicOp() && pkt->cmd == MemCmd::SwapReq;
+    DPRINTF(LupioRTC,
+        "Read request - addr: %#x, size: %#x, atomic:%d\n",
+        pkt->getAddr(), pkt->getSize(), is_atomic);
+
+    Addr rtc_addr = pkt->getAddr() - pioAddr;
+    uint8_t time_val = lupioRTCRead(rtc_addr);
+    DPRINTF(LupioRTC, "time value: %d\n", time_val);
+
+    pkt->setData(&time_val);
+
+    if (is_atomic) {
+        pkt->makeAtomicResponse();
+    } else {
+        pkt->makeResponse();
+    }
+
+    return pioDelay;
+}
+
+Tick
+LupioRTC::write(PacketPtr pkt)
+{
+    panic("Unexpected write to the LupioRTC device!");
+    return pioDelay;
+}
+
+} // namespace gem5
diff --git a/src/dev/lupio/lupio_rtc.hh b/src/dev/lupio/lupio_rtc.hh
new file mode 100644
index 0000000..4d1c79a
--- /dev/null
+++ b/src/dev/lupio/lupio_rtc.hh
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2021 The Regents of the University of California
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * 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;
+ * neither the name of the copyright holders 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
+ * OWNER 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.
+ */
+
+#ifndef __DEV_LUPIO_LUPIO_RTC_HH__
+#define __DEV_LUPIO_LUPIO_RTC_HH__
+
+#include "debug/LupioRTC.hh"
+#include "dev/io_device.hh"
+#include "params/LupioRTC.hh"
+#include "sim/system.hh"
+
+namespace gem5
+{
+
+/**
+ * LupioRTC:
+ * A Real-Time Clock Virtual Device that returns the current date and time
+ * in ISO 8601 format.
+ */
+class LupioRTC : public BasicPioDevice
+{
+  protected:
+    time_t start;
+    struct tm time;
+
+  // Register map
+  private:
+    enum
+    {
+        LUPIO_RTC_SECD,
+        LUPIO_RTC_MINT,
+        LUPIO_RTC_HOUR,
+        LUPIO_RTC_DYMO,
+        LUPIO_RTC_MNTH,
+        LUPIO_RTC_YEAR,
+        LUPIO_RTC_CENT,
+        LUPIO_RTC_DYWK,
+        LUPIO_RTC_DYYR,
+
+        // Max offset
+        LUPIO_RTC_MAX,
+    };
+
+    /**
+     * Function to return current time and date using system's wall-clock time
+     */
+    uint8_t lupioRTCRead(const uint8_t addr);
+
+  public:
+    PARAMS(LupioRTC);
+    LupioRTC(const Params &params);
+
+    /**
+     * Implement BasicPioDevice virtual functions
+     */
+    Tick read(PacketPtr pkt) override;
+    Tick write(PacketPtr pkt) override;
+};
+
+} // namespace gem5
+
+#endif // __DEV_LUPIO_LUPIO_RTC_HH__