/*
 * Copyright (c) 2014 Advanced Micro Devices, Inc.
 * 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.
 */

/**
 * @file
 * Declaration of a multi-level page table.
 */

#ifndef __MEM_MULTI_LEVEL_PAGE_TABLE_HH__
#define __MEM_MULTI_LEVEL_PAGE_TABLE_HH__

#include <string>

#include "base/types.hh"
#include "debug/MMU.hh"
#include "mem/page_table.hh"
#include "sim/se_workload.hh"
#include "sim/system.hh"

namespace gem5
{

/**
 * This class implements an in-memory multi-level page table that can be
 * configured to follow ISA specifications. It can be used instead of the
 * PageTable class in SE mode to allow CPU models (e.g. X86KvmCPU)
 * to do a normal page table walk.
 *
 * To reduce memory required to store the page table, a multi-level page
 * table stores its translations similarly with a radix tree. Let n be
 * the number of levels and {Ln, Ln-1, ..., L1, L0} a set that specifies
 * the number of entries for each level as base 2 logarithm values. A
 * multi-level page table will store its translations at level 0 (the
 * leaves of the tree) and it will be layed out in memory in the
 * following way:
 *
 *                              +------------------------------+
 * level n                      |Ln-1_E0|Ln-1_E1|...|Ln-1_E2^Ln|
 *                              +------------------------------+
 *                                 /       \
 *            +------------------------+   +------------------------+
 * level n-1  |Ln-2_E0|...|Ln-2_E2^Ln-1|   |Ln-2_E0|...|Ln-2_E2^Ln-1|
 *            +------------------------+   +------------------------+
 *                /            \             /              \
 *                                  .
 *                                  .
 *                                  .
 *               /                      /               \
 *          +------------------+   +------------+     +------------+
 * level 1  |L0_E1|...|L0_E2^L1|   |...|L0_E2^L1| ... |...|L0_E2^L1|
 *          +------------------+   +------------+     +------------+
 * , where
 * +------------------------------+
 * |Lk-1_E0|Lk-1_E1|...|Lk-1_E2^Lk|
 * +------------------------------+
 * is a level k entry that holds 2^Lk entries in Lk-1 level.
 *
 * Essentially, a level n entry will contain 2^Ln level n-1 entries,
 * a level n-1 entry will hold 2^Ln-1 level n-2 entries etc.
 *
 * The virtual address is split into offsets that index into the
 * different levels of the page table.
 *
 * +--------------------------------+
 * |LnOffset|...|L1Offset|PageOffset|
 * +--------------------------------+
 *
 * For example L0Offset will be formed by the bits in range
 * [log2(PageOffset), log2(PageOffset)+L0].
 *
 * For every level of the page table, from n to 1, the base address
 * of the entry is loaded, the offset in the virtual address for
 * that particular level is used to index into the entry which
 * will reveal the memory address of the entry in the next level.
 *
 * @see MultiLevelPageTable
 */

namespace {

template <class First, class ...Rest>
Addr
prepTopTable(System *system, Addr pageSize)
{
    auto *se_workload = dynamic_cast<SEWorkload *>(system->workload);
    fatal_if(!se_workload, "Couldn't find an appropriate workload object.");
    Addr addr = se_workload->allocPhysPages(First::tableSize());
    PortProxy &p = system->physProxy;
    p.memsetBlob(addr, 0, First::tableSize() * pageSize);
    return addr;
}

template <class ...Types>
struct LastType;

template <class First, class Second, class ...Rest>
struct LastType<First, Second, Rest...>
{
    typedef typename LastType<Second, Rest...>::type type;
};

template <class Only>
struct LastType<Only>
{
    typedef Only type;
};


template <class ...Types>
struct WalkWrapper;

template <class Final, class Only>
struct WalkWrapper<Final, Only>
{
    static void
    walk(System *system, Addr pageSize, Addr table, Addr vaddr,
         bool allocate, Final *entry)
    {
        entry->read(system->physProxy, table, vaddr);
    }
};

template <class Final, class First, class Second, class ...Rest>
struct WalkWrapper<Final, First, Second, Rest...>
{
    static void
    walk(System *system, Addr pageSize, Addr table, Addr vaddr,
         bool allocate, Final *entry)
    {
        First first;
        first.read(system->physProxy, table, vaddr);

        Addr next;
        if (!first.present()) {
            fatal_if(!allocate,
                     "Page fault while walking the page table.");
            next = prepTopTable<Second>(system, pageSize);
            first.reset(next);
            first.write(system->physProxy);
        } else {
            next = first.paddr();
        }
        WalkWrapper<Final, Second, Rest...>::walk(
                system, pageSize, next, vaddr, allocate, entry);
    }
};

template <class ...EntryTypes>
void
walk(System *system, Addr pageSize, Addr table, Addr vaddr,
     bool allocate, typename LastType<EntryTypes...>::type *entry)
{
    WalkWrapper<typename LastType<EntryTypes...>::type, EntryTypes...>::walk(
            system, pageSize, table, vaddr, allocate, entry);
}

}


template <class ...EntryTypes>
class MultiLevelPageTable : public EmulationPageTable
{
    typedef typename LastType<EntryTypes...>::type Final;

