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_TRANSL_HH__
4114039Sstacze01@arm.com#define __DEV_ARM_SMMU_V3_TRANSL_HH__
4214039Sstacze01@arm.com
4314039Sstacze01@arm.com#include "dev/arm/smmu_v3_proc.hh"
4414039Sstacze01@arm.com#include "dev/arm/smmu_v3_ptops.hh"
4514039Sstacze01@arm.com#include "dev/arm/smmu_v3_slaveifc.hh"
4614039Sstacze01@arm.com#include "mem/packet.hh"
4714039Sstacze01@arm.com
4814039Sstacze01@arm.comstruct SMMUTranslRequest
4914039Sstacze01@arm.com{
5014039Sstacze01@arm.com    Addr     addr;
5114039Sstacze01@arm.com    unsigned size;
5214039Sstacze01@arm.com    uint32_t sid;  // streamId
5314039Sstacze01@arm.com    uint32_t ssid; // substreamId
5414039Sstacze01@arm.com    bool     isWrite;
5514039Sstacze01@arm.com    bool     isPrefetch;
5614039Sstacze01@arm.com    bool     isAtsRequest;
5714039Sstacze01@arm.com
5814039Sstacze01@arm.com    PacketPtr pkt;
5914039Sstacze01@arm.com
6014039Sstacze01@arm.com    static SMMUTranslRequest fromPacket(PacketPtr pkt, bool ats = false);
6114039Sstacze01@arm.com    static SMMUTranslRequest prefetch(Addr addr, uint32_t sid, uint32_t ssid);
6214039Sstacze01@arm.com};
6314039Sstacze01@arm.com
6414039Sstacze01@arm.comclass SMMUTranslationProcess : public SMMUProcess
6514039Sstacze01@arm.com{
6614039Sstacze01@arm.com  private:
6714039Sstacze01@arm.com    struct TranslContext
6814039Sstacze01@arm.com    {
6914039Sstacze01@arm.com        bool stage1Enable;
7014039Sstacze01@arm.com        bool stage2Enable;
7114039Sstacze01@arm.com        Addr ttb0, ttb1, httb;
7214039Sstacze01@arm.com        uint16_t asid;
7314039Sstacze01@arm.com        uint16_t vmid;
7414039Sstacze01@arm.com        uint8_t stage1TranslGranule;
7514039Sstacze01@arm.com        uint8_t stage2TranslGranule;
7614100Sgiacomo.travaglini@arm.com        uint8_t t0sz;
7714100Sgiacomo.travaglini@arm.com        uint8_t s2t0sz;
7814039Sstacze01@arm.com    };
7914039Sstacze01@arm.com
8014039Sstacze01@arm.com    enum FaultType
8114039Sstacze01@arm.com    {
8214039Sstacze01@arm.com        FAULT_NONE,
8314039Sstacze01@arm.com        FAULT_TRANSLATION, // F_TRANSLATION
8414039Sstacze01@arm.com        FAULT_PERMISSION,  // F_PERMISSION
8514039Sstacze01@arm.com    };
8614039Sstacze01@arm.com
8714039Sstacze01@arm.com    struct TranslResult
8814039Sstacze01@arm.com    {
8914039Sstacze01@arm.com        FaultType  fault;
9014039Sstacze01@arm.com        Addr       addr;
9114039Sstacze01@arm.com        Addr       addrMask;
9214039Sstacze01@arm.com        bool       writable;
9314039Sstacze01@arm.com    };
9414039Sstacze01@arm.com
9514039Sstacze01@arm.com    SMMUv3SlaveInterface &ifc;
9614039Sstacze01@arm.com
9714039Sstacze01@arm.com    SMMUTranslRequest request;
9814039Sstacze01@arm.com    TranslContext context;
9914039Sstacze01@arm.com
10014039Sstacze01@arm.com    Tick recvTick;
10114039Sstacze01@arm.com    Tick faultTick;
10214039Sstacze01@arm.com
10314039Sstacze01@arm.com    virtual void main(Yield &yield);
10414039Sstacze01@arm.com
10514039Sstacze01@arm.com    TranslResult bypass(Addr addr) const;
10614039Sstacze01@arm.com    TranslResult smmuTranslation(Yield &yield);
10714039Sstacze01@arm.com
10814039Sstacze01@arm.com    bool microTLBLookup(Yield &yield, TranslResult &tr);
10914039Sstacze01@arm.com    bool ifcTLBLookup(Yield &yield, TranslResult &tr, bool &wasPrefetched);
11014039Sstacze01@arm.com    bool smmuTLBLookup(Yield &yield, TranslResult &tr);
11114039Sstacze01@arm.com
11214039Sstacze01@arm.com    void microTLBUpdate(Yield &yield, const TranslResult &tr);
11314039Sstacze01@arm.com    void ifcTLBUpdate(Yield &yield, const TranslResult &tr);
11414039Sstacze01@arm.com    void smmuTLBUpdate(Yield &yield, const TranslResult &tr);
11514039Sstacze01@arm.com
11614039Sstacze01@arm.com    bool configCacheLookup(Yield &yield, TranslContext &tc);
11714039Sstacze01@arm.com    void configCacheUpdate(Yield &yield, const TranslContext &tc);
11814039Sstacze01@arm.com    bool findConfig(Yield &yield, TranslContext &tc, TranslResult &tr);
11914039Sstacze01@arm.com
12014039Sstacze01@arm.com    void walkCacheLookup(Yield &yield,
12114039Sstacze01@arm.com                         const WalkCache::Entry *&walkEntry,
12214039Sstacze01@arm.com                         Addr addr, uint16_t asid, uint16_t vmid,
12314039Sstacze01@arm.com                         unsigned stage, unsigned level);
12414039Sstacze01@arm.com
12514039Sstacze01@arm.com    void walkCacheUpdate(Yield &yield, Addr va, Addr vaMask, Addr pa,
12614039Sstacze01@arm.com                         unsigned stage, unsigned level,
12714039Sstacze01@arm.com                         bool leaf, uint8_t permissions);
12814039Sstacze01@arm.com
12914039Sstacze01@arm.com    TranslResult walkStage1And2(Yield &yield, Addr addr,
13014039Sstacze01@arm.com                                const PageTableOps *pt_ops,
13114039Sstacze01@arm.com                                unsigned level, Addr walkPtr);
13214039Sstacze01@arm.com
13314039Sstacze01@arm.com    TranslResult walkStage2(Yield &yield, Addr addr, bool final_tr,
13414039Sstacze01@arm.com                            const PageTableOps *pt_ops,
13514039Sstacze01@arm.com                            unsigned level, Addr walkPtr);
13614039Sstacze01@arm.com
13714039Sstacze01@arm.com    TranslResult translateStage1And2(Yield &yield, Addr addr);
13814039Sstacze01@arm.com    TranslResult translateStage2(Yield &yield, Addr addr, bool final_tr);
13914039Sstacze01@arm.com
14014039Sstacze01@arm.com    TranslResult combineTranslations(const TranslResult &s1tr,
14114039Sstacze01@arm.com                                     const TranslResult &s2tr) const;
14214039Sstacze01@arm.com
14314039Sstacze01@arm.com    /**
14414039Sstacze01@arm.com     * Used to force ordering on transactions with same
14514039Sstacze01@arm.com     * (SID, SSID, 4k page) to avoid multiple identical
14614039Sstacze01@arm.com     * page-table walks.
14714039Sstacze01@arm.com     */
14814039Sstacze01@arm.com    bool hazard4kCheck();
14914039Sstacze01@arm.com    void hazard4kRegister();
15014039Sstacze01@arm.com    void hazard4kHold(Yield &yield);
15114039Sstacze01@arm.com    void hazard4kRelease();
15214039Sstacze01@arm.com
15314039Sstacze01@arm.com    /**
15414039Sstacze01@arm.com     * Used to force ordering on transactions with the same orderId.
15514039Sstacze01@arm.com     * This attempts to model AXI IDs.
15614039Sstacze01@arm.com     */
15714039Sstacze01@arm.com    void hazardIdRegister();
15814039Sstacze01@arm.com    void hazardIdHold(Yield &yield);
15914039Sstacze01@arm.com    void hazardIdRelease();
16014039Sstacze01@arm.com
16114039Sstacze01@arm.com    void issuePrefetch(Addr addr);
16214039Sstacze01@arm.com
16314039Sstacze01@arm.com    void completeTransaction(Yield &yield, const TranslResult &tr);
16414039Sstacze01@arm.com    void completePrefetch(Yield &yield);
16514039Sstacze01@arm.com
16614039Sstacze01@arm.com    void sendEvent(Yield &yield, const SMMUEvent &ev);
16714039Sstacze01@arm.com
16814039Sstacze01@arm.com    void doReadSTE(Yield &yield, StreamTableEntry &ste, uint32_t sid);
16914039Sstacze01@arm.com    void doReadCD(Yield &yield, ContextDescriptor &cd,
17014039Sstacze01@arm.com                  const StreamTableEntry &ste, uint32_t sid, uint32_t ssid);
17114039Sstacze01@arm.com    void doReadConfig(Yield &yield, Addr addr, void *ptr, size_t size,
17214039Sstacze01@arm.com                      uint32_t sid, uint32_t ssid);
17314039Sstacze01@arm.com    void doReadPTE(Yield &yield, Addr va, Addr addr, void *ptr,
17414039Sstacze01@arm.com                   unsigned stage, unsigned level);
17514039Sstacze01@arm.com
17614039Sstacze01@arm.com  public:
17714039Sstacze01@arm.com    SMMUTranslationProcess(const std::string &name, SMMUv3 &_smmu,
17814063Sadrian.herrera@arm.com        SMMUv3SlaveInterface &_ifc);
17914039Sstacze01@arm.com
18014063Sadrian.herrera@arm.com    virtual ~SMMUTranslationProcess();
18114039Sstacze01@arm.com
18214039Sstacze01@arm.com    void beginTransaction(const SMMUTranslRequest &req);
18314039Sstacze01@arm.com    void resumeTransaction();
18414039Sstacze01@arm.com};
18514039Sstacze01@arm.com
18614039Sstacze01@arm.com#endif /* __DEV_ARM_SMMU_V3_TRANSL_HH__ */
187