/*
 * Copyright (c) 2010-2013, 2016, 2020 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.
 *
 * Copyright (c) 2002-2006 The Regents of The University of Michigan
 * 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 "arch/arm/linux/fs_workload.hh"

#include "arch/arm/linux/atag.hh"
#include "arch/arm/system.hh"
#include "arch/arm/utility.hh"
#include "arch/generic/linux/threadinfo.hh"
#include "base/loader/dtb_file.hh"
#include "base/loader/object_file.hh"
#include "base/loader/symtab.hh"
#include "cpu/base.hh"
#include "cpu/pc_event.hh"
#include "cpu/thread_context.hh"
#include "debug/Loader.hh"
#include "kern/linux/events.hh"
#include "kern/linux/helpers.hh"
#include "kern/system_events.hh"
#include "mem/physical.hh"
#include "sim/stat_control.hh"

namespace gem5
{

using namespace linux;

namespace ArmISA
{

FsLinux::FsLinux(const Params &p) : ArmISA::FsWorkload(p),
    enableContextSwitchStatsDump(p.enable_context_switch_stats_dump)
{}

void
FsLinux::initState()
{
    ArmISA::FsWorkload::initState();

    // Load symbols at physical address, we might not want
    // to do this permanently, for but early bootup work
    // it is helpful.
    if (params().early_kernel_symbols) {
        auto phys_globals = kernelObj->symtab().globals()->mask(_loadAddrMask);
        kernelSymtab.insert(*phys_globals);
        loader::debugSymbolTable.insert(*phys_globals);
    }

    // Setup boot data structure
    // Check if the kernel image has a symbol that tells us it supports
    // device trees.
    bool kernel_has_fdt_support =
        kernelSymtab.find("unflatten_device_tree") != kernelSymtab.end();
    bool dtb_file_specified = params().dtb_filename != "";

    if (kernel_has_fdt_support && dtb_file_specified) {
        // Kernel supports flattened device tree and dtb file specified.
        // Using Device Tree Blob to describe system configuration.
        inform("Loading DTB file: %s at address %#x\n", params().dtb_filename,
                params().dtb_addr);

        auto *dtb_file = new loader::DtbFile(params().dtb_filename);

        if (!dtb_file->addBootCmdLine(
                    commandLine.c_str(), commandLine.size())) {
            warn("couldn't append bootargs to DTB file: %s\n",
                 params().dtb_filename);
        }

        dtb_file->buildImage().offset(params().dtb_addr)
            .write(system->physProxy);
        delete dtb_file;
    } else {
        // Using ATAGS
        // Warn if the kernel supports FDT and we haven't specified one
        if (kernel_has_fdt_support) {
            assert(!dtb_file_specified);
            warn("Kernel supports device tree, but no DTB file specified\n");
        }
        // Warn if the kernel doesn't support FDT and we have specified one
        if (dtb_file_specified) {
            assert(!kernel_has_fdt_support);
            warn("DTB file specified, but no device tree support in kernel\n");
        }

        AtagCore ac;
        ac.flags(1); // read-only
        ac.pagesize(8192);
        ac.rootdev(0);

        AddrRangeList atagRanges = system->getPhysMem().getConfAddrRanges();
        fatal_if(atagRanges.size() != 1,
                 "Expected a single ATAG memory entry but got %d",
                 atagRanges.size());
        AtagMem am;
        am.memSize(atagRanges.begin()->size());
        am.memStart(atagRanges.begin()->start());

        AtagCmdline ad;
        ad.cmdline(commandLine);

        DPRINTF(Loader, "boot command line %d bytes: %s\n",
                ad.size() << 2, commandLine);

        AtagNone an;

        uint32_t size = ac.size() + am.size() + ad.size() + an.size();
        uint32_t offset = 0;
        uint8_t *boot_data = new uint8_t[size << 2];

        offset += ac.copyOut(boot_data + offset);
        offset += am.copyOut(boot_data + offset);
        offset += ad.copyOut(boot_data + offset);
        offset += an.copyOut(boot_data + offset);

        DPRINTF(Loader, "Boot atags was %d bytes in total\n", size << 2);
        DDUMP(Loader, boot_data, size << 2);

        system->physProxy.writeBlob(params().dtb_addr,
                                    boot_data, size << 2);

        delete[] boot_data;
    }

    if (getArch() == loader::Arm64) {
        // We inform the bootloader of the kernel entry point. This was added
        // originally done because the entry offset changed in kernel v5.8.
        // Previously the bootloader just used a hardcoded address.
        for (auto *tc: system->threads) {
            tc->setIntReg(0, params().dtb_addr);
            tc->setIntReg(5, params().cpu_release_addr);
        }
    } else {
        // Kernel boot requirements to set up r0, r1 and r2 in ARMv7
        for (auto *tc: system->threads) {
            tc->setIntReg(0, 0);
            tc->setIntReg(1, params().machine_type);
            tc->setIntReg(2, params().dtb_addr);
        }
    }
}

FsLinux::~FsLinux()
{
    delete debugPrintk;
    delete skipUDelay;
    delete skipConstUDelay;
    delete kernelOops;
    delete kernelPanic;

    delete dumpStats;
}

void
FsLinux::startup()
{
    FsWorkload::startup();

    if (enableContextSwitchStatsDump) {
        if (getArch() == loader::Arm64)
            dumpStats = addKernelFuncEvent<DumpStats64>("__switch_to");
        else
            dumpStats = addKernelFuncEvent<DumpStats>("__switch_to");

        panic_if(!dumpStats, "dumpStats not created!");

        std::string task_filename = "tasks.txt";
        taskFile = simout.create(name() + "." + task_filename);

        for (auto *tc: system->threads) {
            uint32_t pid = tc->getCpuPtr()->getPid();
            if (pid != BaseCPU::invldPid) {
                mapPid(tc, pid);
                tc->getCpuPtr()->taskId(taskMap[pid]);
            }
        }
    }

    const std::string dmesg_output = name() + ".dmesg";
    if (params().panic_on_panic) {
        kernelPanic = addKernelFuncEventOrPanic<linux::KernelPanic>(
            "panic", "Kernel panic in simulated kernel", dmesg_output);
    } else {
        kernelPanic = addKernelFuncEventOrPanic<linux::DmesgDump>(
            "panic", "Kernel panic in simulated kernel", dmesg_output);
    }

    if (params().panic_on_oops) {
        kernelOops = addKernelFuncEventOrPanic<linux::KernelPanic>(
            "oops_exit", "Kernel oops in guest", dmesg_output);
    } else {
        kernelOops = addKernelFuncEventOrPanic<linux::DmesgDump>(
            "oops_exit", "Kernel oops in guest", dmesg_output);
    }

    // With ARM udelay() is #defined to __udelay
    // newer kernels use __loop_udelay and __loop_const_udelay symbols
    skipUDelay = addSkipFunc<SkipUDelay>(
        "__loop_udelay", "__udelay", 1000, 0);
    if (!skipUDelay) {
        skipUDelay = addSkipFuncOrPanic<SkipUDelay>(
                "__udelay", "__udelay", 1000, 0);
    }

    // constant arguments to udelay() have some precomputation done ahead of
    // time. Constant comes from code.
    skipConstUDelay = addSkipFunc<SkipUDelay>(
        "__loop_const_udelay", "__const_udelay", 1000, 107374);
    if (!skipConstUDelay) {
        skipConstUDelay = addSkipFuncOrPanic<SkipUDelay>(
            "__const_udelay", "__const_udelay", 1000, 107374);
    }

    debugPrintk = addSkipFunc<DebugPrintk>("dprintk");
}

void
FsLinux::mapPid(ThreadContext *tc, uint32_t pid)
{
    // Create a new unique identifier for this pid
    std::map<uint32_t, uint32_t>::iterator itr = taskMap.find(pid);
    if (itr == taskMap.end()) {
        uint32_t map_size = taskMap.size();
        if (map_size > context_switch_task_id::MaxNormalTaskId + 1) {
            warn_once("Error out of identifiers for cache occupancy stats");
            taskMap[pid] = context_switch_task_id::Unknown;
        } else {
            taskMap[pid] = map_size;
        }
    }
}

void
FsLinux::dumpDmesg()
{
    linux::dumpDmesg(system->threads[0], std::cout);
}

/**
 * Extracts the information used by the DumpStatsPCEvent by reading the
 * thread_info pointer passed to __switch_to() in 32 bit ARM Linux
 *
 *  r0 = task_struct of the previously running process
 *  r1 = thread_info of the previously running process
 *  r2 = thread_info of the next process to run
 */
void
DumpStats::getTaskDetails(ThreadContext *tc, uint32_t &pid,
    uint32_t &tgid, std::string &next_task_str, int32_t &mm) {

    linux::ThreadInfo ti(tc);
    Addr task_descriptor = tc->readIntReg(2);
    pid = ti.curTaskPID(task_descriptor);
    tgid = ti.curTaskTGID(task_descriptor);
    next_task_str = ti.curTaskName(task_descriptor);

    // Streamline treats pid == -1 as the kernel process.
    // Also pid == 0 implies idle process (except during Linux boot)
    mm = ti.curTaskMm(task_descriptor);
}

/**
 * Extracts the information used by the DumpStatsPCEvent64 by reading the
 * task_struct pointer passed to __switch_to() in 64 bit ARM Linux
 *
 *  r0 = task_struct of the previously running process
 *  r1 = task_struct of next process to run
 */
void
DumpStats64::getTaskDetails(ThreadContext *tc, uint32_t &pid,
    uint32_t &tgid, std::string &next_task_str, int32_t &mm) {

    linux::ThreadInfo ti(tc);
    Addr task_struct = tc->readIntReg(1);
    pid = ti.curTaskPIDFromTaskStruct(task_struct);
    tgid = ti.curTaskTGIDFromTaskStruct(task_struct);
    next_task_str = ti.curTaskNameFromTaskStruct(task_struct);

    // Streamline treats pid == -1 as the kernel process.
    // Also pid == 0 implies idle process (except during Linux boot)
    mm = ti.curTaskMmFromTaskStruct(task_struct);
}

/** This function is called whenever the the kernel function
 *  "__switch_to" is called to change running tasks.
 */
void
DumpStats::process(ThreadContext *tc)
{
    uint32_t pid = 0;
    uint32_t tgid = 0;
    std::string next_task_str;
    int32_t mm = 0;

    getTaskDetails(tc, pid, tgid, next_task_str, mm);

    bool is_kernel = (mm == 0);
    if (is_kernel && (pid != 0)) {
        pid = -1;
        tgid = -1;
        next_task_str = "kernel";
    }

    FsLinux* wl = dynamic_cast<FsLinux *>(tc->getSystemPtr()->workload);
    panic_if(!wl, "System workload is not ARM Linux!");
    std::map<uint32_t, uint32_t>& taskMap = wl->taskMap;

    // Create a new unique identifier for this pid
    wl->mapPid(tc, pid);

    // Set cpu task id, output process info, and dump stats
    tc->getCpuPtr()->taskId(taskMap[pid]);
    tc->getCpuPtr()->setPid(pid);

    OutputStream* taskFile = wl->taskFile;

    // Task file is read by cache occupancy plotting script or
    // Streamline conversion script.
    ccprintf(*(taskFile->stream()),
             "tick=%lld %d cpu_id=%d next_pid=%d next_tgid=%d next_task=%s\n",
             curTick(), taskMap[pid], tc->cpuId(), (int)pid, (int)tgid,
             next_task_str);
    taskFile->stream()->flush();

    // Dump and reset statistics
    statistics::schedStatEvent(true, true, curTick(), 0);
}

} // namespace ArmISA
} // namespace gem5