    /**
     * Pointer to System object
     */
    System *system;

    /**
     * Physical address to the last level of the page table
     */
    Addr _basePtr;

public:
    MultiLevelPageTable(const std::string &__name, uint64_t _pid,
                        System *_sys, Addr _pageSize) :
            EmulationPageTable(__name, _pid, _pageSize), system(_sys)
    {}

    ~MultiLevelPageTable() {}

    void
    initState() override
    {
        if (shared)
            return;

        _basePtr = prepTopTable<EntryTypes...>(system, _pageSize);
    }

    Addr basePtr() { return _basePtr; }

    void
    map(Addr vaddr, Addr paddr, int64_t size, uint64_t flags = 0) override
    {
        EmulationPageTable::map(vaddr, paddr, size, flags);

        Final entry;

        for (int64_t offset = 0; offset < size; offset += _pageSize) {
            walk<EntryTypes...>(system, _pageSize, _basePtr,
                                vaddr + offset, true, &entry);

            entry.reset(paddr + offset, true, flags & Uncacheable,
                        flags & ReadOnly);
            entry.write(system->physProxy);

            DPRINTF(MMU, "New mapping: %#x-%#x\n",
                    vaddr + offset, paddr + offset);
        }
    }

    void
    remap(Addr vaddr, int64_t size, Addr new_vaddr) override
    {
        EmulationPageTable::remap(vaddr, size, new_vaddr);

        Final old_entry, new_entry;

        for (int64_t offset = 0; offset < size; offset += _pageSize) {
            // Unmap the original mapping.
            walk<EntryTypes...>(system, _pageSize, _basePtr, vaddr + offset,
                                false, &old_entry);
            old_entry.present(false);
            old_entry.write(system->physProxy);

            // Map the new one.
            walk<EntryTypes...>(system, _pageSize, _basePtr,
                                new_vaddr + offset, true, &new_entry);
            new_entry.reset(old_entry.paddr(), true, old_entry.uncacheable(),
                            old_entry.readonly());
            new_entry.write(system->physProxy);
        }
    }

    void
    unmap(Addr vaddr, int64_t size) override
    {
        EmulationPageTable::unmap(vaddr, size);

        Final entry;

        for (int64_t offset = 0; offset < size; offset += _pageSize) {
            walk<EntryTypes...>(system, _pageSize, _basePtr,
                                vaddr + offset, false, &entry);
            fatal_if(!entry.present(),
                     "PageTable::unmap: Address %#x not mapped.", vaddr);
            entry.present(false);
            entry.write(system->physProxy);
            DPRINTF(MMU, "Unmapping: %#x\n", vaddr);
        }
    }

    void
    serialize(CheckpointOut &cp) const override
    {
        EmulationPageTable::serialize(cp);
        /** Since, the page table is stored in system memory
         * which is serialized separately, we will serialize
         * just the base pointer
         */
        paramOut(cp, "ptable.pointer", _basePtr);
    }

    void
    unserialize(CheckpointIn &cp) override
    {
        EmulationPageTable::unserialize(cp);
        paramIn(cp, "ptable.pointer", _basePtr);
    }
};

} // namespace gem5

#endif // __MEM_MULTI_LEVEL_PAGE_TABLE_HH__
