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#ifndef __DEV_ARM_SMMU_V3_HH__
41#define __DEV_ARM_SMMU_V3_HH__
42
43#include <list>
44#include <map>
45#include <queue>
46#include <string>
47#include <vector>
48
49#include "base/statistics.hh"
50#include "dev/arm/smmu_v3_caches.hh"
51#include "dev/arm/smmu_v3_cmdexec.hh"
52#include "dev/arm/smmu_v3_defs.hh"
53#include "dev/arm/smmu_v3_events.hh"
54#include "dev/arm/smmu_v3_ports.hh"
55#include "dev/arm/smmu_v3_proc.hh"
56#include "dev/arm/smmu_v3_ptops.hh"
57#include "dev/arm/smmu_v3_slaveifc.hh"
58#include "mem/packet.hh"
59#include "params/SMMUv3.hh"
60#include "sim/clocked_object.hh"
61#include "sim/eventq.hh"
62
63/**
64 * @file:
65 * This is an implementation of the SMMUv3 architecture.
66 *
67 * What can it do?
68 * - Single-stage and nested translation with 4k or 64k granule.  16k would
69 *   be straightforward to add.
70 * - Large pages are supported.
71 * - Works with any gem5 device as long as it is issuing packets with a
72 *   valid (Sub)StreamId
73 *
74 * What it can't do?
75 * - Fragment stage 1 page when the underlying stage 2 page is smaller.  S1
76 *   page size > S2 page size is not supported
77 * - Invalidations take zero time. This wouldn't be hard to fix.
78 * - Checkpointing is not supported
79 * - Stall/resume for faulting transactions is not supported
80 */
81class SMMUTranslationProcess;
82
83class SMMUv3 : public ClockedObject
84{
85  protected:
86
87    friend class SMMUProcess;
88    friend class SMMUTranslationProcess;
89    friend class SMMUCommandExecProcess;
90    friend class SMMUv3SlaveInterface;
91
92    const System &system;
93    const MasterID masterId;
94
95    SMMUMasterPort    masterPort;
96    SMMUMasterTableWalkPort masterTableWalkPort;
97    SMMUControlPort   controlPort;
98
99    ARMArchTLB  tlb;
100    ConfigCache configCache;
101    IPACache    ipaCache;
102    WalkCache   walkCache;
103
104    const bool tlbEnable;
105    const bool configCacheEnable;
106    const bool ipaCacheEnable;
107    const bool walkCacheEnable;
108    bool tableWalkPortEnable;
109
110    const bool walkCacheNonfinalEnable;
111    const unsigned walkCacheS1Levels;
112    const unsigned walkCacheS2Levels;
113    const unsigned masterPortWidth; // in bytes
114
115    SMMUSemaphore tlbSem;
116    SMMUSemaphore ifcSmmuSem;
117    SMMUSemaphore smmuIfcSem;
118    SMMUSemaphore configSem;
119    SMMUSemaphore ipaSem;
120    SMMUSemaphore walkSem;
121    SMMUSemaphore masterPortSem;
122
123    SMMUSemaphore transSem; // max N transactions in SMMU
124    SMMUSemaphore ptwSem; // max N concurrent PTWs
125    SMMUSemaphore cycleSem; // max 1 table walk per cycle
126
127    // Timing parameters
128    const Cycles tlbLat;
129    const Cycles ifcSmmuLat;
130    const Cycles smmuIfcLat;
131    const Cycles configLat;
132    const Cycles ipaLat;
133    const Cycles walkLat;
134
135    // Stats
136    Stats::Scalar steL1Fetches;
137    Stats::Scalar steFetches;
138    Stats::Scalar cdL1Fetches;
139    Stats::Scalar cdFetches;
140    Stats::Distribution translationTimeDist;
141    Stats::Distribution ptwTimeDist;
142
143    std::vector<SMMUv3SlaveInterface *> slaveInterfaces;
144
145    SMMUCommandExecProcess commandExecutor;
146
147    const AddrRange regsMap;
148    SMMURegs regs;
149
150    bool inSecureBlock(uint32_t offs) const;
151
152    std::queue<SMMUAction> packetsToRetry;
153    std::queue<SMMUAction> packetsTableWalkToRetry;
154
155
156    void scheduleSlaveRetries();
157
158    SMMUAction runProcess(SMMUProcess *proc, PacketPtr pkt);
159    SMMUAction runProcessAtomic(SMMUProcess *proc, PacketPtr pkt);
160    SMMUAction runProcessTiming(SMMUProcess *proc, PacketPtr pkt);
161
162    void processCommands();
163    EventWrapper<SMMUv3, &SMMUv3::processCommands> processCommandsEvent;
164
165    void processCommand(const SMMUCommand &cmd);
166
167    const PageTableOps *getPageTableOps(uint8_t trans_granule);
168
169  public:
170    SMMUv3(SMMUv3Params *p);
171    virtual ~SMMUv3() {}
172
173    virtual void init() override;
174    virtual void regStats() override;
175
176    Tick slaveRecvAtomic(PacketPtr pkt, PortID id);
177    bool slaveRecvTimingReq(PacketPtr pkt, PortID id);
178    bool masterRecvTimingResp(PacketPtr pkt);
179    void masterRecvReqRetry();
180
181    bool masterTableWalkRecvTimingResp(PacketPtr pkt);
182    void masterTableWalkRecvReqRetry();
183
184    Tick readControl(PacketPtr pkt);
185    Tick writeControl(PacketPtr pkt);
186
187    DrainState drain() override;
188    void serialize(CheckpointOut &cp) const override;
189    void unserialize(CheckpointIn &cp) override;
190
191    virtual Port &getPort(const std::string &name,
192                          PortID id = InvalidPortID) override;
193};
194
195#endif /* __DEV_ARM_SMMU_V3_HH__ */
196