From 4cca1d89e8a1af1934237a203072e7c832155a39 Mon Sep 17 00:00:00 2001 From: Peter Date: Thu, 4 Feb 2021 12:08:18 +0800 Subject: [PATCH] arch-riscv: Implementation of CLINT This patch implements the CLINT device model based on the SiFive U54MC datasheet. CLINT is modelled to receive its clock signal via an interrupt pin. A generic RTC (non-MMIO) is also implemented to provide this signal at arbitrary frequencies. isa.cc is also modified to provide a correct implementation of the rdtime instruction. It will read from the miscreg file (which is updated by CLINT every time mtime is incremented). Change-Id: I6f5393f3a8fdbd059f25df51d3d74bcb28da09f1 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/40597 Tested-by: kokoro Reviewed-by: Ayaz Akram Reviewed-by: Jason Lowe-Power Maintainer: Jason Lowe-Power --- src/arch/riscv/isa.cc | 2 +- src/dev/riscv/Clint.py | 53 +++++++++ src/dev/riscv/RTC.py | 51 +++++++++ src/dev/riscv/SConscript | 39 +++++++ src/dev/riscv/clint.cc | 226 +++++++++++++++++++++++++++++++++++++++ src/dev/riscv/clint.hh | 149 ++++++++++++++++++++++++++ src/dev/riscv/rtc.cc | 96 +++++++++++++++++ src/dev/riscv/rtc.hh | 81 ++++++++++++++ 8 files changed, 696 insertions(+), 1 deletion(-) create mode 100644 src/dev/riscv/Clint.py create mode 100644 src/dev/riscv/RTC.py create mode 100755 src/dev/riscv/SConscript create mode 100644 src/dev/riscv/clint.cc create mode 100644 src/dev/riscv/clint.hh create mode 100644 src/dev/riscv/rtc.cc create mode 100644 src/dev/riscv/rtc.hh diff --git a/src/arch/riscv/isa.cc b/src/arch/riscv/isa.cc index 98798e748b..8d200d4021 100644 --- a/src/arch/riscv/isa.cc +++ b/src/arch/riscv/isa.cc @@ -255,7 +255,7 @@ ISA::readMiscReg(int misc_reg) if (hpmCounterEnabled(MISCREG_TIME)) { DPRINTF(RiscvMisc, "Wall-clock counter at: %llu.\n", std::time(nullptr)); - return std::time(nullptr); + return readMiscRegNoEffect(MISCREG_TIME); } else { warn("Wall clock disabled.\n"); return 0; diff --git a/src/dev/riscv/Clint.py b/src/dev/riscv/Clint.py new file mode 100644 index 0000000000..25b595b3a6 --- /dev/null +++ b/src/dev/riscv/Clint.py @@ -0,0 +1,53 @@ +# Copyright (c) 2021 Huawei International +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# +# 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.objects.IntPin import IntSinkPin +from m5.params import * +from m5.proxy import * + +class Clint(BasicPioDevice): + """ + This implementation of CLINT is based on + the SiFive U54MC datasheet: + https://sifive.cdn.prismic.io/sifive/fab000f6- + 0e07-48d0-9602-e437d5367806_sifive_U54MC_rtl_ + full_20G1.03.00_manual.pdf + """ + type = 'Clint' + cxx_header = 'dev/riscv/clint.hh' + intrctrl = Param.IntrControl(Parent.any, "interrupt controller") + int_pin = IntSinkPin('Pin to receive RTC signal') + pio_size = Param.Addr(0xC000, "PIO Size") diff --git a/src/dev/riscv/RTC.py b/src/dev/riscv/RTC.py new file mode 100644 index 0000000000..2de7d328e1 --- /dev/null +++ b/src/dev/riscv/RTC.py @@ -0,0 +1,51 @@ +# Copyright (c) 2021 Huawei International +# All rights reserved. +# +# The license below extends only to copyright in the software and shall +# not be construed as granting a license to any other intellectual +# property including but not limited to intellectual property relating +# to a hardware implementation of the functionality of the software +# licensed hereunder. You may use the software subject to the license +# terms below provided that you ensure that this notice is replicated +# unmodified and in its entirety in all distributions of the software, +# modified or unmodified, in source code or in binary form. +# +# 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.params import * +from m5.proxy import * +from m5.SimObject import SimObject +from m5.objects.IntPin import IntSourcePin + +class RiscvRTC(SimObject): + type = 'RiscvRTC' + cxx_class='RiscvRTC' + cxx_header = "dev/riscv/rtc.hh" + time = Param.Time('01/01/2012', + "System time to use") + int_pin = IntSourcePin('Pin to signal RTC interrupts to') + # The default 1MHz setting is taken from SiFive's U54MC + # core complex. Set to other frequencies if necessary. + frequency = Param.Frequency("1MHz", "RTC Frequency") + bcd = Param.Bool(False, "Binary Coded Decimal Mode for MC146818") \ No newline at end of file diff --git a/src/dev/riscv/SConscript b/src/dev/riscv/SConscript new file mode 100755 index 0000000000..43946c2bfa --- /dev/null +++ b/src/dev/riscv/SConscript @@ -0,0 +1,39 @@ +# -*- mode:python -*- + +# Copyright (c) 2021 Huawei International +# 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('*') + +if env['TARGET_ISA'] == 'riscv': + + SimObject('Clint.py') + SimObject('RTC.py') + + DebugFlag('Clint') + + Source('clint.cc') + Source('rtc.cc') diff --git a/src/dev/riscv/clint.cc b/src/dev/riscv/clint.cc new file mode 100644 index 0000000000..641ba6f773 --- /dev/null +++ b/src/dev/riscv/clint.cc @@ -0,0 +1,226 @@ +/* + * Copyright (c) 2021 Huawei International + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * 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/riscv/clint.hh" + +#include "debug/Clint.hh" +#include "mem/packet.hh" +#include "mem/packet_access.hh" +#include "params/Clint.hh" +#include "sim/system.hh" + +using namespace RiscvISA; + +Clint::Clint(const Params ¶ms) : + BasicPioDevice(params, params.pio_size), + system(params.system), + intrctrl(params.intrctrl), + signal(params.name + ".signal", 0, this), + registers(params.name + ".registers", params.pio_addr, this) +{ +} + +void +Clint::raiseInterruptPin(int id) +{ + // Increment mtime + uint64_t& mtime = registers.mtime.get(); + mtime++; + + for (int context_id = 0; context_id < nThread; context_id++) { + + // Update misc reg file + system->threads[context_id]->setMiscRegNoEffect(MISCREG_TIME, mtime); + + // Post timer interrupt + uint64_t mtimecmp = registers.mtimecmp[context_id].get(); + if (mtime >= mtimecmp) { + if (mtime == mtimecmp) { + DPRINTF(Clint, + "MTIP posted - thread: %d, mtime: %d, mtimecmp: %d\n", + context_id, mtime, mtimecmp); + } + intrctrl->post(context_id, ExceptionCode::INT_TIMER_MACHINE, 0); + } else { + intrctrl->clear(context_id, ExceptionCode::INT_TIMER_MACHINE, 0); + } + } +} + +void +Clint::ClintRegisters::init() +{ + using namespace std::placeholders; + + // Calculate reserved space size + const size_t reserved0_size = mtimecmpStart - clint->nThread * 4; + reserved.emplace_back("reserved0", reserved0_size); + const size_t reserved1_size = mtimeStart + - mtimecmpStart - clint->nThread * 8; + reserved.emplace_back("reserved1", reserved1_size); + + // Sanity check + assert((int) clint->pioSize <= maxBankSize); + + // Initialize registers + for (int i = 0; i < clint->nThread; i++) { + msip.emplace_back(std::string("msip") + std::to_string(i), 0); + mtimecmp.emplace_back(std::string("mtimecmp") + std::to_string(i), 0); + } + + // Add registers to bank + for (int i = 0; i < clint->nThread; i++) { + auto read_cb = std::bind(&Clint::readMSIP, clint, _1, i); + msip[i].reader(read_cb); + auto write_cb = std::bind(&Clint::writeMSIP, clint, _1, _2, i); + msip[i].writer(write_cb); + addRegister(msip[i]); + } + addRegister(reserved[0]); + for (int i = 0; i < clint->nThread; i++) { + addRegister(mtimecmp[i]); + } + addRegister(reserved[1]); + mtime.readonly(); + addRegister(mtime); +} + +uint32_t +Clint::readMSIP(Register32& reg, const int thread_id) +{ + // To avoid discrepancies if mip is externally set using remote_gdb etc. + auto tc = system->threads[thread_id]; + RegVal mip = tc->readMiscReg(MISCREG_IP); + uint32_t msip = bits(mip, ExceptionCode::INT_SOFTWARE_MACHINE); + reg.update(msip); + return reg.get(); +}; + +void +Clint::writeMSIP(Register32& reg, const uint32_t& data, const int thread_id) +{ + reg.update(data); + assert(data <= 1); + if (data > 0) { + DPRINTF(Clint, + "MSIP posted - thread: %d\n", thread_id); + intrctrl->post(thread_id, + ExceptionCode::INT_SOFTWARE_MACHINE, 0); + } else { + DPRINTF(Clint, + "MSIP cleared - thread: %d\n", thread_id); + intrctrl->clear(thread_id, + ExceptionCode::INT_SOFTWARE_MACHINE, 0); + } +}; + +Tick +Clint::read(PacketPtr pkt) +{ + // Check for atomic operation + bool is_atomic = pkt->isAtomicOp() && pkt->cmd == MemCmd::SwapReq; + DPRINTF(Clint, + "Read request - addr: %#x, size: %#x, atomic:%d\n", + pkt->getAddr(), pkt->getSize(), is_atomic); + + // Perform register read + registers.read(pkt->getAddr(), pkt->getPtr(), pkt->getSize()); + + if (is_atomic) { + // Perform atomic operation + (*(pkt->getAtomicOp()))(pkt->getPtr()); + return write(pkt); + } else { + pkt->makeResponse(); + return pioDelay; + } +} + +Tick +Clint::write(PacketPtr pkt) +{ + DPRINTF(Clint, + "Write request - addr: %#x, size: %#x\n", + pkt->getAddr(), pkt->getSize()); + + // Perform register write + registers.write(pkt->getAddr(), pkt->getPtr(), pkt->getSize()); + + pkt->makeResponse(); + return pioDelay; +} + +void +Clint::init() +{ + nThread = system->threads.size(); + registers.init(); + BasicPioDevice::init(); +} + +Port & +Clint::getPort(const std::string &if_name, PortID idx) +{ + if (if_name == "int_pin") + return signal; + else + return BasicPioDevice::getPort(if_name, idx); +} + +void +Clint::serialize(CheckpointOut &cp) const +{ + for (auto const ®: registers.msip) { + paramOut(cp, reg.name(), reg); + } + for (auto const ®: registers.mtimecmp) { + paramOut(cp, reg.name(), reg); + } + paramOut(cp, "mtime", registers.mtime); +} + +void +Clint::unserialize(CheckpointIn &cp) +{ + for (auto ®: registers.msip) { + paramIn(cp, reg.name(), reg); + } + for (auto ®: registers.mtimecmp) { + paramIn(cp, reg.name(), reg); + } + paramIn(cp, "mtime", registers.mtime); +} diff --git a/src/dev/riscv/clint.hh b/src/dev/riscv/clint.hh new file mode 100644 index 0000000000..7b1745c64b --- /dev/null +++ b/src/dev/riscv/clint.hh @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2021 Huawei International + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * 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_RISCV_CLINT_HH__ +#define __DEV_RISCV_CLINT_HH__ + +#include "arch/riscv/interrupts.hh" +#include "arch/riscv/registers.hh" +#include "cpu/intr_control.hh" +#include "dev/intpin.hh" +#include "dev/io_device.hh" +#include "dev/mc146818.hh" +#include "dev/reg_bank.hh" +#include "mem/packet.hh" +#include "mem/packet_access.hh" +#include "params/Clint.hh" +#include "sim/system.hh" + +using namespace RiscvISA; + +/** + * NOTE: + * This implementation of CLINT is based on + * the SiFive U54MC datasheet: + * https://sifive.cdn.prismic.io/sifive/fab000f6- + * 0e07-48d0-9602-e437d5367806_sifive_U54MC_rtl_ + * full_20G1.03.00_manual.pdf + */ + +/** + * Future improvement of the model can check + * the current privilege mode and enforce + * access control. + */ +class Clint : public BasicPioDevice +{ + // Params + protected: + System *system; + IntrControl *intrctrl; + int nThread; + IntSinkPin signal; + + public: + typedef ClintParams Params; + Clint(const Params ¶ms); + + // RTC Signal + public: + /** + * Timer tick callback. Separated from RTC class + * for easier implementation of a separate RTC + * PioDevice. + */ + void raiseInterruptPin(int id); + void lowerInterruptPin(int id) {} + + // Register bank + public: + + /** + * MMIO Registers + * 0x0000 - 0x3FFF: msip (write-through to misc reg file) + * ...: reserved[0] + * 0x4000 - 0xBFF7: mtimecmp + * ...: reserved[1] + * 0xBFF8: mtime (read-only) + */ + class ClintRegisters: public RegisterBankLE { + + public: + const Addr mtimecmpStart = 0x4000; + const Addr mtimeStart = 0xBFF8; + const Addr maxBankSize = 0xC000; + + std::vector msip; + std::vector mtimecmp; + Register64 mtime = {"mtime", 0}; + std::vector reserved; + + ClintRegisters(const std::string &name, Addr base, Clint* clint) : + RegisterBankLE(name, base), + clint(clint) {} + + Clint *clint; + + void init(); + + } registers; + + using Register32 = ClintRegisters::Register32; + + uint32_t readMSIP(Register32& reg, const int thread_id); + void writeMSIP(Register32& reg, const uint32_t& data, const int thread_id); + + // External API + public: + /** + * PioDevice interface functions + */ + Tick read(PacketPtr pkt) override; + Tick write(PacketPtr pkt) override; + + /** + * SimObject functions + */ + void init() override; + Port & getPort(const std::string &if_name, PortID idx=InvalidPortID); + void serialize(CheckpointOut &cp) const override; + void unserialize(CheckpointIn &cp) override; + +}; + + +#endif // __DEV_RISCV_CLINT_HH__ diff --git a/src/dev/riscv/rtc.cc b/src/dev/riscv/rtc.cc new file mode 100644 index 0000000000..0f6e8446f4 --- /dev/null +++ b/src/dev/riscv/rtc.cc @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2021 Huawei International + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * 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/riscv/rtc.hh" + +#include "dev/mc146818.hh" +#include "params/RiscvRTC.hh" + +RiscvRTC::RiscvRTC(const Params ¶ms) : + SimObject(params), + rtc(this, params.name, params.time, params.bcd, + params.frequency, params.port_int_pin_connection_count) +{ +} + +RiscvRTC::RTC::RTC(EventManager *em, const std::string &n, + const struct tm time, bool bcd, Tick frequency, int int_pin_count) : + MC146818(em, n, time, bcd, frequency) +{ + for (int i = 0; i < int_pin_count; i++) { + intPin.emplace_back(new IntSourcePin( + csprintf("%s.int_pin[%d]", n, i), i, this)); + } +} + +void +RiscvRTC::RTC::handleEvent() +{ + for (auto &pin: intPin) { + pin->raise(); + pin->lower(); + } +} + +Port & +RiscvRTC::getPort(const std::string &if_name, PortID idx) +{ + if (if_name == "int_pin") + return *rtc.intPin.at(idx); + else + panic("Getting invalid port " + if_name); +} + +void +RiscvRTC::startup() +{ + rtc.startup(); +} + +void +RiscvRTC::serialize(CheckpointOut &cp) const +{ + // Serialize the timer + rtc.serialize("rtc", cp); +} + +void +RiscvRTC::unserialize(CheckpointIn &cp) +{ + // Serialize the timer + rtc.unserialize("rtc", cp); +} diff --git a/src/dev/riscv/rtc.hh b/src/dev/riscv/rtc.hh new file mode 100644 index 0000000000..bfd9071333 --- /dev/null +++ b/src/dev/riscv/rtc.hh @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2021 Huawei International + * All rights reserved + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * + * 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_RISCV_RTC_HH__ +#define __DEV_RISCV_RTC_HH__ + +#include "dev/intpin.hh" +#include "dev/mc146818.hh" +#include "params/RiscvRTC.hh" +#include "sim/sim_object.hh" + +/** + * NOTE: + * This is a generic wrapper around the MC146818 RTC + */ + +class RiscvRTC : public SimObject +{ + public: + + class RTC: public MC146818 + { + public: + using IntSource = IntSourcePin; + + std::vector> intPin; + + RTC(EventManager *em, const std::string &n, const struct tm time, + bool bcd, Tick frequency, int int_pin_count); + + protected: + void handleEvent(); + } rtc; + + typedef RiscvRTCParams Params; + + RiscvRTC(const Params ¶ms); + + Port & getPort(const std::string &if_name, PortID idx=InvalidPortID); + + void startup(); + + void serialize(CheckpointOut &cp) const override; + void unserialize(CheckpointIn &cp) override; +}; + +#endif //__DEV_RISCV_RTC_HH__