/*
 * 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
 */

#include "dev/arm/smmu_v3.hh"

#include <cstddef>
#include <cstring>

#include "base/bitfield.hh"
#include "base/cast.hh"
#include "base/logging.hh"
#include "base/trace.hh"
#include "base/types.hh"
#include "debug/Checkpoint.hh"
#include "debug/SMMUv3.hh"
#include "dev/arm/smmu_v3_transl.hh"
#include "mem/packet_access.hh"
#include "sim/system.hh"

SMMUv3::SMMUv3(SMMUv3Params *params) :
    ClockedObject(params),
    system(*params->system),
    masterId(params->system->getMasterId(this)),
    masterPort(name() + ".master", *this),
    masterTableWalkPort(name() + ".master_walker", *this),
    controlPort(name() + ".control", *this, params->reg_map),
    tlb(params->tlb_entries, params->tlb_assoc, params->tlb_policy),
    configCache(params->cfg_entries, params->cfg_assoc, params->cfg_policy),
    ipaCache(params->ipa_entries, params->ipa_assoc, params->ipa_policy),
    walkCache({ { params->walk_S1L0, params->walk_S1L1,
                  params->walk_S1L2, params->walk_S1L3,
                  params->walk_S2L0, params->walk_S2L1,
                  params->walk_S2L2, params->walk_S2L3 } },
              params->walk_assoc, params->walk_policy),
    tlbEnable(params->tlb_enable),
    configCacheEnable(params->cfg_enable),
    ipaCacheEnable(params->ipa_enable),
    walkCacheEnable(params->walk_enable),
    tableWalkPortEnable(false),
    walkCacheNonfinalEnable(params->wc_nonfinal_enable),
    walkCacheS1Levels(params->wc_s1_levels),
    walkCacheS2Levels(params->wc_s2_levels),
    masterPortWidth(params->master_port_width),
    tlbSem(params->tlb_slots),
    ifcSmmuSem(1),
    smmuIfcSem(1),
    configSem(params->cfg_slots),
    ipaSem(params->ipa_slots),
    walkSem(params->walk_slots),
    masterPortSem(1),
    transSem(params->xlate_slots),
    ptwSem(params->ptw_slots),
    cycleSem(1),
    tlbLat(params->tlb_lat),
    ifcSmmuLat(params->ifc_smmu_lat),
    smmuIfcLat(params->smmu_ifc_lat),
    configLat(params->cfg_lat),
    ipaLat(params->ipa_lat),
    walkLat(params->walk_lat),
    slaveInterfaces(params->slave_interfaces),
    commandExecutor(name() + ".cmd_exec", *this),
    regsMap(params->reg_map),
    processCommandsEvent(this)
{
    fatal_if(regsMap.size() != SMMU_REG_SIZE,
        "Invalid register map size: %#x different than SMMU_REG_SIZE = %#x\n",
        regsMap.size(), SMMU_REG_SIZE);

    // Init smmu registers to 0
    memset(&regs, 0, sizeof(regs));

    // Setup RO ID registers
    regs.idr0 = params->smmu_idr0;
    regs.idr1 = params->smmu_idr1;
    regs.idr2 = params->smmu_idr2;
    regs.idr3 = params->smmu_idr3;
    regs.idr4 = params->smmu_idr4;
    regs.idr5 = params->smmu_idr5;
    regs.iidr = params->smmu_iidr;
    regs.aidr = params->smmu_aidr;

    // TODO: At the moment it possible to set the ID registers to hold
    // any possible value. It would be nice to have a sanity check here
    // at construction time in case some idx registers are programmed to
    // store an unallowed values or if the are configuration conflicts.
    warn("SMMUv3 IDx register values unchecked\n");

    for (auto ifc : slaveInterfaces)
        ifc->setSMMU(this);
}

