dev: Added new LupIO-TMR device
This device is a virtual timer that provides both a real-time counter, as well as a configurable timer with periodic and one-shot modes. It uses Ticks to measure time, and is implemented as a BasicPioDevice. The following are the specifications regarding the LupIO-TMR: https://gitlab.com/luplab/lupio/lupio-specs/-/blob/main/lupio-tmr.md Change-Id: I6fd6f4926494a44d20e1e0289f502535e84d7a69 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/53035 Maintainer: Bobby Bruce <bbruce@ucdavis.edu> Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
This commit is contained in:
committed by
melissa jost
parent
64f7a6c371
commit
fadb88c06b
36
src/dev/lupio/LupioTMR.py
Normal file
36
src/dev/lupio/LupioTMR.py
Normal file
@@ -0,0 +1,36 @@
|
||||
# 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 LupioTMR(BasicPioDevice):
|
||||
type = 'LupioTMR'
|
||||
cxx_class='gem5::LupioTMR'
|
||||
cxx_header = 'dev/lupio/lupio_tmr.hh'
|
||||
pio_size = Param.Addr(0x1000, "PIO Size")
|
||||
num_threads = Param.Int("Number of threads in the system.")
|
||||
int_type = Param.Int("Type of interrupt.")
|
||||
@@ -29,14 +29,17 @@ Import('*')
|
||||
SimObject('LupioBLK.py', tags='riscv isa')
|
||||
SimObject('LupioRNG.py', tags='riscv isa')
|
||||
SimObject('LupioRTC.py', tags='riscv isa')
|
||||
SimObject('LupioTMR.py', tags='riscv isa')
|
||||
SimObject('LupioTTY.py', tags='riscv isa')
|
||||
|
||||
DebugFlag('LupioBLK')
|
||||
DebugFlag('LupioRNG')
|
||||
DebugFlag('LupioRTC')
|
||||
DebugFlag('LupioTMR')
|
||||
DebugFlag('LupioTTY')
|
||||
|
||||
Source('lupio_blk.cc', tags='riscv isa')
|
||||
Source('lupio_rng.cc', tags='riscv isa')
|
||||
Source('lupio_rtc.cc', tags='riscv isa')
|
||||
Source('lupio_tty.cc', tags='riscv isa')
|
||||
Source('lupio_tmr.cc', tags='riscv isa')
|
||||
Source('lupio_tty.cc', tags='riscv isa')
|
||||
203
src/dev/lupio/lupio_tmr.cc
Normal file
203
src/dev/lupio/lupio_tmr.cc
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* 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_tmr.hh"
|
||||
|
||||
#include "cpu/base.hh"
|
||||
#include "debug/LupioTMR.hh"
|
||||
#include "mem/packet_access.hh"
|
||||
#include "params/LupioTMR.hh"
|
||||
|
||||
// Specific fields for CTRL
|
||||
#define LUPIO_TMR_IE 0x1
|
||||
#define LUPIO_TMR_PD 0x2
|
||||
|
||||
// Specific fields for STAT
|
||||
#define LUPIO_TMR_EX 0x1
|
||||
|
||||
namespace gem5
|
||||
{
|
||||
|
||||
LupioTMR::LupioTMR(const Params ¶ms) :
|
||||
BasicPioDevice(params, params.pio_size),
|
||||
system(params.system),
|
||||
nThread(params.num_threads),
|
||||
tmrEvent([this]{ lupioTMRCallback(); }, name()),
|
||||
intType(params.int_type)
|
||||
{
|
||||
DPRINTF(LupioTMR, "LupioTMR initalized\n");
|
||||
}
|
||||
|
||||
void
|
||||
LupioTMR::updateIRQ(int level)
|
||||
{
|
||||
if (nThread > 1) {
|
||||
panic("This device currently does not offer SMP support\n");
|
||||
}
|
||||
|
||||
auto tc = system->threads[0];
|
||||
// post an interrupt
|
||||
if (level) {
|
||||
tc->getCpuPtr()->postInterrupt(tc->threadId(), intType, 0);
|
||||
}
|
||||
// clear the interrupt
|
||||
else {
|
||||
tc->getCpuPtr()->clearInterrupt(tc->threadId(), intType, 0);
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t
|
||||
LupioTMR::lupioTMRCurrentTime()
|
||||
{
|
||||
return curTick() / sim_clock::as_int::ns;
|
||||
}
|
||||
|
||||
void
|
||||
LupioTMR::lupioTMRSet()
|
||||
{
|
||||
startTime = curTick();
|
||||
if (!tmrEvent.scheduled()) {
|
||||
schedule(tmrEvent, (reload * sim_clock::as_int::ns) + curTick());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LupioTMR::lupioTMRCallback()
|
||||
{
|
||||
// Signal expiration
|
||||
expired = true;
|
||||
if (ie) {
|
||||
updateIRQ(1);
|
||||
}
|
||||
|
||||
// If periodic timer, reload
|
||||
if (pd && reload) {
|
||||
lupioTMRSet();
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t
|
||||
LupioTMR::lupioTMRRead(uint8_t addr, int size)
|
||||
{
|
||||
uint64_t r = 0;
|
||||
|
||||
switch (addr >> 2) {
|
||||
case LUPIO_TMR_TIME:
|
||||
r = lupioTMRCurrentTime();
|
||||
DPRINTF(LupioTMR, "Read LUPIO_TMR_TME: %d\n", r);
|
||||
break;
|
||||
case LUPIO_TMR_LOAD:
|
||||
r = reload;
|
||||
DPRINTF(LupioTMR, "Read LUPIO_TMR_LOAD: %d\n", r);
|
||||
break;
|
||||
case LUPIO_TMR_STAT:
|
||||
if (expired) {
|
||||
r |= LUPIO_TMR_EX;
|
||||
}
|
||||
|
||||
// Acknowledge expiration
|
||||
expired = false;
|
||||
DPRINTF(LupioTMR, "Read LUPIO_TMR_STAT: %d\n", r);
|
||||
updateIRQ(0);
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("Unexpected read to the LupioTMR device at address %#llx!",
|
||||
addr);
|
||||
break;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
void
|
||||
LupioTMR::lupioTMRWrite(uint8_t addr, uint64_t val64, int size)
|
||||
{
|
||||
uint32_t val = val64;
|
||||
|
||||
switch (addr >> 2) {
|
||||
case LUPIO_TMR_LOAD:
|
||||
reload = val;
|
||||
DPRINTF(LupioTMR, "Write LUPIO_TMR_LOAD: %d\n", reload);
|
||||
break;
|
||||
|
||||
case LUPIO_TMR_CTRL:
|
||||
ie = val & LUPIO_TMR_IE;
|
||||
pd = val & LUPIO_TMR_PD;
|
||||
DPRINTF(LupioTMR, "Write LUPIO_TMR_CTRL\n");
|
||||
|
||||
// Stop current timer if any
|
||||
if (curTick() < startTime + (reload * sim_clock::as_int::ns)
|
||||
&& tmrEvent.scheduled()) {
|
||||
deschedule(tmrEvent);
|
||||
}
|
||||
|
||||
// If reload isn't 0, start a new one
|
||||
if (reload) {
|
||||
lupioTMRSet();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
panic("Unexpected write to the LupioTMR device at address %#llx!",
|
||||
addr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Tick
|
||||
LupioTMR::read(PacketPtr pkt)
|
||||
{
|
||||
Addr tmr_addr = pkt->getAddr() - pioAddr;
|
||||
|
||||
DPRINTF(LupioTMR,
|
||||
"Read request - addr: %#x, size: %#x\n", tmr_addr, pkt->getSize());
|
||||
|
||||
uint64_t read_val = lupioTMRRead(tmr_addr, pkt->getSize());
|
||||
DPRINTF(LupioTMR, "Packet Read: %#x\n", read_val);
|
||||
pkt->setUintX(read_val, byteOrder);
|
||||
pkt->makeResponse();
|
||||
|
||||
return pioDelay;
|
||||
}
|
||||
|
||||
Tick
|
||||
LupioTMR::write(PacketPtr pkt)
|
||||
{
|
||||
Addr tmr_addr = pkt->getAddr() - pioAddr;
|
||||
|
||||
DPRINTF(LupioTMR, "Write register %#x value %#x\n", tmr_addr,
|
||||
pkt->getUintX(byteOrder));
|
||||
|
||||
lupioTMRWrite(tmr_addr, pkt->getUintX(byteOrder), pkt->getSize());
|
||||
DPRINTF(LupioTMR, "Packet Write Value: %d\n", pkt->getUintX(byteOrder));
|
||||
|
||||
pkt->makeResponse();
|
||||
|
||||
return pioDelay;
|
||||
}
|
||||
} // namespace gem5
|
||||
120
src/dev/lupio/lupio_tmr.hh
Normal file
120
src/dev/lupio/lupio_tmr.hh
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* 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_TMR_HH__
|
||||
#define __DEV_LUPIO_LUPIO_TMR_HH__
|
||||
|
||||
#include "arch/riscv/interrupts.hh"
|
||||
#include "dev/io_device.hh"
|
||||
#include "dev/platform.hh"
|
||||
#include "params/LupioTMR.hh"
|
||||
|
||||
namespace gem5
|
||||
{
|
||||
|
||||
/**
|
||||
* LupioTMR:
|
||||
* A virtual timer device which provides a real time counter, as well as a
|
||||
* configurable timer offering periodic and one shot modes.
|
||||
*/
|
||||
|
||||
class LupioTMR : public BasicPioDevice
|
||||
{
|
||||
private:
|
||||
const ByteOrder byteOrder = ByteOrder::little;
|
||||
System *system;
|
||||
int nThread;
|
||||
EventFunctionWrapper tmrEvent;
|
||||
int intType;
|
||||
|
||||
Tick startTime = 0;
|
||||
|
||||
// Register map
|
||||
enum
|
||||
{
|
||||
LUPIO_TMR_TIME,
|
||||
LUPIO_TMR_LOAD,
|
||||
LUPIO_TMR_CTRL,
|
||||
LUPIO_TMR_STAT,
|
||||
|
||||
// Max offset
|
||||
LUPIO_TMR_MAX,
|
||||
};
|
||||
|
||||
// Timer registers
|
||||
uint64_t reload = 0;
|
||||
|
||||
// Control
|
||||
bool ie = false;
|
||||
bool pd = false;
|
||||
|
||||
// Status
|
||||
bool expired = false;
|
||||
|
||||
/**
|
||||
* Function to return data pertaining to the timer, such as the simulated
|
||||
* time in ticks
|
||||
*/
|
||||
uint64_t lupioTMRRead(const uint8_t addr, int size);
|
||||
/**
|
||||
* Function to launch or stop the timer depending on the load value
|
||||
*/
|
||||
void lupioTMRWrite(const uint8_t addr, uint64_t val64, int size);
|
||||
|
||||
/**
|
||||
* Return the simulated time
|
||||
*/
|
||||
uint64_t lupioTMRCurrentTime();
|
||||
/**
|
||||
* Schedule the next timer event
|
||||
*/
|
||||
void lupioTMRSet();
|
||||
/**
|
||||
* Process the timer's event
|
||||
*/
|
||||
void lupioTMRCallback();
|
||||
|
||||
/**
|
||||
* Post or clear timer interrupts
|
||||
*/
|
||||
void updateIRQ(int level);
|
||||
|
||||
public:
|
||||
PARAMS(LupioTMR);
|
||||
LupioTMR(const Params ¶ms);
|
||||
|
||||
/**
|
||||
* Implement BasicPioDevice virtual functions
|
||||
*/
|
||||
Tick read(PacketPtr pkt) override;
|
||||
Tick write(PacketPtr pkt) override;
|
||||
};
|
||||
|
||||
} // namespace gem5
|
||||
|
||||
#endif // __DEV_LUPIO_LUPIO_TMR_HH_
|
||||
Reference in New Issue
Block a user