blob: bc1dfef69b8a5a21fd49cacf7522de12453116a9 [file] [log] [blame]
Nico Huber312433c2019-09-28 03:15:48 +02001--
2-- Copyright (C) 2014-2016, 2019 secunet Security Networks AG
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 GNAT.Source_Info;
16
17with HW.Debug;
18with HW.GFX.GMA.Registers;
19
20use HW.GFX.GMA.Registers;
21
22package body HW.GFX.GMA.PCode is
23
24 GT_MAILBOX_READY : constant := 1 * 2 ** 31;
25
26 -- Send a command and optionally wait for and return the reply.
27 procedure Mailbox_Write_Read
28 (MBox : in Word32;
29 Command : in Word64;
30 Reply : out Word64;
31 Wait_Ready : in Boolean := False;
32 Wait_Ack : in Boolean := True;
33 Success : out Boolean)
34 with
35 Pre => Mailbox_Ready or Wait_Ready,
36 Post => (if Wait_Ack and Success then Mailbox_Ready)
37 is
38 use type HW.Word64;
39
40 Data : Word32;
41 begin
42 pragma Debug (Debug.Put_Line (GNAT.Source_Info.Enclosing_Entity));
43
44 Reply := 0;
45 Success := True;
46
47 if Wait_Ready then
48 Wait_Unset_Mask (GT_MAILBOX, GT_MAILBOX_READY, Success => Success);
49 if not Success then
50 return;
51 end if;
52 end if;
53
54 Write (GT_MAILBOX_DATA, Word32 (Command and 16#ffff_ffff#));
55 Write (GT_MAILBOX_DATA_1, Word32 (Shift_Right (Command, 32)));
56 Write (GT_MAILBOX, GT_MAILBOX_READY or MBox);
57 Mailbox_Ready := False;
58
59 if Wait_Ack then
60 Wait_Unset_Mask (GT_MAILBOX, GT_MAILBOX_READY, Success => Success);
61 Mailbox_Ready := Success;
62
63 Read (GT_MAILBOX_DATA, Data);
64 Reply := Word64 (Data);
65 Read (GT_MAILBOX_DATA_1, Data);
66 Reply := Shift_Left (Word64 (Data), 32) or Reply;
67
68 Write (GT_MAILBOX_DATA, 0);
69 Write (GT_MAILBOX_DATA_1, 0);
70 end if;
71 end Mailbox_Write_Read;
72
73 procedure Mailbox_Write
74 (MBox : in Word32;
75 Command : in Word64;
76 Wait_Ready : in Boolean := False;
77 Wait_Ack : in Boolean := True;
78 Success : out Boolean)
79 is
80 pragma Warnings (GNATprove, Off, "unused assignment to ""Ignored_R""");
81 Ignored_R : Word64;
82 begin
83 Mailbox_Write_Read
84 (MBox, Command, Ignored_R, Wait_Ready, Wait_Ack, Success);
85 end Mailbox_Write;
86
Tim Wawrzynczak79a53792022-09-09 10:24:35 -060087 procedure Mailbox_Read
88 (MBox : in Word32;
89 Command : in Word64 := 0;
90 Wait_Ready : in Boolean := False;
91 Reply : out Word64;
92 Success : out Boolean)
93 is
94 begin
95 Mailbox_Write_Read (MBox, Command, Reply, Wait_Ready, True, Success);
96 end Mailbox_Read;
97
Nico Huber312433c2019-09-28 03:15:48 +020098 procedure Mailbox_Request
99 (MBox : in Word32;
100 Command : in Word64;
101 Reply_Mask : in Word64;
102 Reply : in Word64 := 16#ffff_ffff_ffff_ffff#;
103 TOut_MS : in Natural := Registers.Default_Timeout_MS;
104 Wait_Ready : in Boolean := False;
105 Success : out Boolean)
106 is
107 use type HW.Word64;
108
109 Timeout : constant Time.T := Time.MS_From_Now (TOut_MS);
110 Timed_Out : Boolean := False;
111
112 Received_Reply : Word64;
113 begin
114 Success := False;
115 loop
116 pragma Loop_Invariant ((not Success and Wait_Ready) or Mailbox_Ready);
117 Mailbox_Write_Read
118 (MBox => MBox,
119 Command => Command,
120 Reply => Received_Reply,
121 Wait_Ready => not Success and Wait_Ready,
122 Success => Success);
123 exit when not Success;
124
125 if (Received_Reply and Reply_Mask) = (Reply and Reply_Mask) then
126 -- Ignore timeout if we succeeded anyway.
127 Timed_Out := False;
128 exit;
129 end if;
130 exit when Timed_Out;
131
132 Timed_Out := Time.Timed_Out (Timeout);
133 end loop;
134
135 Success := Success and then not Timed_Out;
136 end Mailbox_Request;
137
138 procedure Mailbox_Write
139 (MBox : Word32;
140 Command : Word64;
141 Wait_Ready : Boolean := False)
142 is
143 pragma Warnings (GNATprove, Off, "unused assignment to ""Ignored_S""");
144 Ignored_S : Boolean;
145 begin
146 Mailbox_Write (MBox, Command, Wait_Ready, False, Ignored_S);
147 end Mailbox_Write;
148
149end HW.GFX.GMA.PCode;