bool
SMMUv3::masterRecvTimingResp(PacketPtr pkt)
{
    DPRINTF(SMMUv3, "[t] master resp addr=%#x size=%#x\n",
        pkt->getAddr(), pkt->getSize());

    // @todo: We need to pay for this and not just zero it out
    pkt->headerDelay = pkt->payloadDelay = 0;

    SMMUProcess *proc =
        safe_cast<SMMUProcess *>(pkt->popSenderState());

    runProcessTiming(proc, pkt);

    return true;
}

void
SMMUv3::masterRecvReqRetry()
{
    assert(!packetsToRetry.empty());

    while (!packetsToRetry.empty()) {
        SMMUAction a = packetsToRetry.front();

        assert(a.type==ACTION_SEND_REQ || a.type==ACTION_SEND_REQ_FINAL);

        DPRINTF(SMMUv3, "[t] master retr addr=%#x size=%#x\n",
            a.pkt->getAddr(), a.pkt->getSize());

        if (!masterPort.sendTimingReq(a.pkt))
            break;

        packetsToRetry.pop();

        /*
         * ACTION_SEND_REQ_FINAL means that we have just forwarded the packet
         * on the master interface; this means that we no longer hold on to
         * that transaction and therefore can accept a new one.
         * If the slave port was stalled then unstall it (send retry).
         */
        if (a.type == ACTION_SEND_REQ_FINAL)
            scheduleSlaveRetries();
    }
}

bool
SMMUv3::masterTableWalkRecvTimingResp(PacketPtr pkt)
{
    DPRINTF(SMMUv3, "[t] master HWTW resp addr=%#x size=%#x\n",
        pkt->getAddr(), pkt->getSize());

    // @todo: We need to pay for this and not just zero it out
    pkt->headerDelay = pkt->payloadDelay = 0;

    SMMUProcess *proc =
        safe_cast<SMMUProcess *>(pkt->popSenderState());

    runProcessTiming(proc, pkt);

    return true;
}

void
SMMUv3::masterTableWalkRecvReqRetry()
{
    assert(tableWalkPortEnable);
    assert(!packetsTableWalkToRetry.empty());

    while (!packetsTableWalkToRetry.empty()) {
        SMMUAction a = packetsTableWalkToRetry.front();

        assert(a.type==ACTION_SEND_REQ);

        DPRINTF(SMMUv3, "[t] master HWTW retr addr=%#x size=%#x\n",
            a.pkt->getAddr(), a.pkt->getSize());

        if (!masterTableWalkPort.sendTimingReq(a.pkt))
            break;

        packetsTableWalkToRetry.pop();
    }
}

void
SMMUv3::scheduleSlaveRetries()
{
    for (auto ifc : slaveInterfaces) {
        ifc->scheduleDeviceRetry();
    }
}

SMMUAction
SMMUv3::runProcess(SMMUProcess *proc, PacketPtr pkt)
{
    if (system.isAtomicMode()) {
        return runProcessAtomic(proc, pkt);
    } else if (system.isTimingMode()) {
        return runProcessTiming(proc, pkt);
    } else {
        panic("Not in timing or atomic mode!");
    }
}

SMMUAction
SMMUv3::runProcessAtomic(SMMUProcess *proc, PacketPtr pkt)
{
    SMMUAction action;
    Tick delay = 0;
    bool finished = false;

    do {
        action = proc->run(pkt);

        switch (action.type) {
            case ACTION_SEND_REQ:
                // Send an MMU initiated request on the table walk port if it is
                // enabled. Otherwise, fall through and handle same as the final
                // ACTION_SEND_REQ_FINAL request.
                if (tableWalkPortEnable) {
                    delay += masterTableWalkPort.sendAtomic(action.pkt);
                    pkt = action.pkt;
                    break;
                }
                M5_FALLTHROUGH;
            case ACTION_SEND_REQ_FINAL:
                delay += masterPort.sendAtomic(action.pkt);
                pkt = action.pkt;
                break;

            case ACTION_SEND_RESP:
            case ACTION_SEND_RESP_ATS:
            case ACTION_SLEEP:
                finished = true;
                break;

            case ACTION_DELAY:
                delay += action.delay;
                break;

            case ACTION_TERMINATE:
                panic("ACTION_TERMINATE in atomic mode\n");

            default:
                panic("Unknown action\n");
        }
    } while (!finished);

    action.delay = delay;

    return action;
}

