/* * Copyright (c) 2013, 2018-2019 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall * not be construed as granting a license to any other intellectual * property including but not limited to intellectual property relating * to a hardware implementation of the functionality of the software * licensed hereunder. You may use the software subject to the license * terms below provided that you ensure that this notice is replicated * unmodified and in its entirety in all distributions of the software, * modified or unmodified, in source code or in binary form. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are * met: redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer; * redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution; * neither the name of the copyright holders nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * Authors: Stan Czerniawski */ #ifndef __DEV_ARM_SMMU_V3_HH__ #define __DEV_ARM_SMMU_V3_HH__ #include #include #include #include #include #include "base/statistics.hh" #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_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" #include "sim/eventq.hh" /** * @file: * This is an implementation of the SMMUv3 architecture. * * What can it do? * - Single-stage and nested translation with 4k or 64k granule. 16k would * be straightforward to add. * - Large pages are supported. * - Works with any gem5 device as long as it is issuing packets with a * valid (Sub)StreamId * * What it can't do? * - Fragment stage 1 page when the underlying stage 2 page is smaller. S1 * page size > S2 page size is not supported * - Invalidations take zero time. This wouldn't be hard to fix. * - Checkpointing is not supported * - Stall/resume for faulting transactions is not supported */ class SMMUTranslationProcess; class SMMUv3 : public ClockedObject { protected: friend class SMMUProcess; friend class SMMUTranslationProcess; friend class SMMUCommandExecProcess; friend class SMMUv3SlaveInterface; const System &system; const MasterID masterId; SMMUMasterPort masterPort; SMMUMasterTableWalkPort masterTableWalkPort; SMMUControlPort controlPort; ARMArchTLB tlb; ConfigCache configCache; IPACache ipaCache; WalkCache walkCache; const bool tlbEnable; const bool configCacheEnable; const bool ipaCacheEnable; const bool walkCacheEnable; bool tableWalkPortEnable; const bool walkCacheNonfinalEnable; const unsigned walkCacheS1Levels; const unsigned walkCacheS2Levels; const unsigned masterPortWidth; // in bytes SMMUSemaphore tlbSem; SMMUSemaphore ifcSmmuSem; SMMUSemaphore smmuIfcSem; SMMUSemaphore configSem; SMMUSemaphore ipaSem; SMMUSemaphore walkSem; SMMUSemaphore masterPortSem; SMMUSemaphore transSem; // max N transactions in SMMU SMMUSemaphore ptwSem; // max N concurrent PTWs SMMUSemaphore cycleSem; // max 1 table walk per cycle // Timing parameters const Cycles tlbLat; const Cycles ifcSmmuLat; const Cycles smmuIfcLat; const Cycles configLat; const Cycles ipaLat; const Cycles walkLat; // Stats Stats::Scalar steL1Fetches; Stats::Scalar steFetches; Stats::Scalar cdL1Fetches; Stats::Scalar cdFetches; Stats::Distribution translationTimeDist; Stats::Distribution ptwTimeDist; std::vector slaveInterfaces; SMMUCommandExecProcess commandExecutor; const AddrRange regsMap; SMMURegs regs; bool inSecureBlock(uint32_t offs) const; std::queue packetsToRetry; std::queue packetsTableWalkToRetry; void scheduleSlaveRetries(); SMMUAction runProcess(SMMUProcess *proc, PacketPtr pkt); SMMUAction runProcessAtomic(SMMUProcess *proc, PacketPtr pkt); SMMUAction runProcessTiming(SMMUProcess *proc, PacketPtr pkt); void processCommands(); EventWrapper processCommandsEvent; void processCommand(const SMMUCommand &cmd); const PageTableOps *getPageTableOps(uint8_t trans_granule); public: SMMUv3(SMMUv3Params *p); virtual ~SMMUv3() {} 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(); bool masterTableWalkRecvTimingResp(PacketPtr pkt); void masterTableWalkRecvReqRetry(); Tick readControl(PacketPtr pkt); Tick writeControl(PacketPtr pkt); DrainState drain() override; void serialize(CheckpointOut &cp) const override; void unserialize(CheckpointIn &cp) override; virtual Port &getPort(const std::string &name, PortID id = InvalidPortID) override; }; #endif /* __DEV_ARM_SMMU_V3_HH__ */