1/*
2 * Copyright (c) 2013, 2018-2019 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder.  You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 *
37 * Authors: Stan Czerniawski
38 */
39
40#include "dev/arm/smmu_v3_ports.hh"
41
42#include "base/logging.hh"
43#include "dev/arm/smmu_v3.hh"
44#include "dev/arm/smmu_v3_slaveifc.hh"
45
46SMMUMasterPort::SMMUMasterPort(const std::string &_name, SMMUv3 &_smmu) :
47    MasterPort(_name, &_smmu),
48    smmu(_smmu)
49{}
50
51bool
52SMMUMasterPort::recvTimingResp(PacketPtr pkt)
53{
54    return smmu.masterRecvTimingResp(pkt);
55}
56
57void
58SMMUMasterPort::recvReqRetry()
59{
60    return smmu.masterRecvReqRetry();
61}
62
63SMMUMasterTableWalkPort::SMMUMasterTableWalkPort(const std::string &_name,
64                                                 SMMUv3 &_smmu) :
65    MasterPort(_name, &_smmu),
66    smmu(_smmu)
67{}
68
69bool
70SMMUMasterTableWalkPort::recvTimingResp(PacketPtr pkt)
71{
72    return smmu.masterTableWalkRecvTimingResp(pkt);
73}
74
75void
76SMMUMasterTableWalkPort::recvReqRetry()
77{
78    return smmu.masterTableWalkRecvReqRetry();
79}
80
81SMMUSlavePort::SMMUSlavePort(const std::string &_name,
82                             SMMUv3SlaveInterface &_ifc,
83                             PortID _id)
84:
85    QueuedSlavePort(_name, &_ifc, respQueue, _id),
86    ifc(_ifc),
87    respQueue(_ifc, *this)
88{}
89
90void
91SMMUSlavePort::recvFunctional(PacketPtr pkt)
92{
93    if (!respQueue.trySatisfyFunctional(pkt))
94        recvAtomic(pkt);
95}
96
97Tick
98SMMUSlavePort::recvAtomic(PacketPtr pkt)
99{
100    return ifc.recvAtomic(pkt);
101}
102
103bool
104SMMUSlavePort::recvTimingReq(PacketPtr pkt)
105{
106    return ifc.recvTimingReq(pkt);
107}
108
109SMMUControlPort::SMMUControlPort(const std::string &_name,
110                                 SMMUv3 &_smmu, AddrRange _addrRange)
111:
112    SimpleTimingPort(_name, &_smmu),
113    smmu(_smmu),
114    addrRange(_addrRange)
115{}
116
117Tick
118SMMUControlPort::recvAtomic(PacketPtr pkt)
119{
120    Addr addr = pkt->getAddr();
121    unsigned size = pkt->getSize();
122
123    if (!addrRange.contains(addr) || !addrRange.contains(addr+size))
124        panic("SMMU: invalid address on control port %x, packet size %d",
125                addr, size);
126
127    // @todo: We need to pay for this and not just zero it out
128    pkt->headerDelay = pkt->payloadDelay = 0;
129
130    return pkt->isRead() ? smmu.readControl(pkt) : smmu.writeControl(pkt);
131}
132
133AddrRangeList
134SMMUControlPort::getAddrRanges() const
135{
136    AddrRangeList list;
137    list.push_back(addrRange);
138    return list;
139}
140
141SMMUATSMasterPort::SMMUATSMasterPort(const std::string &_name,
142                                     SMMUv3SlaveInterface &_ifc) :
143    QueuedMasterPort(_name, &_ifc, reqQueue, snoopRespQueue),
144    ifc(_ifc),
145    reqQueue(_ifc, *this),
146    snoopRespQueue(_ifc, *this)
147{}
148
149bool
150SMMUATSMasterPort::recvTimingResp(PacketPtr pkt)
151{
152    return ifc.atsMasterRecvTimingResp(pkt);
153}
154
155SMMUATSSlavePort::SMMUATSSlavePort(const std::string &_name,
156                                   SMMUv3SlaveInterface &_ifc) :
157    QueuedSlavePort(_name, &_ifc, respQueue),
158    ifc(_ifc),
159    respQueue(_ifc, *this)
160{}
161
162void
163SMMUATSSlavePort::recvFunctional(PacketPtr pkt)
164{
165    panic("Functional access on ATS port!");
166}
167
168Tick
169SMMUATSSlavePort::recvAtomic(PacketPtr pkt)
170{
171    return ifc.atsSlaveRecvAtomic(pkt);
172}
173
174bool
175SMMUATSSlavePort::recvTimingReq(PacketPtr pkt)
176{
177    return ifc.atsSlaveRecvTimingReq(pkt);
178}
179