//
// Copyright (c) 2023 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using System.Collections.Generic;
using System.Collections.Concurrent;
using Antmicro.Renode.Core;
using Antmicro.Renode.Core.Structure.Registers;
using Antmicro.Renode.Exceptions;
using Antmicro.Renode.Logging;
using Antmicro.Renode.Peripherals.Bus;
using Antmicro.Renode.Peripherals.CPU;
using Antmicro.Renode.Peripherals.Memory;
using Antmicro.Renode.Peripherals.Timers;
using Antmicro.Renode.Peripherals.CPU.Disassembler;
using Antmicro.Renode.Peripherals.CPU.Registers;
using Antmicro.Renode.Utilities;
using Antmicro.Renode.Time;
using Antmicro.Renode.Utilities.Binding;
using ELFSharp.ELF;
using ELFSharp.UImage;
using Machine = Antmicro.Renode.Core.Machine;


namespace Antmicro.Renode.Peripherals.CPU
{

    public class KelvinCPU : BaseCPU, ICPUWithRegisters, ITimeSink, IDisposable
    {
        [StructLayout(LayoutKind.Explicit, CharSet = CharSet.Ansi, Pack = 1)]
        private struct RegInfo
        {
            [FieldOffset(0)]
            public Int32 index;
            [FieldOffset(4)]
            public Int32 width;
            [FieldOffset(8)]
            public bool isGeneral;
            [FieldOffset(9)]
            public bool isReadOnly;
        }

        public KelvinCPU(uint id, string cpuType, Machine machine,
            MappedMemory memory,
            Endianess endianess = Endianess.LittleEndian,
            CpuBitness bitness = CpuBitness.Bits32)
            : base(id, cpuType, machine, endianess, bitness)
        {
            error_ptr = Marshal.AllocHGlobal(4);
            value_ptr = Marshal.AllocHGlobal(8);
            reg_info_ptr = Marshal.AllocHGlobal(Marshal.SizeOf<RegInfo>());
            string_ptr = Marshal.AllocHGlobal(maxStringLen);
            dataMemory = memory;

            // Touch all the memory segments to ensure all of segments are
            // allocated with valid pointers.
            dataMemory.TouchAllSegments();
            cpuLibraryRegistered = false;
        }

        ~KelvinCPU()
        {
            Marshal.FreeHGlobal(error_ptr);
            Marshal.FreeHGlobal(value_ptr);
            Marshal.FreeHGlobal(reg_info_ptr);
            Marshal.FreeHGlobal(string_ptr);
        }

        public override void Start()
        {
            base.Start();
            if (kelvin_id < 0)
            {
                LogAndThrowRE("Failed to create kelvin sim instance");
                return;
            }
            PC = 0;
        }

        public void RegisterControlBlock(MlTopControlBlock controlBlock)
        {
            this.controlBlock = controlBlock;
            controlBlockRegistered = true;
        }

        private void HandleKelvinEBreak()
        {
            if (controlBlockRegistered)
            {
                controlBlock.ExecEBreak();
            }
            else
            {
                IsHalted = true;
            }
        }

        private void HandleKelvinMPause()
        {
            if (controlBlockRegistered)
            {
                controlBlock.ExecMPause();
            }
            else
            {
                IsHalted = true;
            }
        }

        public override void Reset()
        {
            base.Reset();
            instructionsExecutedThisRound = 0;
            totalExecutedInstructions = 0;
            // Reset simulator.
            var result = reset(kelvin_id);
            if (result < 0)
            {
                LogAndThrowRE("Failed to reset kelvin");
            }
            this.NoisyLog("Reset kelvin");
        }

        public override void Dispose()
        {
            base.Dispose();
            // Cleanup: simulator and any unmanaged resources.
            lock(nativeLock)
            {
                destruct(kelvin_id);
            }
        }

        // No-op public API to match RiscVCPU
        public Int32 PerformanceInMips { get; set; }

