pci direct: Allow a preset MMConf address per `Dev` instance

In virtualized environments (e.g. PCI pass-through),  it's possible
that the MMConf/ECAM space might not be fully mapped into the guest,
so allow to override it per device.

Change-Id: I2447cec8e413e746f492c0e32126b34a7bfb2195
Signed-off-by: Nico Huber <nico.huber@secunet.com>
Reviewed-on: https://review.sourcearcade.org/c/libhwbase/+/550
Tested-by: Ada SPARK <gnatbot@sourcearcade.org>
Reviewed-by: Thomas Heijligen <src@posteo.de>
diff --git a/common/direct/hw-pci-dev.adb b/common/direct/hw-pci-dev.adb
index 8a1a56b..903dde1 100644
--- a/common/direct/hw-pci-dev.adb
+++ b/common/direct/hw-pci-dev.adb
@@ -25,7 +25,7 @@
       PCI_State      => MM.PCI_State)
 is
 
-   package MM is new HW.PCI.MMConf (Dev);
+   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;
@@ -103,7 +103,9 @@
       Write16 (PCI.Command, Cmd);
    end Resource_Size;
 
-   procedure Initialize (Success : out Boolean; MMConf_Base : Word64 := 0)
+   procedure Initialize
+     (Success     :    out Boolean;
+      MMConf_Base : in     Word64 := PCI.Dev.MMConf_Base)
    is
    begin
       if MMConf_Base /= 0 then
diff --git a/common/hw-pci-dev.ads b/common/hw-pci-dev.ads
index 5b20aa1..130515c 100644
--- a/common/hw-pci-dev.ads
+++ b/common/hw-pci-dev.ads
@@ -14,6 +14,7 @@
 
 generic
    Dev : PCI.Address := (0, 0, 0);
+   MMConf_Base : Word64 := 0;
 package HW.PCI.Dev
 with
    Abstract_State => (Address_State, (PCI_State with External)),
@@ -50,7 +51,9 @@
 
    pragma Warnings (GNATprove, Off, "unused variable ""MMConf_Base""*",
                     Reason => "Used for a common interface");
-   procedure Initialize (Success : out Boolean; MMConf_Base : Word64 := 0);
+   procedure Initialize
+     (Success     :    out Boolean;
+      MMConf_Base : in     Word64 := PCI.Dev.MMConf_Base);
    pragma Warnings (GNATprove, On, "unused variable ""MMConf_Base""*");
 
 end HW.PCI.Dev;
diff --git a/common/hw-pci-mmconf.adb b/common/hw-pci-mmconf.adb
index 180f2d7..f7da219 100644
--- a/common/hw-pci-mmconf.adb
+++ b/common/hw-pci-mmconf.adb
@@ -12,8 +12,6 @@
 -- GNU General Public License for more details.
 --
 
-with HW.Config;
-
 package body HW.PCI.MMConf
 with
    Refined_State =>
@@ -24,7 +22,7 @@
 is
 
    Default_Base_Address : constant Word64 :=
-      Calc_Base_Address (Config.Default_MMConf_Base, Dev);
+      Calc_Base_Address (MMConf_Base, Dev);
 
    type Index16 is new Index range 0 .. Index'Last / 2;
    type Index32 is new Index range 0 .. Index'Last / 4;
diff --git a/common/hw-pci-mmconf.ads b/common/hw-pci-mmconf.ads
index 597ebfa..7a3777d 100644
--- a/common/hw-pci-mmconf.ads
+++ b/common/hw-pci-mmconf.ads
@@ -13,12 +13,14 @@
 --
 
 with System;
+with HW.Config;
 with HW.MMIO_Range;
 
 pragma Elaborate_All (HW.MMIO_Range);
 
 generic
    Dev : Address := (0, 0, 0);
+   MMConf_Base : Word64 := Config.Default_MMConf_Base;
 package HW.PCI.MMConf
 with
    Abstract_State => (Address_State, (PCI_State with External)),
diff --git a/common/linux/hw-pci-dev.adb b/common/linux/hw-pci-dev.adb
index 0017abf..841bbf9 100644
--- a/common/linux/hw-pci-dev.adb
+++ b/common/linux/hw-pci-dev.adb
@@ -142,7 +142,7 @@
       File.Size (Length, Path);
    end Resource_Size;
 
-   procedure Initialize (Success : out Boolean; MMConf_Base : Word64 := 0)
+   procedure Initialize (Success : out Boolean; MMConf_Base : Word64 := PCI.Dev.MMConf_Base)
    is
       Addr  : Word64;
       Path  : String (1 .. 43) := "/sys/devices/pci0000:xx/0000:xx:xx.x/config";