--
-- Copyright (C) 2015-2016 secunet Security Networks AG
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--

with HW.Time;
with HW.MMIO_Range;
pragma Elaborate_All (HW.MMIO_Range);

with HW.Debug;
with GNAT.Source_Info;

use type HW.Word64;

package body HW.GFX.GMA.Registers
with
   Refined_State =>
     (Address_State  =>
        (Regs.Base_Address, GTT_32.Base_Address, GTT_64.Base_Address),
      Register_State => Regs.State,
      GTT_State      => (GTT_32.State, GTT_64.State))
is
   pragma Disable_Atomic_Synchronization;

   type Registers_Range is
      new Natural range 0 .. 16#0020_0000# / Register_Width - 1;
   type Registers_Type is array (Registers_Range) of Word32
   with
      Atomic_Components,
      Size => 16#20_0000# * 8;
   package Regs is new MMIO_Range
     (Base_Addr   => Config.Default_MMIO_Base,
      Element_T   => Word32,
      Index_T     => Registers_Range,
      Array_T     => Registers_Type);

   ----------------------------------------------------------------------------

   MMIO_GTT_32_Size : constant := 16#20_0000#;
   -- Limit Broadwell+ to 4MiB to have a stable
   -- interface (i.e. same number of entries):
   MMIO_GTT_64_Size : constant := 16#40_0000#;

   type GTT_PTE_32 is mod 2 ** 32;
   type GTT_Registers_32 is array (GTT_Range) of GTT_PTE_32
   with
      Volatile_Components,
      Size => MMIO_GTT_32_Size * 8;
   package GTT_32 is new MMIO_Range
     (Base_Addr   =>
        Config.Default_MMIO_Base + Word64 (Config.Default_MMIO_GTT_32_Offset),
      Element_T   => GTT_PTE_32,
      Index_T     => GTT_Range,
      Array_T     => GTT_Registers_32);

   type GTT_PTE_64 is mod 2 ** 64;
   type GTT_Registers_64 is array (GTT_Range) of GTT_PTE_64
   with
      Volatile_Components,
      Size => MMIO_GTT_64_Size * 8;
   package GTT_64 is new MMIO_Range
     (Base_Addr   => Config.Default_MMIO_Base + Word64 (Config.MMIO_GTT_64_Offset),
      Element_T   => GTT_PTE_64,
      Index_T     => GTT_Range,
      Array_T     => GTT_Registers_64);

   GTT_PTE_Valid : constant := 1;

   ----------------------------------------------------------------------------

   subtype Fence_Range is Natural range 0 .. 31;

   FENCE_PAGE_SHIFT                    : constant := 12;
   FENCE_PAGE_MASK                     : constant := 16#ffff_f000#;
   FENCE_VALID                         : constant := 1 * 2 ** 0;

   -- Gen4+ (i965/G45+): 64-bit fence pairs at Fence_Base + i*8
   FENCE_TILE_WALK_YMAJOR              : constant := 1 * 2 ** 1;

   function Fence_Lower_Idx (Fence : Fence_Range) return Registers_Range is
      (Registers_Range (Config.Fence_Base / Register_Width + 2 * Fence));
   function Fence_Upper_Idx (Fence : Fence_Range) return Registers_Range is
      (Fence_Lower_Idx (Fence) + 1);

   -- Gen3 (i915/i945): 32-bit fences, split layout:
   --   Fences 0-7:  0x2000 + i*4
   --   Fences 8-15: 0x3000 + (i-8)*4
   -- FENCE_REG(i) = 0x2000 + (((i) & 8) << 9) + ((i) & 7) * 4
   GEN3_FENCE_TILING_Y_SHIFT           : constant := 12;
   GEN3_FENCE_SIZE_SHIFT               : constant := 8;
   GEN3_FENCE_PITCH_SHIFT              : constant := 4;

   function Gen3_Fence_Idx (Fence : Fence_Range) return Registers_Range is
      (Registers_Range
         ((16#2000# + (Fence / 8) * 16#1000# + (Fence mod 8) * 4) /
          Register_Width));

   -- Compute floor(log2(n)) for n >= 1 (fence size/pitch encoding).
   function Floor_Log2 (N : Word32) return Natural
   with
      Pre => N >= 1
   is
      Result : Natural := 0;
      Val    : Word32 := N;
   begin
      for I in 0 .. 31 loop
         exit when Val <= 1;
         Val    := Shift_Right (Val, 1);
         Result := I + 1;
      end loop;
      return Result;
   end Floor_Log2;

   procedure Clear_Fences
   is
   begin
      if Config.Has_Gen3_Fences then
         for Fence in Fence_Range range 0 .. Config.Fence_Count - 1 loop
            Regs.Write (Gen3_Fence_Idx (Fence), 0);
         end loop;
      else
         for Fence in Fence_Range range 0 .. Config.Fence_Count - 1 loop
            Regs.Write (Fence_Lower_Idx (Fence), 0);
         end loop;
      end if;
   end Clear_Fences;

   procedure Add_Fence
     (First_Page  : in     GTT_Range;
      Last_Page   : in     GTT_Range;
      Tiling      : in     XY_Tiling;
      Pitch       : in     Natural;
      Success     :    out Boolean)
   is
      Y_Tiles : constant Boolean := Tiling = Y_Tiled;
      Reg32 : Word32;
   begin
      pragma Debug (Debug.Put (GNAT.Source_Info.Enclosing_Entity & ": "));
      pragma Debug (Debug.Put_Word32 (Shift_Left (Word32 (First_Page), 12)));
      pragma Debug (Debug.Put (":"));
      pragma Debug (Debug.Put_Word32 (Shift_Left (Word32 (Last_Page), 12)));
      pragma Debug (not Y_Tiles, Debug.Put (" X tiled in "));
      pragma Debug (    Y_Tiles, Debug.Put (" Y tiled in "));
      pragma Debug (Debug.Put_Int32 (Int32 (Pitch)));
      pragma Debug (Debug.Put_Line (" tiles per row."));

      Success := False;

      if Config.Has_Gen3_Fences then
         -- Gen3 i945: single 32-bit fence register per fence
         -- Format: start[31:20] | tiling_y[12] | size_bits[11:8] |
         --         pitch_log2[7:4] | valid[0]
         -- stride: Y-tiled /128, X-tiled /512 (i945 has 128-byte Y tiling)
         -- size_bits: log2(size_in_pages / 256) = log2(size_in_MB)
         for Fence in Fence_Range range 0 .. Config.Fence_Count - 1 loop
            Regs.Read (Reg32, Gen3_Fence_Idx (Fence));
            if (Reg32 and FENCE_VALID) = 0 then
               declare
                  Start_Addr : constant Word32 :=
                     Shift_Left (Word32 (First_Page), FENCE_PAGE_SHIFT);
                  Size_Pages : constant Word32 :=
                     Word32 (Last_Page - First_Page + 1);
                  -- Size in MB (pages / 256, since page = 4KB, 256*4KB = 1MB)
                  Size_MB    : constant Word32 := Size_Pages / 256;
                  -- Pitch in tiles (X: 512B tiles, Y: 128B tiles for i945)
                  Stride     : constant Word32 :=
                     Word32 (Pitch) / (if Y_Tiles then 128 else 512);
                  Size_Bits  : constant Word32 :=
                     (if Size_MB >= 1
                      then Word32 (Floor_Log2 (Size_MB))
                      else 0);
               begin
                  Regs.Write
                    (Index => Gen3_Fence_Idx (Fence),
                     Value => Start_Addr or
                              (if Y_Tiles
                               then Shift_Left (1, GEN3_FENCE_TILING_Y_SHIFT)
                               else 0) or
                              Shift_Left (Size_Bits, GEN3_FENCE_SIZE_SHIFT) or
                              Shift_Left
                                ((if Stride >= 1
                                  then Word32 (Floor_Log2 (Stride))
                                  else 0),
                                 GEN3_FENCE_PITCH_SHIFT) or
                              FENCE_VALID);
               end;
               Success := True;
               exit;
            end if;
         end loop;
      else
         -- Gen4+ (i965/G45+): 64-bit fence register pairs
         for Fence in Fence_Range range 0 .. Config.Fence_Count - 1 loop
            Regs.Read (Reg32, Fence_Lower_Idx (Fence));
            if (Reg32 and FENCE_VALID) = 0 then
               Regs.Write
                 (Index => Fence_Lower_Idx (Fence),
                  Value => Shift_Left (Word32 (First_Page), FENCE_PAGE_SHIFT) or
                           (if Y_Tiles then FENCE_TILE_WALK_YMAJOR else 0) or
                           FENCE_VALID);
               Regs.Write
                 (Index => Fence_Upper_Idx (Fence),
                  Value => Shift_Left (Word32 (Last_Page), FENCE_PAGE_SHIFT) or
                           Word32 (Pitch) * (if Y_Tiles then 1 else 4) - 1);
               Success := True;
               exit;
            end if;
         end loop;
      end if;
   end Add_Fence;

   procedure Remove_Fence (First_Page, Last_Page : GTT_Range)
   is
      Page_Lower : constant Word32 :=
         Shift_Left (Word32 (First_Page), FENCE_PAGE_SHIFT);
      Reg32 : Word32;
   begin
      if Config.Has_Gen3_Fences then
         -- Gen3: match start address in single 32-bit register
         for Fence in Fence_Range range 0 .. Config.Fence_Count - 1 loop
            Regs.Read (Reg32, Gen3_Fence_Idx (Fence));
            if (Reg32 and FENCE_VALID) /= 0 and
               (Reg32 and 16#fff0_0000#) = (Page_Lower and 16#fff0_0000#)
            then
               Regs.Write (Gen3_Fence_Idx (Fence), 0);
               exit;
            end if;
         end loop;
      else
         -- Gen4+: match start in lower, end in upper register
         declare
            Page_Upper : constant Word32 :=
               Shift_Left (Word32 (Last_Page), FENCE_PAGE_SHIFT);
            Fence_Upper, Fence_Lower : Word32;
         begin
            for Fence in Fence_Range range 0 .. Config.Fence_Count - 1 loop
               Regs.Read (Fence_Lower, Fence_Lower_Idx (Fence));
               Regs.Read (Fence_Upper, Fence_Upper_Idx (Fence));
               if (Fence_Lower and FENCE_PAGE_MASK) = Page_Lower and
                  (Fence_Upper and FENCE_PAGE_MASK) = Page_Upper
               then
                  Regs.Write (Fence_Lower_Idx (Fence), 0);
                  exit;
               end if;
            end loop;
         end;
      end if;
   end Remove_Fence;

   ----------------------------------------------------------------------------

   procedure Write_GTT
     (GTT_Page       : GTT_Range;
      Device_Address : GTT_Address_Type;
      Valid          : Boolean)
   is
   begin
      if Config.Has_I945_Simple_GTT_PTE then
         -- i945: simple 32-bit PTE, no high address bits
         GTT_32.Write
           (Index => GTT_Page,
            Value => GTT_PTE_32 (Device_Address and 16#ffff_f000#) or
                     Boolean'Pos (Valid));
      elsif not Config.Has_64bit_GTT then
         GTT_32.Write
           (Index => GTT_Page,
            Value => GTT_PTE_32 (Device_Address and 16#ffff_f000#) or
                     GTT_PTE_32 (Shift_Right (Word64 (Device_Address), 32 - 4)
                                   and 16#0000_07f0#) or
                     Boolean'Pos (Valid));
      else
         GTT_64.Write
           (Index => GTT_Page,
            Value => GTT_PTE_64 (Device_Address and 16#7f_ffff_f000#) or
                     Boolean'Pos (Valid));
      end if;
   end Write_GTT;

   procedure Read_GTT
     (Device_Address :    out GTT_Address_Type;
      Valid          :    out Boolean;
      GTT_Page       : in     GTT_Range)
   is
   begin
      if Config.Has_I945_Simple_GTT_PTE then
         declare
            PTE : GTT_PTE_32;
         begin
            GTT_32.Read (PTE, GTT_Page);
            Valid := (PTE and GTT_PTE_Valid) /= 0;
            Device_Address := GTT_Address_Type (PTE and 16#ffff_f000#);
         end;
      elsif not Config.Has_64bit_GTT then
         declare
            PTE : GTT_PTE_32;
         begin
            GTT_32.Read (PTE, GTT_Page);
            Valid := (PTE and GTT_PTE_Valid) /= 0;
            Device_Address := GTT_Address_Type
              (Shift_Left (Word64 (PTE and 16#07f0#), 32 - 4) or
               Word64 (PTE and 16#ffff_f000#));
         end;
      else
         declare
            PTE : GTT_PTE_64;
         begin
            GTT_64.Read (PTE, GTT_Page);
            Valid := (PTE and GTT_PTE_Valid) /= 0;
            Device_Address := GTT_Address_Type (PTE and 16#7f_ffff_f000#);
         end;
      end if;
   end Read_GTT;

   ----------------------------------------------------------------------------

   package Rep is
      function Index (Reg : Registers_Index) return Registers_Range;
   end Rep;

   package body Rep is
      function Index (Reg : Registers_Index) return Registers_Range
      with
         SPARK_Mode => Off
      is
      begin
         return Reg'Enum_Rep;
      end Index;
   end Rep;

   -- Read a specific register
   procedure Read
     (Register : in     Registers_Index;
      Value    :    out Word32;
      Verbose  : in     Boolean := True)
   is
   begin
      Regs.Read (Value, Rep.Index (Register));

      pragma Debug (Verbose, Debug.Put (GNAT.Source_Info.Enclosing_Entity & ":  "));
      pragma Debug (Verbose, Debug.Put_Word32 (Value));
      pragma Debug (Verbose, Debug.Put (" <- "));
      pragma Debug (Verbose, Debug.Put_Word32 (Register'Enum_Rep * Register_Width));
      pragma Debug (Verbose, Debug.Put (":"));
      pragma Debug (Verbose, Debug.Put_Line (Registers_Index'Image (Register)));
   end Read;

   procedure Read_AUD_VID_DID (Value : out Word32)
   is
   begin
      Regs.Read
        (Value,
         Registers_Range (Config.AUD_VID_DID_Offset / Register_Width));
   end Read_AUD_VID_DID;

   ----------------------------------------------------------------------------

   -- Read a specific register to post a previous write
   procedure Posting_Read (Register : Registers_Index)
   is
      Discard_Value : Word32;
   begin
      pragma Warnings
        (Off, "unused assignment to ""Discard_Value""",
         Reason => "Intentional dummy read to affect hardware.");

      Read (Register, Discard_Value);

      pragma Warnings
        (On, "unused assignment to ""Discard_Value""");
   end Posting_Read;

   ----------------------------------------------------------------------------

   -- Write a specific register
   procedure Write (Register : Registers_Index; Value : Word32)
   is
   begin
      pragma Debug (Debug.Put (GNAT.Source_Info.Enclosing_Entity & ": "));
      pragma Debug (Debug.Put_Word32 (Value));
      pragma Debug (Debug.Put (" -> "));
      pragma Debug (Debug.Put_Word32 (Register'Enum_Rep * Register_Width));
      pragma Debug (Debug.Put (":"));
      pragma Debug (Debug.Put_Line (Registers_Index'Image (Register)));

      Regs.Write (Rep.Index (Register), Value);
      pragma Debug (Debug.Register_Write_Wait);
   end Write;

   ----------------------------------------------------------------------------

   -- Check whether all bits in @Register@ indicated by @Mask@ are set
   procedure Is_Set_Mask
      (Register : in     Registers_Index;
       Mask     : in     Word32;
       Result   :    out Boolean)
   is
      Value : Word32;
   begin
      pragma Debug (Debug.Put (GNAT.Source_Info.Enclosing_Entity & ": "));
      pragma Debug (Debug.Put_Line (Registers_Index'Image (Register)));

      Read (Register, Value);
      Result := (Value and Mask) = Mask;

   end Is_Set_Mask;

   ----------------------------------------------------------------------------

   pragma Warnings (GNATprove, Off, "unused assignment to ""Ignored_Success""");

   -- Wait for the bits in @Register@ indicated by @Mask@ to be of @Value@
   procedure Wait
     (Register : in     Registers_Index;
      Mask     : in     Word32;
      Value    : in     Word32;
      TOut_MS  : in     Natural := Default_Timeout_MS;
      Verbose  : in     Boolean := False;
      Success  :    out Boolean)
   is
      Current : Word32;
      Timeout : Time.T;
      Timed_Out : Boolean := False;
   begin
      pragma Debug (Debug.Put (GNAT.Source_Info.Enclosing_Entity & ":  "));
      pragma Debug (Debug.Put_Word32 (Value));
      pragma Debug (Debug.Put (" <- "));
      pragma Debug (Debug.Put_Word32 (Mask));
      pragma Debug (Debug.Put (" & "));
      pragma Debug (Debug.Put_Word32 (Register'Enum_Rep * Register_Width));
      pragma Debug (Debug.Put (":"));
      pragma Debug (Debug.Put_Line (Registers_Index'Image (Register)));

      Timeout := Time.MS_From_Now (TOut_MS);
      loop
         Read (Register, Current, Verbose);
         if (Current and Mask) = Value then
            -- Ignore timeout if we succeeded anyway.
            Timed_Out := False;
            exit;
         end if;
         pragma Debug (Timed_Out, Debug.Put (GNAT.Source_Info.Enclosing_Entity));
         pragma Debug (Timed_Out, Debug.Put_Line (": Timed Out!"));
         exit when Timed_Out;

         Timed_Out := Time.Timed_Out (Timeout);
      end loop;

      Success := not Timed_Out;
   end Wait;

   procedure Wait
     (Register : Registers_Index;
      Mask     : Word32;
      Value    : Word32;
      TOut_MS  : Natural := Default_Timeout_MS;
      Verbose  : Boolean := False)
   is
      Ignored_Success : Boolean;
   begin
      Wait (Register, Mask, Value, TOut_MS, Verbose, Ignored_Success);
   end Wait;

   ----------------------------------------------------------------------------

   -- Wait for all bits in @Register@ indicated by @Mask@ to be set
   procedure Wait_Set_Mask
     (Register : in     Registers_Index;
      Mask     : in     Word32;
      TOut_MS  : in     Natural := Default_Timeout_MS;
      Verbose  : in     Boolean := False;
      Success  :    out Boolean) is
   begin
      Wait (Register, Mask, Mask, TOut_MS, Verbose, Success);
   end Wait_Set_Mask;

   procedure Wait_Set_Mask
     (Register : Registers_Index;
      Mask     : Word32;
      TOut_MS  : Natural := Default_Timeout_MS;
      Verbose  : Boolean := False)
   is
      Ignored_Success : Boolean;
   begin
      Wait (Register, Mask, Mask, TOut_MS, Verbose, Ignored_Success);
   end Wait_Set_Mask;

   ----------------------------------------------------------------------------

   -- Wait for bits in @Register@ indicated by @Mask@ to be clear
   procedure Wait_Unset_Mask
     (Register   : in     Registers_Index;
      Mask       : in     Word32;
      TOut_MS    : in     Natural := Default_Timeout_MS;
      Verbose    : in     Boolean := False;
      Success    :    out Boolean) is
   begin
      Wait (Register, Mask, 0, TOut_MS, Verbose, Success);
   end;

   procedure Wait_Unset_Mask
     (Register : Registers_Index;
      Mask     : Word32;
      TOut_MS  : Natural := Default_Timeout_MS;
      Verbose  : Boolean := False)
   is
      Ignored_Success : Boolean;
   begin
      Wait (Register, Mask, 0, TOut_MS, Verbose, Ignored_Success);
   end Wait_Unset_Mask;

   ----------------------------------------------------------------------------

   -- Set bits from @Mask@ in @Register@
   procedure Set_Mask
      (Register : Registers_Index;
       Mask     : Word32)
   is
      Value : Word32;
   begin
      pragma Debug (Debug.Put (GNAT.Source_Info.Enclosing_Entity & ": "));
      pragma Debug (Debug.Put_Word32 (Mask));
      pragma Debug (Debug.Put (" .S "));
      pragma Debug (Debug.Put_Line (Registers_Index'Image (Register)));

      Read (Register, Value);
      Value := Value or Mask;
      Write (Register, Value);
   end Set_Mask;

   ----------------------------------------------------------------------------

   -- Mask out @Mask@ in @Register@
   procedure Unset_Mask
      (Register : Registers_Index;
       Mask     : Word32)
   is
      Value : Word32;
   begin
      pragma Debug (Debug.Put (GNAT.Source_Info.Enclosing_Entity & ": "));
      pragma Debug (Debug.Put_Word32 (Mask));
      pragma Debug (Debug.Put (" !S "));
      pragma Debug (Debug.Put_Line (Registers_Index'Image (Register)));

      Read (Register, Value);
      Value := Value and not Mask;
      Write (Register, Value);
   end Unset_Mask;

   ----------------------------------------------------------------------------

   -- Mask out @Unset_Mask@ and set @Set_Mask@ in @Register@
   procedure Unset_And_Set_Mask
      (Register   : Registers_Index;
       Mask_Unset : Word32;
       Mask_Set   : Word32)
   is
      Value : Word32;
   begin
      pragma Debug (Debug.Put (GNAT.Source_Info.Enclosing_Entity & ": "));
      pragma Debug (Debug.Put_Line (Registers_Index'Image (Register)));

      Read (Register, Value);
      Value := (Value and not Mask_Unset) or Mask_Set;
      Write (Register, Value);
   end Unset_And_Set_Mask;

   ----------------------------------------------------------------------------

   procedure Set_Register_Base (Base : Word64; GTT_Base : Word64 := 0)
   is
   begin
      Regs.Set_Base_Address (Base);
      if GTT_Base = 0 then
         GTT_32.Set_Base_Address
           (Base + Word64 (Config.Default_MMIO_GTT_32_Offset));
         GTT_64.Set_Base_Address (Base + Word64 (Config.MMIO_GTT_64_Offset));
      else
         GTT_32.Set_Base_Address (GTT_Base);
         GTT_64.Set_Base_Address (GTT_Base);
      end if;
   end Set_Register_Base;

end HW.GFX.GMA.Registers;