        public override string Architecture { get { return "kelvin"; } }

        public override ulong ExecutedInstructions => totalExecutedInstructions;

        public override ExecutionMode ExecutionMode
        {
            get
            {
                return executionMode;
            }
            set
            {
                lock (singleStepSynchronizer.Guard)
                {
                    if (executionMode == value)
                    {
                        return;
                    }

                    executionMode = value;

                    singleStepSynchronizer.Enabled = IsSingleStepMode;
                    UpdateHaltedState();
                }
            }
        }

        [Register]
        public override RegisterValue PC
        {
            get
            {
                Int64 value = 0;
                lock(nativeLock)
                {
                    Int32 error = read_register(kelvin_id, PC_ID, value_ptr);
                    // TODO(hcindyl): Check different error types.
                    if (error < 0)
                    {
                        this.ErrorLog("Failed to read PC");
                    }
                    value = Marshal.ReadInt64(value_ptr);

                }
                return Convert.ToUInt64(value);
            }

            set
            {
                lock(nativeLock)
                {
                    Int32 error = write_register(kelvin_id, PC_ID, value);

                    // TODO(hcindyl): Check different error types.
                    if (error < 0)
                    {
                        this.NoisyLog("Failed to write PC");
                    }
                }
            }
        }

        protected override ExecutionResult ExecuteInstructions(
            ulong numberOfInstructionsToExecute,
            out ulong numberOfExecutedInstructions)
        {
            UInt64 instructionsExecutedThisRound = 0UL;
            ExecutionResult result = ExecutionResult.Ok;
            try
            {
                lock(nativeLock)
                {
                    // Invoke simulator for the number of instructions.
                    instructionsExecutedThisRound = step(kelvin_id,
                                                         numberOfInstructionsToExecute,
                                                         error_ptr);
                    // Parse the result.
                    Int32 step_result = Marshal.ReadInt32(error_ptr);
                    switch (step_result)
                    {
                        case -1:
                            result = ExecutionResult.Aborted;
                            break;
                        case 0:
                            result = ExecutionResult.Ok;
                            break;
                        case 1:
                            result = ExecutionResult.Interrupted;
                            break;
                        case 2:
                            result = ExecutionResult.WaitingForInterrupt;
                            break;
                        case 3:
                            result = ExecutionResult.StoppedAtBreakpoint;
                            break;
                        case 4:
                            result = ExecutionResult.StoppedAtWatchpoint;
                            break;
                        case 5:
                            result = ExecutionResult.ExternalMmuFault;
                            break;
                        default:
                            LogAndThrowRE("Unknown return value from step - " + step_result);
                            break;
                    }
                }
            }
            catch (Exception)
            {
                this.NoisyLog("CPU exception detected, halting.");
                InvokeHalted(new HaltArguments(HaltReason.Abort, Id));
                return ExecutionResult.Aborted;
            }
            finally
            {
                numberOfExecutedInstructions = instructionsExecutedThisRound;
                totalExecutedInstructions += instructionsExecutedThisRound;
            }

            if (numberOfInstructionsToExecute > instructionsExecutedThisRound &&
                result == ExecutionResult.Ok)
            {
                this.DebugLog("CPU finish execution.");
                this.DebugLog("Total instruction count: {0}",
                              totalExecutedInstructions);
                HandleKelvinMPause();
            }

            if (numberOfInstructionsToExecute > instructionsExecutedThisRound &&
                result == ExecutionResult.Aborted)
            {
                this.DebugLog("CPU finish execution.");
                HandleKelvinEBreak();
            }

            return result;
        }

        // ICPUWithRegisters methods implementations.
        public void SetRegisterUnsafe(int register, RegisterValue value)
        {
            lock(nativeLock)
            {
                var status = write_register((Int32)kelvin_id, (Int32)register, (UInt64)value);
                if (status < 0)
                {
                    LogAndThrowRE("Failed to write register " + register);
                }
            }
        }

        public RegisterValue GetRegisterUnsafe(int register)
        {
            Int64 value = 0;
            lock(nativeLock)
            {
                var status = read_register(kelvin_id, (UInt32)register, value_ptr);
                if (status < 0)
                {
                    LogAndThrowRE("Failed to read register " + register);
                }
                value = Marshal.ReadInt64(value_ptr);
            }
            return (UInt64)value;
        }

        public IEnumerable<CPURegister> GetRegisters()
        {
            if (registerMap.Count == 0)
            {
                lock(nativeLock)
                {
                    Int32 num_regs = get_reg_info_size(kelvin_id);
                    for (Int32 i = 0; i < num_regs; i++)
                    {
                        Int32 result = get_reg_info(kelvin_id, i, string_ptr, reg_info_ptr);
                        if (result < 0)
                        {
                            this.ErrorLog("Failed to get register info for index " + i);
                            continue;
                        }
                        var reg_info = Marshal.PtrToStructure<RegInfo>(reg_info_ptr);
                        var cpu_reg = new CPURegister(reg_info.index, reg_info.width,
                                                    reg_info.isGeneral,
                                                    reg_info.isReadOnly);
                        var reg_name = Marshal.PtrToStringAuto(string_ptr);
                        registerMap.Add(reg_info.index, cpu_reg);
                        registerNamesMap.Add(reg_name, reg_info.index);
                    }
                }
            }
            return registerMap.Values.OrderBy(x => x.Index);
        }

        public string[,] GetRegistersValues()
        {
            if (registerMap.Count == 0)
            {
                GetRegisters();
            }
            var result = new Dictionary<string, ulong>();
            foreach (var reg in registerNamesMap)
            {
                Int64 value = 0;
                lock(nativeLock)
                {
                    var status = read_register(kelvin_id, (UInt32)reg.Value, value_ptr);
                    if (status < 0) continue;
                    value = Marshal.ReadInt64(value_ptr);
                }
                result.Add(reg.Key, Convert.ToUInt64(value));
            }
            var table = new Table().AddRow("Name", "Value");
            table.AddRows(result, x => x.Key, x => "0x{0:X}".FormatWith(x.Value));
            return table.ToArray();
        }

        public string CpuLibraryPath
        {
            get
            {
                return cpuLibraryPath;
            }
            set
            {
                if (!String.IsNullOrWhiteSpace(value))
                {
                    if (cpuLibraryRegistered)
                    {
                        this.WarningLog("cpu library already registerd and " +
                                        "should not be updated again.");
                        return;
                    }
                    cpuLibraryPath = value;
                    try
                    {
                        binder = new NativeBinder(this, cpuLibraryPath);
                    }
                    catch (System.Exception e)
                    {
                        LogAndThrowRE("Failed to load CPU library: " + e.Message);
                    }
                    cpuLibraryRegistered = true;

                    this.NoisyLog("Memory block size: {0}, total size: {1}",
                                  dataMemory.SegmentSize, dataMemory.Size);
                    IntPtr[] memoryBlocks = new IntPtr[dataMemory.SegmentCount];
                    for (int i = 0; i < dataMemory.SegmentCount; i++)
                    {
                        this.NoisyLog("Segment {0}: pointer {1:8X}, size {2}",
                                      i, dataMemory.GetSegment(i),
                                      dataMemory.SegmentSize);
                        memoryBlocks[i] = dataMemory.GetSegment(i);
                    }

                    // Simulator initialization code goes here.
                    IntPtr memoryBlocksPtr = Marshal.AllocHGlobal(
                        dataMemory.SegmentCount * Marshal.SizeOf<IntPtr>());
                    Marshal.Copy(memoryBlocks, 0, memoryBlocksPtr, memoryBlocks.Length);
                    lock(nativeLock)
                    {
                        // Initiate a kelvin_sim simulator. For memory access
                        // inside the kelvin_sim, it refers to the memory block
                        // pointers provided by the dataMemory here.
                        //
                        // Note we don't preempt the memory access from other
                        // cores (e.g., MlCoordinator) with the nativeLock. The
                        // control flow we have in CantripOS should not cause
                        // the conflict memory access.
                        kelvin_id = construct_with_memory(maxStringLen,
                                                        (ulong)dataMemory.SegmentSize,
                                                        (ulong)dataMemory.Size,
                                                        memoryBlocksPtr);
                    }
                    Marshal.FreeHGlobal(memoryBlocksPtr);

                    if (kelvin_id < 0)
                    {
                        LogAndThrowRE("Failed to create simulator instance");
                        return;
                    }
                    this.NoisyLog("Construct kelvin");
                }
                else
                {
                    return;
                }
            }
        }

        private void LogAndThrowRE(string info)
        {
            this.Log(LogLevel.Error, info);
            throw new RecoverableException(info);
        }

        protected string cpuLibraryPath;
        private bool cpuLibraryRegistered;

        private readonly MappedMemory dataMemory;
        private NativeBinder binder;
        // lock to ensure only one binding function call is running.
        private readonly object nativeLock = new object();
        private readonly Int32 maxStringLen = 32;
        private IntPtr value_ptr { get; set; }
        private IntPtr error_ptr { get; set; }
        private IntPtr reg_info_ptr { get; set; }
        private IntPtr string_ptr { get; set; }

        // Functions from cpuLibrary
        [Import(UseExceptionWrapper = false)]
        // Int32(Int32 max_string_lenth, UInt64 mem_block_size,
        //       UInt64 mem_size, uint8_t ** mem_block_ptr_list);
        private FuncInt32Int32UInt64UInt64IntPtr construct_with_memory;
        [Import(UseExceptionWrapper = false)]
        // Int32(Int32 id);
        private FuncInt32Int32 destruct;
        [Import(UseExceptionWrapper = false)]
        // Int32(Int32 id);
        private FuncInt32Int32 reset;
        [Import(UseExceptionWrapper = false)]
        // Int32(Int32 id)
        private FuncInt32Int32 get_reg_info_size;
        [Import(UseExceptionWrapper = false)]
        // Int32(Int32 id, Int32 index, char *name, IntPtr *info);
        private FuncInt32Int32Int32IntPtrIntPtr get_reg_info;
        [Import(UseExceptionWrapper = false)]
        // UInt64(Int32 id, UInt64 step, IntPtr *status);
        private FuncUInt64Int32UInt64IntPtr step;
        [Import(UseExceptionWrapper = false)]
        // Int32(Int32 id, UInt32 reg_id, IntPtr *value);
        private FuncInt32Int32UInt32IntPtr read_register;
        [Import(UseExceptionWrapper = false)]
        // Int32(Int32 id, Int32 reg_id, UInt64 value);
        private FuncInt32Int32Int32UInt64 write_register;

        // Register access.
        private Dictionary<Int32, CPURegister> registerMap = new Dictionary<Int32, CPURegister>();
        private Dictionary<string, Int32> registerNamesMap = new Dictionary<string, Int32>();

        // PC magic ID. Defined in
        // https://github.com/riscv/riscv-opcodes/blob/d752f193cec46cfd33300abba2a3a0d020c36755/constants.py#L317
        // It is used to set/get PC by passing this register ID via `read_register`
        // and `write_register`.
        private const int PC_ID = 0x07b1;

        private ulong instructionsExecutedThisRound { get; set; }
        private ulong totalExecutedInstructions { get; set; }

        private Int32 kelvin_id { get; set; }

        // MlTopControlBlock
        private MlTopControlBlock controlBlock;
        private bool controlBlockRegistered = false;
    }


    public class MlTopControlBlock :
            IDoubleWordPeripheral,
            IProvidesRegisterCollection<DoubleWordRegisterCollection>,
            IKnownSize
    {

        public MlTopControlBlock(Machine machine,
                                 KelvinCPU core)
        {
            Machine = machine;
            Core = core;

            HostReqIRQ = new GPIO();
            FinishIRQ = new GPIO();
            InstructionFaultIRQ = new GPIO();

            Core.RegisterControlBlock(this);

            RegistersCollection = new DoubleWordRegisterCollection(this);
            DefineRegisters();

            Reset();
        }

        public void Reset()
        {
            mode = Mode.Freeze | Mode.SwReset;
            RegistersCollection.Reset();
        }

        private void DefineRegisters()
        {
            Registers.IntrState.Define32(this)
                .WithValueField(0, 4,
                                writeCallback: (_, value) =>
                                {
                                    this.NoisyLog("Got {0} to clear IRQ pending bits", value);
                                    irqsPending = irqsPending & ~(InterruptBits)value;
                                    IrqUpdate();
                                },
                                valueProviderCallback: (_) =>
                                {
                                    return (uint)irqsPending;
                                });

            Registers.IntrEnable.Define32(this)
                .WithValueField(0, 4,
                                writeCallback: (_, value) =>
                                {
                                    this.NoisyLog("Got {0} to write IRQ enable bits", value);
                                    irqsEnabled = (InterruptBits)value & InterruptBits.Mask;
                                    IrqUpdate();
                                },
                                valueProviderCallback: (_) =>
                                {
                                    return (uint)irqsEnabled;
                                });

            Registers.IntrTest.Define32(this)
                .WithValueField(0, 4,
                                writeCallback: (_, value) =>
                                {
                                    this.NoisyLog("Got {0} to set IRQ pending bits", value);
                                    irqsPending |= ((InterruptBits)value & InterruptBits.Mask);
                                    IrqUpdate();
                                });

            Registers.Control.Define32(this, resetValue: 0x00000002)
                .WithValueField(0, 24, name: "FREEZE_RESET_PC",
                                writeCallback: (_, val) =>
                                {
                                    Mode newMode = (Mode)val & Mode.Mask;
                                    // Pause the core when either freeze or swreset is asserted.
                                    if ((mode == Mode.Run) && (newMode != Mode.Run))
                                    {
                                        this.NoisyLog("Pausing core.");
                                        Core.IsHalted = true;
                                    }

                                    // Trigger the core's reset when SwReset is deasserted.
                                    if (((mode & Mode.SwReset) != 0) &&
                                        ((newMode & Mode.SwReset) == 0))
                                    {
                                        this.NoisyLog("Resetting core.");
                                        // Reset PC
                                        ulong startAddress = (val >> (int)Mode.NumBits);
                                        if (Core.PC != startAddress)
                                        {
                                            this.DebugLog("Setting PC to 0x{0:X8}.",
                                                          startAddress);
                                            Core.PC = startAddress;
                                        }
                                        Core.Reset();
                                    }

                                    // Raise reset bit, but the core will not be
                                    // reset until SwReset is deasserted.
                                    if ((mode & Mode.SwReset) == 0 &&
                                        ((newMode & Mode.SwReset) != 0))
                                    {
                                        this.NoisyLog("Raise reset bit");
                                    }

                                    // Unpause the core when both freeze and
                                    // SwReset are deasserted.
                                    if ((mode != Mode.Run) && (newMode == Mode.Run))
                                    {
                                        this.NoisyLog("Resuming core.");
                                        Core.IsHalted = false;

                                        Core.Resume();
                                    }

                                    this.mode = newMode;
                                })
                .WithTaggedFlag("VOLT_SEL", 24)
                .WithIgnoredBits(25, 32 - 25);

            // TODO: No implementation to memory bank control.
            Registers.MemoryBankControl.Define32(this)
                .WithTag("MEM_ENABLE", 0, 16)
                .WithIgnoredBits(16, 32 - 16);

            // TODO: No implementation of memory access error.
            Registers.ErrorStatus.Define32(this)
                .WithTaggedFlag("MEM_OUT_OF_RANGE", 0)
                .WithTag("MEM_DISABLE_ACCESS", 1, 8)
                .WithIgnoredBits(9, 32 - 9);

            Registers.InitStart.Define32(this)
                .WithTag("ADDRESS", 0, 22)
                .WithIgnoredBits(22, 32 - 22);

            Registers.InitEnd.Define32(this)
                .WithTag("ADDRESS", 0, 22)
                .WithTaggedFlag("VALID", 22)
                .WithIgnoredBits(23, 32 - 23);

            Registers.InitStatus.Define32(this)
                .WithTaggedFlag("INIT_PENDING", 0)
                .WithTaggedFlag("INIT_DONE", 1)
                .WithIgnoredBits(2, 32 - 2);

        }

        public virtual uint ReadDoubleWord(long offset)
        {
            return RegistersCollection.Read(offset);
        }

        public virtual void WriteDoubleWord(long offset, uint value)
        {
            RegistersCollection.Write(offset, value);
        }

        public void ExecMPause()
        {
            // Pause and trigger a host interrupt indicating completion
            if (mode == Mode.Run)
            {
                this.NoisyLog("Pausing the core for host completion notification.");
            }
            else
            {
                this.ErrorLog("Pausing the core for host completion notification, " +
                              "but core was not expected to be running. Did you " +
                              "clear IsHalted manually?");
            }
            Core.IsHalted = true;
            mode = Mode.Freeze;
            irqsPending |= InterruptBits.Finish;
            IrqUpdate();
        }

        public void ExecEBreak()
        {
            // Pause and trigger a host interrupt indicating completion with
            // fault
            if (mode == Mode.Run)
            {
                this.NoisyLog("Core executed ebreak.");
            }
            else
            {
                this.ErrorLog("Core executed ebreak, but core was not expected " +
                              "to be running. Did you clear IsHalted manually?");
            }
            Core.IsHalted = true;
            mode = Mode.Freeze;
            irqsPending |= InterruptBits.Finish | InterruptBits.InstructionFault;
            IrqUpdate();
        }

        public DoubleWordRegisterCollection RegistersCollection { get; private set; }

        public GPIO HostReqIRQ { get; }
        public GPIO FinishIRQ { get; }
        public GPIO InstructionFaultIRQ { get; }

        private InterruptBits irqsEnabled;
        private InterruptBits irqsPending;

        private void IrqUpdate()
        {
            InterruptBits irqsPassed = irqsEnabled & irqsPending;
            HostReqIRQ.Set((irqsPassed & InterruptBits.HostReq) != 0);
            FinishIRQ.Set((irqsPassed & InterruptBits.Finish) != 0);
            InstructionFaultIRQ.Set((irqsPassed & InterruptBits.InstructionFault) != 0);
        }

        private Mode mode;
        private readonly Machine Machine;
        private readonly KelvinCPU Core;
        // Length of register space. Required by IKnowSize.
        public long Size => 0x1000;
        private enum Registers
        {
            IntrState = 0x00,
            IntrEnable = 0x04,
            IntrTest = 0x08,
            Control = 0x0C,
            MemoryBankControl = 0x10,
            ErrorStatus = 0x14,
            InitStart = 0x18,
            InitEnd = 0x1C,
            InitStatus = 0x20,
        };
        [Flags]
        private enum Mode
        {
            Run = 0x00,
            Freeze = 0x01,
            SwReset = 0x02,
            Mask = 0x03,
            NumBits = 2,
        };
        [Flags]
        private enum InterruptBits
        {
            HostReq = 1,
            Finish = 2,
            InstructionFault = 4,
            Mask = 7,
        };
    }

}