SMMUAction
SMMUv3::runProcessTiming(SMMUProcess *proc, PacketPtr pkt)
{
    SMMUAction action = proc->run(pkt);

    switch (action.type) {
        case ACTION_SEND_REQ:
            // Send an MMU initiated request on the table walk port if it is
            // enabled. Otherwise, fall through and handle same as the final
            // ACTION_SEND_REQ_FINAL request.
            if (tableWalkPortEnable) {
                action.pkt->pushSenderState(proc);

                DPRINTF(SMMUv3, "[t] master HWTW req  addr=%#x size=%#x\n",
                        action.pkt->getAddr(), action.pkt->getSize());

                if (packetsTableWalkToRetry.empty()
                        && masterTableWalkPort.sendTimingReq(action.pkt)) {
                    scheduleSlaveRetries();
                } else {
                    DPRINTF(SMMUv3, "[t] master HWTW req  needs retry,"
                            " qlen=%d\n", packetsTableWalkToRetry.size());
                    packetsTableWalkToRetry.push(action);
                }

                break;
            }
            M5_FALLTHROUGH;
        case ACTION_SEND_REQ_FINAL:
            action.pkt->pushSenderState(proc);

            DPRINTF(SMMUv3, "[t] master req  addr=%#x size=%#x\n",
                    action.pkt->getAddr(), action.pkt->getSize());

            if (packetsToRetry.empty() && masterPort.sendTimingReq(action.pkt)) {
                scheduleSlaveRetries();
            } else {
                DPRINTF(SMMUv3, "[t] master req  needs retry, qlen=%d\n",
                        packetsToRetry.size());
                packetsToRetry.push(action);
            }

            break;

        case ACTION_SEND_RESP:
            // @todo: We need to pay for this and not just zero it out
            action.pkt->headerDelay = action.pkt->payloadDelay = 0;

            DPRINTF(SMMUv3, "[t] slave resp addr=%#x size=%#x\n",
                    action.pkt->getAddr(),
                    action.pkt->getSize());

            assert(action.ifc);
            action.ifc->schedTimingResp(action.pkt);

            delete proc;
            break;

        case ACTION_SEND_RESP_ATS:
            // @todo: We need to pay for this and not just zero it out
            action.pkt->headerDelay = action.pkt->payloadDelay = 0;

            DPRINTF(SMMUv3, "[t] ATS slave resp addr=%#x size=%#x\n",
                    action.pkt->getAddr(), action.pkt->getSize());

            assert(action.ifc);
            action.ifc->schedAtsTimingResp(action.pkt);

            delete proc;
            break;

        case ACTION_DELAY:
        case ACTION_SLEEP:
            break;

        case ACTION_TERMINATE:
            delete proc;
            break;

        default:
            panic("Unknown action\n");
    }

    return action;
}

void
SMMUv3::processCommands()
{
    DPRINTF(SMMUv3, "processCommands()\n");

    if (system.isAtomicMode()) {
        SMMUAction a = runProcessAtomic(&commandExecutor, NULL);
        (void) a;
    } else if (system.isTimingMode()) {
        if (!commandExecutor.isBusy())
            runProcessTiming(&commandExecutor, NULL);
    } else {
        panic("Not in timing or atomic mode!");
    }
}

void
SMMUv3::processCommand(const SMMUCommand &cmd)
{
    switch (cmd.dw0.type) {
        case CMD_PRF_CONFIG:
            DPRINTF(SMMUv3, "CMD_PREFETCH_CONFIG - ignored\n");
            break;

        case CMD_PRF_ADDR:
            DPRINTF(SMMUv3, "CMD_PREFETCH_ADDR - ignored\n");
            break;

        case CMD_CFGI_STE: {
            DPRINTF(SMMUv3, "CMD_CFGI_STE sid=%#x\n", cmd.dw0.sid);
            configCache.invalidateSID(cmd.dw0.sid);

            for (auto slave_interface : slaveInterfaces) {
                slave_interface->microTLB->invalidateSID(cmd.dw0.sid);
                slave_interface->mainTLB->invalidateSID(cmd.dw0.sid);
            }
            break;
        }

        case CMD_CFGI_STE_RANGE: {
            const auto range = cmd.dw1.range;
            if (range == 31) {
                // CMD_CFGI_ALL is an alias of CMD_CFGI_STE_RANGE with
                // range = 31
                DPRINTF(SMMUv3, "CMD_CFGI_ALL\n");
                configCache.invalidateAll();

                for (auto slave_interface : slaveInterfaces) {
                    slave_interface->microTLB->invalidateAll();
                    slave_interface->mainTLB->invalidateAll();
                }
            } else {
                DPRINTF(SMMUv3, "CMD_CFGI_STE_RANGE\n");
                const auto start_sid = cmd.dw0.sid & ~((1 << (range + 1)) - 1);
                const auto end_sid = start_sid + (1 << (range + 1)) - 1;
                for (auto sid = start_sid; sid <= end_sid; sid++) {
                    configCache.invalidateSID(sid);

                    for (auto slave_interface : slaveInterfaces) {
                        slave_interface->microTLB->invalidateSID(sid);
                        slave_interface->mainTLB->invalidateSID(sid);
                    }
                }
            }
            break;
        }

        case CMD_CFGI_CD: {
            DPRINTF(SMMUv3, "CMD_CFGI_CD sid=%#x ssid=%#x\n",
                    cmd.dw0.sid, cmd.dw0.ssid);
            configCache.invalidateSSID(cmd.dw0.sid, cmd.dw0.ssid);

            for (auto slave_interface : slaveInterfaces) {
                slave_interface->microTLB->invalidateSSID(
                    cmd.dw0.sid, cmd.dw0.ssid);
                slave_interface->mainTLB->invalidateSSID(
                    cmd.dw0.sid, cmd.dw0.ssid);
            }
            break;
        }

        case CMD_CFGI_CD_ALL: {
            DPRINTF(SMMUv3, "CMD_CFGI_CD_ALL sid=%#x\n", cmd.dw0.sid);
            configCache.invalidateSID(cmd.dw0.sid);

            for (auto slave_interface : slaveInterfaces) {
                slave_interface->microTLB->invalidateSID(cmd.dw0.sid);
                slave_interface->mainTLB->invalidateSID(cmd.dw0.sid);
            }
            break;
        }

        case CMD_TLBI_NH_ALL: {
            DPRINTF(SMMUv3, "CMD_TLBI_NH_ALL vmid=%#x\n", cmd.dw0.vmid);
            for (auto slave_interface : slaveInterfaces) {
                slave_interface->microTLB->invalidateVMID(cmd.dw0.vmid);
                slave_interface->mainTLB->invalidateVMID(cmd.dw0.vmid);
            }
            tlb.invalidateVMID(cmd.dw0.vmid);
            walkCache.invalidateVMID(cmd.dw0.vmid);
            break;
        }

        case CMD_TLBI_NH_ASID: {
            DPRINTF(SMMUv3, "CMD_TLBI_NH_ASID asid=%#x vmid=%#x\n",
                    cmd.dw0.asid, cmd.dw0.vmid);
            for (auto slave_interface : slaveInterfaces) {
                slave_interface->microTLB->invalidateASID(
                    cmd.dw0.asid, cmd.dw0.vmid);
                slave_interface->mainTLB->invalidateASID(
                    cmd.dw0.asid, cmd.dw0.vmid);
            }
            tlb.invalidateASID(cmd.dw0.asid, cmd.dw0.vmid);
            walkCache.invalidateASID(cmd.dw0.asid, cmd.dw0.vmid);
            break;
        }

        case CMD_TLBI_NH_VAA: {
            const Addr addr = cmd.addr();
            DPRINTF(SMMUv3, "CMD_TLBI_NH_VAA va=%#08x vmid=%#x\n",
                    addr, cmd.dw0.vmid);
            for (auto slave_interface : slaveInterfaces) {
                slave_interface->microTLB->invalidateVAA(
                    addr, cmd.dw0.vmid);
                slave_interface->mainTLB->invalidateVAA(
                    addr, cmd.dw0.vmid);
            }
            tlb.invalidateVAA(addr, cmd.dw0.vmid);
            const bool leaf_only = cmd.dw1.leaf ? true : false;
            walkCache.invalidateVAA(addr, cmd.dw0.vmid, leaf_only);
            break;
        }

        case CMD_TLBI_NH_VA: {
            const Addr addr = cmd.addr();
            DPRINTF(SMMUv3, "CMD_TLBI_NH_VA va=%#08x asid=%#x vmid=%#x\n",
                    addr, cmd.dw0.asid, cmd.dw0.vmid);
            for (auto slave_interface : slaveInterfaces) {
                slave_interface->microTLB->invalidateVA(
                    addr, cmd.dw0.asid, cmd.dw0.vmid);
                slave_interface->mainTLB->invalidateVA(
                    addr, cmd.dw0.asid, cmd.dw0.vmid);
            }
            tlb.invalidateVA(addr, cmd.dw0.asid, cmd.dw0.vmid);
            const bool leaf_only = cmd.dw1.leaf ? true : false;
            walkCache.invalidateVA(addr, cmd.dw0.asid, cmd.dw0.vmid,
                                   leaf_only);
            break;
        }

        case CMD_TLBI_S2_IPA: {
            const Addr addr = cmd.addr();
            DPRINTF(SMMUv3, "CMD_TLBI_S2_IPA ipa=%#08x vmid=%#x\n",
                    addr, cmd.dw0.vmid);
            // This does not invalidate TLBs containing
            // combined Stage1 + Stage2 translations, as per the spec.
            ipaCache.invalidateIPA(addr, cmd.dw0.vmid);

            if (!cmd.dw1.leaf)
                walkCache.invalidateVMID(cmd.dw0.vmid);
            break;
        }

        case CMD_TLBI_S12_VMALL: {
            DPRINTF(SMMUv3, "CMD_TLBI_S12_VMALL vmid=%#x\n", cmd.dw0.vmid);
            for (auto slave_interface : slaveInterfaces) {
                slave_interface->microTLB->invalidateVMID(cmd.dw0.vmid);
                slave_interface->mainTLB->invalidateVMID(cmd.dw0.vmid);
            }
            tlb.invalidateVMID(cmd.dw0.vmid);
            ipaCache.invalidateVMID(cmd.dw0.vmid);
            walkCache.invalidateVMID(cmd.dw0.vmid);
            break;
        }

        case CMD_TLBI_NSNH_ALL: {
            DPRINTF(SMMUv3, "CMD_TLBI_NSNH_ALL\n");
            for (auto slave_interface : slaveInterfaces) {
                slave_interface->microTLB->invalidateAll();
                slave_interface->mainTLB->invalidateAll();
            }
            tlb.invalidateAll();
            ipaCache.invalidateAll();
            walkCache.invalidateAll();
            break;
        }

        case CMD_RESUME:
            DPRINTF(SMMUv3, "CMD_RESUME\n");
            panic("resume unimplemented");
            break;

        default:
            warn("Unimplemented command %#x\n", cmd.dw0.type);
            break;
    }
}

