--
-- Copyright (C) 2017 Nico Huber <nico.h@gmx.de>
--
-- 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.Config;
with HW.PCI.MMConf;

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

package body HW.PCI.Dev
with
   Refined_State =>
     (Address_State  => MM.Address_State,
      PCI_State      => MM.PCI_State)
is

   package MM is new HW.PCI.MMConf (Dev, MMConf_Base);

   procedure Read8 (Value : out Word8; Offset : Index) renames MM.Read8;
   procedure Read16 (Value : out Word16; Offset : Index) renames MM.Read16;
   procedure Read32 (Value : out Word32; Offset : Index) renames MM.Read32;

   procedure Write8 (Offset : Index; Value : Word8) renames MM.Write8;
   procedure Write16 (Offset : Index; Value : Word16) renames MM.Write16;
   procedure Write32 (Offset : Index; Value : Word32) renames MM.Write32;

   procedure Map
     (Addr     :    out Word64;
      Res      : in     Resource;
      Length   : in     Natural := 0;
      Offset   : in     Natural := 0;
      WC       : in     Boolean := False)
   is
      use type HW.Word8;
      use type HW.Word32;

      Header_Type : Word8;
      Reg32       : Word32;
   begin
      Addr := 0;
      Read8 (Header_Type, PCI.Header_Type);
      if (Header_Type and Header_Type_Mask) = Header_Type_Normal then
         Read32 (Reg32, Base_Address (Res));
         if (Reg32 and Base_Address_Space_Mask) = Base_Address_Space_Mem then
            case Reg32 and Base_Address_Mem_Type_Mask is
               when Base_Address_Mem_Type_64 =>
                  if Res < Res5 then
                     Addr := Word64 (Reg32 and Base_Address_Mem_Mask);
                     Read32 (Reg32, Base_Address (Resource'Succ (Res)));
                     Addr := Addr or Shift_Left (Word64 (Reg32), 32);
                  end if;
               when others =>
                  Addr := Word64 (Reg32 and Base_Address_Mem_Mask);
            end case;
         end if;
      end if;
      if Addr /= 0 then
         if Length = 0 or else
            Addr <= Word64'Last - Word64 (Length) - Word64 (Offset) + 1
         then
            Addr := Addr + Word64 (Offset);
         else
            Addr := 0;
         end if;
      end if;
   end Map;

   procedure Resource_Size (Length : out Natural; Res : Resource)
   is
      use type HW.Word16;
      use type HW.Word32;

      Cmd : Word16;
      Base, Backup : Word32;
   begin
      Length := 0;

      Read16 (Cmd, PCI.Command);
      Write16 (PCI.Command, Cmd and not PCI.Command_Memory);

      Read32 (Backup, Base_Address (Res));
      if (Backup and Base_Address_Space_Mask) = Base_Address_Space_Mem then
         Write32 (Base_Address (Res), 16#ffff_ffff#);
         Read32 (Base, Base_Address (Res));
         Base := not (Base and Base_Address_Mem_Mask) + 1;
         if Base <= Word32 (Natural'Last) then
            Length := Natural (Base);
         end if;
         Write32 (Base_Address (Res), Backup);
      end if;

      Write16 (PCI.Command, Cmd);
   end Resource_Size;

   procedure Initialize
     (Success     :    out Boolean;
      MMConf_Base : in     Word64 := PCI.Dev.MMConf_Base)
   is
   begin
      if MMConf_Base /= 0 then
         MM.Set_Base_Address (MMConf_Base);
      else
         MM.Set_Base_Address (Config.Default_MMConf_Base);
      end if;
      Success := MMConf_Base /= 0 or Config.Default_MMConf_Base_Set;
   end Initialize;

end HW.PCI.Dev;
