114039Sstacze01@arm.com/*
214039Sstacze01@arm.com * Copyright (c) 2013, 2018-2019 ARM Limited
314039Sstacze01@arm.com * All rights reserved
414039Sstacze01@arm.com *
514039Sstacze01@arm.com * The license below extends only to copyright in the software and shall
614039Sstacze01@arm.com * not be construed as granting a license to any other intellectual
714039Sstacze01@arm.com * property including but not limited to intellectual property relating
814039Sstacze01@arm.com * to a hardware implementation of the functionality of the software
914039Sstacze01@arm.com * licensed hereunder.  You may use the software subject to the license
1014039Sstacze01@arm.com * terms below provided that you ensure that this notice is replicated
1114039Sstacze01@arm.com * unmodified and in its entirety in all distributions of the software,
1214039Sstacze01@arm.com * modified or unmodified, in source code or in binary form.
1314039Sstacze01@arm.com *
1414039Sstacze01@arm.com * Redistribution and use in source and binary forms, with or without
1514039Sstacze01@arm.com * modification, are permitted provided that the following conditions are
1614039Sstacze01@arm.com * met: redistributions of source code must retain the above copyright
1714039Sstacze01@arm.com * notice, this list of conditions and the following disclaimer;
1814039Sstacze01@arm.com * redistributions in binary form must reproduce the above copyright
1914039Sstacze01@arm.com * notice, this list of conditions and the following disclaimer in the
2014039Sstacze01@arm.com * documentation and/or other materials provided with the distribution;
2114039Sstacze01@arm.com * neither the name of the copyright holders nor the names of its
2214039Sstacze01@arm.com * contributors may be used to endorse or promote products derived from
2314039Sstacze01@arm.com * this software without specific prior written permission.
2414039Sstacze01@arm.com *
2514039Sstacze01@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2614039Sstacze01@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2714039Sstacze01@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2814039Sstacze01@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2914039Sstacze01@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3014039Sstacze01@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3114039Sstacze01@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3214039Sstacze01@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3314039Sstacze01@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3414039Sstacze01@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3514039Sstacze01@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3614039Sstacze01@arm.com *
3714039Sstacze01@arm.com * Authors: Stan Czerniawski
3814039Sstacze01@arm.com */
3914039Sstacze01@arm.com
4014039Sstacze01@arm.com#ifndef __DEV_ARM_SMMU_V3_HH__
4114039Sstacze01@arm.com#define __DEV_ARM_SMMU_V3_HH__
4214039Sstacze01@arm.com
4314039Sstacze01@arm.com#include <list>
4414039Sstacze01@arm.com#include <map>
4514039Sstacze01@arm.com#include <queue>
4614039Sstacze01@arm.com#include <string>
4714039Sstacze01@arm.com#include <vector>
4814039Sstacze01@arm.com
4914039Sstacze01@arm.com#include "base/statistics.hh"
5014039Sstacze01@arm.com#include "dev/arm/smmu_v3_caches.hh"
5114039Sstacze01@arm.com#include "dev/arm/smmu_v3_cmdexec.hh"
5214039Sstacze01@arm.com#include "dev/arm/smmu_v3_defs.hh"
5314039Sstacze01@arm.com#include "dev/arm/smmu_v3_events.hh"
5414039Sstacze01@arm.com#include "dev/arm/smmu_v3_ports.hh"
5514039Sstacze01@arm.com#include "dev/arm/smmu_v3_proc.hh"
5614039Sstacze01@arm.com#include "dev/arm/smmu_v3_ptops.hh"
5714039Sstacze01@arm.com#include "dev/arm/smmu_v3_slaveifc.hh"
5814039Sstacze01@arm.com#include "mem/packet.hh"
5914039Sstacze01@arm.com#include "params/SMMUv3.hh"
6014252Sgabeblack@google.com#include "sim/clocked_object.hh"
6114039Sstacze01@arm.com#include "sim/eventq.hh"
6214039Sstacze01@arm.com
6314039Sstacze01@arm.com/**
6414039Sstacze01@arm.com * @file:
6514039Sstacze01@arm.com * This is an implementation of the SMMUv3 architecture.
6614039Sstacze01@arm.com *
6714039Sstacze01@arm.com * What can it do?
6814039Sstacze01@arm.com * - Single-stage and nested translation with 4k or 64k granule.  16k would
6914039Sstacze01@arm.com *   be straightforward to add.
7014039Sstacze01@arm.com * - Large pages are supported.
7114039Sstacze01@arm.com * - Works with any gem5 device as long as it is issuing packets with a
7214039Sstacze01@arm.com *   valid (Sub)StreamId
7314039Sstacze01@arm.com *
7414039Sstacze01@arm.com * What it can't do?
7514039Sstacze01@arm.com * - Fragment stage 1 page when the underlying stage 2 page is smaller.  S1
7614039Sstacze01@arm.com *   page size > S2 page size is not supported
7714039Sstacze01@arm.com * - Invalidations take zero time. This wouldn't be hard to fix.
7814039Sstacze01@arm.com * - Checkpointing is not supported
7914039Sstacze01@arm.com * - Stall/resume for faulting transactions is not supported
8014039Sstacze01@arm.com */
8114039Sstacze01@arm.comclass SMMUTranslationProcess;
8214039Sstacze01@arm.com
8314252Sgabeblack@google.comclass SMMUv3 : public ClockedObject
8414039Sstacze01@arm.com{
8514039Sstacze01@arm.com  protected:
8614039Sstacze01@arm.com
8714039Sstacze01@arm.com    friend class SMMUProcess;
8814039Sstacze01@arm.com    friend class SMMUTranslationProcess;
8914039Sstacze01@arm.com    friend class SMMUCommandExecProcess;
9014039Sstacze01@arm.com    friend class SMMUv3SlaveInterface;
9114039Sstacze01@arm.com
9214039Sstacze01@arm.com    const System &system;
9314039Sstacze01@arm.com    const MasterID masterId;
9414039Sstacze01@arm.com
9514039Sstacze01@arm.com    SMMUMasterPort    masterPort;
9614039Sstacze01@arm.com    SMMUMasterTableWalkPort masterTableWalkPort;
9714039Sstacze01@arm.com    SMMUControlPort   controlPort;
9814039Sstacze01@arm.com
9914039Sstacze01@arm.com    ARMArchTLB  tlb;
10014039Sstacze01@arm.com    ConfigCache configCache;
10114039Sstacze01@arm.com    IPACache    ipaCache;
10214039Sstacze01@arm.com    WalkCache   walkCache;
10314039Sstacze01@arm.com
10414039Sstacze01@arm.com    const bool tlbEnable;
10514039Sstacze01@arm.com    const bool configCacheEnable;
10614039Sstacze01@arm.com    const bool ipaCacheEnable;
10714039Sstacze01@arm.com    const bool walkCacheEnable;
10814039Sstacze01@arm.com    bool tableWalkPortEnable;
10914039Sstacze01@arm.com
11014039Sstacze01@arm.com    const bool walkCacheNonfinalEnable;
11114039Sstacze01@arm.com    const unsigned walkCacheS1Levels;
11214039Sstacze01@arm.com    const unsigned walkCacheS2Levels;
11314039Sstacze01@arm.com    const unsigned masterPortWidth; // in bytes
11414039Sstacze01@arm.com
11514039Sstacze01@arm.com    SMMUSemaphore tlbSem;
11614039Sstacze01@arm.com    SMMUSemaphore ifcSmmuSem;
11714039Sstacze01@arm.com    SMMUSemaphore smmuIfcSem;
11814039Sstacze01@arm.com    SMMUSemaphore configSem;
11914039Sstacze01@arm.com    SMMUSemaphore ipaSem;
12014039Sstacze01@arm.com    SMMUSemaphore walkSem;
12114039Sstacze01@arm.com    SMMUSemaphore masterPortSem;
12214039Sstacze01@arm.com
12314039Sstacze01@arm.com    SMMUSemaphore transSem; // max N transactions in SMMU
12414039Sstacze01@arm.com    SMMUSemaphore ptwSem; // max N concurrent PTWs
12514039Sstacze01@arm.com    SMMUSemaphore cycleSem; // max 1 table walk per cycle
12614039Sstacze01@arm.com
12714039Sstacze01@arm.com    // Timing parameters
12814039Sstacze01@arm.com    const Cycles tlbLat;
12914039Sstacze01@arm.com    const Cycles ifcSmmuLat;
13014039Sstacze01@arm.com    const Cycles smmuIfcLat;
13114039Sstacze01@arm.com    const Cycles configLat;
13214039Sstacze01@arm.com    const Cycles ipaLat;
13314039Sstacze01@arm.com    const Cycles walkLat;
13414039Sstacze01@arm.com
13514039Sstacze01@arm.com    // Stats
13614039Sstacze01@arm.com    Stats::Scalar steL1Fetches;
13714039Sstacze01@arm.com    Stats::Scalar steFetches;
13814039Sstacze01@arm.com    Stats::Scalar cdL1Fetches;
13914039Sstacze01@arm.com    Stats::Scalar cdFetches;
14014039Sstacze01@arm.com    Stats::Distribution translationTimeDist;
14114039Sstacze01@arm.com    Stats::Distribution ptwTimeDist;
14214039Sstacze01@arm.com
14314039Sstacze01@arm.com    std::vector<SMMUv3SlaveInterface *> slaveInterfaces;
14414039Sstacze01@arm.com
14514039Sstacze01@arm.com    SMMUCommandExecProcess commandExecutor;
14614039Sstacze01@arm.com
14714039Sstacze01@arm.com    const AddrRange regsMap;
14814039Sstacze01@arm.com    SMMURegs regs;
14914039Sstacze01@arm.com
15014039Sstacze01@arm.com    bool inSecureBlock(uint32_t offs) const;
15114039Sstacze01@arm.com
15214039Sstacze01@arm.com    std::queue<SMMUAction> packetsToRetry;
15314039Sstacze01@arm.com    std::queue<SMMUAction> packetsTableWalkToRetry;
15414039Sstacze01@arm.com
15514039Sstacze01@arm.com
15614039Sstacze01@arm.com    void scheduleSlaveRetries();
15714039Sstacze01@arm.com
15814039Sstacze01@arm.com    SMMUAction runProcess(SMMUProcess *proc, PacketPtr pkt);
15914039Sstacze01@arm.com    SMMUAction runProcessAtomic(SMMUProcess *proc, PacketPtr pkt);
16014039Sstacze01@arm.com    SMMUAction runProcessTiming(SMMUProcess *proc, PacketPtr pkt);
16114039Sstacze01@arm.com
16214039Sstacze01@arm.com    void processCommands();
16314039Sstacze01@arm.com    EventWrapper<SMMUv3, &SMMUv3::processCommands> processCommandsEvent;
16414039Sstacze01@arm.com
16514039Sstacze01@arm.com    void processCommand(const SMMUCommand &cmd);
16614039Sstacze01@arm.com
16714039Sstacze01@arm.com    const PageTableOps *getPageTableOps(uint8_t trans_granule);
16814039Sstacze01@arm.com
16914039Sstacze01@arm.com  public:
17014039Sstacze01@arm.com    SMMUv3(SMMUv3Params *p);
17114039Sstacze01@arm.com    virtual ~SMMUv3() {}
17214039Sstacze01@arm.com
17314039Sstacze01@arm.com    virtual void init() override;
17414039Sstacze01@arm.com    virtual void regStats() override;
17514039Sstacze01@arm.com
17614039Sstacze01@arm.com    Tick slaveRecvAtomic(PacketPtr pkt, PortID id);
17714039Sstacze01@arm.com    bool slaveRecvTimingReq(PacketPtr pkt, PortID id);
17814039Sstacze01@arm.com    bool masterRecvTimingResp(PacketPtr pkt);
17914039Sstacze01@arm.com    void masterRecvReqRetry();
18014039Sstacze01@arm.com
18114039Sstacze01@arm.com    bool masterTableWalkRecvTimingResp(PacketPtr pkt);
18214039Sstacze01@arm.com    void masterTableWalkRecvReqRetry();
18314039Sstacze01@arm.com
18414039Sstacze01@arm.com    Tick readControl(PacketPtr pkt);
18514039Sstacze01@arm.com    Tick writeControl(PacketPtr pkt);
18614039Sstacze01@arm.com
18714039Sstacze01@arm.com    DrainState drain() override;
18814039Sstacze01@arm.com    void serialize(CheckpointOut &cp) const override;
18914039Sstacze01@arm.com    void unserialize(CheckpointIn &cp) override;
19014039Sstacze01@arm.com
19114039Sstacze01@arm.com    virtual Port &getPort(const std::string &name,
19214039Sstacze01@arm.com                          PortID id = InvalidPortID) override;
19314039Sstacze01@arm.com};
19414039Sstacze01@arm.com
19514039Sstacze01@arm.com#endif /* __DEV_ARM_SMMU_V3_HH__ */
196