63f15c2605c8306a1447354824cb8e4436fbf3b4
[libxhcidbg.git] / src / hw-dbc-trbs.adb
1 --
2 -- Copyright (C) 2016-2017 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
15 with HW.DbC;
16 with HW.Debug;
17
18 use type HW.Bit;
19 use type HW.Word32;
20
21 package body HW.DbC.TRBs
22 is
23
24    Debug_Error_Codes : constant Boolean := False;
25
26    function CC_To_Usb_Error (CC : Completion_Code) return Error
27    is
28       use type HW.DbC.Error;
29       Err : Error;
30    begin
31       case CC is
32       when Success                     => Err := DbC.Success;
33       when Data_Buffer_Error           => Err := DbC.Communication_Error;
34       when Babble_Detected_Error       => Err := DbC.Communication_Error;
35       when USB_Transaction_Error       => Err := DbC.Communication_Error;
36       when TRB_Error                   => Err := DbC.Driver_Error;
37       when Stall_Error                 => Err := DbC.Stall_Error;
38       when Short_Packet                => Err := DbC.Data_Residue;
39       when Bandwidth_Error             => Err := DbC.Not_Enough_Bandwidth;
40       when Command_Aborted             => Err := DbC.Timeout;
41       when Secondary_Bandwidth_Error   => Err := DbC.Not_Enough_Bandwidth;
42       when Split_Transaction_Error     => Err := DbC.Communication_Error;
43       when others                      => Err := DbC.Unknown_Error;
44          pragma Debug (Debug.Put_Reg8 ("Unknown_Error", Word8 (CC)));
45       end case;
46       pragma Debug
47         (Debug_Error_Codes and Err /= DbC.Success and Err /= DbC.Unknown_Error,
48          Debug.Put_Reg8 ("Completion code", Word8 (CC)));
49       return Err;
50    end CC_To_Usb_Error;
51
52    ----------------------------------------------------------------------------
53
54    procedure Set_Length (Data : in out T; Length : in Natural)
55    is
56       Status : constant Word32 := Data.Status;
57    begin
58       Data.Status := (Status and not 16#1_ffff#) or
59         (Word32 (Length) and 16#1_ffff#);
60    end Set_Length;
61
62    function Get_Event_Length (Data : T) return Natural
63    is
64       Status : constant Word32 := Data.Status;
65    begin
66       return Natural (Status and 16#ff_ffff#);
67    end Get_Event_Length;
68
69    ----------------------------------------------------------------------------
70
71    function Get_Completion_Code (Data : T) return Completion_Code
72    is
73       Status : constant Word32 := Data.Status;
74    begin
75       return Completion_Code (Shift_Right (Status, 24));
76    end Get_Completion_Code;
77
78    ----------------------------------------------------------------------------
79
80    procedure Set_Cycle (Data : in out T; Cycle : in Bit)
81    is
82       Control : constant Word32 := Data.Control;
83    begin
84       Data.Control := (Control and not 1) or Word32 (Cycle);
85    end Set_Cycle;
86
87    function Get_Cycle (Data : T) return Bit
88    is
89       Control : constant Word32 := Data.Control;
90    begin
91       return Bit (Control and 1);
92    end Get_Cycle;
93
94    procedure Set_Toggle_Cycle (Data : in out T)
95    is
96       Control : constant Word32 := Data.Control;
97    begin
98       Data.Control := Control or 16#00_02#;
99    end Set_Toggle_Cycle;
100
101    procedure Set_ISP (Data : in out T)
102    is
103       Control : constant Word32 := Data.Control;
104    begin
105       Data.Control := Control or 16#00_04#;
106    end Set_ISP;
107
108    procedure Set_IOC (Data : in out T)
109    is
110       Control : constant Word32 := Data.Control;
111    begin
112       Data.Control := Control or 16#00_20#;
113    end Set_IOC;
114
115    ----------------------------------------------------------------------------
116
117    procedure Set_Type (Data : in out T; TRB_Type : in TRB_Types)
118    is
119       Control : constant Word32 := Data.Control;
120    begin
121       Data.Control := (Control and not 16#fc00#) or
122         Shift_Left (Word32 (TRB_Type), 10);
123    end Set_Type;
124
125    function Get_Type (Data : T) return TRB_Types
126    is
127       Control : constant Word32 := Data.Control;
128    begin
129       return TRB_Types (Shift_Right (Control, 10) and 63);
130    end Get_Type;
131
132    ----------------------------------------------------------------------------
133
134    function Get_Endpoint_ID (Data : T) return Natural
135    is
136       Control : constant Word32 := Data.Control;
137    begin
138       return Natural (Shift_Right (Control, 16) and 16#1f#);
139    end Get_Endpoint_ID;
140
141    function Get_Slot_ID (Data : T) return Word8
142    is
143       Control : constant Word32 := Data.Control;
144    begin
145       return Word8 (Shift_Right (Control, 24));
146    end Get_Slot_ID;
147
148    ----------------------------------------------------------------------------
149
150    procedure Set_Parameter (Data : in out T; Parameter : Word64)
151    is
152    begin
153       Data.Parameter := Parameter;
154    end Set_Parameter;
155
156    function Get_Parameter (Data : T) return Word64
157    is
158       Result : constant Word64 := Data.Parameter;
159    begin
160       return Result;
161    end Get_Parameter;
162
163    ----------------------------------------------------------------------------
164
165    procedure Clear (TR : out T; PCS : in Bit)
166    is
167    begin
168       TR := T'
169         (Parameter => 0, Status => 0, Control => Word32 ((not PCS) and 1));
170    end Clear;
171
172    procedure Clear_Ring (TR : out Transfer_Ring; PCS : in Bit)
173    is
174    begin
175       TR := Transfer_Ring'
176         (Ring_Range => T'
177            (Parameter => 0, Status => 0, Control => Word32 ((not PCS) and 1)));
178    end Clear_Ring;
179
180    procedure Init_Cycle_Ring
181      (Ring     :    out Transfer_Ring;
182       Physical : in     Word64)
183    is
184    begin
185       Clear_Ring (Ring, 1);
186
187       declare
188          Last : constant Ring_Range := Ring'Last;
189       begin
190
191          -- Link last T in the ring to the first.
192
193          Set_Type (Ring (Last), Link);
194          Set_Toggle_Cycle (Ring (Last));
195          Ring (Last).Parameter := Physical;
196       end;
197    end Init_Cycle_Ring;
198
199 end HW.DbC.TRBs;
200
201 --  vim: set ts=8 sts=3 sw=3 et: