/*
 * Copyright (c) 2017-2020 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.
 */

#include "sim/mem_state.hh"

#include <cassert>

#include "arch/generic/mmu.hh"
#include "debug/Vma.hh"
#include "mem/se_translating_port_proxy.hh"
#include "sim/process.hh"
#include "sim/syscall_debug_macros.hh"
#include "sim/system.hh"
#include "sim/vma.hh"

namespace gem5
{

MemState::MemState(Process *owner, Addr brk_point, Addr stack_base,
                   Addr max_stack_size, Addr next_thread_stack_base,
                   Addr mmap_end)
    : _ownerProcess(owner),
      _pageBytes(owner->pTable->pageSize()), _brkPoint(brk_point),
      _stackBase(stack_base), _stackSize(max_stack_size),
      _maxStackSize(max_stack_size), _stackMin(stack_base - max_stack_size),
      _nextThreadStackBase(next_thread_stack_base),
      _mmapEnd(mmap_end), _endBrkPoint(brk_point)
{
}

MemState&
MemState::operator=(const MemState &in)
{
    if (this == &in)
        return *this;

    _pageBytes = in._pageBytes;
    _brkPoint = in._brkPoint;
    _stackBase = in._stackBase;
    _stackSize = in._stackSize;
    _maxStackSize = in._maxStackSize;
    _stackMin = in._stackMin;
    _nextThreadStackBase = in._nextThreadStackBase;
    _mmapEnd = in._mmapEnd;
    _endBrkPoint = in._endBrkPoint;
    _vmaList = in._vmaList; /* This assignment does a deep copy. */

    return *this;
}

void
MemState::resetOwner(Process *owner)
{
    _ownerProcess = owner;
}

bool
MemState::isUnmapped(Addr start_addr, Addr length)
{
    Addr end_addr = start_addr + length;
    const AddrRange range(start_addr, end_addr);
    for (const auto &vma : _vmaList) {
        if (vma.intersects(range))
            return false;
    }

    /**
     * In case someone skips the VMA interface and just directly maps memory
     * also consult the page tables to make sure that this memory isnt mapped.
     */
    for (auto start = start_addr; start < end_addr;
         start += _pageBytes) {
        if (_ownerProcess->pTable->lookup(start) != nullptr) {
            panic("Someone allocated physical memory at VA %p without "
                  "creating a VMA!\n", start);
            return false;
        }
    }
    return true;
}

void
MemState::updateBrkRegion(Addr old_brk, Addr new_brk)
{
    /**
     * To make this simple, avoid reducing the heap memory area if the
     * new_brk point is less than the old_brk; this occurs when the heap is
     * receding because the application has given back memory. The brk point
     * is still tracked in the MemState class as an independent field so that
     * it can be returned to the application; we just do not update the
     * region unless we expand it out.
     */
    if (new_brk < old_brk) {
        _brkPoint = new_brk;
        return;
    }

    /**
     * The regions must be page aligned but the break point can be set on
     * byte boundaries. Ensure that the restriction is maintained here by
     * extending the request out to the end of the page. (The roundUp
     * function will not round up an already aligned page.)
     */
    auto page_aligned_brk = roundUp(new_brk, _pageBytes);

    /**
     * Create a new mapping for the heap region. We only create a mapping
     * for the extra memory that is requested so we do not create a situation
     * where there can be overlapping mappings in the regions.
     *
     * Since we do not track the type of the region and we also do not
     * coalesce the regions together, we can create a fragmented set of
     * heap regions. To resolve this, we keep the furthest point ever mapped
     * by the _endBrkPoint field.
     */
    if (page_aligned_brk > _endBrkPoint) {
        auto length = page_aligned_brk - _endBrkPoint;
        /**
         * Check if existing mappings impede the expansion of brk expansion.
         * If brk cannot expand, it must return the original, unmodified brk
         * address and should not modify the mappings here.
         */
        if (!isUnmapped(_endBrkPoint, length)) {
            return;
        }

        /**
         * Note that the heap regions are always contiguous but there is
         * no mechanism right now to coalesce together memory that belongs
         * to the same region with similar access permissions. This could be
         * implemented if it actually becomes necessary; probably only
         * necessary if the list becomes too long to walk.
         */
        mapRegion(_endBrkPoint, length, "heap");
        _endBrkPoint = page_aligned_brk;
    }

    _brkPoint = new_brk;
}

void
MemState::mapRegion(Addr start_addr, Addr length,
                    const std::string& region_name, int sim_fd, Addr offset)
{
    DPRINTF(Vma, "memstate: creating vma (%s) [0x%x - 0x%x]\n",
            region_name.c_str(), start_addr, start_addr + length);

    /**
     * Avoid creating a region that has preexisting mappings. This should
     * not happen under normal circumstances so consider this to be a bug.
     */
    assert(isUnmapped(start_addr, length));

    /**
     * Record the region in our list structure.
     */
    _vmaList.emplace_back(AddrRange(start_addr, start_addr + length),
                          _pageBytes, region_name, sim_fd, offset);
}

void
MemState::unmapRegion(Addr start_addr, Addr length)
{
    Addr end_addr = start_addr + length;
    const AddrRange range(start_addr, end_addr);

    auto vma = std::begin(_vmaList);
    while (vma != std::end(_vmaList)) {
        if (vma->isStrictSuperset(range)) {
            DPRINTF(Vma, "memstate: split vma [0x%x - 0x%x] into "
                    "[0x%x - 0x%x] and [0x%x - 0x%x]\n",
                    vma->start(), vma->end(),
                    vma->start(), start_addr,
                    end_addr, vma->end());
            /**
             * Need to split into two smaller regions.
             * Create a clone of the old VMA and slice it to the right.
             */
            _vmaList.push_back(*vma);
            _vmaList.back().sliceRegionRight(start_addr);

            /**
             * Slice old VMA to encapsulate the left region.
             */
            vma->sliceRegionLeft(end_addr);

            /**
             * Region cannot be in any more VMA, because it is completely
             * contained in this one!
             */
            break;
        } else if (vma->isSubset(range)) {
            DPRINTF(Vma, "memstate: destroying vma [0x%x - 0x%x]\n",
                    vma->start(), vma->end());
            /**
             * Need to nuke the existing VMA.
             */
            vma = _vmaList.erase(vma);

            continue;

        } else if (vma->intersects(range)) {
            /**
             * Trim up the existing VMA.
             */
            if (vma->start() < start_addr) {
                DPRINTF(Vma, "memstate: resizing vma [0x%x - 0x%x] "
                        "into [0x%x - 0x%x]\n",
                        vma->start(), vma->end(),
                        vma->start(), start_addr);
                /**
                 * Overlaps from the right.
                 */
                vma->sliceRegionRight(start_addr);
            } else {
                DPRINTF(Vma, "memstate: resizing vma [0x%x - 0x%x] "
                        "into [0x%x - 0x%x]\n",
                        vma->start(), vma->end(),
                        end_addr, vma->end());
                /**
                 * Overlaps from the left.
                 */
                vma->sliceRegionLeft(end_addr);
            }
        }

        vma++;
    }

    /**
     * TLBs need to be flushed to remove any stale mappings from regions
     * which were unmapped. Currently the entire TLB is flushed. This results
     * in functionally correct execution, but real systems do not flush all
     * entries when a single mapping changes since it degrades performance.
     * There is currently no general method across all TLB implementations
     * that can flush just part of the address space.
     */
    for (auto *tc: _ownerProcess->system->threads) {
        tc->getMMUPtr()->flushAll();
    }

    do {
        if (!_ownerProcess->pTable->isUnmapped(start_addr, _pageBytes))
            _ownerProcess->pTable->unmap(start_addr, _pageBytes);

        start_addr += _pageBytes;

        /**
         * The regions need to always be page-aligned otherwise the while
         * condition will loop indefinitely. (The Addr type is currently
         * defined to be uint64_t in src/base/types.hh; it can underflow
         * since it is unsigned.)
         */
        length -= _pageBytes;
    } while (length > 0);
}

void
MemState::remapRegion(Addr start_addr, Addr new_start_addr, Addr length)
{
    Addr end_addr = start_addr + length;
    const AddrRange range(start_addr, end_addr);

    auto vma = std::begin(_vmaList);
    while (vma != std::end(_vmaList)) {
        if (vma->isStrictSuperset(range)) {
            /**
             * Create clone of the old VMA and slice right.
             */
            _vmaList.push_back(*vma);
            _vmaList.back().sliceRegionRight(start_addr);

            /**
             * Create clone of the old VMA and slice it left.
             */
            _vmaList.push_back(*vma);
            _vmaList.back().sliceRegionLeft(end_addr);

            /**
             * Slice the old VMA left and right to adjust the file backing,
             * then overwrite the virtual addresses!
             */
            vma->sliceRegionLeft(start_addr);
            vma->sliceRegionRight(end_addr);
            vma->remap(new_start_addr);

            /**
             * The region cannot be in any more VMAs, because it is
             * completely contained in this one!
             */
            break;
        } else if (vma->isSubset(range)) {
            /**
             * Just go ahead and remap it!
             */
            vma->remap(vma->start() - start_addr + new_start_addr);
        } else if (vma->intersects(range)) {
            /**
             * Create a clone of the old VMA.
             */
            _vmaList.push_back(*vma);

            if (vma->start() < start_addr) {
                /**
                 * Overlaps from the right.
                 */
                _vmaList.back().sliceRegionRight(start_addr);

                /**
                 * Remap the old region.
                 */
                vma->sliceRegionLeft(start_addr);
                vma->remap(new_start_addr);
            } else {
                /**
                 * Overlaps from the left.
                 */
                _vmaList.back().sliceRegionLeft(end_addr);

                /**
                 * Remap the old region.
                 */
                vma->sliceRegionRight(end_addr);
                vma->remap(new_start_addr + vma->start() - start_addr);
            }
        }

        vma++;
    }

    /**
     * TLBs need to be flushed to remove any stale mappings from regions
     * which were remapped. Currently the entire TLB is flushed. This results
     * in functionally correct execution, but real systems do not flush all
     * entries when a single mapping changes since it degrades performance.
     * There is currently no general method across all TLB implementations
     * that can flush just part of the address space.
     */
    for (auto *tc: _ownerProcess->system->threads) {
        tc->getMMUPtr()->flushAll();
    }

    do {
        if (!_ownerProcess->pTable->isUnmapped(start_addr, _pageBytes))
            _ownerProcess->pTable->remap(start_addr, _pageBytes,
                                         new_start_addr);

        start_addr += _pageBytes;
        new_start_addr += _pageBytes;

        /**
         * The regions need to always be page-aligned otherwise the while
         * condition will loop indefinitely. (The Addr type is currently
         * defined to be uint64_t in src/base/types.hh; it can underflow
         * since it is unsigned.)
         */
        length -= _pageBytes;
    } while (length > 0);
}

bool
MemState::fixupFault(Addr vaddr)
{
    /**
     * Check if we are accessing a mapped virtual address. If so then we
     * just haven't allocated it a physical page yet and can do so here.
     */
    for (const auto &vma : _vmaList) {
        if (vma.contains(vaddr)) {
            Addr vpage_start = roundDown(vaddr, _pageBytes);
            _ownerProcess->allocateMem(vpage_start, _pageBytes);

            /**
             * We are assuming that fresh pages are zero-filled, so there is
             * no need to zero them out when there is no backing file.
             * This assumption will not hold true if/when physical pages
             * are recycled.
             */
            if (vma.hasHostBuf()) {
                /**
                 * Write the memory for the host buffer contents for all
                 * ThreadContexts associated with this process.
                 */
                for (auto &cid : _ownerProcess->contextIds) {
                    auto *tc = _ownerProcess->system->threads[cid];
                    SETranslatingPortProxy
                        virt_mem(tc, SETranslatingPortProxy::Always);
                    vma.fillMemPages(vpage_start, _pageBytes, virt_mem);
                }
            }
            return true;
        }
    }

    /**
     * Check if the stack needs to be grown in the case where the ISAs
     * process argsInit does not explicitly map the entire stack.
     *
     * Check if this is already on the stack and there's just no page there
     * yet.
     */
    if (vaddr >= _stackMin && vaddr < _stackBase) {
        _ownerProcess->allocateMem(roundDown(vaddr, _pageBytes), _pageBytes);
        return true;
    }

    /**
     * We've accessed the next page of the stack, so extend it to include
     * this address.
     */
    if (vaddr < _stackMin && vaddr >= _stackBase - _maxStackSize) {
        while (vaddr < _stackMin) {
            _stackMin -= _pageBytes;
            if (_stackBase - _stackMin > _maxStackSize) {
                fatal("Maximum stack size exceeded\n");
            }
            _ownerProcess->allocateMem(_stackMin, _pageBytes);
            inform("Increasing stack size by one page.");
        }
        return true;
    }

    return false;
}

Addr
MemState::extendMmap(Addr length)
{
    Addr start = _mmapEnd;

    if (_ownerProcess->mmapGrowsDown())
        start = _mmapEnd - length;

    // Look for a contiguous region of free virtual memory.  We can't assume
    // that the region beyond mmap_end is free because of fixed mappings from
    // the user.
    while (!isUnmapped(start, length)) {
        DPRINTF(Vma, "memstate: cannot extend vma for mmap region at %p. "
                "Virtual address range is already reserved! Skipping a page "
                "and trying again!\n", start);
        start = (_ownerProcess->mmapGrowsDown()) ? start - _pageBytes :
            start + _pageBytes;
    }

    DPRINTF(Vma, "memstate: extending mmap region (old %p) (new %p)\n",
            _mmapEnd,
            _ownerProcess->mmapGrowsDown() ? start : start + length);

    _mmapEnd = _ownerProcess->mmapGrowsDown() ? start : start + length;

    return start;
}

std::string
MemState::printVmaList()
{
    std::stringstream file_content;

    for (auto vma : _vmaList) {
        std::stringstream line;
        line << std::hex << vma.start() << "-";
        line << std::hex << vma.end() << " ";
        line << "r-xp 00000000 00:00 0 ";
        line << "[" << vma.getName() << "]" << std::endl;
        file_content << line.str();
    }

    return file_content.str();
}

} // namespace gem5