const PageTableOps*
SMMUv3::getPageTableOps(uint8_t trans_granule)
{
    static V8PageTableOps4k  ptOps4k;
    static V8PageTableOps16k ptOps16k;
    static V8PageTableOps64k ptOps64k;

    switch (trans_granule) {
    case TRANS_GRANULE_4K:  return &ptOps4k;
    case TRANS_GRANULE_16K: return &ptOps16k;
    case TRANS_GRANULE_64K: return &ptOps64k;
    default:
        panic("Unknown translation granule size %d", trans_granule);
    }
}

Tick
SMMUv3::readControl(PacketPtr pkt)
{
    DPRINTF(SMMUv3, "readControl:  addr=%08x size=%d\n",
            pkt->getAddr(), pkt->getSize());

    int offset = pkt->getAddr() - regsMap.start();
    assert(offset >= 0 && offset < SMMU_REG_SIZE);

    if (inSecureBlock(offset)) {
        warn("smmu: secure registers (0x%x) are not implemented\n",
             offset);
    }

    auto reg_ptr = regs.data + offset;

    switch (pkt->getSize()) {
      case sizeof(uint32_t):
        pkt->setLE<uint32_t>(*reinterpret_cast<uint32_t *>(reg_ptr));
        break;
      case sizeof(uint64_t):
        pkt->setLE<uint64_t>(*reinterpret_cast<uint64_t *>(reg_ptr));
        break;
      default:
        panic("smmu: unallowed access size: %d bytes\n", pkt->getSize());
        break;
    }

    pkt->makeAtomicResponse();

    return 0;
}

Tick
SMMUv3::writeControl(PacketPtr pkt)
{
    int offset = pkt->getAddr() - regsMap.start();
    assert(offset >= 0 && offset < SMMU_REG_SIZE);

    DPRINTF(SMMUv3, "writeControl: addr=%08x size=%d data=%16x\n",
            pkt->getAddr(), pkt->getSize(),
            pkt->getSize() == sizeof(uint64_t) ?
            pkt->getLE<uint64_t>() : pkt->getLE<uint32_t>());

    switch (offset) {
        case offsetof(SMMURegs, cr0):
            assert(pkt->getSize() == sizeof(uint32_t));
            regs.cr0 = regs.cr0ack = pkt->getLE<uint32_t>();
            break;

        case offsetof(SMMURegs, cr1):
        case offsetof(SMMURegs, cr2):
        case offsetof(SMMURegs, strtab_base_cfg):
        case offsetof(SMMURegs, eventq_cons):
        case offsetof(SMMURegs, eventq_irq_cfg1):
        case offsetof(SMMURegs, priq_cons):
            assert(pkt->getSize() == sizeof(uint32_t));
            *reinterpret_cast<uint32_t *>(regs.data + offset) =
                pkt->getLE<uint32_t>();
            break;

        case offsetof(SMMURegs, cmdq_cons):
            assert(pkt->getSize() == sizeof(uint32_t));
            if (regs.cr0 & CR0_CMDQEN_MASK) {
                warn("CMDQ is enabled: ignoring write to CMDQ_CONS\n");
            } else {
                *reinterpret_cast<uint32_t *>(regs.data + offset) =
                    pkt->getLE<uint32_t>();
            }
            break;

        case offsetof(SMMURegs, cmdq_prod):
            assert(pkt->getSize() == sizeof(uint32_t));
            *reinterpret_cast<uint32_t *>(regs.data + offset) =
                pkt->getLE<uint32_t>();
            schedule(processCommandsEvent, nextCycle());
            break;

        case offsetof(SMMURegs, strtab_base):
        case offsetof(SMMURegs, eventq_irq_cfg0):
            assert(pkt->getSize() == sizeof(uint64_t));
            *reinterpret_cast<uint64_t *>(regs.data + offset) =
                pkt->getLE<uint64_t>();
            break;

        case offsetof(SMMURegs, cmdq_base):
            assert(pkt->getSize() == sizeof(uint64_t));
            if (regs.cr0 & CR0_CMDQEN_MASK) {
                warn("CMDQ is enabled: ignoring write to CMDQ_BASE\n");
            } else {
                *reinterpret_cast<uint64_t *>(regs.data + offset) =
                    pkt->getLE<uint64_t>();
                regs.cmdq_cons = 0;
                regs.cmdq_prod = 0;
            }
            break;

        case offsetof(SMMURegs, eventq_base):
            assert(pkt->getSize() == sizeof(uint64_t));
            *reinterpret_cast<uint64_t *>(regs.data + offset) =
                pkt->getLE<uint64_t>();
            regs.eventq_cons = 0;
            regs.eventq_prod = 0;
            break;

        case offsetof(SMMURegs, priq_base):
            assert(pkt->getSize() == sizeof(uint64_t));
            *reinterpret_cast<uint64_t *>(regs.data + offset) =
                pkt->getLE<uint64_t>();
            regs.priq_cons = 0;
            regs.priq_prod = 0;
            break;

        default:
            if (inSecureBlock(offset)) {
                warn("smmu: secure registers (0x%x) are not implemented\n",
                     offset);
            } else {
                warn("smmu: write to read-only/undefined register at 0x%x\n",
                     offset);
            }
    }

    pkt->makeAtomicResponse();

    return 0;
}

bool
SMMUv3::inSecureBlock(uint32_t offs) const
{
    if (offs >= offsetof(SMMURegs, _secure_regs) && offs < SMMU_SECURE_SZ)
        return true;
    else
        return false;
}

void
SMMUv3::init()
{
    // make sure both sides are connected and have the same block size
    if (!masterPort.isConnected())
        fatal("Master port is not connected.\n");

    // If the second master port is connected for the table walks, enable
    // the mode to send table walks through this port instead
    if (masterTableWalkPort.isConnected())
        tableWalkPortEnable = true;

    // notify the master side  of our address ranges
    for (auto ifc : slaveInterfaces) {
        ifc->sendRange();
    }

    if (controlPort.isConnected())
        controlPort.sendRangeChange();
}

void
SMMUv3::regStats()
{
    ClockedObject::regStats();

    using namespace Stats;

    for (size_t i = 0; i < slaveInterfaces.size(); i++) {
        slaveInterfaces[i]->microTLB->regStats(
            csprintf("%s.utlb%d", name(), i));
        slaveInterfaces[i]->mainTLB->regStats(
            csprintf("%s.maintlb%d", name(), i));
    }

    tlb.regStats(name() + ".tlb");
    configCache.regStats(name() + ".cfg");
    ipaCache.regStats(name() + ".ipa");
    walkCache.regStats(name() + ".walk");

    steL1Fetches
        .name(name() + ".steL1Fetches")
        .desc("STE L1 fetches")
        .flags(pdf);

    steFetches
        .name(name() + ".steFetches")
        .desc("STE fetches")
        .flags(pdf);

    cdL1Fetches
        .name(name() + ".cdL1Fetches")
        .desc("CD L1 fetches")
        .flags(pdf);

    cdFetches
        .name(name() + ".cdFetches")
        .desc("CD fetches")
        .flags(pdf);

    translationTimeDist
        .init(0, 2000000, 2000)
        .name(name() + ".translationTimeDist")
        .desc("Time to translate address")
        .flags(pdf);

    ptwTimeDist
        .init(0, 2000000, 2000)
        .name(name() + ".ptwTimeDist")
        .desc("Time to walk page tables")
        .flags(pdf);
}

DrainState
SMMUv3::drain()
{
    // Wait until the Command Executor is not busy
    if (commandExecutor.isBusy()) {
        return DrainState::Draining;
    }
    return DrainState::Drained;
}

void
SMMUv3::serialize(CheckpointOut &cp) const
{
    DPRINTF(Checkpoint, "Serializing SMMUv3\n");

    SERIALIZE_ARRAY(regs.data, sizeof(regs.data) / sizeof(regs.data[0]));
}

void
SMMUv3::unserialize(CheckpointIn &cp)
{
    DPRINTF(Checkpoint, "Unserializing SMMUv3\n");

    UNSERIALIZE_ARRAY(regs.data, sizeof(regs.data) / sizeof(regs.data[0]));
}

Port&
SMMUv3::getPort(const std::string &name, PortID id)
{
    if (name == "master") {
        return masterPort;
    } else if (name == "master_walker") {
        return masterTableWalkPort;
    } else if (name == "control") {
        return controlPort;
    } else {
        return ClockedObject::getPort(name, id);
    }
}

SMMUv3*
SMMUv3Params::create()
{
    return new SMMUv3(this);
}
