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