//
// Copyright (c) 2021 Google LLC
//
// This file is licensed under the MIT License.
// Full license text is available in 'licenses/MIT.txt'.
//
using System;
using System.Linq;
using System.Text;

using Antmicro.Renode.Core;
using Antmicro.Renode.Core.Structure.Registers;
using Antmicro.Renode.Exceptions;
using Antmicro.Renode.Logging;
using Antmicro.Renode.Peripherals.Miscellaneous;
using Antmicro.Renode.Peripherals.Bus;
using Antmicro.Renode.Utilities;
using Antmicro.Renode.Debugging;

using Endianess = ELFSharp.ELF.Endianess;

namespace Antmicro.Renode.Peripherals.CPU
{
    public class KelvinRiscV32 : RiscV32
    {
        public KelvinRiscV32(Core.Machine machine,
                             uint hartId = 0,
                             PrivilegeArchitecture privilegeArchitecture = PrivilegeArchitecture.Priv1_11,
                             Endianess endianness = Endianess.LittleEndian,
                             string cpuType = "rv32im")
            : base(null, cpuType, machine, hartId, privilegeArchitecture, endianness)
        {
            InstallCustomInstruction(pattern: "00000000000100000000000001110011", handler: HandleKelvinEBreak); // Kelvin doesn't implement rv32i ebreak correctly
            InstallCustomInstruction(pattern: "00000010000000000000000001110011", handler: HandleKelvinEExit);
            InstallCustomInstruction(pattern: "00000100000000000000000001110011", handler: HandleKelvinEYield);
            InstallCustomInstruction(pattern: "00000110000000000000000001110011", handler: HandleKelvinECtxSw);
            InstallCustomInstruction(pattern: "00001000000000000000000001110011", handler: HandleKelvinMPause);
            InstallCustomInstruction(pattern: "011110000000-----000000001110111", handler: HandleKelvinFLog);
            InstallCustomInstruction(pattern: "011110000000-----001000001110111", handler: HandleKelvinSLog);
            InstallCustomInstruction(pattern: "011110000000-----010000001110111", handler: HandleKelvinCLog);
            InstallCustomInstruction(pattern: "011110000000-----011000001110111", handler: HandleKelvinKLog);
            InstallCustomInstruction(pattern: "00100110000000000000000001110111", handler: HandleKelvinFlushAll);
            InstallCustomInstruction(pattern: "001001100000-----000000001110111", handler: HandleKelvinFlushAt);

            Reset();
        }

        public override void Reset()
        {
            base.Reset();

            // This core comes out of reset paused.
            this.IsHalted = true;

            if(ControlBlockRegistered)
            {
                ControlBlock.Reset();
            }
        }

        public void RegisterControlBlock(KelvinRiscV32_ControlBlock controlBlock)
        {
            ControlBlock = controlBlock;
            ControlBlockRegistered = true;
        }

        private KelvinRiscV32_ControlBlock ControlBlock;
        private bool ControlBlockRegistered = false;

        private void HandleKelvinEBreak(UInt64 opcode)
        {
            ControlBlock.ExecEBreak();
        }

        private void HandleKelvinEExit(UInt64 opcode)
        {
            ControlBlock.ExecEBreak();
        }

        private void HandleKelvinEYield(UInt64 opcode)
        {
            // To be implemented
            ControlBlock.ExecEBreak();
        }

        private void HandleKelvinECtxSw(UInt64 opcode)
        {
            // To be implemented
            ControlBlock.ExecEBreak();
        }

        private void HandleKelvinMPause(UInt64 opcode)
        {
            ControlBlock.ExecMPause();
        }

        private void HandleKelvinFLog(UInt64 opcode)
        {
            this.Log(LogLevel.Noisy, "FLog dropped (unimplemented)");
            // To be implemented
        }

        private void HandleKelvinSLog(UInt64 opcode)
        {
            this.Log(LogLevel.Noisy, "SLog dropped (unimplemented)");
            // To be implemented
        }

        private void HandleKelvinCLog(UInt64 opcode)
        {
            this.Log(LogLevel.Noisy, "CLog dropped (unimplemented)");
            // To be implemented
        }

        private void HandleKelvinKLog(UInt64 opcode)
        {
            this.Log(LogLevel.Noisy, "KLog dropped (unimplemented)");
            // To be implemented
        }

        private void HandleKelvinFlushAll(UInt64 opcode)
        {
            // No-op in simulator
        }

        private void HandleKelvinFlushAt(UInt64 opcode)
        {
            // No-op in simulator
        }
    }

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

        public KelvinRiscV32_ControlBlock(Machine machine,
                                          KelvinRiscV32 core,
                                          ulong tcmSize,
                                          ulong tcmRangeStart)
        {
            Machine = machine;
            Core = core;

            this.tcmRangeStart = tcmRangeStart;
            this.tcmSize = tcmSize;

            Mmu = InitMmu(tcmRangeStart, tcmSize);

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

            Core.RegisterControlBlock(this);

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

            Core.AddHookOnMmuFault(HandleFault);

            Reset();
        }

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

        private ExternalMmuBase InitMmu(ulong rangeStart, ulong tcmSize)
        {
            var mmu = new ExternalMmuBase(this.Core, 1);

            mmu.SetWindowStart(0, 0);
            mmu.SetWindowEnd(0, tcmSize);
            mmu.SetWindowAddend(0, tcmRangeStart);
            mmu.SetWindowPrivileges(0, 7); // Read / write / execute

            return mmu;
        }

        private void DefineRegisters()
        {
            Registers.IntrState.Define32(this)
              .WithValueField(0, 4,
                              writeCallback: (_, value) =>
                              {
                                  this.Log(LogLevel.Noisy, "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.Log(LogLevel.Noisy, "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.Log(LogLevel.Noisy, "Got {0} to set IRQ pending bits", value);
                                  irqsPending = irqsPending | ((InterruptBits)value & InterruptBits.Mask);
                                  IrqUpdate();
                              })
            ;

            Registers.Control.Define32(this, resetValue: 0x00000002)
                    .WithValueField(0, 24, name: "FREEZE_VC_RESET_PC_START",
                                    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.Log(LogLevel.Noisy, "Pausing core.");
                                            Core.IsHalted = true;
                                        }

                                        // Trigger the core's reset when SwReset is deasserted.
                                        if (((mode & Mode.SwReset) != 0) && ((newMode & Mode.SwReset) == 0))
                                        {
                                            this.Log(LogLevel.Noisy, "Resetting core.");
                                            Core.Reset();
                                        }

                                        if ((mode & Mode.SwReset) != 0)
                                        {
                                            // Always set the PC on assignment to help with GDB.
                                            ulong startAddress = (val >> (int)Mode.NumBits);
                                            if ((Core.PC != startAddress))
                                            {
                                                this.Log(LogLevel.Noisy, "Setting PC to 0x{0:X}.", startAddress);
                                                Core.PC = startAddress;
                                            }
                                        }

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

                                            Core.Resume();
                                        }

                                        this.mode = newMode;
                                    })
                    .WithIgnoredBits(24, 32 - 24)
            ;

            // To-do: Not sure how to implement disablable memory banks.
            Registers.MemoryBankControl.Define32(this)
                    .WithValueField(0, 4, out MemoryEnable, name: "MEM_ENABLE")
                    .WithIgnoredBits(16, 32 - 16)
            ;

            // To-do: Not sure how to implement memory access range checks.
            Registers.ErrorStatus.Define32(this)
                    .WithFlag(0, name: "MEM_OUT_OF_RANGE")
                    .WithValueField(2, 4, out MemoryDisableAccess, name: "MEM_DISABLE_ACCESS")
                    .WithIgnoredBits(16, 32 - 16)
            ;

            Registers.InitStart.Define32(this)
                    .WithValueField(0, 22, out InitStartAddress, name: "ADDRESS")
                    .WithIgnoredBits(24, 32 - 24)
            ;

            Registers.InitEnd.Define32(this)
                    .WithValueField(0, 22, out InitEndAddress, name: "ADDRESS")
                    .WithFlag(22, name: "VALID", mode: FieldMode.Read | FieldMode.Write,
                              writeCallback: (_, val) =>
                              {
                                  // If valid, do the memory clear.
                                  if (val)
                                  {
                                      var dataPageMask = ~((ulong)(DataPageSize - 1));
                                      InitStatusPending.Value = true;
                                      InitStatusDone.Value = false;
                                      Machine.LocalTimeSource.ExecuteInNearestSyncedState( __ =>
                                      {
                                          for(ulong writeAddress = InitStartAddress.Value & dataPageMask;
                                              writeAddress < ((InitEndAddress.Value + DataPageSize - 1) & dataPageMask);
                                              writeAddress += DataPageSize)
                                          {
                                              Machine.SystemBus.WriteBytes(DataErasePattern,
                                                                           (ulong)writeAddress,
                                                                           (uint)DataPageSize, true);
                                          }
                                          InitStatusPending.Value = false;
                                          InitStatusDone.Value = true;
                                      });
                                  }
                              })
                    .WithIgnoredBits(23, 32 - 23)
            ;

            Registers.InitStatus.Define32(this)
                    .WithFlag(0, out InitStatusPending, name: "INIT_PENDING")
                    .WithFlag(1, out InitStatusDone, name: "INIT_DONE")
                    .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, reset the core (actual reset occurs when SwReset is cleared) and trigger a host interrupt indicating completion
            if (mode == Mode.Run)
            {
                this.Log(LogLevel.Noisy, "Pausing and resetting core for host completion notification.");
            }
            else
            {
                this.Log(LogLevel.Error, "Pausing and resetting core for host completion notification, but core was not expected to be running. Did you clear IsHalted manually?");
            }
            Core.IsHalted = true;
            mode = Mode.Freeze | Mode.SwReset;
            irqsPending |= InterruptBits.Finish;
            IrqUpdate();
        }

        public void ExecEBreak()
        {
            // Pause and trigger a host interrupt indicating completion with fault
            if (mode == Mode.Run)
            {
                this.Log(LogLevel.Noisy, "Core executed ebreak.");
            }
            else
            {
                this.Log(LogLevel.Error, "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; }


        private void HandleFault(ulong faultAddress, AccessType accessType, int windowIndex)
        {
            LogFaultType(Mmu, faultAddress, accessType);
            ExecEBreak();
        }

        private void LogFaultType(ExternalMmuBase mmu, ulong faultAddress, AccessType accessType)
        {
            var mmuName = mmu.GetType().Name;
            var virtualWindowIndex = (uint)(faultAddress / tcmSize);

            if(virtualWindowIndex >= 1)
            {
                this.Log(LogLevel.Error, "{0}: Translation request for {1} at 0x{2:X}: failure, no window at address", mmuName, accessType, faultAddress);
            }
            else
            {
                var windowEnd = mmu.GetWindowEnd(virtualWindowIndex);
                var windowPrivilege = mmu.GetWindowPrivileges(virtualWindowIndex);

                if(faultAddress > windowEnd)
                {
                    this.Log(LogLevel.Error, "{0}: Translation request for {1} at 0x{2:X}: failure on window {3}, out of range, window ends at 0x{4:X}",
                             mmuName, accessType, faultAddress, virtualWindowIndex, windowEnd);
                }
                else if((windowPrivilege & (uint)accessType) == 0)
                {
                    this.Log(LogLevel.Error, "{0}: Translation request for {1} at 0x{2:X}: failure on window {3}, no permission, window permissions are 0x{4:X}",
                             mmuName, accessType, faultAddress, virtualWindowIndex, windowPrivilege);
                }
                else
                {
                    this.Log(LogLevel.Error, "{0}: Translation request for {1} at 0x{2:X}: failed for unknown reason. This should not occur",
                             mmuName, accessType, faultAddress);
                }
            }
        }

        public GPIO HostReqIRQ { get; }
        public GPIO FinishIRQ { get; }
        public GPIO InstructionFaultIRQ { get; }
        public GPIO DataFaultIRQ { 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);
            DataFaultIRQ.Set((irqsPassed & InterruptBits.DataFault) != 0);
        }

        // To-do: Set the erase pattern to what the hardware actually does. 0x5A is
        // only for debugging purposes.
        private const int DataPageSize = 64;
        private readonly byte[] DataErasePattern = (byte[])Enumerable.Repeat((byte)0x5A, DataPageSize).ToArray();

        // Disable unused variable warnings. These warnings will go away on their
        // their own when each register's behavior is implemented.
#pragma warning disable 414
        private IValueRegisterField MemoryEnable;
        private IValueRegisterField MemoryDisableAccess;
        private IValueRegisterField InitStartAddress;
        private IValueRegisterField InitEndAddress;
        private IFlagRegisterField InitStatusPending;
        private IFlagRegisterField InitStatusDone;
#pragma warning restore 414

        private Mode mode;
        private readonly Machine Machine;
        private readonly KelvinRiscV32 Core;
        private readonly ExternalMmuBase Mmu;
        private readonly ulong tcmSize;
        private readonly ulong tcmRangeStart;

        // Length of register space.
        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,
            DataFault = 8,
            Mask = 15,
        };
    }

}
