/*
 * Copyright (c) 2010, 2012-2013, 2015,2017-2018 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.
 *
 * Authors: Ali Saidi
 */

#include "arch/arm/system.hh"

#include <iostream>

#include "arch/arm/semihosting.hh"
#include "base/loader/object_file.hh"
#include "base/loader/symtab.hh"
#include "cpu/thread_context.hh"
#include "dev/arm/gic_v3.hh"
#include "mem/fs_translating_port_proxy.hh"
#include "mem/physical.hh"
#include "sim/full_system.hh"

using namespace std;
using namespace Linux;

ArmSystem::ArmSystem(Params *p)
    : System(p),
      bootLoaders(), bootldr(nullptr),
      _haveSecurity(p->have_security),
      _haveLPAE(p->have_lpae),
      _haveVirtualization(p->have_virtualization),
      _haveCrypto(p->have_crypto),
      _genericTimer(nullptr),
      _gic(nullptr),
      _resetAddr(p->auto_reset_addr ?
                 (kernelEntry & loadAddrMask) + loadAddrOffset :
                 p->reset_addr),
      _highestELIs64(p->highest_el_is_64),
      _physAddrRange64(p->phys_addr_range_64),
      _haveLargeAsid64(p->have_large_asid_64),
      _haveSVE(p->have_sve),
      _sveVL(p->sve_vl),
      _m5opRange(p->m5ops_base ?
                 RangeSize(p->m5ops_base, 0x10000) :
                 AddrRange(1, 0)), // Create an empty range if disabled
      semihosting(p->semihosting),
      multiProc(p->multi_proc)
{
    // Check if the physical address range is valid
    if (_highestELIs64 && (
            _physAddrRange64 < 32 ||
            _physAddrRange64 > 48 ||
            (_physAddrRange64 % 4 != 0 && _physAddrRange64 != 42))) {
        fatal("Invalid physical address range (%d)\n", _physAddrRange64);
    }

    bootLoaders.reserve(p->boot_loader.size());
    for (const auto &bl : p->boot_loader) {
        std::unique_ptr<ObjectFile> obj;
        obj.reset(createObjectFile(bl));

        fatal_if(!obj, "Could not read bootloader: %s\n", bl);
        bootLoaders.emplace_back(std::move(obj));
    }

    if (kernel) {
        bootldr = getBootLoader(kernel);
    } else if (!bootLoaders.empty()) {
        // No kernel specified, default to the first boot loader
        bootldr = bootLoaders[0].get();
    }

    if (!bootLoaders.empty() && !bootldr)
        fatal("Can't find a matching boot loader / kernel combination!");

    if (bootldr) {
        bootldr->loadGlobalSymbols(debugSymbolTable);

        warn_if(bootldr->entryPoint() != _resetAddr,
                "Bootloader entry point %#x overriding reset address %#x",
                bootldr->entryPoint(), _resetAddr);
        const_cast<Addr&>(_resetAddr) = bootldr->entryPoint();

        if ((bootldr->getArch() == ObjectFile::Arm64) && !_highestELIs64) {
            warn("Highest ARM exception-level set to AArch32 but bootloader "
                  "is for AArch64. Assuming you wanted these to match.\n");
            _highestELIs64 = true;
        } else if ((bootldr->getArch() == ObjectFile::Arm) && _highestELIs64) {
            warn("Highest ARM exception-level set to AArch64 but bootloader "
                  "is for AArch32. Assuming you wanted these to match.\n");
            _highestELIs64 = false;
        }
    }

    debugPrintkEvent = addKernelFuncEvent<DebugPrintkEvent>("dprintk");
}

void
ArmSystem::initState()
{
    // Moved from the constructor to here since it relies on the
    // address map being resolved in the interconnect

    // Call the initialisation of the super class
    System::initState();

    const Params* p = params();

    if (bootldr) {
        bool isGICv3System = dynamic_cast<Gicv3 *>(getGIC()) != nullptr;
        bootldr->loadSections(physProxy);

        inform("Using bootloader at address %#x\n", bootldr->entryPoint());

        // Put the address of the boot loader into r7 so we know
        // where to branch to after the reset fault
        // All other values needed by the boot loader to know what to do
        if (!p->flags_addr)
           fatal("flags_addr must be set with bootloader\n");

        if (!p->gic_cpu_addr && !isGICv3System)
            fatal("gic_cpu_addr must be set with bootloader\n");

        for (int i = 0; i < threadContexts.size(); i++) {
            if (!_highestELIs64)
                threadContexts[i]->setIntReg(3, (kernelEntry & loadAddrMask) +
                        loadAddrOffset);
            if (!isGICv3System)
                threadContexts[i]->setIntReg(4, params()->gic_cpu_addr);
            threadContexts[i]->setIntReg(5, params()->flags_addr);
        }
        inform("Using kernel entry physical address at %#x\n",
               (kernelEntry & loadAddrMask) + loadAddrOffset);
    } else {
        // Set the initial PC to be at start of the kernel code
        if (!_highestELIs64)
            threadContexts[0]->pcState((kernelEntry & loadAddrMask) +
                    loadAddrOffset);
    }
}

ArmSystem*
ArmSystem::getArmSystem(ThreadContext *tc)
{
    ArmSystem *a_sys = dynamic_cast<ArmSystem *>(tc->getSystemPtr());
    assert(a_sys);
    return a_sys;
}

bool
ArmSystem::haveSecurity(ThreadContext *tc)
{
    return FullSystem? getArmSystem(tc)->haveSecurity() : false;
}


ArmSystem::~ArmSystem()
{
    if (debugPrintkEvent)
        delete debugPrintkEvent;
}

ObjectFile *
ArmSystem::getBootLoader(ObjectFile *const obj)
{
    for (auto &bl : bootLoaders) {
        if (bl->getArch() == obj->getArch())
            return bl.get();
    }

    return nullptr;
}

bool
ArmSystem::haveLPAE(ThreadContext *tc)
{
    return FullSystem? getArmSystem(tc)->haveLPAE() : false;
}

bool
ArmSystem::haveVirtualization(ThreadContext *tc)
{
    return FullSystem? getArmSystem(tc)->haveVirtualization() : false;
}

bool
ArmSystem::highestELIs64(ThreadContext *tc)
{
    return FullSystem? getArmSystem(tc)->highestELIs64() : true;
}

ExceptionLevel
ArmSystem::highestEL(ThreadContext *tc)
{
    return FullSystem? getArmSystem(tc)->highestEL() : EL1;
}

bool
ArmSystem::haveEL(ThreadContext *tc, ExceptionLevel el)
{
    switch (el) {
      case EL0:
      case EL1:
        return true;
      case EL2:
        return haveVirtualization(tc);
      case EL3:
        return haveSecurity(tc);
      default:
        warn("Unimplemented Exception Level\n");
        return false;
    }
}

Addr
ArmSystem::resetAddr(ThreadContext *tc)
{
    return getArmSystem(tc)->resetAddr();
}

uint8_t
ArmSystem::physAddrRange(ThreadContext *tc)
{
    return getArmSystem(tc)->physAddrRange();
}

Addr
ArmSystem::physAddrMask(ThreadContext *tc)
{
    return getArmSystem(tc)->physAddrMask();
}

bool
ArmSystem::haveLargeAsid64(ThreadContext *tc)
{
    return getArmSystem(tc)->haveLargeAsid64();
}

bool
ArmSystem::haveSemihosting(ThreadContext *tc)
{
    return FullSystem && getArmSystem(tc)->haveSemihosting();
}

uint64_t
ArmSystem::callSemihosting64(ThreadContext *tc,
                             uint32_t op, uint64_t param)
{
    ArmSystem *sys = getArmSystem(tc);
    return sys->semihosting->call64(tc, op, param);
}

uint32_t
ArmSystem::callSemihosting32(ThreadContext *tc,
                             uint32_t op, uint32_t param)
{
    ArmSystem *sys = getArmSystem(tc);
    return sys->semihosting->call32(tc, op, param);
}

ArmSystem *
ArmSystemParams::create()
{
    return new ArmSystem(this);
}

void
GenericArmSystem::initState()
{
    // Moved from the constructor to here since it relies on the
    // address map being resolved in the interconnect

    // Call the initialisation of the super class
    ArmSystem::initState();
}

GenericArmSystem *
GenericArmSystemParams::create()
{

    return new GenericArmSystem(this);
}
