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 <noreply+kokoro@google.com> Reviewed-by: Ayaz Akram <yazakram@ucdavis.edu> Reviewed-by: Jason Lowe-Power <power.jg@gmail.com> Maintainer: Jason Lowe-Power <power.jg@gmail.com>
This commit is contained in:
@@ -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;
|
||||
|
||||
53
src/dev/riscv/Clint.py
Normal file
53
src/dev/riscv/Clint.py
Normal file
@@ -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")
|
||||
51
src/dev/riscv/RTC.py
Normal file
51
src/dev/riscv/RTC.py
Normal file
@@ -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")
|
||||
39
src/dev/riscv/SConscript
Executable file
39
src/dev/riscv/SConscript
Executable file
@@ -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')
|
||||
226
src/dev/riscv/clint.cc
Normal file
226
src/dev/riscv/clint.cc
Normal file
@@ -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<uint32_t>(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<void>(), pkt->getSize());
|
||||
|
||||
if (is_atomic) {
|
||||
// Perform atomic operation
|
||||
(*(pkt->getAtomicOp()))(pkt->getPtr<uint8_t>());
|
||||
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<void>(), 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);
|
||||
}
|
||||
149
src/dev/riscv/clint.hh
Normal file
149
src/dev/riscv/clint.hh
Normal file
@@ -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<Clint> 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<Register32> msip;
|
||||
std::vector<Register64> mtimecmp;
|
||||
Register64 mtime = {"mtime", 0};
|
||||
std::vector<RegisterRaz> 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__
|
||||
96
src/dev/riscv/rtc.cc
Normal file
96
src/dev/riscv/rtc.cc
Normal file
@@ -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<RTC>(
|
||||
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);
|
||||
}
|
||||
81
src/dev/riscv/rtc.hh
Normal file
81
src/dev/riscv/rtc.hh
Normal file
@@ -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<RTC>;
|
||||
|
||||
std::vector<std::unique_ptr<IntSource>> 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__
|
||||
Reference in New Issue
Block a user