misc: Replaced master/slave terminology
Change-Id: I4df2557c71e38cc4e3a485b0e590e85eb45de8b6 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/33553 Maintainer: Jason Lowe-Power <power.jg@gmail.com> Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br> Reviewed-by: Bobby R. Bruce <bbruce@ucdavis.edu> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -93,8 +93,9 @@ class AmbaDmaDevice(DmaDevice):
|
||||
type = 'AmbaDmaDevice'
|
||||
abstract = True
|
||||
cxx_header = "dev/arm/amba_device.hh"
|
||||
pio_addr = Param.Addr("Address for AMBA slave interface")
|
||||
pio_latency = Param.Latency("10ns", "Time between action and write/read result by AMBA DMA Device")
|
||||
pio_addr = Param.Addr("Address for AMBA responder interface")
|
||||
pio_latency = Param.Latency("10ns", "Time between action and write/read"
|
||||
"result by AMBA DMA Device")
|
||||
interrupt = Param.ArmInterruptPin("Interrupt that connects to GIC")
|
||||
amba_id = Param.UInt32("ID of AMBA device for kernel detection")
|
||||
|
||||
@@ -576,16 +577,16 @@ class RealView(Platform):
|
||||
def _attach_memory(self, mem, bus, mem_ports=None):
|
||||
if hasattr(mem, "port"):
|
||||
if mem_ports is None:
|
||||
mem.port = bus.master
|
||||
mem.port = bus.mem_side_ports
|
||||
else:
|
||||
mem_ports.append(mem.port)
|
||||
|
||||
def _attach_device(self, device, bus, dma_ports=None):
|
||||
if hasattr(device, "pio"):
|
||||
device.pio = bus.master
|
||||
device.pio = bus.mem_side_ports
|
||||
if hasattr(device, "dma"):
|
||||
if dma_ports is None:
|
||||
device.dma = bus.slave
|
||||
device.dma = bus.cpu_side_ports
|
||||
else:
|
||||
dma_ports.append(device.dma)
|
||||
|
||||
@@ -1092,15 +1093,15 @@ Interrupts:
|
||||
"""
|
||||
Instantiate a single SMMU and attach a group of client devices to it.
|
||||
The devices' dma port is wired to the SMMU and the SMMU's dma port
|
||||
(master) is attached to the bus. In order to make it work, the list
|
||||
of clients shouldn't contain any device part of the _off_chip_devices
|
||||
or _on_chip_devices.
|
||||
is attached to the bus. In order to make it work, the list of clients
|
||||
shouldn't contain any device part of the _off_chip_devices or
|
||||
_on_chip_devices.
|
||||
This method should be called only once.
|
||||
|
||||
Parameters:
|
||||
devices (list): List of devices which will be using the SMMU
|
||||
bus (Bus): The bus downstream of the SMMU. Its slave port will
|
||||
receive memory requests from the SMMU, and its master
|
||||
bus (Bus): The bus downstream of the SMMU. Its response port will
|
||||
receive memory requests from the SMMU, and its request
|
||||
port will forward accesses to the memory mapped devices
|
||||
"""
|
||||
if hasattr(self, 'smmu'):
|
||||
@@ -1108,8 +1109,8 @@ Interrupts:
|
||||
|
||||
self.smmu = SMMUv3(reg_map=AddrRange(0x2b400000, size=0x00020000))
|
||||
|
||||
self.smmu.master = bus.slave
|
||||
self.smmu.control = bus.master
|
||||
self.smmu.request = bus.cpu_side_ports
|
||||
self.smmu.control = bus.mem_side_ports
|
||||
|
||||
dma_ports = []
|
||||
for dev in devices:
|
||||
|
||||
@@ -77,7 +77,7 @@ if env['TARGET_ISA'] == 'arm':
|
||||
Source('smmu_v3_ports.cc');
|
||||
Source('smmu_v3_proc.cc');
|
||||
Source('smmu_v3_ptops.cc');
|
||||
Source('smmu_v3_slaveifc.cc');
|
||||
Source('smmu_v3_deviceifc.cc');
|
||||
Source('smmu_v3_transl.cc');
|
||||
Source('timer_sp804.cc')
|
||||
Source('watchdog_sp805.cc')
|
||||
|
||||
@@ -39,13 +39,21 @@ from m5.util.fdthelper import *
|
||||
from m5.SimObject import *
|
||||
from m5.objects.ClockedObject import ClockedObject
|
||||
|
||||
class SMMUv3SlaveInterface(ClockedObject):
|
||||
type = 'SMMUv3SlaveInterface'
|
||||
cxx_header = 'dev/arm/smmu_v3_slaveifc.hh'
|
||||
class SMMUv3DeviceInterface(ClockedObject):
|
||||
type = 'SMMUv3DeviceInterface'
|
||||
cxx_header = 'dev/arm/smmu_v3_deviceifc.hh'
|
||||
|
||||
slave = ResponsePort('Device port')
|
||||
ats_master = RequestPort('ATS master port')
|
||||
ats_slave = ResponsePort('ATS slave port')
|
||||
device_port = ResponsePort('Device port')
|
||||
slave = DeprecatedParam(device_port,
|
||||
'`slave` is now called `device_port`')
|
||||
ats_mem_side_port = RequestPort('ATS mem side port,'
|
||||
'sends requests and receives responses')
|
||||
ats_master = DeprecatedParam(ats_mem_side_port,
|
||||
'`ats_master` is now called `ats_mem_side_port`')
|
||||
ats_dev_side_port = ResponsePort('ATS dev_side_port,'
|
||||
'sends responses and receives requests')
|
||||
ats_slave = DeprecatedParam(ats_dev_side_port,
|
||||
'`ats_slave` is now called `ats_dev_side_port`')
|
||||
|
||||
port_width = Param.Unsigned(16, 'Port width in bytes (= 1 beat)')
|
||||
wrbuf_slots = Param.Unsigned(16, 'Write buffer size (in beats)')
|
||||
@@ -74,18 +82,19 @@ class SMMUv3(ClockedObject):
|
||||
type = 'SMMUv3'
|
||||
cxx_header = 'dev/arm/smmu_v3.hh'
|
||||
|
||||
master = RequestPort('Master port')
|
||||
master_walker = RequestPort(
|
||||
'Master port for SMMU initiated HWTW requests (optional)')
|
||||
request = RequestPort('Request port')
|
||||
walker = RequestPort(
|
||||
'Request port for SMMU initiated HWTW requests (optional)')
|
||||
control = ResponsePort(
|
||||
'Control port for accessing memory-mapped registers')
|
||||
sample_period = Param.Clock('10us', 'Stats sample period')
|
||||
reg_map = Param.AddrRange('Address range for control registers')
|
||||
system = Param.System(Parent.any, "System this device is part of")
|
||||
|
||||
slave_interfaces = VectorParam.SMMUv3SlaveInterface([], "Slave interfaces")
|
||||
device_interfaces = VectorParam.SMMUv3DeviceInterface([],
|
||||
"Responder interfaces")
|
||||
|
||||
# SLAVE INTERFACE<->SMMU link parameters
|
||||
# RESPONDER INTERFACE<->SMMU link parameters
|
||||
ifc_smmu_lat = Param.Cycles(8, 'IFC to SMMU communication latency')
|
||||
smmu_ifc_lat = Param.Cycles(8, 'SMMU to IFC communication latency')
|
||||
|
||||
@@ -93,8 +102,8 @@ class SMMUv3(ClockedObject):
|
||||
xlate_slots = Param.Unsigned(64, 'SMMU translation slots')
|
||||
ptw_slots = Param.Unsigned(16, 'SMMU page table walk slots')
|
||||
|
||||
master_port_width = Param.Unsigned(16,
|
||||
'Master port width in bytes (= 1 beat)')
|
||||
request_port_width = Param.Unsigned(16,
|
||||
'Request port width in bytes (= 1 beat)')
|
||||
|
||||
tlb_entries = Param.Unsigned(2048, 'TLB size (entries)')
|
||||
tlb_assoc = Param.Unsigned(4, 'TLB associativity (0=full)')
|
||||
@@ -185,23 +194,23 @@ class SMMUv3(ClockedObject):
|
||||
|
||||
def connect(self, device):
|
||||
"""
|
||||
Helper method used to connect the SMMU. The master could
|
||||
Helper method used to connect the SMMU. The requestor could
|
||||
be either a dma port (if the SMMU is attached directly to a
|
||||
dma device), or to a master port (this is the case where the SMMU
|
||||
dma device), or to a request port (this is the case where the SMMU
|
||||
is attached to a bridge).
|
||||
"""
|
||||
|
||||
slave_interface = SMMUv3SlaveInterface()
|
||||
device_interface = SMMUv3DeviceInterface()
|
||||
|
||||
if hasattr(device, "master"):
|
||||
slave_interface.slave = device.master
|
||||
if hasattr(device, "request_port"):
|
||||
device_interface.device_port = device.request_port
|
||||
elif hasattr(device, "dma"):
|
||||
slave_interface.slave = device.dma
|
||||
device_interface.device_port = device.dma
|
||||
else:
|
||||
print("Unable to attach SMMUv3\n")
|
||||
sys.exit(1)
|
||||
|
||||
self.slave_interfaces.append(slave_interface)
|
||||
self.device_interfaces.append(device_interface)
|
||||
|
||||
# Storing a reference to the smmu to be used when generating
|
||||
# the binding in the device DTB.
|
||||
|
||||
@@ -42,7 +42,7 @@ from m5.objects.AbstractNVM import *
|
||||
class UFSHostDevice(DmaDevice):
|
||||
type = 'UFSHostDevice'
|
||||
cxx_header = "dev/arm/ufs_device.hh"
|
||||
pio_addr = Param.Addr("Address for SCSI configuration slave interface")
|
||||
pio_addr = Param.Addr("Address for SCSI configuration responder interface")
|
||||
pio_latency = Param.Latency("10ns", "Time between action and write/read \
|
||||
result by AMBA DMA Device")
|
||||
gic = Param.BaseGic(Parent.any, "Gic to use for interrupting")
|
||||
|
||||
@@ -43,12 +43,12 @@
|
||||
namespace AMBA
|
||||
{
|
||||
|
||||
typedef MasterID OrderID;
|
||||
typedef RequestorID OrderID;
|
||||
|
||||
static OrderID
|
||||
orderId(PacketPtr pkt)
|
||||
{
|
||||
return pkt->req->masterId();
|
||||
return pkt->req->requestorId();
|
||||
}
|
||||
|
||||
} // namespace AMBA
|
||||
|
||||
@@ -89,7 +89,7 @@ ItsProcess::doRead(Yield &yield, Addr addr, void *ptr, size_t size)
|
||||
a.type = ItsActionType::SEND_REQ;
|
||||
|
||||
RequestPtr req = std::make_shared<Request>(
|
||||
addr, size, 0, its.masterId);
|
||||
addr, size, 0, its.requestorId);
|
||||
|
||||
req->taskId(ContextSwitchTaskId::DMA);
|
||||
|
||||
@@ -113,7 +113,7 @@ ItsProcess::doWrite(Yield &yield, Addr addr, void *ptr, size_t size)
|
||||
a.type = ItsActionType::SEND_REQ;
|
||||
|
||||
RequestPtr req = std::make_shared<Request>(
|
||||
addr, size, 0, its.masterId);
|
||||
addr, size, 0, its.requestorId);
|
||||
|
||||
req->taskId(ContextSwitchTaskId::DMA);
|
||||
|
||||
@@ -779,7 +779,7 @@ Gicv3Its::Gicv3Its(const Gicv3ItsParams *params)
|
||||
gitsCbaser(0), gitsCreadr(0),
|
||||
gitsCwriter(0), gitsIidr(0),
|
||||
tableBases(NUM_BASER_REGS, 0),
|
||||
masterId(params->system->getMasterId(this)),
|
||||
requestorId(params->system->getRequestorId(this)),
|
||||
gic(nullptr),
|
||||
commandEvent([this] { checkCommandQueue(); }, name()),
|
||||
pendingCommands(false),
|
||||
|
||||
@@ -319,7 +319,7 @@ class Gicv3Its : public BasicPioDevice
|
||||
|
||||
private:
|
||||
std::queue<ItsAction> packetsToRetry;
|
||||
uint32_t masterId;
|
||||
uint32_t requestorId;
|
||||
Gicv3 *gic;
|
||||
EventFunctionWrapper commandEvent;
|
||||
|
||||
|
||||
@@ -54,9 +54,9 @@
|
||||
SMMUv3::SMMUv3(SMMUv3Params *params) :
|
||||
ClockedObject(params),
|
||||
system(*params->system),
|
||||
masterId(params->system->getMasterId(this)),
|
||||
masterPort(name() + ".master", *this),
|
||||
masterTableWalkPort(name() + ".master_walker", *this),
|
||||
requestorId(params->system->getRequestorId(this)),
|
||||
requestPort(name() + ".request", *this),
|
||||
tableWalkPort(name() + ".walker", *this),
|
||||
controlPort(name() + ".control", *this, params->reg_map),
|
||||
tlb(params->tlb_entries, params->tlb_assoc, params->tlb_policy),
|
||||
configCache(params->cfg_entries, params->cfg_assoc, params->cfg_policy),
|
||||
@@ -74,14 +74,14 @@ SMMUv3::SMMUv3(SMMUv3Params *params) :
|
||||
walkCacheNonfinalEnable(params->wc_nonfinal_enable),
|
||||
walkCacheS1Levels(params->wc_s1_levels),
|
||||
walkCacheS2Levels(params->wc_s2_levels),
|
||||
masterPortWidth(params->master_port_width),
|
||||
requestPortWidth(params->request_port_width),
|
||||
tlbSem(params->tlb_slots),
|
||||
ifcSmmuSem(1),
|
||||
smmuIfcSem(1),
|
||||
configSem(params->cfg_slots),
|
||||
ipaSem(params->ipa_slots),
|
||||
walkSem(params->walk_slots),
|
||||
masterPortSem(1),
|
||||
requestPortSem(1),
|
||||
transSem(params->xlate_slots),
|
||||
ptwSem(params->ptw_slots),
|
||||
cycleSem(1),
|
||||
@@ -91,7 +91,7 @@ SMMUv3::SMMUv3(SMMUv3Params *params) :
|
||||
configLat(params->cfg_lat),
|
||||
ipaLat(params->ipa_lat),
|
||||
walkLat(params->walk_lat),
|
||||
slaveInterfaces(params->slave_interfaces),
|
||||
deviceInterfaces(params->device_interfaces),
|
||||
commandExecutor(name() + ".cmd_exec", *this),
|
||||
regsMap(params->reg_map),
|
||||
processCommandsEvent(this)
|
||||
@@ -119,14 +119,14 @@ SMMUv3::SMMUv3(SMMUv3Params *params) :
|
||||
// store an unallowed values or if the are configuration conflicts.
|
||||
warn("SMMUv3 IDx register values unchecked\n");
|
||||
|
||||
for (auto ifc : slaveInterfaces)
|
||||
for (auto ifc : deviceInterfaces)
|
||||
ifc->setSMMU(this);
|
||||
}
|
||||
|
||||
bool
|
||||
SMMUv3::masterRecvTimingResp(PacketPtr pkt)
|
||||
SMMUv3::recvTimingResp(PacketPtr pkt)
|
||||
{
|
||||
DPRINTF(SMMUv3, "[t] master resp addr=%#x size=%#x\n",
|
||||
DPRINTF(SMMUv3, "[t] requestor resp addr=%#x size=%#x\n",
|
||||
pkt->getAddr(), pkt->getSize());
|
||||
|
||||
// @todo: We need to pay for this and not just zero it out
|
||||
@@ -141,7 +141,7 @@ SMMUv3::masterRecvTimingResp(PacketPtr pkt)
|
||||
}
|
||||
|
||||
void
|
||||
SMMUv3::masterRecvReqRetry()
|
||||
SMMUv3::recvReqRetry()
|
||||
{
|
||||
assert(!packetsToRetry.empty());
|
||||
|
||||
@@ -150,29 +150,29 @@ SMMUv3::masterRecvReqRetry()
|
||||
|
||||
assert(a.type==ACTION_SEND_REQ || a.type==ACTION_SEND_REQ_FINAL);
|
||||
|
||||
DPRINTF(SMMUv3, "[t] master retr addr=%#x size=%#x\n",
|
||||
DPRINTF(SMMUv3, "[t] requestor retr addr=%#x size=%#x\n",
|
||||
a.pkt->getAddr(), a.pkt->getSize());
|
||||
|
||||
if (!masterPort.sendTimingReq(a.pkt))
|
||||
if (!requestPort.sendTimingReq(a.pkt))
|
||||
break;
|
||||
|
||||
packetsToRetry.pop();
|
||||
|
||||
/*
|
||||
* ACTION_SEND_REQ_FINAL means that we have just forwarded the packet
|
||||
* on the master interface; this means that we no longer hold on to
|
||||
* on the requestor interface; this means that we no longer hold on to
|
||||
* that transaction and therefore can accept a new one.
|
||||
* If the slave port was stalled then unstall it (send retry).
|
||||
* If the response port was stalled then unstall it (send retry).
|
||||
*/
|
||||
if (a.type == ACTION_SEND_REQ_FINAL)
|
||||
scheduleSlaveRetries();
|
||||
scheduleDeviceRetries();
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
SMMUv3::masterTableWalkRecvTimingResp(PacketPtr pkt)
|
||||
SMMUv3::tableWalkRecvTimingResp(PacketPtr pkt)
|
||||
{
|
||||
DPRINTF(SMMUv3, "[t] master HWTW resp addr=%#x size=%#x\n",
|
||||
DPRINTF(SMMUv3, "[t] requestor HWTW resp addr=%#x size=%#x\n",
|
||||
pkt->getAddr(), pkt->getSize());
|
||||
|
||||
// @todo: We need to pay for this and not just zero it out
|
||||
@@ -187,7 +187,7 @@ SMMUv3::masterTableWalkRecvTimingResp(PacketPtr pkt)
|
||||
}
|
||||
|
||||
void
|
||||
SMMUv3::masterTableWalkRecvReqRetry()
|
||||
SMMUv3::tableWalkRecvReqRetry()
|
||||
{
|
||||
assert(tableWalkPortEnable);
|
||||
assert(!packetsTableWalkToRetry.empty());
|
||||
@@ -197,10 +197,10 @@ SMMUv3::masterTableWalkRecvReqRetry()
|
||||
|
||||
assert(a.type==ACTION_SEND_REQ);
|
||||
|
||||
DPRINTF(SMMUv3, "[t] master HWTW retr addr=%#x size=%#x\n",
|
||||
DPRINTF(SMMUv3, "[t] requestor HWTW retr addr=%#x size=%#x\n",
|
||||
a.pkt->getAddr(), a.pkt->getSize());
|
||||
|
||||
if (!masterTableWalkPort.sendTimingReq(a.pkt))
|
||||
if (!tableWalkPort.sendTimingReq(a.pkt))
|
||||
break;
|
||||
|
||||
packetsTableWalkToRetry.pop();
|
||||
@@ -208,9 +208,9 @@ SMMUv3::masterTableWalkRecvReqRetry()
|
||||
}
|
||||
|
||||
void
|
||||
SMMUv3::scheduleSlaveRetries()
|
||||
SMMUv3::scheduleDeviceRetries()
|
||||
{
|
||||
for (auto ifc : slaveInterfaces) {
|
||||
for (auto ifc : deviceInterfaces) {
|
||||
ifc->scheduleDeviceRetry();
|
||||
}
|
||||
}
|
||||
@@ -239,17 +239,17 @@ SMMUv3::runProcessAtomic(SMMUProcess *proc, PacketPtr pkt)
|
||||
|
||||
switch (action.type) {
|
||||
case ACTION_SEND_REQ:
|
||||
// Send an MMU initiated request on the table walk port if it is
|
||||
// enabled. Otherwise, fall through and handle same as the final
|
||||
// ACTION_SEND_REQ_FINAL request.
|
||||
// Send an MMU initiated request on the table walk port if
|
||||
// it is enabled. Otherwise, fall through and handle same
|
||||
// as the final ACTION_SEND_REQ_FINAL request.
|
||||
if (tableWalkPortEnable) {
|
||||
delay += masterTableWalkPort.sendAtomic(action.pkt);
|
||||
delay += tableWalkPort.sendAtomic(action.pkt);
|
||||
pkt = action.pkt;
|
||||
break;
|
||||
}
|
||||
M5_FALLTHROUGH;
|
||||
case ACTION_SEND_REQ_FINAL:
|
||||
delay += masterPort.sendAtomic(action.pkt);
|
||||
delay += requestPort.sendAtomic(action.pkt);
|
||||
pkt = action.pkt;
|
||||
break;
|
||||
|
||||
@@ -289,14 +289,14 @@ SMMUv3::runProcessTiming(SMMUProcess *proc, PacketPtr pkt)
|
||||
if (tableWalkPortEnable) {
|
||||
action.pkt->pushSenderState(proc);
|
||||
|
||||
DPRINTF(SMMUv3, "[t] master HWTW req addr=%#x size=%#x\n",
|
||||
DPRINTF(SMMUv3, "[t] requestor HWTW req addr=%#x size=%#x\n",
|
||||
action.pkt->getAddr(), action.pkt->getSize());
|
||||
|
||||
if (packetsTableWalkToRetry.empty()
|
||||
&& masterTableWalkPort.sendTimingReq(action.pkt)) {
|
||||
scheduleSlaveRetries();
|
||||
&& tableWalkPort.sendTimingReq(action.pkt)) {
|
||||
scheduleDeviceRetries();
|
||||
} else {
|
||||
DPRINTF(SMMUv3, "[t] master HWTW req needs retry,"
|
||||
DPRINTF(SMMUv3, "[t] requestor HWTW req needs retry,"
|
||||
" qlen=%d\n", packetsTableWalkToRetry.size());
|
||||
packetsTableWalkToRetry.push(action);
|
||||
}
|
||||
@@ -307,13 +307,14 @@ SMMUv3::runProcessTiming(SMMUProcess *proc, PacketPtr pkt)
|
||||
case ACTION_SEND_REQ_FINAL:
|
||||
action.pkt->pushSenderState(proc);
|
||||
|
||||
DPRINTF(SMMUv3, "[t] master req addr=%#x size=%#x\n",
|
||||
DPRINTF(SMMUv3, "[t] requestor req addr=%#x size=%#x\n",
|
||||
action.pkt->getAddr(), action.pkt->getSize());
|
||||
|
||||
if (packetsToRetry.empty() && masterPort.sendTimingReq(action.pkt)) {
|
||||
scheduleSlaveRetries();
|
||||
if (packetsToRetry.empty() &&
|
||||
requestPort.sendTimingReq(action.pkt)) {
|
||||
scheduleDeviceRetries();
|
||||
} else {
|
||||
DPRINTF(SMMUv3, "[t] master req needs retry, qlen=%d\n",
|
||||
DPRINTF(SMMUv3, "[t] requestor req needs retry, qlen=%d\n",
|
||||
packetsToRetry.size());
|
||||
packetsToRetry.push(action);
|
||||
}
|
||||
@@ -324,7 +325,7 @@ SMMUv3::runProcessTiming(SMMUProcess *proc, PacketPtr pkt)
|
||||
// @todo: We need to pay for this and not just zero it out
|
||||
action.pkt->headerDelay = action.pkt->payloadDelay = 0;
|
||||
|
||||
DPRINTF(SMMUv3, "[t] slave resp addr=%#x size=%#x\n",
|
||||
DPRINTF(SMMUv3, "[t] responder resp addr=%#x size=%#x\n",
|
||||
action.pkt->getAddr(),
|
||||
action.pkt->getSize());
|
||||
|
||||
@@ -338,7 +339,7 @@ SMMUv3::runProcessTiming(SMMUProcess *proc, PacketPtr pkt)
|
||||
// @todo: We need to pay for this and not just zero it out
|
||||
action.pkt->headerDelay = action.pkt->payloadDelay = 0;
|
||||
|
||||
DPRINTF(SMMUv3, "[t] ATS slave resp addr=%#x size=%#x\n",
|
||||
DPRINTF(SMMUv3, "[t] ATS responder resp addr=%#x size=%#x\n",
|
||||
action.pkt->getAddr(), action.pkt->getSize());
|
||||
|
||||
assert(action.ifc);
|
||||
@@ -394,9 +395,9 @@ SMMUv3::processCommand(const SMMUCommand &cmd)
|
||||
DPRINTF(SMMUv3, "CMD_CFGI_STE sid=%#x\n", cmd.dw0.sid);
|
||||
configCache.invalidateSID(cmd.dw0.sid);
|
||||
|
||||
for (auto slave_interface : slaveInterfaces) {
|
||||
slave_interface->microTLB->invalidateSID(cmd.dw0.sid);
|
||||
slave_interface->mainTLB->invalidateSID(cmd.dw0.sid);
|
||||
for (auto dev_interface : deviceInterfaces) {
|
||||
dev_interface->microTLB->invalidateSID(cmd.dw0.sid);
|
||||
dev_interface->mainTLB->invalidateSID(cmd.dw0.sid);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -409,9 +410,9 @@ SMMUv3::processCommand(const SMMUCommand &cmd)
|
||||
DPRINTF(SMMUv3, "CMD_CFGI_ALL\n");
|
||||
configCache.invalidateAll();
|
||||
|
||||
for (auto slave_interface : slaveInterfaces) {
|
||||
slave_interface->microTLB->invalidateAll();
|
||||
slave_interface->mainTLB->invalidateAll();
|
||||
for (auto dev_interface : deviceInterfaces) {
|
||||
dev_interface->microTLB->invalidateAll();
|
||||
dev_interface->mainTLB->invalidateAll();
|
||||
}
|
||||
} else {
|
||||
DPRINTF(SMMUv3, "CMD_CFGI_STE_RANGE\n");
|
||||
@@ -420,9 +421,9 @@ SMMUv3::processCommand(const SMMUCommand &cmd)
|
||||
for (auto sid = start_sid; sid <= end_sid; sid++) {
|
||||
configCache.invalidateSID(sid);
|
||||
|
||||
for (auto slave_interface : slaveInterfaces) {
|
||||
slave_interface->microTLB->invalidateSID(sid);
|
||||
slave_interface->mainTLB->invalidateSID(sid);
|
||||
for (auto dev_interface : deviceInterfaces) {
|
||||
dev_interface->microTLB->invalidateSID(sid);
|
||||
dev_interface->mainTLB->invalidateSID(sid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -434,10 +435,10 @@ SMMUv3::processCommand(const SMMUCommand &cmd)
|
||||
cmd.dw0.sid, cmd.dw0.ssid);
|
||||
configCache.invalidateSSID(cmd.dw0.sid, cmd.dw0.ssid);
|
||||
|
||||
for (auto slave_interface : slaveInterfaces) {
|
||||
slave_interface->microTLB->invalidateSSID(
|
||||
for (auto dev_interface : deviceInterfaces) {
|
||||
dev_interface->microTLB->invalidateSSID(
|
||||
cmd.dw0.sid, cmd.dw0.ssid);
|
||||
slave_interface->mainTLB->invalidateSSID(
|
||||
dev_interface->mainTLB->invalidateSSID(
|
||||
cmd.dw0.sid, cmd.dw0.ssid);
|
||||
}
|
||||
break;
|
||||
@@ -447,18 +448,18 @@ SMMUv3::processCommand(const SMMUCommand &cmd)
|
||||
DPRINTF(SMMUv3, "CMD_CFGI_CD_ALL sid=%#x\n", cmd.dw0.sid);
|
||||
configCache.invalidateSID(cmd.dw0.sid);
|
||||
|
||||
for (auto slave_interface : slaveInterfaces) {
|
||||
slave_interface->microTLB->invalidateSID(cmd.dw0.sid);
|
||||
slave_interface->mainTLB->invalidateSID(cmd.dw0.sid);
|
||||
for (auto dev_interface : deviceInterfaces) {
|
||||
dev_interface->microTLB->invalidateSID(cmd.dw0.sid);
|
||||
dev_interface->mainTLB->invalidateSID(cmd.dw0.sid);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CMD_TLBI_NH_ALL: {
|
||||
DPRINTF(SMMUv3, "CMD_TLBI_NH_ALL vmid=%#x\n", cmd.dw0.vmid);
|
||||
for (auto slave_interface : slaveInterfaces) {
|
||||
slave_interface->microTLB->invalidateVMID(cmd.dw0.vmid);
|
||||
slave_interface->mainTLB->invalidateVMID(cmd.dw0.vmid);
|
||||
for (auto dev_interface : deviceInterfaces) {
|
||||
dev_interface->microTLB->invalidateVMID(cmd.dw0.vmid);
|
||||
dev_interface->mainTLB->invalidateVMID(cmd.dw0.vmid);
|
||||
}
|
||||
tlb.invalidateVMID(cmd.dw0.vmid);
|
||||
walkCache.invalidateVMID(cmd.dw0.vmid);
|
||||
@@ -468,10 +469,10 @@ SMMUv3::processCommand(const SMMUCommand &cmd)
|
||||
case CMD_TLBI_NH_ASID: {
|
||||
DPRINTF(SMMUv3, "CMD_TLBI_NH_ASID asid=%#x vmid=%#x\n",
|
||||
cmd.dw0.asid, cmd.dw0.vmid);
|
||||
for (auto slave_interface : slaveInterfaces) {
|
||||
slave_interface->microTLB->invalidateASID(
|
||||
for (auto dev_interface : deviceInterfaces) {
|
||||
dev_interface->microTLB->invalidateASID(
|
||||
cmd.dw0.asid, cmd.dw0.vmid);
|
||||
slave_interface->mainTLB->invalidateASID(
|
||||
dev_interface->mainTLB->invalidateASID(
|
||||
cmd.dw0.asid, cmd.dw0.vmid);
|
||||
}
|
||||
tlb.invalidateASID(cmd.dw0.asid, cmd.dw0.vmid);
|
||||
@@ -483,10 +484,10 @@ SMMUv3::processCommand(const SMMUCommand &cmd)
|
||||
const Addr addr = cmd.addr();
|
||||
DPRINTF(SMMUv3, "CMD_TLBI_NH_VAA va=%#08x vmid=%#x\n",
|
||||
addr, cmd.dw0.vmid);
|
||||
for (auto slave_interface : slaveInterfaces) {
|
||||
slave_interface->microTLB->invalidateVAA(
|
||||
for (auto dev_interface : deviceInterfaces) {
|
||||
dev_interface->microTLB->invalidateVAA(
|
||||
addr, cmd.dw0.vmid);
|
||||
slave_interface->mainTLB->invalidateVAA(
|
||||
dev_interface->mainTLB->invalidateVAA(
|
||||
addr, cmd.dw0.vmid);
|
||||
}
|
||||
tlb.invalidateVAA(addr, cmd.dw0.vmid);
|
||||
@@ -499,10 +500,10 @@ SMMUv3::processCommand(const SMMUCommand &cmd)
|
||||
const Addr addr = cmd.addr();
|
||||
DPRINTF(SMMUv3, "CMD_TLBI_NH_VA va=%#08x asid=%#x vmid=%#x\n",
|
||||
addr, cmd.dw0.asid, cmd.dw0.vmid);
|
||||
for (auto slave_interface : slaveInterfaces) {
|
||||
slave_interface->microTLB->invalidateVA(
|
||||
for (auto dev_interface : deviceInterfaces) {
|
||||
dev_interface->microTLB->invalidateVA(
|
||||
addr, cmd.dw0.asid, cmd.dw0.vmid);
|
||||
slave_interface->mainTLB->invalidateVA(
|
||||
dev_interface->mainTLB->invalidateVA(
|
||||
addr, cmd.dw0.asid, cmd.dw0.vmid);
|
||||
}
|
||||
tlb.invalidateVA(addr, cmd.dw0.asid, cmd.dw0.vmid);
|
||||
@@ -527,9 +528,9 @@ SMMUv3::processCommand(const SMMUCommand &cmd)
|
||||
|
||||
case CMD_TLBI_S12_VMALL: {
|
||||
DPRINTF(SMMUv3, "CMD_TLBI_S12_VMALL vmid=%#x\n", cmd.dw0.vmid);
|
||||
for (auto slave_interface : slaveInterfaces) {
|
||||
slave_interface->microTLB->invalidateVMID(cmd.dw0.vmid);
|
||||
slave_interface->mainTLB->invalidateVMID(cmd.dw0.vmid);
|
||||
for (auto dev_interface : deviceInterfaces) {
|
||||
dev_interface->microTLB->invalidateVMID(cmd.dw0.vmid);
|
||||
dev_interface->mainTLB->invalidateVMID(cmd.dw0.vmid);
|
||||
}
|
||||
tlb.invalidateVMID(cmd.dw0.vmid);
|
||||
ipaCache.invalidateVMID(cmd.dw0.vmid);
|
||||
@@ -539,9 +540,9 @@ SMMUv3::processCommand(const SMMUCommand &cmd)
|
||||
|
||||
case CMD_TLBI_NSNH_ALL: {
|
||||
DPRINTF(SMMUv3, "CMD_TLBI_NSNH_ALL\n");
|
||||
for (auto slave_interface : slaveInterfaces) {
|
||||
slave_interface->microTLB->invalidateAll();
|
||||
slave_interface->mainTLB->invalidateAll();
|
||||
for (auto dev_interface : deviceInterfaces) {
|
||||
dev_interface->microTLB->invalidateAll();
|
||||
dev_interface->mainTLB->invalidateAll();
|
||||
}
|
||||
tlb.invalidateAll();
|
||||
ipaCache.invalidateAll();
|
||||
@@ -717,16 +718,16 @@ void
|
||||
SMMUv3::init()
|
||||
{
|
||||
// make sure both sides are connected and have the same block size
|
||||
if (!masterPort.isConnected())
|
||||
fatal("Master port is not connected.\n");
|
||||
if (!requestPort.isConnected())
|
||||
fatal("Request port is not connected.\n");
|
||||
|
||||
// If the second master port is connected for the table walks, enable
|
||||
// If the second request port is connected for the table walks, enable
|
||||
// the mode to send table walks through this port instead
|
||||
if (masterTableWalkPort.isConnected())
|
||||
if (tableWalkPort.isConnected())
|
||||
tableWalkPortEnable = true;
|
||||
|
||||
// notify the master side of our address ranges
|
||||
for (auto ifc : slaveInterfaces) {
|
||||
// notify the request side of our address ranges
|
||||
for (auto ifc : deviceInterfaces) {
|
||||
ifc->sendRange();
|
||||
}
|
||||
|
||||
@@ -741,10 +742,10 @@ SMMUv3::regStats()
|
||||
|
||||
using namespace Stats;
|
||||
|
||||
for (size_t i = 0; i < slaveInterfaces.size(); i++) {
|
||||
slaveInterfaces[i]->microTLB->regStats(
|
||||
for (size_t i = 0; i < deviceInterfaces.size(); i++) {
|
||||
deviceInterfaces[i]->microTLB->regStats(
|
||||
csprintf("%s.utlb%d", name(), i));
|
||||
slaveInterfaces[i]->mainTLB->regStats(
|
||||
deviceInterfaces[i]->mainTLB->regStats(
|
||||
csprintf("%s.maintlb%d", name(), i));
|
||||
}
|
||||
|
||||
@@ -815,10 +816,10 @@ SMMUv3::unserialize(CheckpointIn &cp)
|
||||
Port&
|
||||
SMMUv3::getPort(const std::string &name, PortID id)
|
||||
{
|
||||
if (name == "master") {
|
||||
return masterPort;
|
||||
} else if (name == "master_walker") {
|
||||
return masterTableWalkPort;
|
||||
if (name == "request") {
|
||||
return requestPort;
|
||||
} else if (name == "walker") {
|
||||
return tableWalkPort;
|
||||
} else if (name == "control") {
|
||||
return controlPort;
|
||||
} else {
|
||||
|
||||
@@ -48,11 +48,11 @@
|
||||
#include "dev/arm/smmu_v3_caches.hh"
|
||||
#include "dev/arm/smmu_v3_cmdexec.hh"
|
||||
#include "dev/arm/smmu_v3_defs.hh"
|
||||
#include "dev/arm/smmu_v3_deviceifc.hh"
|
||||
#include "dev/arm/smmu_v3_events.hh"
|
||||
#include "dev/arm/smmu_v3_ports.hh"
|
||||
#include "dev/arm/smmu_v3_proc.hh"
|
||||
#include "dev/arm/smmu_v3_ptops.hh"
|
||||
#include "dev/arm/smmu_v3_slaveifc.hh"
|
||||
#include "mem/packet.hh"
|
||||
#include "params/SMMUv3.hh"
|
||||
#include "sim/clocked_object.hh"
|
||||
@@ -85,13 +85,13 @@ class SMMUv3 : public ClockedObject
|
||||
friend class SMMUProcess;
|
||||
friend class SMMUTranslationProcess;
|
||||
friend class SMMUCommandExecProcess;
|
||||
friend class SMMUv3SlaveInterface;
|
||||
friend class SMMUv3DeviceInterface;
|
||||
|
||||
const System &system;
|
||||
const MasterID masterId;
|
||||
const RequestorID requestorId;
|
||||
|
||||
SMMUMasterPort masterPort;
|
||||
SMMUMasterTableWalkPort masterTableWalkPort;
|
||||
SMMURequestPort requestPort;
|
||||
SMMUTableWalkPort tableWalkPort;
|
||||
SMMUControlPort controlPort;
|
||||
|
||||
ARMArchTLB tlb;
|
||||
@@ -108,7 +108,7 @@ class SMMUv3 : public ClockedObject
|
||||
const bool walkCacheNonfinalEnable;
|
||||
const unsigned walkCacheS1Levels;
|
||||
const unsigned walkCacheS2Levels;
|
||||
const unsigned masterPortWidth; // in bytes
|
||||
const unsigned requestPortWidth; // in bytes
|
||||
|
||||
SMMUSemaphore tlbSem;
|
||||
SMMUSemaphore ifcSmmuSem;
|
||||
@@ -116,7 +116,7 @@ class SMMUv3 : public ClockedObject
|
||||
SMMUSemaphore configSem;
|
||||
SMMUSemaphore ipaSem;
|
||||
SMMUSemaphore walkSem;
|
||||
SMMUSemaphore masterPortSem;
|
||||
SMMUSemaphore requestPortSem;
|
||||
|
||||
SMMUSemaphore transSem; // max N transactions in SMMU
|
||||
SMMUSemaphore ptwSem; // max N concurrent PTWs
|
||||
@@ -138,7 +138,7 @@ class SMMUv3 : public ClockedObject
|
||||
Stats::Distribution translationTimeDist;
|
||||
Stats::Distribution ptwTimeDist;
|
||||
|
||||
std::vector<SMMUv3SlaveInterface *> slaveInterfaces;
|
||||
std::vector<SMMUv3DeviceInterface *> deviceInterfaces;
|
||||
|
||||
SMMUCommandExecProcess commandExecutor;
|
||||
|
||||
@@ -151,7 +151,7 @@ class SMMUv3 : public ClockedObject
|
||||
std::queue<SMMUAction> packetsTableWalkToRetry;
|
||||
|
||||
|
||||
void scheduleSlaveRetries();
|
||||
void scheduleDeviceRetries();
|
||||
|
||||
SMMUAction runProcess(SMMUProcess *proc, PacketPtr pkt);
|
||||
SMMUAction runProcessAtomic(SMMUProcess *proc, PacketPtr pkt);
|
||||
@@ -171,13 +171,13 @@ class SMMUv3 : public ClockedObject
|
||||
virtual void init() override;
|
||||
virtual void regStats() override;
|
||||
|
||||
Tick slaveRecvAtomic(PacketPtr pkt, PortID id);
|
||||
bool slaveRecvTimingReq(PacketPtr pkt, PortID id);
|
||||
bool masterRecvTimingResp(PacketPtr pkt);
|
||||
void masterRecvReqRetry();
|
||||
Tick recvAtomic(PacketPtr pkt, PortID id);
|
||||
bool recvTimingReq(PacketPtr pkt, PortID id);
|
||||
bool recvTimingResp(PacketPtr pkt);
|
||||
void recvReqRetry();
|
||||
|
||||
bool masterTableWalkRecvTimingResp(PacketPtr pkt);
|
||||
void masterTableWalkRecvReqRetry();
|
||||
bool tableWalkRecvTimingResp(PacketPtr pkt);
|
||||
void tableWalkRecvReqRetry();
|
||||
|
||||
Tick readControl(PacketPtr pkt);
|
||||
Tick writeControl(PacketPtr pkt);
|
||||
|
||||
@@ -35,15 +35,15 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "dev/arm/smmu_v3_slaveifc.hh"
|
||||
#include "dev/arm/smmu_v3_deviceifc.hh"
|
||||
|
||||
#include "base/trace.hh"
|
||||
#include "debug/SMMUv3.hh"
|
||||
#include "dev/arm/smmu_v3.hh"
|
||||
#include "dev/arm/smmu_v3_transl.hh"
|
||||
|
||||
SMMUv3SlaveInterface::SMMUv3SlaveInterface(
|
||||
const SMMUv3SlaveInterfaceParams *p) :
|
||||
SMMUv3DeviceInterface::SMMUv3DeviceInterface(
|
||||
const SMMUv3DeviceInterfaceParams *p) :
|
||||
ClockedObject(p),
|
||||
smmu(nullptr),
|
||||
microTLB(new SMMUTLB(p->utlb_entries,
|
||||
@@ -54,14 +54,15 @@ SMMUv3SlaveInterface::SMMUv3SlaveInterface(
|
||||
p->tlb_policy)),
|
||||
microTLBEnable(p->utlb_enable),
|
||||
mainTLBEnable(p->tlb_enable),
|
||||
slavePortSem(1),
|
||||
devicePortSem(1),
|
||||
microTLBSem(p->utlb_slots),
|
||||
mainTLBSem(p->tlb_slots),
|
||||
microTLBLat(p->utlb_lat),
|
||||
mainTLBLat(p->tlb_lat),
|
||||
slavePort(new SMMUSlavePort(csprintf("%s.slave", name()), *this)),
|
||||
atsSlavePort(name() + ".atsSlave", *this),
|
||||
atsMasterPort(name() + ".atsMaster", *this),
|
||||
devicePort(new SMMUDevicePort(csprintf("%s.device_port",
|
||||
name()), *this)),
|
||||
atsDevicePort(name() + ".atsDevicePort", *this),
|
||||
atsMemPort(name() + ".atsMemPort", *this),
|
||||
portWidth(p->port_width),
|
||||
wrBufSlotsRemaining(p->wrbuf_slots),
|
||||
xlateSlotsRemaining(p->xlate_slots),
|
||||
@@ -76,41 +77,41 @@ SMMUv3SlaveInterface::SMMUv3SlaveInterface(
|
||||
{}
|
||||
|
||||
void
|
||||
SMMUv3SlaveInterface::sendRange()
|
||||
SMMUv3DeviceInterface::sendRange()
|
||||
{
|
||||
if (slavePort->isConnected()) {
|
||||
inform("Slave port is connected to %s\n", slavePort->getPeer());
|
||||
if (devicePort->isConnected()) {
|
||||
inform("Device port is connected to %s\n", devicePort->getPeer());
|
||||
|
||||
slavePort->sendRangeChange();
|
||||
devicePort->sendRangeChange();
|
||||
} else {
|
||||
fatal("Slave port is not connected.\n");
|
||||
fatal("Device port is not connected.\n");
|
||||
}
|
||||
}
|
||||
|
||||
Port&
|
||||
SMMUv3SlaveInterface::getPort(const std::string &name, PortID id)
|
||||
SMMUv3DeviceInterface::getPort(const std::string &name, PortID id)
|
||||
{
|
||||
if (name == "ats_master") {
|
||||
return atsMasterPort;
|
||||
} else if (name == "slave") {
|
||||
return *slavePort;
|
||||
} else if (name == "ats_slave") {
|
||||
return atsSlavePort;
|
||||
if (name == "ats_mem_side_port") {
|
||||
return atsMemPort;
|
||||
} else if (name == "device_port") {
|
||||
return *devicePort;
|
||||
} else if (name == "ats_dev_side_port") {
|
||||
return atsDevicePort;
|
||||
} else {
|
||||
return ClockedObject::getPort(name, id);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SMMUv3SlaveInterface::schedTimingResp(PacketPtr pkt)
|
||||
SMMUv3DeviceInterface::schedTimingResp(PacketPtr pkt)
|
||||
{
|
||||
slavePort->schedTimingResp(pkt, nextCycle());
|
||||
devicePort->schedTimingResp(pkt, nextCycle());
|
||||
}
|
||||
|
||||
void
|
||||
SMMUv3SlaveInterface::schedAtsTimingResp(PacketPtr pkt)
|
||||
SMMUv3DeviceInterface::schedAtsTimingResp(PacketPtr pkt)
|
||||
{
|
||||
atsSlavePort.schedTimingResp(pkt, nextCycle());
|
||||
atsDevicePort.schedTimingResp(pkt, nextCycle());
|
||||
|
||||
if (atsDeviceNeedsRetry) {
|
||||
atsDeviceNeedsRetry = false;
|
||||
@@ -119,10 +120,10 @@ SMMUv3SlaveInterface::schedAtsTimingResp(PacketPtr pkt)
|
||||
}
|
||||
|
||||
Tick
|
||||
SMMUv3SlaveInterface::recvAtomic(PacketPtr pkt)
|
||||
SMMUv3DeviceInterface::recvAtomic(PacketPtr pkt)
|
||||
{
|
||||
DPRINTF(SMMUv3, "[a] req from %s addr=%#x size=%#x\n",
|
||||
slavePort->getPeer(), pkt->getAddr(), pkt->getSize());
|
||||
devicePort->getPeer(), pkt->getAddr(), pkt->getSize());
|
||||
|
||||
std::string proc_name = csprintf("%s.port", name());
|
||||
SMMUTranslationProcess proc(proc_name, *smmu, *this);
|
||||
@@ -135,10 +136,10 @@ SMMUv3SlaveInterface::recvAtomic(PacketPtr pkt)
|
||||
}
|
||||
|
||||
bool
|
||||
SMMUv3SlaveInterface::recvTimingReq(PacketPtr pkt)
|
||||
SMMUv3DeviceInterface::recvTimingReq(PacketPtr pkt)
|
||||
{
|
||||
DPRINTF(SMMUv3, "[t] req from %s addr=%#x size=%#x\n",
|
||||
slavePort->getPeer(), pkt->getAddr(), pkt->getSize());
|
||||
devicePort->getPeer(), pkt->getAddr(), pkt->getSize());
|
||||
|
||||
// @todo: We need to pay for this and not just zero it out
|
||||
pkt->headerDelay = pkt->payloadDelay = 0;
|
||||
@@ -167,9 +168,9 @@ SMMUv3SlaveInterface::recvTimingReq(PacketPtr pkt)
|
||||
}
|
||||
|
||||
Tick
|
||||
SMMUv3SlaveInterface::atsSlaveRecvAtomic(PacketPtr pkt)
|
||||
SMMUv3DeviceInterface::atsRecvAtomic(PacketPtr pkt)
|
||||
{
|
||||
DPRINTF(SMMUv3, "[a] ATS slave req addr=%#x size=%#x\n",
|
||||
DPRINTF(SMMUv3, "[a] ATS responder req addr=%#x size=%#x\n",
|
||||
pkt->getAddr(), pkt->getSize());
|
||||
|
||||
std::string proc_name = csprintf("%s.atsport", name());
|
||||
@@ -185,9 +186,9 @@ SMMUv3SlaveInterface::atsSlaveRecvAtomic(PacketPtr pkt)
|
||||
}
|
||||
|
||||
bool
|
||||
SMMUv3SlaveInterface::atsSlaveRecvTimingReq(PacketPtr pkt)
|
||||
SMMUv3DeviceInterface::atsRecvTimingReq(PacketPtr pkt)
|
||||
{
|
||||
DPRINTF(SMMUv3, "[t] ATS slave req addr=%#x size=%#x\n",
|
||||
DPRINTF(SMMUv3, "[t] ATS responder req addr=%#x size=%#x\n",
|
||||
pkt->getAddr(), pkt->getSize());
|
||||
|
||||
// @todo: We need to pay for this and not just zero it out
|
||||
@@ -210,9 +211,9 @@ SMMUv3SlaveInterface::atsSlaveRecvTimingReq(PacketPtr pkt)
|
||||
}
|
||||
|
||||
bool
|
||||
SMMUv3SlaveInterface::atsMasterRecvTimingResp(PacketPtr pkt)
|
||||
SMMUv3DeviceInterface::atsRecvTimingResp(PacketPtr pkt)
|
||||
{
|
||||
DPRINTF(SMMUv3, "[t] ATS master resp addr=%#x size=%#x\n",
|
||||
DPRINTF(SMMUv3, "[t] ATS requestor resp addr=%#x size=%#x\n",
|
||||
pkt->getAddr(), pkt->getSize());
|
||||
|
||||
// @todo: We need to pay for this and not just zero it out
|
||||
@@ -227,30 +228,30 @@ SMMUv3SlaveInterface::atsMasterRecvTimingResp(PacketPtr pkt)
|
||||
}
|
||||
|
||||
void
|
||||
SMMUv3SlaveInterface::sendDeviceRetry()
|
||||
SMMUv3DeviceInterface::sendDeviceRetry()
|
||||
{
|
||||
slavePort->sendRetryReq();
|
||||
devicePort->sendRetryReq();
|
||||
}
|
||||
|
||||
void
|
||||
SMMUv3SlaveInterface::atsSendDeviceRetry()
|
||||
SMMUv3DeviceInterface::atsSendDeviceRetry()
|
||||
{
|
||||
DPRINTF(SMMUv3, "ATS retry\n");
|
||||
atsSlavePort.sendRetryReq();
|
||||
atsDevicePort.sendRetryReq();
|
||||
}
|
||||
|
||||
void
|
||||
SMMUv3SlaveInterface::scheduleDeviceRetry()
|
||||
SMMUv3DeviceInterface::scheduleDeviceRetry()
|
||||
{
|
||||
if (deviceNeedsRetry && !sendDeviceRetryEvent.scheduled()) {
|
||||
DPRINTF(SMMUv3, "sched slave retry\n");
|
||||
DPRINTF(SMMUv3, "sched responder retry\n");
|
||||
deviceNeedsRetry = false;
|
||||
schedule(sendDeviceRetryEvent, nextCycle());
|
||||
}
|
||||
}
|
||||
|
||||
DrainState
|
||||
SMMUv3SlaveInterface::drain()
|
||||
SMMUv3DeviceInterface::drain()
|
||||
{
|
||||
// Wait until all SMMU translations are completed
|
||||
if (xlateSlotsRemaining < params()->xlate_slots) {
|
||||
@@ -259,8 +260,8 @@ SMMUv3SlaveInterface::drain()
|
||||
return DrainState::Drained;
|
||||
}
|
||||
|
||||
SMMUv3SlaveInterface*
|
||||
SMMUv3SlaveInterfaceParams::create()
|
||||
SMMUv3DeviceInterface*
|
||||
SMMUv3DeviceInterfaceParams::create()
|
||||
{
|
||||
return new SMMUv3SlaveInterface(this);
|
||||
return new SMMUv3DeviceInterface(this);
|
||||
}
|
||||
@@ -35,8 +35,8 @@
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __DEV_ARM_SMMU_V3_SLAVEIFC_HH__
|
||||
#define __DEV_ARM_SMMU_V3_SLAVEIFC_HH__
|
||||
#ifndef __DEV_ARM_SMMU_V3_DEVICEIFC_HH__
|
||||
#define __DEV_ARM_SMMU_V3_DEVICEIFC_HH__
|
||||
|
||||
#include <list>
|
||||
|
||||
@@ -45,14 +45,14 @@
|
||||
#include "dev/arm/smmu_v3_events.hh"
|
||||
#include "dev/arm/smmu_v3_ports.hh"
|
||||
#include "dev/arm/smmu_v3_proc.hh"
|
||||
#include "params/SMMUv3SlaveInterface.hh"
|
||||
#include "params/SMMUv3DeviceInterface.hh"
|
||||
#include "sim/clocked_object.hh"
|
||||
|
||||
class SMMUTranslationProcess;
|
||||
class SMMUv3;
|
||||
class SMMUSlavePort;
|
||||
class SMMUDevicePort;
|
||||
|
||||
class SMMUv3SlaveInterface : public ClockedObject
|
||||
class SMMUv3DeviceInterface : public ClockedObject
|
||||
{
|
||||
protected:
|
||||
friend class SMMUTranslationProcess;
|
||||
@@ -65,16 +65,16 @@ class SMMUv3SlaveInterface : public ClockedObject
|
||||
const bool microTLBEnable;
|
||||
const bool mainTLBEnable;
|
||||
|
||||
SMMUSemaphore slavePortSem;
|
||||
SMMUSemaphore devicePortSem;
|
||||
SMMUSemaphore microTLBSem;
|
||||
SMMUSemaphore mainTLBSem;
|
||||
|
||||
const Cycles microTLBLat;
|
||||
const Cycles mainTLBLat;
|
||||
|
||||
SMMUSlavePort *slavePort;
|
||||
SMMUATSSlavePort atsSlavePort;
|
||||
SMMUATSMasterPort atsMasterPort;
|
||||
SMMUDevicePort *devicePort;
|
||||
SMMUATSDevicePort atsDevicePort;
|
||||
SMMUATSMemoryPort atsMemPort;
|
||||
|
||||
// in bytes
|
||||
const unsigned portWidth;
|
||||
@@ -93,14 +93,14 @@ class SMMUv3SlaveInterface : public ClockedObject
|
||||
std::list<SMMUTranslationProcess *> dependentWrites[SMMU_MAX_TRANS_ID];
|
||||
SMMUSignal dependentReqRemoved;
|
||||
|
||||
// Receiving translation requests from the master device
|
||||
// Receiving translation requests from the requestor device
|
||||
Tick recvAtomic(PacketPtr pkt);
|
||||
bool recvTimingReq(PacketPtr pkt);
|
||||
void schedTimingResp(PacketPtr pkt);
|
||||
|
||||
Tick atsSlaveRecvAtomic(PacketPtr pkt);
|
||||
bool atsSlaveRecvTimingReq(PacketPtr pkt);
|
||||
bool atsMasterRecvTimingResp(PacketPtr pkt);
|
||||
Tick atsRecvAtomic(PacketPtr pkt);
|
||||
bool atsRecvTimingReq(PacketPtr pkt);
|
||||
bool atsRecvTimingResp(PacketPtr pkt);
|
||||
void schedAtsTimingResp(PacketPtr pkt);
|
||||
|
||||
void scheduleDeviceRetry();
|
||||
@@ -112,24 +112,24 @@ class SMMUv3SlaveInterface : public ClockedObject
|
||||
|
||||
SMMUDeviceRetryEvent sendDeviceRetryEvent;
|
||||
EventWrapper<
|
||||
SMMUv3SlaveInterface,
|
||||
&SMMUv3SlaveInterface::atsSendDeviceRetry> atsSendDeviceRetryEvent;
|
||||
SMMUv3DeviceInterface,
|
||||
&SMMUv3DeviceInterface::atsSendDeviceRetry> atsSendDeviceRetryEvent;
|
||||
|
||||
Port& getPort(const std::string &name, PortID id) override;
|
||||
|
||||
public:
|
||||
SMMUv3SlaveInterface(const SMMUv3SlaveInterfaceParams *p);
|
||||
SMMUv3DeviceInterface(const SMMUv3DeviceInterfaceParams *p);
|
||||
|
||||
~SMMUv3SlaveInterface()
|
||||
~SMMUv3DeviceInterface()
|
||||
{
|
||||
delete microTLB;
|
||||
delete mainTLB;
|
||||
}
|
||||
|
||||
const SMMUv3SlaveInterfaceParams *
|
||||
const SMMUv3DeviceInterfaceParams *
|
||||
params() const
|
||||
{
|
||||
return static_cast<const SMMUv3SlaveInterfaceParams *>(_params);
|
||||
return static_cast<const SMMUv3DeviceInterfaceParams *>(_params);
|
||||
}
|
||||
|
||||
DrainState drain() override;
|
||||
@@ -138,4 +138,4 @@ class SMMUv3SlaveInterface : public ClockedObject
|
||||
void sendRange();
|
||||
};
|
||||
|
||||
#endif /* __DEV_ARM_SMMU_V3_SLAVEIFC_HH__ */
|
||||
#endif /* __DEV_ARM_SMMU_V3_DEVICEIFC_HH__ */
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
#include "dev/arm/smmu_v3_events.hh"
|
||||
|
||||
#include "dev/arm/smmu_v3_slaveifc.hh"
|
||||
#include "dev/arm/smmu_v3_deviceifc.hh"
|
||||
|
||||
void
|
||||
SMMUDeviceRetryEvent::process()
|
||||
|
||||
@@ -41,15 +41,15 @@
|
||||
#include <base/types.hh>
|
||||
#include <sim/eventq.hh>
|
||||
|
||||
class SMMUv3SlaveInterface;
|
||||
class SMMUv3DeviceInterface;
|
||||
|
||||
class SMMUDeviceRetryEvent : public Event
|
||||
{
|
||||
private:
|
||||
SMMUv3SlaveInterface &smmuIfc;
|
||||
SMMUv3DeviceInterface &smmuIfc;
|
||||
|
||||
public:
|
||||
SMMUDeviceRetryEvent(SMMUv3SlaveInterface &ifc)
|
||||
SMMUDeviceRetryEvent(SMMUv3DeviceInterface &ifc)
|
||||
: smmuIfc(ifc)
|
||||
{}
|
||||
|
||||
@@ -58,7 +58,7 @@ class SMMUDeviceRetryEvent : public Event
|
||||
const std::string name() const;
|
||||
|
||||
const char *description() const
|
||||
{ return "SlaveRetryEvent"; }
|
||||
{ return "DeviceRetryEvent"; }
|
||||
};
|
||||
|
||||
#endif /* __DEV_ARM_SMMU_V3_EVENTS_HH__ */
|
||||
|
||||
@@ -39,67 +39,67 @@
|
||||
|
||||
#include "base/logging.hh"
|
||||
#include "dev/arm/smmu_v3.hh"
|
||||
#include "dev/arm/smmu_v3_slaveifc.hh"
|
||||
#include "dev/arm/smmu_v3_deviceifc.hh"
|
||||
|
||||
SMMUMasterPort::SMMUMasterPort(const std::string &_name, SMMUv3 &_smmu) :
|
||||
SMMURequestPort::SMMURequestPort(const std::string &_name, SMMUv3 &_smmu) :
|
||||
RequestPort(_name, &_smmu),
|
||||
smmu(_smmu)
|
||||
{}
|
||||
|
||||
bool
|
||||
SMMUMasterPort::recvTimingResp(PacketPtr pkt)
|
||||
SMMURequestPort::recvTimingResp(PacketPtr pkt)
|
||||
{
|
||||
return smmu.masterRecvTimingResp(pkt);
|
||||
return smmu.recvTimingResp(pkt);
|
||||
}
|
||||
|
||||
void
|
||||
SMMUMasterPort::recvReqRetry()
|
||||
SMMURequestPort::recvReqRetry()
|
||||
{
|
||||
return smmu.masterRecvReqRetry();
|
||||
return smmu.recvReqRetry();
|
||||
}
|
||||
|
||||
SMMUMasterTableWalkPort::SMMUMasterTableWalkPort(const std::string &_name,
|
||||
SMMUTableWalkPort::SMMUTableWalkPort(const std::string &_name,
|
||||
SMMUv3 &_smmu) :
|
||||
RequestPort(_name, &_smmu),
|
||||
smmu(_smmu)
|
||||
{}
|
||||
|
||||
bool
|
||||
SMMUMasterTableWalkPort::recvTimingResp(PacketPtr pkt)
|
||||
SMMUTableWalkPort::recvTimingResp(PacketPtr pkt)
|
||||
{
|
||||
return smmu.masterTableWalkRecvTimingResp(pkt);
|
||||
return smmu.tableWalkRecvTimingResp(pkt);
|
||||
}
|
||||
|
||||
void
|
||||
SMMUMasterTableWalkPort::recvReqRetry()
|
||||
SMMUTableWalkPort::recvReqRetry()
|
||||
{
|
||||
return smmu.masterTableWalkRecvReqRetry();
|
||||
return smmu.tableWalkRecvReqRetry();
|
||||
}
|
||||
|
||||
SMMUSlavePort::SMMUSlavePort(const std::string &_name,
|
||||
SMMUv3SlaveInterface &_ifc,
|
||||
SMMUDevicePort::SMMUDevicePort(const std::string &_name,
|
||||
SMMUv3DeviceInterface &_ifc,
|
||||
PortID _id)
|
||||
:
|
||||
QueuedSlavePort(_name, &_ifc, respQueue, _id),
|
||||
QueuedResponsePort(_name, &_ifc, respQueue, _id),
|
||||
ifc(_ifc),
|
||||
respQueue(_ifc, *this)
|
||||
{}
|
||||
|
||||
void
|
||||
SMMUSlavePort::recvFunctional(PacketPtr pkt)
|
||||
SMMUDevicePort::recvFunctional(PacketPtr pkt)
|
||||
{
|
||||
if (!respQueue.trySatisfyFunctional(pkt))
|
||||
recvAtomic(pkt);
|
||||
}
|
||||
|
||||
Tick
|
||||
SMMUSlavePort::recvAtomic(PacketPtr pkt)
|
||||
SMMUDevicePort::recvAtomic(PacketPtr pkt)
|
||||
{
|
||||
return ifc.recvAtomic(pkt);
|
||||
}
|
||||
|
||||
bool
|
||||
SMMUSlavePort::recvTimingReq(PacketPtr pkt)
|
||||
SMMUDevicePort::recvTimingReq(PacketPtr pkt)
|
||||
{
|
||||
return ifc.recvTimingReq(pkt);
|
||||
}
|
||||
@@ -136,41 +136,41 @@ SMMUControlPort::getAddrRanges() const
|
||||
return list;
|
||||
}
|
||||
|
||||
SMMUATSMasterPort::SMMUATSMasterPort(const std::string &_name,
|
||||
SMMUv3SlaveInterface &_ifc) :
|
||||
QueuedMasterPort(_name, &_ifc, reqQueue, snoopRespQueue),
|
||||
SMMUATSMemoryPort::SMMUATSMemoryPort(const std::string &_name,
|
||||
SMMUv3DeviceInterface &_ifc) :
|
||||
QueuedRequestPort(_name, &_ifc, reqQueue, snoopRespQueue),
|
||||
ifc(_ifc),
|
||||
reqQueue(_ifc, *this),
|
||||
snoopRespQueue(_ifc, *this)
|
||||
{}
|
||||
|
||||
bool
|
||||
SMMUATSMasterPort::recvTimingResp(PacketPtr pkt)
|
||||
SMMUATSMemoryPort::recvTimingResp(PacketPtr pkt)
|
||||
{
|
||||
return ifc.atsMasterRecvTimingResp(pkt);
|
||||
return ifc.atsRecvTimingResp(pkt);
|
||||
}
|
||||
|
||||
SMMUATSSlavePort::SMMUATSSlavePort(const std::string &_name,
|
||||
SMMUv3SlaveInterface &_ifc) :
|
||||
QueuedSlavePort(_name, &_ifc, respQueue),
|
||||
SMMUATSDevicePort::SMMUATSDevicePort(const std::string &_name,
|
||||
SMMUv3DeviceInterface &_ifc) :
|
||||
QueuedResponsePort(_name, &_ifc, respQueue),
|
||||
ifc(_ifc),
|
||||
respQueue(_ifc, *this)
|
||||
{}
|
||||
|
||||
void
|
||||
SMMUATSSlavePort::recvFunctional(PacketPtr pkt)
|
||||
SMMUATSDevicePort::recvFunctional(PacketPtr pkt)
|
||||
{
|
||||
panic("Functional access on ATS port!");
|
||||
}
|
||||
|
||||
Tick
|
||||
SMMUATSSlavePort::recvAtomic(PacketPtr pkt)
|
||||
SMMUATSDevicePort::recvAtomic(PacketPtr pkt)
|
||||
{
|
||||
return ifc.atsSlaveRecvAtomic(pkt);
|
||||
return ifc.atsRecvAtomic(pkt);
|
||||
}
|
||||
|
||||
bool
|
||||
SMMUATSSlavePort::recvTimingReq(PacketPtr pkt)
|
||||
SMMUATSDevicePort::recvTimingReq(PacketPtr pkt)
|
||||
{
|
||||
return ifc.atsSlaveRecvTimingReq(pkt);
|
||||
return ifc.atsRecvTimingReq(pkt);
|
||||
}
|
||||
|
||||
@@ -42,9 +42,9 @@
|
||||
#include "mem/tport.hh"
|
||||
|
||||
class SMMUv3;
|
||||
class SMMUv3SlaveInterface;
|
||||
class SMMUv3DeviceInterface;
|
||||
|
||||
class SMMUMasterPort : public RequestPort
|
||||
class SMMURequestPort : public RequestPort
|
||||
{
|
||||
protected:
|
||||
SMMUv3 &smmu;
|
||||
@@ -53,12 +53,12 @@ class SMMUMasterPort : public RequestPort
|
||||
virtual void recvReqRetry();
|
||||
|
||||
public:
|
||||
SMMUMasterPort(const std::string &_name, SMMUv3 &_smmu);
|
||||
virtual ~SMMUMasterPort() {}
|
||||
SMMURequestPort(const std::string &_name, SMMUv3 &_smmu);
|
||||
virtual ~SMMURequestPort() {}
|
||||
};
|
||||
|
||||
// Separate master port to send MMU initiated requests on
|
||||
class SMMUMasterTableWalkPort : public RequestPort
|
||||
// Separate request port to send MMU initiated requests on
|
||||
class SMMUTableWalkPort : public RequestPort
|
||||
{
|
||||
protected:
|
||||
SMMUv3 &smmu;
|
||||
@@ -67,14 +67,14 @@ class SMMUMasterTableWalkPort : public RequestPort
|
||||
virtual void recvReqRetry();
|
||||
|
||||
public:
|
||||
SMMUMasterTableWalkPort(const std::string &_name, SMMUv3 &_smmu);
|
||||
virtual ~SMMUMasterTableWalkPort() {}
|
||||
SMMUTableWalkPort(const std::string &_name, SMMUv3 &_smmu);
|
||||
virtual ~SMMUTableWalkPort() {}
|
||||
};
|
||||
|
||||
class SMMUSlavePort : public QueuedSlavePort
|
||||
class SMMUDevicePort : public QueuedResponsePort
|
||||
{
|
||||
protected:
|
||||
SMMUv3SlaveInterface &ifc;
|
||||
SMMUv3DeviceInterface &ifc;
|
||||
RespPacketQueue respQueue;
|
||||
|
||||
virtual void recvFunctional(PacketPtr pkt);
|
||||
@@ -82,10 +82,10 @@ class SMMUSlavePort : public QueuedSlavePort
|
||||
virtual bool recvTimingReq(PacketPtr pkt);
|
||||
|
||||
public:
|
||||
SMMUSlavePort(const std::string &_name,
|
||||
SMMUv3SlaveInterface &_ifc,
|
||||
SMMUDevicePort(const std::string &_name,
|
||||
SMMUv3DeviceInterface &_ifc,
|
||||
PortID _id = InvalidPortID);
|
||||
virtual ~SMMUSlavePort() {}
|
||||
virtual ~SMMUDevicePort() {}
|
||||
|
||||
virtual AddrRangeList getAddrRanges() const
|
||||
{ return AddrRangeList { AddrRange(0, UINT64_MAX) }; }
|
||||
@@ -106,24 +106,24 @@ class SMMUControlPort : public SimpleTimingPort
|
||||
virtual ~SMMUControlPort() {}
|
||||
};
|
||||
|
||||
class SMMUATSMasterPort : public QueuedMasterPort
|
||||
class SMMUATSMemoryPort : public QueuedRequestPort
|
||||
{
|
||||
protected:
|
||||
SMMUv3SlaveInterface &ifc;
|
||||
SMMUv3DeviceInterface &ifc;
|
||||
ReqPacketQueue reqQueue;
|
||||
SnoopRespPacketQueue snoopRespQueue;
|
||||
|
||||
virtual bool recvTimingResp(PacketPtr pkt);
|
||||
|
||||
public:
|
||||
SMMUATSMasterPort(const std::string &_name, SMMUv3SlaveInterface &_ifc);
|
||||
virtual ~SMMUATSMasterPort() {}
|
||||
SMMUATSMemoryPort(const std::string &_name, SMMUv3DeviceInterface &_ifc);
|
||||
virtual ~SMMUATSMemoryPort() {}
|
||||
};
|
||||
|
||||
class SMMUATSSlavePort : public QueuedSlavePort
|
||||
class SMMUATSDevicePort : public QueuedResponsePort
|
||||
{
|
||||
protected:
|
||||
SMMUv3SlaveInterface &ifc;
|
||||
SMMUv3DeviceInterface &ifc;
|
||||
RespPacketQueue respQueue;
|
||||
|
||||
virtual void recvFunctional(PacketPtr pkt);
|
||||
@@ -134,8 +134,8 @@ class SMMUATSSlavePort : public QueuedSlavePort
|
||||
{ return AddrRangeList(); }
|
||||
|
||||
public:
|
||||
SMMUATSSlavePort(const std::string &_name, SMMUv3SlaveInterface &_ifc);
|
||||
virtual ~SMMUATSSlavePort() {}
|
||||
SMMUATSDevicePort(const std::string &_name, SMMUv3DeviceInterface &_ifc);
|
||||
virtual ~SMMUATSDevicePort() {}
|
||||
};
|
||||
|
||||
#endif /* __DEV_ARM_SMMU_V3_PORTS_HH__ */
|
||||
|
||||
@@ -68,15 +68,15 @@ SMMUProcess::reinit()
|
||||
void
|
||||
SMMUProcess::doRead(Yield &yield, Addr addr, void *ptr, size_t size)
|
||||
{
|
||||
doSemaphoreDown(yield, smmu.masterPortSem);
|
||||
doSemaphoreDown(yield, smmu.requestPortSem);
|
||||
doDelay(yield, Cycles(1)); // request - assume 1 cycle
|
||||
doSemaphoreUp(smmu.masterPortSem);
|
||||
doSemaphoreUp(smmu.requestPortSem);
|
||||
|
||||
SMMUAction a;
|
||||
a.type = ACTION_SEND_REQ;
|
||||
|
||||
RequestPtr req = std::make_shared<Request>(
|
||||
addr, size, 0, smmu.masterId);
|
||||
addr, size, 0, smmu.requestorId);
|
||||
|
||||
req->taskId(ContextSwitchTaskId::DMA);
|
||||
|
||||
@@ -97,18 +97,19 @@ SMMUProcess::doRead(Yield &yield, Addr addr, void *ptr, size_t size)
|
||||
void
|
||||
SMMUProcess::doWrite(Yield &yield, Addr addr, const void *ptr, size_t size)
|
||||
{
|
||||
unsigned nbeats = (size + (smmu.masterPortWidth-1)) / smmu.masterPortWidth;
|
||||
unsigned nbeats = (size + (smmu.requestPortWidth-1))
|
||||
/ smmu.requestPortWidth;
|
||||
|
||||
doSemaphoreDown(yield, smmu.masterPortSem);
|
||||
doSemaphoreDown(yield, smmu.requestPortSem);
|
||||
doDelay(yield, Cycles(nbeats));
|
||||
doSemaphoreUp(smmu.masterPortSem);
|
||||
doSemaphoreUp(smmu.requestPortSem);
|
||||
|
||||
|
||||
SMMUAction a;
|
||||
a.type = ACTION_SEND_REQ;
|
||||
|
||||
RequestPtr req = std::make_shared<Request>(
|
||||
addr, size, 0, smmu.masterId);
|
||||
addr, size, 0, smmu.requestorId);
|
||||
|
||||
req->taskId(ContextSwitchTaskId::DMA);
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
#include "base/types.hh"
|
||||
#include "mem/packet.hh"
|
||||
|
||||
class SMMUv3SlaveInterface;
|
||||
class SMMUv3DeviceInterface;
|
||||
|
||||
/*
|
||||
* The meaning of these becomes apparent when you
|
||||
@@ -67,7 +67,7 @@ struct SMMUAction
|
||||
{
|
||||
SMMUActionType type;
|
||||
PacketPtr pkt;
|
||||
SMMUv3SlaveInterface *ifc;
|
||||
SMMUv3DeviceInterface *ifc;
|
||||
Tick delay;
|
||||
};
|
||||
|
||||
|
||||
@@ -77,12 +77,12 @@ SMMUTranslRequest::prefetch(Addr addr, uint32_t sid, uint32_t ssid)
|
||||
}
|
||||
|
||||
SMMUTranslationProcess::SMMUTranslationProcess(const std::string &name,
|
||||
SMMUv3 &_smmu, SMMUv3SlaveInterface &_ifc)
|
||||
SMMUv3 &_smmu, SMMUv3DeviceInterface &_ifc)
|
||||
:
|
||||
SMMUProcess(name, _smmu),
|
||||
ifc(_ifc)
|
||||
{
|
||||
// Decrease number of pending translation slots on the slave interface
|
||||
// Decrease number of pending translation slots on the device interface
|
||||
assert(ifc.xlateSlotsRemaining > 0);
|
||||
ifc.xlateSlotsRemaining--;
|
||||
|
||||
@@ -92,12 +92,12 @@ SMMUTranslationProcess::SMMUTranslationProcess(const std::string &name,
|
||||
|
||||
SMMUTranslationProcess::~SMMUTranslationProcess()
|
||||
{
|
||||
// Increase number of pending translation slots on the slave interface
|
||||
// Increase number of pending translation slots on the device interface
|
||||
assert(ifc.pendingMemAccesses > 0);
|
||||
ifc.pendingMemAccesses--;
|
||||
|
||||
// If no more SMMU memory accesses are pending,
|
||||
// signal SMMU Slave Interface as drained
|
||||
// signal SMMU Device Interface as drained
|
||||
if (ifc.pendingMemAccesses == 0) {
|
||||
ifc.signalDrainDone();
|
||||
}
|
||||
@@ -147,12 +147,12 @@ SMMUTranslationProcess::main(Yield &yield)
|
||||
request.addr, request.size);
|
||||
|
||||
|
||||
unsigned numSlaveBeats = request.isWrite ?
|
||||
unsigned numResponderBeats = request.isWrite ?
|
||||
(request.size + (ifc.portWidth - 1)) / ifc.portWidth : 1;
|
||||
|
||||
doSemaphoreDown(yield, ifc.slavePortSem);
|
||||
doDelay(yield, Cycles(numSlaveBeats));
|
||||
doSemaphoreUp(ifc.slavePortSem);
|
||||
doSemaphoreDown(yield, ifc.devicePortSem);
|
||||
doDelay(yield, Cycles(numResponderBeats));
|
||||
doSemaphoreUp(ifc.devicePortSem);
|
||||
|
||||
|
||||
recvTick = curTick();
|
||||
@@ -261,7 +261,7 @@ SMMUTranslationProcess::smmuTranslation(Yield &yield)
|
||||
|
||||
bool haveConfig = true;
|
||||
if (!configCacheLookup(yield, context)) {
|
||||
if(findConfig(yield, context, tr)) {
|
||||
if (findConfig(yield, context, tr)) {
|
||||
configCacheUpdate(yield, context);
|
||||
} else {
|
||||
haveConfig = false;
|
||||
@@ -295,7 +295,7 @@ SMMUTranslationProcess::smmuTranslation(Yield &yield)
|
||||
smmuTLBUpdate(yield, tr);
|
||||
}
|
||||
|
||||
// Simulate pipelined SMMU->SLAVE INTERFACE link
|
||||
// Simulate pipelined SMMU->RESPONSE INTERFACE link
|
||||
doSemaphoreDown(yield, smmu.smmuIfcSem);
|
||||
doDelay(yield, Cycles(1)); // serialize transactions
|
||||
doSemaphoreUp(smmu.smmuIfcSem);
|
||||
@@ -353,14 +353,14 @@ SMMUTranslationProcess::ifcTLBLookup(Yield &yield, TranslResult &tr,
|
||||
|
||||
if (!e) {
|
||||
DPRINTF(SMMUv3,
|
||||
"SLAVE Interface TLB miss vaddr=%#x sid=%#x ssid=%#x\n",
|
||||
"RESPONSE Interface TLB miss vaddr=%#x sid=%#x ssid=%#x\n",
|
||||
request.addr, request.sid, request.ssid);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
DPRINTF(SMMUv3,
|
||||
"SLAVE Interface TLB hit vaddr=%#x amask=%#x sid=%#x ssid=%#x "
|
||||
"RESPONSE Interface TLB hit vaddr=%#x amask=%#x sid=%#x ssid=%#x "
|
||||
"paddr=%#x\n", request.addr, e->vaMask, request.sid,
|
||||
request.ssid, e->pa);
|
||||
|
||||
@@ -465,7 +465,7 @@ SMMUTranslationProcess::ifcTLBUpdate(Yield &yield,
|
||||
doSemaphoreDown(yield, ifc.mainTLBSem);
|
||||
|
||||
DPRINTF(SMMUv3,
|
||||
"SLAVE Interface upd vaddr=%#x amask=%#x paddr=%#x sid=%#x "
|
||||
"RESPONSE Interface upd vaddr=%#x amask=%#x paddr=%#x sid=%#x "
|
||||
"ssid=%#x\n", e.va, e.vaMask, e.pa, e.sid, e.ssid);
|
||||
|
||||
ifc.mainTLB->store(e, alloc);
|
||||
@@ -1226,14 +1226,14 @@ SMMUTranslationProcess::completeTransaction(Yield &yield,
|
||||
{
|
||||
assert(tr.fault == FAULT_NONE);
|
||||
|
||||
unsigned numMasterBeats = request.isWrite ?
|
||||
(request.size + (smmu.masterPortWidth-1))
|
||||
/ smmu.masterPortWidth :
|
||||
unsigned numRequestorBeats = request.isWrite ?
|
||||
(request.size + (smmu.requestPortWidth-1))
|
||||
/ smmu.requestPortWidth :
|
||||
1;
|
||||
|
||||
doSemaphoreDown(yield, smmu.masterPortSem);
|
||||
doDelay(yield, Cycles(numMasterBeats));
|
||||
doSemaphoreUp(smmu.masterPortSem);
|
||||
doSemaphoreDown(yield, smmu.requestPortSem);
|
||||
doDelay(yield, Cycles(numRequestorBeats));
|
||||
doSemaphoreUp(smmu.requestPortSem);
|
||||
|
||||
|
||||
smmu.translationTimeDist.sample(curTick() - recvTick);
|
||||
@@ -1242,7 +1242,7 @@ SMMUTranslationProcess::completeTransaction(Yield &yield,
|
||||
ifc.wrBufSlotsRemaining +=
|
||||
(request.size + (ifc.portWidth-1)) / ifc.portWidth;
|
||||
|
||||
smmu.scheduleSlaveRetries();
|
||||
smmu.scheduleDeviceRetries();
|
||||
|
||||
|
||||
SMMUAction a;
|
||||
|
||||
@@ -39,9 +39,9 @@
|
||||
#define __DEV_ARM_SMMU_V3_TRANSL_HH__
|
||||
|
||||
#include "base/compiler.hh"
|
||||
#include "dev/arm/smmu_v3_deviceifc.hh"
|
||||
#include "dev/arm/smmu_v3_proc.hh"
|
||||
#include "dev/arm/smmu_v3_ptops.hh"
|
||||
#include "dev/arm/smmu_v3_slaveifc.hh"
|
||||
#include "mem/packet.hh"
|
||||
|
||||
struct SMMUTranslRequest
|
||||
@@ -91,7 +91,7 @@ class SMMUTranslationProcess : public SMMUProcess
|
||||
bool writable;
|
||||
};
|
||||
|
||||
SMMUv3SlaveInterface &ifc;
|
||||
SMMUv3DeviceInterface &ifc;
|
||||
|
||||
SMMUTranslRequest request;
|
||||
TranslContext context;
|
||||
@@ -174,7 +174,7 @@ class SMMUTranslationProcess : public SMMUProcess
|
||||
|
||||
public:
|
||||
SMMUTranslationProcess(const std::string &name, SMMUv3 &_smmu,
|
||||
SMMUv3SlaveInterface &_ifc);
|
||||
SMMUv3DeviceInterface &_ifc);
|
||||
|
||||
virtual ~SMMUTranslationProcess();
|
||||
|
||||
|
||||
@@ -148,7 +148,7 @@ VGic::readCtrl(PacketPtr pkt)
|
||||
|
||||
DPRINTF(VGIC, "VGIC HVCtrl read register %#x\n", daddr);
|
||||
|
||||
/* Munge the address: 0-0xfff is the usual space banked by requester CPU.
|
||||
/* Munge the address: 0-0xfff is the usual space banked by requestor CPU.
|
||||
* Anything > that is 0x200-sized slices of 'per CPU' regs.
|
||||
*/
|
||||
if (daddr & ~0x1ff) {
|
||||
@@ -292,7 +292,7 @@ VGic::writeCtrl(PacketPtr pkt)
|
||||
DPRINTF(VGIC, "VGIC HVCtrl write register %#x <= %#x\n",
|
||||
daddr, pkt->getLE<uint32_t>());
|
||||
|
||||
/* Munge the address: 0-0xfff is the usual space banked by requester CPU.
|
||||
/* Munge the address: 0-0xfff is the usual space banked by requestor CPU.
|
||||
* Anything > that is 0x200-sized slices of 'per CPU' regs.
|
||||
*/
|
||||
if (daddr & ~0x1ff) {
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
DmaPort::DmaPort(ClockedObject *dev, System *s,
|
||||
uint32_t sid, uint32_t ssid)
|
||||
: RequestPort(dev->name() + ".dma", dev),
|
||||
device(dev), sys(s), masterId(s->getMasterId(dev)),
|
||||
device(dev), sys(s), requestorId(s->getRequestorId(dev)),
|
||||
sendEvent([this]{ sendDma(); }, dev->name()),
|
||||
pendingCount(0), inRetry(false),
|
||||
defaultSid(sid),
|
||||
@@ -166,7 +166,7 @@ DmaPort::dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
|
||||
!gen.done(); gen.next()) {
|
||||
|
||||
req = std::make_shared<Request>(
|
||||
gen.addr(), gen.size(), flag, masterId);
|
||||
gen.addr(), gen.size(), flag, requestorId);
|
||||
|
||||
req->setStreamId(sid);
|
||||
req->setSubStreamId(ssid);
|
||||
|
||||
@@ -114,7 +114,7 @@ class DmaPort : public RequestPort, public Drainable
|
||||
System *const sys;
|
||||
|
||||
/** Id for all requests */
|
||||
const MasterID masterId;
|
||||
const RequestorID requestorId;
|
||||
|
||||
protected:
|
||||
/** Use a deque as we never do any insertion or removal in the middle */
|
||||
|
||||
@@ -59,6 +59,6 @@ class Malta(Platform):
|
||||
# earlier, since the bus object itself is typically defined at the
|
||||
# System level.
|
||||
def attachIO(self, bus):
|
||||
self.cchip.pio = bus.master
|
||||
self.io.pio = bus.master
|
||||
self.uart.pio = bus.master
|
||||
self.cchip.pio = bus.mem_side_ports
|
||||
self.io.pio = bus.mem_side_ports
|
||||
self.uart.pio = bus.mem_side_ports
|
||||
|
||||
@@ -60,7 +60,7 @@ System *DistIface::sys = nullptr;
|
||||
DistIface::SyncEvent *DistIface::syncEvent = nullptr;
|
||||
unsigned DistIface::distIfaceNum = 0;
|
||||
unsigned DistIface::recvThreadsNum = 0;
|
||||
DistIface *DistIface::master = nullptr;
|
||||
DistIface *DistIface::primary = nullptr;
|
||||
bool DistIface::isSwitch = false;
|
||||
|
||||
void
|
||||
@@ -142,7 +142,7 @@ DistIface::SyncNode::run(bool same_tick)
|
||||
needExit = ReqType::pending;
|
||||
if (needStopSync != ReqType::none)
|
||||
needStopSync = ReqType::pending;
|
||||
DistIface::master->sendCmd(header);
|
||||
DistIface::primary->sendCmd(header);
|
||||
// now wait until all receiver threads complete the synchronisation
|
||||
auto lf = [this]{ return waitNum == 0; };
|
||||
cv.wait(sync_lock, lf);
|
||||
@@ -191,7 +191,7 @@ DistIface::SyncSwitch::run(bool same_tick)
|
||||
} else {
|
||||
header.needStopSync = ReqType::none;
|
||||
}
|
||||
DistIface::master->sendCmd(header);
|
||||
DistIface::primary->sendCmd(header);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -410,7 +410,7 @@ DistIface::SyncEvent::process()
|
||||
start();
|
||||
} else {
|
||||
// Wake up thread contexts on non-switch nodes.
|
||||
for (auto *tc: master->sys->threads) {
|
||||
for (auto *tc: primary->sys->threads) {
|
||||
if (tc->status() == ThreadContext::Suspended)
|
||||
tc->activate();
|
||||
else
|
||||
@@ -503,10 +503,10 @@ DistIface::RecvScheduler::pushPacket(EthPacketPtr new_packet,
|
||||
"send_tick:%llu send_delay:%llu link_delay:%llu recv_tick:%llu\n",
|
||||
send_tick, send_delay, linkDelay, recv_tick);
|
||||
// Every packet must be sent and arrive in the same quantum
|
||||
assert(send_tick > master->syncEvent->when() -
|
||||
master->syncEvent->repeat);
|
||||
assert(send_tick > primary->syncEvent->when() -
|
||||
primary->syncEvent->repeat);
|
||||
// No packet may be scheduled for receive in the arrival quantum
|
||||
assert(send_tick + send_delay + linkDelay > master->syncEvent->when());
|
||||
assert(send_tick + send_delay + linkDelay > primary->syncEvent->when());
|
||||
|
||||
// Now we are about to schedule a recvDone event for the new data packet.
|
||||
// We use the same recvDone object for all incoming data packets. Packet
|
||||
@@ -611,8 +611,8 @@ DistIface::DistIface(unsigned dist_rank,
|
||||
rank(dist_rank), size(dist_size)
|
||||
{
|
||||
DPRINTF(DistEthernet, "DistIface() ctor rank:%d\n",dist_rank);
|
||||
isMaster = false;
|
||||
if (master == nullptr) {
|
||||
isPrimary = false;
|
||||
if (primary == nullptr) {
|
||||
assert(sync == nullptr);
|
||||
assert(syncEvent == nullptr);
|
||||
isSwitch = is_switch;
|
||||
@@ -621,8 +621,8 @@ DistIface::DistIface(unsigned dist_rank,
|
||||
else
|
||||
sync = new SyncNode();
|
||||
syncEvent = new SyncEvent();
|
||||
master = this;
|
||||
isMaster = true;
|
||||
primary = this;
|
||||
isPrimary = true;
|
||||
}
|
||||
distIfaceId = distIfaceNum;
|
||||
distIfaceNum++;
|
||||
@@ -639,8 +639,8 @@ DistIface::~DistIface()
|
||||
assert(sync);
|
||||
delete sync;
|
||||
}
|
||||
if (this == master)
|
||||
master = nullptr;
|
||||
if (this == primary)
|
||||
primary = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
@@ -728,7 +728,7 @@ DistIface::drain()
|
||||
{
|
||||
DPRINTF(DistEthernet,"DistIFace::drain() called\n");
|
||||
// This can be called multiple times in the same drain cycle.
|
||||
if (this == master)
|
||||
if (this == primary)
|
||||
syncEvent->draining(true);
|
||||
return DrainState::Drained;
|
||||
}
|
||||
@@ -736,7 +736,7 @@ DistIface::drain()
|
||||
void
|
||||
DistIface::drainResume() {
|
||||
DPRINTF(DistEthernet,"DistIFace::drainResume() called\n");
|
||||
if (this == master)
|
||||
if (this == primary)
|
||||
syncEvent->draining(false);
|
||||
recvScheduler.resumeRecvTicks();
|
||||
}
|
||||
@@ -755,7 +755,7 @@ DistIface::serialize(CheckpointOut &cp) const
|
||||
SERIALIZE_SCALAR(dist_iface_id_orig);
|
||||
|
||||
recvScheduler.serializeSection(cp, "recvScheduler");
|
||||
if (this == master) {
|
||||
if (this == primary) {
|
||||
sync->serializeSection(cp, "Sync");
|
||||
}
|
||||
}
|
||||
@@ -774,7 +774,7 @@ DistIface::unserialize(CheckpointIn &cp)
|
||||
dist_iface_id_orig);
|
||||
|
||||
recvScheduler.unserializeSection(cp, "recvScheduler");
|
||||
if (this == master) {
|
||||
if (this == primary) {
|
||||
sync->unserializeSection(cp, "Sync");
|
||||
}
|
||||
}
|
||||
@@ -801,8 +801,8 @@ DistIface::init(const Event *done_event, Tick link_delay)
|
||||
|
||||
// Initialize the seed for random generator to avoid the same sequence
|
||||
// in all gem5 peer processes
|
||||
assert(master != nullptr);
|
||||
if (this == master)
|
||||
assert(primary != nullptr);
|
||||
if (this == primary)
|
||||
random_mt.init(5489 * (rank+1) + 257);
|
||||
}
|
||||
|
||||
@@ -811,7 +811,7 @@ DistIface::startup()
|
||||
{
|
||||
DPRINTF(DistEthernet, "DistIface::startup() started\n");
|
||||
// Schedule synchronization unless we are not a switch in pseudo_op mode.
|
||||
if (this == master && (!syncStartOnPseudoOp || isSwitch))
|
||||
if (this == primary && (!syncStartOnPseudoOp || isSwitch))
|
||||
syncEvent->start();
|
||||
DPRINTF(DistEthernet, "DistIface::startup() done\n");
|
||||
}
|
||||
@@ -822,7 +822,7 @@ DistIface::readyToCkpt(Tick delay, Tick period)
|
||||
bool ret = true;
|
||||
DPRINTF(DistEthernet, "DistIface::readyToCkpt() called, delay:%lu "
|
||||
"period:%lu\n", delay, period);
|
||||
if (master) {
|
||||
if (primary) {
|
||||
if (delay == 0) {
|
||||
inform("m5 checkpoint called with zero delay => triggering collaborative "
|
||||
"checkpoint\n");
|
||||
@@ -851,38 +851,38 @@ void
|
||||
DistIface::toggleSync(ThreadContext *tc)
|
||||
{
|
||||
// Unforunate that we have to populate the system pointer member this way.
|
||||
master->sys = tc->getSystemPtr();
|
||||
primary->sys = tc->getSystemPtr();
|
||||
|
||||
// The invariant for both syncing and "unsyncing" is that all threads will
|
||||
// stop executing intructions until the desired sync state has been reached
|
||||
// for all nodes. This is the easiest way to prevent deadlock (in the case
|
||||
// of "unsyncing") and causality errors (in the case of syncing).
|
||||
if (master->syncEvent->scheduled()) {
|
||||
if (primary->syncEvent->scheduled()) {
|
||||
inform("Request toggling syncronization off\n");
|
||||
master->sync->requestStopSync(ReqType::collective);
|
||||
primary->sync->requestStopSync(ReqType::collective);
|
||||
|
||||
// At this point, we have no clue when everyone will reach the sync
|
||||
// stop point. Suspend execution of all local thread contexts.
|
||||
// Dist-gem5 will reactivate all thread contexts when everyone has
|
||||
// reached the sync stop point.
|
||||
#if THE_ISA != NULL_ISA
|
||||
for (auto *tc: master->sys->threads) {
|
||||
for (auto *tc: primary->sys->threads) {
|
||||
if (tc->status() == ThreadContext::Active)
|
||||
tc->quiesce();
|
||||
}
|
||||
#endif
|
||||
} else {
|
||||
inform("Request toggling syncronization on\n");
|
||||
master->syncEvent->start();
|
||||
primary->syncEvent->start();
|
||||
|
||||
// We need to suspend all CPUs until the sync point is reached by all
|
||||
// nodes to prevent causality errors. We can also schedule CPU
|
||||
// activation here, since we know exactly when the next sync will
|
||||
// occur.
|
||||
#if THE_ISA != NULL_ISA
|
||||
for (auto *tc: master->sys->threads) {
|
||||
for (auto *tc: primary->sys->threads) {
|
||||
if (tc->status() == ThreadContext::Active)
|
||||
tc->quiesceTick(master->syncEvent->when() + 1);
|
||||
tc->quiesceTick(primary->syncEvent->when() + 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -894,10 +894,10 @@ DistIface::readyToExit(Tick delay)
|
||||
bool ret = true;
|
||||
DPRINTF(DistEthernet, "DistIface::readyToExit() called, delay:%lu\n",
|
||||
delay);
|
||||
if (master) {
|
||||
if (primary) {
|
||||
// To successfully coordinate an exit, all nodes must be synchronising
|
||||
if (!master->syncEvent->scheduled())
|
||||
master->syncEvent->start();
|
||||
if (!primary->syncEvent->scheduled())
|
||||
primary->syncEvent->start();
|
||||
|
||||
if (delay == 0) {
|
||||
inform("m5 exit called with zero delay => triggering collaborative "
|
||||
@@ -917,8 +917,8 @@ uint64_t
|
||||
DistIface::rankParam()
|
||||
{
|
||||
uint64_t val;
|
||||
if (master) {
|
||||
val = master->rank;
|
||||
if (primary) {
|
||||
val = primary->rank;
|
||||
} else {
|
||||
warn("Dist-rank parameter is queried in single gem5 simulation.");
|
||||
val = 0;
|
||||
@@ -930,8 +930,8 @@ uint64_t
|
||||
DistIface::sizeParam()
|
||||
{
|
||||
uint64_t val;
|
||||
if (master) {
|
||||
val = master->size;
|
||||
if (primary) {
|
||||
val = primary->size;
|
||||
} else {
|
||||
warn("Dist-size parameter is queried in single gem5 simulation.");
|
||||
val = 1;
|
||||
|
||||
@@ -491,7 +491,7 @@ class DistIface : public Drainable, public Serializable
|
||||
*/
|
||||
unsigned distIfaceId;
|
||||
|
||||
bool isMaster;
|
||||
bool isPrimary;
|
||||
|
||||
private:
|
||||
/**
|
||||
@@ -507,10 +507,10 @@ class DistIface : public Drainable, public Serializable
|
||||
*/
|
||||
static SyncEvent *syncEvent;
|
||||
/**
|
||||
* The very first DistIface object created becomes the master. We need
|
||||
* a master to co-ordinate the global synchronisation.
|
||||
* The very first DistIface object created becomes the primary interface.
|
||||
* We need a primary interface to co-ordinate the global synchronisation.
|
||||
*/
|
||||
static DistIface *master;
|
||||
static DistIface *primary;
|
||||
/**
|
||||
* System pointer used to wakeup sleeping threads when stopping sync.
|
||||
*/
|
||||
@@ -635,7 +635,7 @@ class DistIface : public Drainable, public Serializable
|
||||
*/
|
||||
static uint64_t sizeParam();
|
||||
/**
|
||||
* Trigger the master to start/stop synchronization.
|
||||
* Trigger the primary to start/stop synchronization.
|
||||
*/
|
||||
static void toggleSync(ThreadContext *tc);
|
||||
};
|
||||
|
||||
@@ -87,7 +87,7 @@ TCPIface::TCPIface(string server_name, unsigned server_port,
|
||||
is_switch, num_nodes), serverName(server_name),
|
||||
serverPort(server_port), isSwitch(is_switch), listening(false)
|
||||
{
|
||||
if (is_switch && isMaster) {
|
||||
if (is_switch && isPrimary) {
|
||||
while (!listen(serverPort)) {
|
||||
DPRINTF(DistEthernet, "TCPIface(listen): Can't bind port %d\n",
|
||||
serverPort);
|
||||
@@ -307,7 +307,7 @@ TCPIface::sendCmd(const Header &header)
|
||||
{
|
||||
DPRINTF(DistEthernetCmd, "TCPIface::sendCmd() type: %d\n",
|
||||
static_cast<int>(header.msgType));
|
||||
// Global commands (i.e. sync request) are always sent by the master
|
||||
// Global commands (i.e. sync request) are always sent by the primary
|
||||
// DistIface. The transfer method is simply implemented as point-to-point
|
||||
// messages for now
|
||||
for (auto s: sockRegistry)
|
||||
|
||||
@@ -33,7 +33,7 @@ from m5.objects.PciDevice import PciDevice
|
||||
class CopyEngine(PciDevice):
|
||||
type = 'CopyEngine'
|
||||
cxx_header = "dev/pci/copy_engine.hh"
|
||||
dma = VectorMasterPort("Copy engine DMA port")
|
||||
dma = VectorRequestPort("Copy engine DMA port")
|
||||
VendorID = 0x8086
|
||||
DeviceID = 0x1a38
|
||||
Revision = 0xA2 # CM2 stepping (newest listed)
|
||||
|
||||
@@ -204,7 +204,7 @@ Terminal::accept()
|
||||
pollQueue.schedule(dataEvent);
|
||||
|
||||
stringstream stream;
|
||||
ccprintf(stream, "==== m5 slave terminal: Terminal %d ====", number);
|
||||
ccprintf(stream, "==== m5 terminal: Terminal %d ====", number);
|
||||
|
||||
// we need an actual carriage return followed by a newline for the
|
||||
// terminal
|
||||
|
||||
@@ -112,8 +112,8 @@ class T1000(Platform):
|
||||
iob = Iob()
|
||||
# Attach I/O devices that are on chip
|
||||
def attachOnChipIO(self, bus):
|
||||
self.iob.pio = bus.master
|
||||
self.htod.pio = bus.master
|
||||
self.iob.pio = bus.mem_side_ports
|
||||
self.htod.pio = bus.mem_side_ports
|
||||
|
||||
|
||||
# Attach I/O devices to specified bus object. Can't do this
|
||||
@@ -122,17 +122,17 @@ class T1000(Platform):
|
||||
def attachIO(self, bus):
|
||||
self.hvuart.device = self.hterm
|
||||
self.puart0.device = self.pterm
|
||||
self.fake_clk.pio = bus.master
|
||||
self.fake_membnks.pio = bus.master
|
||||
self.fake_l2_1.pio = bus.master
|
||||
self.fake_l2_2.pio = bus.master
|
||||
self.fake_l2_3.pio = bus.master
|
||||
self.fake_l2_4.pio = bus.master
|
||||
self.fake_l2esr_1.pio = bus.master
|
||||
self.fake_l2esr_2.pio = bus.master
|
||||
self.fake_l2esr_3.pio = bus.master
|
||||
self.fake_l2esr_4.pio = bus.master
|
||||
self.fake_ssi.pio = bus.master
|
||||
self.fake_jbi.pio = bus.master
|
||||
self.puart0.pio = bus.master
|
||||
self.hvuart.pio = bus.master
|
||||
self.fake_clk.pio = bus.mem_side_ports
|
||||
self.fake_membnks.pio = bus.mem_side_ports
|
||||
self.fake_l2_1.pio = bus.mem_side_ports
|
||||
self.fake_l2_2.pio = bus.mem_side_ports
|
||||
self.fake_l2_3.pio = bus.mem_side_ports
|
||||
self.fake_l2_4.pio = bus.mem_side_ports
|
||||
self.fake_l2esr_1.pio = bus.mem_side_ports
|
||||
self.fake_l2esr_2.pio = bus.mem_side_ports
|
||||
self.fake_l2esr_3.pio = bus.mem_side_ports
|
||||
self.fake_l2esr_4.pio = bus.mem_side_ports
|
||||
self.fake_ssi.pio = bus.mem_side_ports
|
||||
self.fake_jbi.pio = bus.mem_side_ports
|
||||
self.puart0.pio = bus.mem_side_ports
|
||||
self.hvuart.pio = bus.mem_side_ports
|
||||
|
||||
@@ -28,13 +28,13 @@ from m5.SimObject import SimObject
|
||||
from m5.params import *
|
||||
from m5.objects.PciDevice import PciDevice
|
||||
|
||||
class IdeID(Enum): vals = ['master', 'slave']
|
||||
class IdeID(Enum): vals = ['device0', 'device1']
|
||||
|
||||
class IdeDisk(SimObject):
|
||||
type = 'IdeDisk'
|
||||
cxx_header = "dev/storage/ide_disk.hh"
|
||||
delay = Param.Latency('1us', "Fixed disk delay in microseconds")
|
||||
driveID = Param.IdeID('master', "Drive ID")
|
||||
driveID = Param.IdeID('device0', "Drive ID")
|
||||
image = Param.DiskImage("Disk image")
|
||||
|
||||
class IdeController(PciDevice):
|
||||
|
||||
@@ -77,7 +77,7 @@ IdeController::Channel::Channel(
|
||||
string newName, Addr _cmdSize, Addr _ctrlSize) :
|
||||
_name(newName),
|
||||
cmdAddr(0), cmdSize(_cmdSize), ctrlAddr(0), ctrlSize(_ctrlSize),
|
||||
master(NULL), slave(NULL), selected(NULL)
|
||||
device0(NULL), device1(NULL), selected(NULL)
|
||||
{
|
||||
bmiRegs.reset();
|
||||
bmiRegs.status.dmaCap0 = 1;
|
||||
@@ -105,16 +105,16 @@ IdeController::IdeController(Params *p)
|
||||
continue;
|
||||
switch (i) {
|
||||
case 0:
|
||||
primary.master = params()->disks[0];
|
||||
primary.device0 = params()->disks[0];
|
||||
break;
|
||||
case 1:
|
||||
primary.slave = params()->disks[1];
|
||||
primary.device1 = params()->disks[1];
|
||||
break;
|
||||
case 2:
|
||||
secondary.master = params()->disks[2];
|
||||
secondary.device0 = params()->disks[2];
|
||||
break;
|
||||
case 3:
|
||||
secondary.slave = params()->disks[3];
|
||||
secondary.device1 = params()->disks[3];
|
||||
break;
|
||||
default:
|
||||
panic("IDE controllers support a maximum "
|
||||
@@ -156,9 +156,9 @@ void
|
||||
IdeController::setDmaComplete(IdeDisk *disk)
|
||||
{
|
||||
Channel *channel;
|
||||
if (disk == primary.master || disk == primary.slave) {
|
||||
if (disk == primary.device0 || disk == primary.device1) {
|
||||
channel = &primary;
|
||||
} else if (disk == secondary.master || disk == secondary.slave) {
|
||||
} else if (disk == secondary.device0 || disk == secondary.device1) {
|
||||
channel = &secondary;
|
||||
} else {
|
||||
panic("Unable to find disk based on pointer %#x\n", disk);
|
||||
|
||||
@@ -89,8 +89,13 @@ class IdeController : public PciDevice
|
||||
uint32_t bmidtp;
|
||||
} bmiRegs;
|
||||
|
||||
/** IDE disks connected to this controller */
|
||||
IdeDisk *master, *slave;
|
||||
/** IDE disks connected to this controller
|
||||
* For more details about device0 and device1 see:
|
||||
* https://en.wikipedia.org/wiki/Parallel_ATA
|
||||
* #Multiple_devices_on_a_cable
|
||||
*
|
||||
*/
|
||||
IdeDisk *device0, *device1;
|
||||
|
||||
/** Currently selected disk */
|
||||
IdeDisk *selected;
|
||||
@@ -98,10 +103,10 @@ class IdeController : public PciDevice
|
||||
bool selectBit;
|
||||
|
||||
void
|
||||
select(bool selSlave)
|
||||
select(bool select_device_1)
|
||||
{
|
||||
selectBit = selSlave;
|
||||
selected = selectBit ? slave : master;
|
||||
selectBit = select_device_1;
|
||||
selected = selectBit ? device1 : device0;
|
||||
}
|
||||
|
||||
void accessCommand(Addr offset, int size, uint8_t *data, bool read);
|
||||
|
||||
@@ -245,7 +245,7 @@ class IdeDisk : public SimObject
|
||||
uint32_t curPrdAddr;
|
||||
/** PRD entry */
|
||||
PrdTableEntry curPrd;
|
||||
/** Device ID (master=0/slave=1) */
|
||||
/** Device ID (device0=0/device1=1) */
|
||||
int devID;
|
||||
/** Interrupt pending */
|
||||
bool intrPending;
|
||||
|
||||
@@ -34,7 +34,7 @@ class I82094AA(BasicPioDevice):
|
||||
cxx_class = 'X86ISA::I82094AA'
|
||||
cxx_header = "dev/x86/i82094aa.hh"
|
||||
apic_id = Param.Int(1, 'APIC id for this IO APIC')
|
||||
int_master = RequestPort("Port for sending interrupt messages")
|
||||
int_requestor = RequestPort("Port for sending interrupt messages")
|
||||
int_latency = Param.Latency('1ns', \
|
||||
"Latency for an interrupt to propagate through this device.")
|
||||
external_int_pic = Param.I8259(NULL, "External PIC, if any")
|
||||
|
||||
@@ -75,12 +75,12 @@ class Pc(Platform):
|
||||
|
||||
def attachIO(self, bus, dma_ports = []):
|
||||
self.south_bridge.attachIO(bus, dma_ports)
|
||||
self.i_dont_exist1.pio = bus.master
|
||||
self.i_dont_exist2.pio = bus.master
|
||||
self.behind_pci.pio = bus.master
|
||||
self.com_1.pio = bus.master
|
||||
self.fake_com_2.pio = bus.master
|
||||
self.fake_com_3.pio = bus.master
|
||||
self.fake_com_4.pio = bus.master
|
||||
self.fake_floppy.pio = bus.master
|
||||
self.i_dont_exist1.pio = bus.mem_side_ports
|
||||
self.i_dont_exist2.pio = bus.mem_side_ports
|
||||
self.behind_pci.pio = bus.mem_side_ports
|
||||
self.com_1.pio = bus.mem_side_ports
|
||||
self.fake_com_2.pio = bus.mem_side_ports
|
||||
self.fake_com_3.pio = bus.mem_side_ports
|
||||
self.fake_com_4.pio = bus.mem_side_ports
|
||||
self.fake_floppy.pio = bus.mem_side_ports
|
||||
self.pci_host.pio = bus.default
|
||||
|
||||
@@ -97,15 +97,15 @@ class SouthBridge(SimObject):
|
||||
self.speaker.i8254 = self.pit
|
||||
self.io_apic.external_int_pic = self.pic1
|
||||
# Connect to the bus
|
||||
self.cmos.pio = bus.master
|
||||
self.dma1.pio = bus.master
|
||||
self.ide.pio = bus.master
|
||||
self.cmos.pio = bus.mem_side_ports
|
||||
self.dma1.pio = bus.mem_side_ports
|
||||
self.ide.pio = bus.mem_side_ports
|
||||
if dma_ports.count(self.ide.dma) == 0:
|
||||
self.ide.dma = bus.slave
|
||||
self.keyboard.pio = bus.master
|
||||
self.pic1.pio = bus.master
|
||||
self.pic2.pio = bus.master
|
||||
self.pit.pio = bus.master
|
||||
self.speaker.pio = bus.master
|
||||
self.io_apic.pio = bus.master
|
||||
self.io_apic.int_master = bus.slave
|
||||
self.ide.dma = bus.cpu_side_ports
|
||||
self.keyboard.pio = bus.mem_side_ports
|
||||
self.pic1.pio = bus.mem_side_ports
|
||||
self.pic2.pio = bus.mem_side_ports
|
||||
self.pit.pio = bus.mem_side_ports
|
||||
self.speaker.pio = bus.mem_side_ports
|
||||
self.io_apic.pio = bus.mem_side_ports
|
||||
self.io_apic.int_requestor = bus.cpu_side_ports
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
X86ISA::I82094AA::I82094AA(Params *p)
|
||||
: BasicPioDevice(p, 20), extIntPic(p->external_int_pic),
|
||||
lowestPriorityOffset(0),
|
||||
intMasterPort(name() + ".int_master", this, this, p->int_latency)
|
||||
intRequestPort(name() + ".int_request", this, this, p->int_latency)
|
||||
{
|
||||
// This assumes there's only one I/O APIC in the system and since the apic
|
||||
// id is stored in a 8-bit field with 0xff meaning broadcast, the id must
|
||||
@@ -71,16 +71,16 @@ X86ISA::I82094AA::init()
|
||||
// the piodevice init() function.
|
||||
BasicPioDevice::init();
|
||||
|
||||
// If the master port isn't connected, we can't send interrupts anywhere.
|
||||
panic_if(!intMasterPort.isConnected(),
|
||||
// If the request port isn't connected, we can't send interrupts anywhere.
|
||||
panic_if(!intRequestPort.isConnected(),
|
||||
"Int port not connected to anything!");
|
||||
}
|
||||
|
||||
Port &
|
||||
X86ISA::I82094AA::getPort(const std::string &if_name, PortID idx)
|
||||
{
|
||||
if (if_name == "int_master")
|
||||
return intMasterPort;
|
||||
if (if_name == "int_request")
|
||||
return intRequestPort;
|
||||
if (if_name == "inputs")
|
||||
return *inputs.at(idx);
|
||||
else
|
||||
@@ -242,7 +242,7 @@ X86ISA::I82094AA::signalInterrupt(int line)
|
||||
}
|
||||
for (auto id: apics) {
|
||||
PacketPtr pkt = buildIntTriggerPacket(id, message);
|
||||
intMasterPort.sendMessage(pkt, sys->isTimingMode());
|
||||
intRequestPort.sendMessage(pkt, sys->isTimingMode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ class I82094AA : public BasicPioDevice
|
||||
|
||||
std::vector<IntSinkPin<I82094AA> *> inputs;
|
||||
|
||||
IntMasterPort<I82094AA> intMasterPort;
|
||||
IntRequestPort<I82094AA> intRequestPort;
|
||||
|
||||
public:
|
||||
typedef I82094AAParams Params;
|
||||
|
||||
@@ -191,7 +191,8 @@ X86ISA::I8259::write(PacketPtr pkt)
|
||||
case 0x2:
|
||||
DPRINTF(I8259, "Received initialization command word 3.\n");
|
||||
if (mode == Enums::I8259Master) {
|
||||
DPRINTF(I8259, "Slaves attached to IRQs:%s%s%s%s%s%s%s%s\n",
|
||||
DPRINTF(I8259, "Responders attached to "
|
||||
"IRQs:%s%s%s%s%s%s%s%s\n",
|
||||
bits(val, 0) ? " 0" : "",
|
||||
bits(val, 1) ? " 1" : "",
|
||||
bits(val, 2) ? " 2" : "",
|
||||
@@ -202,7 +203,7 @@ X86ISA::I8259::write(PacketPtr pkt)
|
||||
bits(val, 7) ? " 7" : "");
|
||||
cascadeBits = val;
|
||||
} else {
|
||||
DPRINTF(I8259, "Slave ID is %d.\n", val & mask(3));
|
||||
DPRINTF(I8259, "Responder ID is %d.\n", val & mask(3));
|
||||
cascadeBits = val & mask(3);
|
||||
}
|
||||
if (expectICW4)
|
||||
@@ -307,10 +308,10 @@ int
|
||||
X86ISA::I8259::getVector()
|
||||
{
|
||||
/*
|
||||
* This code only handles one slave. Since that's how the PC platform
|
||||
* This code only handles one responder. Since that's how the PC platform
|
||||
* always uses the 8259 PIC, there shouldn't be any need for more. If
|
||||
* there -is- a need for more for some reason, "slave" can become a
|
||||
* vector of slaves.
|
||||
* there -is- a need for more for some reason, "responder" can become a
|
||||
* vector of responders.
|
||||
*/
|
||||
int line = findMsbSet(IRR);
|
||||
IRR &= ~(1 << line);
|
||||
@@ -321,7 +322,7 @@ X86ISA::I8259::getVector()
|
||||
ISR |= 1 << line;
|
||||
}
|
||||
if (slave && bits(cascadeBits, line)) {
|
||||
DPRINTF(I8259, "Interrupt was from slave who will "
|
||||
DPRINTF(I8259, "Interrupt was from responder who will "
|
||||
"provide the vector.\n");
|
||||
return slave->getVector();
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ class I8259 : public BasicPioDevice
|
||||
std::vector<IntSourcePin<I8259> *> output;
|
||||
std::vector<IntSinkPin<I8259> *> inputs;
|
||||
Enums::X86I8259CascadeMode mode;
|
||||
I8259 * slave;
|
||||
I8259 *slave;
|
||||
|
||||
// Interrupt Request Register
|
||||
uint8_t IRR;
|
||||
@@ -62,8 +62,9 @@ class I8259 : public BasicPioDevice
|
||||
uint8_t vectorOffset;
|
||||
|
||||
bool cascadeMode;
|
||||
// A bit vector of lines with slaves attached, or the slave id, depending
|
||||
// on if this is a master or slave PIC.
|
||||
// A bit vector of lines with responders attached, or the
|
||||
// responder id, depending
|
||||
// on if this is a requestor or responder PIC.
|
||||
uint8_t cascadeBits;
|
||||
|
||||
bool edgeTriggered;
|
||||
|
||||
@@ -53,12 +53,12 @@ namespace X86ISA
|
||||
{
|
||||
|
||||
template <class Device>
|
||||
class IntSlavePort : public SimpleTimingPort
|
||||
class IntResponsePort : public SimpleTimingPort
|
||||
{
|
||||
Device * device;
|
||||
|
||||
public:
|
||||
IntSlavePort(const std::string& _name, SimObject* _parent,
|
||||
IntResponsePort(const std::string& _name, SimObject* _parent,
|
||||
Device* dev) :
|
||||
SimpleTimingPort(_name, _parent), device(dev)
|
||||
{
|
||||
@@ -86,7 +86,7 @@ PacketPtr
|
||||
buildIntPacket(Addr addr, T payload)
|
||||
{
|
||||
RequestPtr req = std::make_shared<Request>(
|
||||
addr, sizeof(T), Request::UNCACHEABLE, Request::intMasterId);
|
||||
addr, sizeof(T), Request::UNCACHEABLE, Request::intRequestorId);
|
||||
PacketPtr pkt = new Packet(req, MemCmd::WriteReq);
|
||||
pkt->allocate();
|
||||
pkt->setRaw<T>(payload);
|
||||
@@ -94,7 +94,7 @@ buildIntPacket(Addr addr, T payload)
|
||||
}
|
||||
|
||||
template <class Device>
|
||||
class IntMasterPort : public QueuedMasterPort
|
||||
class IntRequestPort : public QueuedRequestPort
|
||||
{
|
||||
private:
|
||||
ReqPacketQueue reqQueue;
|
||||
@@ -113,9 +113,9 @@ class IntMasterPort : public QueuedMasterPort
|
||||
static void defaultOnCompletion(PacketPtr pkt) { delete pkt; }
|
||||
|
||||
public:
|
||||
IntMasterPort(const std::string& _name, SimObject* _parent,
|
||||
IntRequestPort(const std::string& _name, SimObject* _parent,
|
||||
Device* dev, Tick _latency) :
|
||||
QueuedMasterPort(_name, _parent, reqQueue, snoopRespQueue),
|
||||
QueuedRequestPort(_name, _parent, reqQueue, snoopRespQueue),
|
||||
reqQueue(*_parent, *this), snoopRespQueue(*_parent, *this),
|
||||
device(dev), latency(_latency)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user