/*
 * 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.
 *
 * Authors: Alexandru Dutu
 */

/**
 * @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 "mem/page_table.hh"

class System;

/**
 * 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)
{
    Addr addr = system->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(ThreadContext* tc) 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);
    }
};
#endif // __MEM_MULTI_LEVEL_PAGE_TABLE_HH__
