blob: 60968e1cd3eaeca38ee04065087ff14b404812cf [file] [log] [blame]
Nico Huber5e9b1b52016-10-08 22:09:33 +02001--
2-- Copyright (C) 2015 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
Nico Huberaab715f2016-10-18 00:22:25 +02006-- the Free Software Foundation; either version 2 of the License, or
7-- (at your option) any later version.
Nico Huber5e9b1b52016-10-08 22:09:33 +02008--
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;
16with HW.Time;
17with HW.Debug_Sink;
18
19use type HW.Word64;
20use type HW.Int64;
21
22package body HW.Debug
23with
24 SPARK_Mode => Off
25is
26
27 Start_Of_Line : Boolean := True;
28 Register_Write_Delay_Nanoseconds : Word64 := 0;
29
30 type Base_Range is new Positive range 2 .. 16;
31 type Width_Range is new Natural range 0 .. 64;
32
33 procedure Put_By_Base
34 (Item : Word64;
35 Min_Width : Width_Range;
36 Base : Base_Range);
37
38 procedure Do_Put_Int64
39 (Item : Int64);
40
41 ----------------------------------------------------------------------------
42
43 procedure Put_Time
44 is
45 Now_US : Int64;
46 begin
47 if Start_Of_Line then
48 Start_Of_Line := False;
49 Now_US := Time.Now_US;
50 Debug_Sink.Put_Char ('[');
51 Do_Put_Int64 ((Now_US / 1_000_000) mod 1_000_000);
52 Debug_Sink.Put_Char ('.');
53 Put_By_Base (Word64 (Now_US mod 1_000_000), 6, 10);
54 Debug_Sink.Put ("] ");
55 end if;
56 end Put_Time;
57
58 ----------------------------------------------------------------------------
59
60 procedure Put (Item : String) is
61 begin
62 Put_Time;
63 HW.Debug_Sink.Put (Item);
64 end Put;
65
66 procedure Put_Line (Item : String) is
67 begin
68 Put (Item);
69 New_Line;
70 end Put_Line;
71
72 procedure New_Line is
73 begin
74 HW.Debug_Sink.New_Line;
75 Start_Of_Line := True;
76 end New_Line;
77
78 ----------------------------------------------------------------------------
79
80 procedure Put_By_Base
81 (Item : Word64;
82 Min_Width : Width_Range;
83 Base : Base_Range)
84 is
85 Temp : Word64 := Item;
86
87 subtype Chars_Range is Width_Range range 0 .. 63;
88 Index : Width_Range := 0;
89
90 type Chars_Array is array (Chars_Range) of Character;
91 Chars : Chars_Array := (others => '0');
92
93 Digit : Natural;
94 begin
95 while Temp > 0 loop
96 Digit := Natural (Temp rem Word64 (Base));
97 if Digit < 10 then
98 Chars (Index) := Character'Val (Character'Pos ('0') + Digit);
99 else
100 Chars (Index) := Character'Val (Character'Pos ('a') + Digit - 10);
101 end if;
102 Temp := Temp / Word64 (Base);
103 Index := Index + 1;
104 end loop;
105 if Index < Min_Width then
106 Index := Min_Width;
107 end if;
108 for I in reverse Width_Range range 0 .. Index - 1 loop
109 HW.Debug_Sink.Put_Char (Chars (I));
110 end loop;
111 end Put_By_Base;
112
113 ----------------------------------------------------------------------------
114
115 procedure Put_Word
116 (Item : Word64;
117 Min_Width : Width_Range;
118 Print_Ox : Boolean := True) is
119 begin
120 Put_Time;
121 if Print_Ox then
122 Put ("0x");
123 end if;
124 Put_By_Base (Item, Min_Width, 16);
125 end Put_Word;
126
127 procedure Put_Word8 (Item : Word8) is
128 begin
129 Put_Word (Word64 (Item), 2);
130 end Put_Word8;
131
132 procedure Put_Word16 (Item : Word16) is
133 begin
134 Put_Word (Word64 (Item), 4);
135 end Put_Word16;
136
137 procedure Put_Word32 (Item : Word32) is
138 begin
139 Put_Word (Word64 (Item), 8);
140 end Put_Word32;
141
142 procedure Put_Word64 (Item : Word64) is
143 begin
144 Put_Word (Item, 16);
145 end Put_Word64;
146
147 ----------------------------------------------------------------------------
148
149 procedure Do_Put_Int64 (Item : Int64)
150 is
151 Temp : Word64;
152 begin
153 if Item < 0 then
154 Debug_Sink.Put_Char ('-');
155 Temp := Word64 (-Item);
156 else
157 Temp := Word64 (Item);
158 end if;
159 Put_By_Base (Temp, 1, 10);
160 end Do_Put_Int64;
161
162 procedure Put_Int64 (Item : Int64)
163 is
164 begin
165 Put_Time;
166 Do_Put_Int64 (Item);
167 end Put_Int64;
168
169 procedure Put_Int8 (Item : Int8) is
170 begin
171 Put_Int64 (Int64 (Item));
172 end Put_Int8;
173
174 procedure Put_Int16 (Item : Int16) is
175 begin
176 Put_Int64 (Int64 (Item));
177 end Put_Int16;
178
179 procedure Put_Int32 (Item : Int32) is
180 begin
181 Put_Int64 (Int64 (Item));
182 end Put_Int32;
183
184 ----------------------------------------------------------------------------
185
186 procedure Put_Reg8 (Name : String; Item : Word8) is
187 begin
188 Put (Name);
189 Put (": ");
190 Put_Word8 (Item);
191 New_Line;
192 end Put_Reg8;
193
194 procedure Put_Reg16 (Name : String; Item : Word16)
195 is
196 begin
197 Put (Name);
198 Put (": ");
199 Put_Word16 (Item);
200 New_Line;
201 end Put_Reg16;
202
203 procedure Put_Reg32 (Name : String; Item : Word32)
204 is
205 begin
206 Put (Name);
207 Put (": ");
208 Put_Word32 (Item);
209 New_Line;
210 end Put_Reg32;
211
212 procedure Put_Reg64 (Name : String; Item : Word64)
213 is
214 begin
215 Put (Name);
216 Put (": ");
217 Put_Word64 (Item);
218 New_Line;
219 end Put_Reg64;
220
221 ----------------------------------------------------------------------------
222
223 procedure Put_Buffer
224 (Name : String;
225 Buf : Buffer;
226 Len : Buffer_Range)
227 is
228 Line_Start, Left : Natural;
229 begin
230 if Len = 0 then
231 if Name'Length > 0 then
232 Put (Name);
233 Put_Line ("+0x00:");
234 end if;
235 else
236 Line_Start := 0;
237 Left := Len - 1;
238 for I in Natural range 1 .. ((Len + 15) / 16) loop
239 if Name'Length > 0 then
240 Put (Name);
241 Debug_Sink.Put_Char ('+');
242 Put_Word16 (Word16 (Line_Start));
243 Put (": ");
244 end if;
245 for J in Natural range 0 .. Natural'Min (7, Left)
246 loop
247 Put_Word (Word64 (Buf (Line_Start + J)), 2, False);
248 Debug_Sink.Put_Char (' ');
249 end loop;
250
251 Debug_Sink.Put_Char (' ');
252 for J in Natural range 8 .. Natural'Min (15, Left)
253 loop
254 Put_Word (Word64(Buf (Line_Start + J)), 2, False);
255 Debug_Sink.Put_Char (' ');
256 end loop;
257 New_Line;
258
259 Line_Start := Line_Start + 16;
260 Left := Left - Natural'Min (Left, 16);
261 end loop;
262 end if;
263 end Put_Buffer;
264
265 ----------------------------------------------------------------------------
266
267 procedure Set_Register_Write_Delay (Value : Word64)
268 is
269 begin
270 Register_Write_Delay_Nanoseconds := Value;
271 end Set_Register_Write_Delay;
272
273 ----------------------------------------------------------------------------
274
275 Procedure Register_Write_Wait
276 is
277 begin
278 if Register_Write_Delay_Nanoseconds > 0 then
279 Time.U_Delay (Natural ((Register_Write_Delay_Nanoseconds + 999) / 1000));
280 end if;
281 end Register_Write_Wait;
282
283end HW.Debug;
284
285-- vim: set ts=8 sts=3 sw=3 et: