blob: 8a1a56bb961ee54aebcf38f45073e1e2c4b651b5 [file] [log] [blame]
Nico Huberae9b8552017-07-09 15:25:41 +02001--
2-- Copyright (C) 2017 Nico Huber <nico.h@gmx.de>
3--
4-- This program is free software; you can redistribute it and/or modify
5-- it under the terms of the GNU General Public License as published by
6-- the Free Software Foundation; either version 2 of the License, or
7-- (at your option) any later version.
8--
9-- This program is distributed in the hope that it will be useful,
10-- but WITHOUT ANY WARRANTY; without even the implied warranty of
11-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12-- GNU General Public License for more details.
13--
14
15with HW.Config;
16with HW.PCI.MMConf;
17
18with HW.MMIO_Range;
19pragma Elaborate_All (HW.MMIO_Range);
20
21package body HW.PCI.Dev
22with
23 Refined_State =>
24 (Address_State => MM.Address_State,
25 PCI_State => MM.PCI_State)
26is
27
28 package MM is new HW.PCI.MMConf (Dev);
29
30 procedure Read8 (Value : out Word8; Offset : Index) renames MM.Read8;
31 procedure Read16 (Value : out Word16; Offset : Index) renames MM.Read16;
32 procedure Read32 (Value : out Word32; Offset : Index) renames MM.Read32;
33
34 procedure Write8 (Offset : Index; Value : Word8) renames MM.Write8;
35 procedure Write16 (Offset : Index; Value : Word16) renames MM.Write16;
36 procedure Write32 (Offset : Index; Value : Word32) renames MM.Write32;
37
38 procedure Map
39 (Addr : out Word64;
40 Res : in Resource;
41 Length : in Natural := 0;
42 Offset : in Natural := 0;
43 WC : in Boolean := False)
44 is
45 use type HW.Word8;
46 use type HW.Word32;
47
48 Header_Type : Word8;
49 Reg32 : Word32;
50 begin
51 Addr := 0;
52 Read8 (Header_Type, PCI.Header_Type);
53 if (Header_Type and Header_Type_Mask) = Header_Type_Normal then
54 Read32 (Reg32, Base_Address (Res));
55 if (Reg32 and Base_Address_Space_Mask) = Base_Address_Space_Mem then
56 case Reg32 and Base_Address_Mem_Type_Mask is
57 when Base_Address_Mem_Type_64 =>
58 if Res < Res5 then
59 Addr := Word64 (Reg32 and Base_Address_Mem_Mask);
60 Read32 (Reg32, Base_Address (Resource'Succ (Res)));
61 Addr := Addr or Shift_Left (Word64 (Reg32), 32);
62 end if;
63 when others =>
64 Addr := Word64 (Reg32 and Base_Address_Mem_Mask);
65 end case;
66 end if;
67 end if;
68 if Addr /= 0 then
69 if Length = 0 or else
70 Addr <= Word64'Last - Word64 (Length) - Word64 (Offset) + 1
71 then
72 Addr := Addr + Word64 (Offset);
73 else
74 Addr := 0;
75 end if;
76 end if;
77 end Map;
78
79 procedure Resource_Size (Length : out Natural; Res : Resource)
80 is
Nico Huber455ed642018-05-18 15:21:23 +020081 use type HW.Word16;
82 use type HW.Word32;
Nico Huberae9b8552017-07-09 15:25:41 +020083
84 Cmd : Word16;
85 Base, Backup : Word32;
86 begin
87 Length := 0;
88
89 Read16 (Cmd, PCI.Command);
90 Write16 (PCI.Command, Cmd and not PCI.Command_Memory);
91
92 Read32 (Backup, Base_Address (Res));
93 if (Backup and Base_Address_Space_Mask) = Base_Address_Space_Mem then
94 Write32 (Base_Address (Res), 16#ffff_ffff#);
95 Read32 (Base, Base_Address (Res));
96 Base := not (Base and Base_Address_Mem_Mask) + 1;
97 if Base <= Word32 (Natural'Last) then
98 Length := Natural (Base);
99 end if;
100 Write32 (Base_Address (Res), Backup);
101 end if;
102
103 Write16 (PCI.Command, Cmd);
104 end Resource_Size;
105
106 procedure Initialize (Success : out Boolean; MMConf_Base : Word64 := 0)
107 is
108 begin
109 if MMConf_Base /= 0 then
110 MM.Set_Base_Address (MMConf_Base);
Nico Hubere05bf872017-08-25 20:02:19 +0200111 else
112 MM.Set_Base_Address (Config.Default_MMConf_Base);
Nico Huberae9b8552017-07-09 15:25:41 +0200113 end if;
114 Success := MMConf_Base /= 0 or Config.Default_MMConf_Base_Set;
115 end Initialize;
116
117end HW.PCI.Dev;