/*
 * Copyright (c) 2021 The Regents of the University of California
 * All rights reserved.
 *
 * 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.
 */

#ifndef __ARCH_RISCV_PMP_HH__
#define __ARCH_RISCV_PMP_HH__

#include "arch/generic/tlb.hh"
#include "arch/riscv/isa.hh"
#include "base/addr_range.hh"
#include "base/types.hh"
#include "mem/packet.hh"
#include "params/PMP.hh"
#include "sim/sim_object.hh"

/**
 * @file
 * PMP header file.
 */

namespace gem5
{

/**
 * This class helps to implement RISCV's physical memory
 * protection (pmp) primitive.
 * @todo Add statistics and debug prints.
 */
class PMP : public SimObject
{
  public:
    PARAMS(PMP);
    PMP(const Params &params);

  private:
    /** maximum number of entries in the pmp table */
    int pmpEntries;

    /** This enum is used for encoding of address matching mode of
     * pmp address register, which is present in bits 3-4 (A) of
     * pmpcfg register for a pmp entry.
     * PMP_OFF = null region (pmp disabled)
     * MP_TOR = top of range mode
     * PMP_NA4 = naturally aligned four byte region
     * PMP_NAPOT = naturally aligned power of two region, >= 8 bytes
     */
    enum pmpAmatch
    {
        PMP_OFF,
        PMP_TOR,
        PMP_NA4,
        PMP_NAPOT
    };

    /** pmpcfg address range read permission mask */
    const uint8_t PMP_READ = 1 << 0;

    /** pmpcfg address range write permission mask */
    const uint8_t PMP_WRITE = 1 << 1;

    /** pmpcfg address range execute permission mask */
    const uint8_t PMP_EXEC = 1 << 2;

    /** pmpcfg address range locked mask */
    const uint8_t PMP_LOCK = 1 << 7;

    /** variable to keep track of active number of rules any time */
    int numRules;

    /** single pmp entry struct*/
    struct PmpEntry
    {
        /** addr range corresponding to a single pmp entry */
        AddrRange pmpAddr = AddrRange(0, 0);
        /** raw addr in pmpaddr register for a pmp entry */
        Addr rawAddr;
        /** pmpcfg reg value for a pmp entry */
        uint8_t pmpCfg = 0;
    };

    /** a table of pmp entries */
    std::vector<PmpEntry> pmpTable;

  public:
    /**
     * pmpCheck checks if a particular memory access
     * is allowed based on the pmp rules.
     * @param req memory request.
     * @param mode mode of request (read, write, execute).
     * @param pmode current privilege mode of execution (U, S, M).
     * @param tc thread context.
     * @param vaddr optional parameter to pass vaddr of original
     * request for which a page table walk is consulted by pmp unit
     * @return Fault.
     */
    Fault pmpCheck(const RequestPtr &req, BaseMMU::Mode mode,
                  RiscvISA::PrivilegeMode pmode, ThreadContext *tc,
                  Addr vaddr = 0);

    /**
     * pmpUpdateCfg updates the pmpcfg for a pmp
     * entry and calls pmpUpdateRule to update the
     * rule of corresponding pmp entry.
     * @param pmp_index pmp entry index.
     * @param this_cfg value to be written to pmpcfg.
     */
    void pmpUpdateCfg(uint32_t pmp_index, uint8_t this_cfg);

    /**
     * pmpUpdateAddr updates the pmpaddr for a pmp
     * entry and calls pmpUpdateRule to update the
     * rule of corresponding pmp entry.
     * @param pmp_index pmp entry index.
     * @param this_addr value to be written to pmpaddr.
     */
    void pmpUpdateAddr(uint32_t pmp_index, Addr this_addr);

  private:
    /**
     * This function is called during a memory
     * access to determine if the pmp table
     * should be consulted for this access.
     * @param pmode current privilege mode of execution (U, S, M).
     * @param mode mode of request (read, write, execute).
     * @param tc thread context.
     * @return true or false.
     */
    bool shouldCheckPMP(RiscvISA::PrivilegeMode pmode,
                BaseMMU::Mode mode, ThreadContext *tc);

    /**
     * createAddrfault creates an address fault
     * if the pmp checks fail to pass for a given
     * access. This function is used by pmpCheck().
     * given pmp entry depending on the value
     * of pmpaddr and pmpcfg for that entry.
     * @param vaddr virtual address of the access.
     * @param mode mode of access(read, write, execute).
     * @return Fault.
     */
    Fault createAddrfault(Addr vaddr, BaseMMU::Mode mode);

    /**
     * pmpUpdateRule updates the pmp rule for a
     * given pmp entry depending on the value
     * of pmpaddr and pmpcfg for that entry.
     * @param pmp_index pmp entry index.
     */
    void pmpUpdateRule(uint32_t pmp_index);

    /**
     * pmpGetAField extracts the A field (address matching mode)
     * from an input pmpcfg register
     * @param cfg pmpcfg register value.
     * @return The A field.
     */
    inline uint8_t pmpGetAField(uint8_t cfg);

    /**
     * This function decodes a pmpaddr register value
     * into an address range when A field of pmpcfg
     * register is set to NAPOT mode (naturally aligned
     * power of two region).
     * @param pmpaddr input address from a pmp entry.
     * @return an address range.
     */
    inline AddrRange pmpDecodeNapot(Addr pmpaddr);

};

} // namespace gem5

#endif // __ARCH_RISCV_PMP_HH__
