Initialize all HW.DbC.State
[libxhcidbg.git] / src / hw-dbc.ads
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.Sub_Regs;
16 with HW.MMIO_Regs;
17 pragma Elaborate_All (HW.MMIO_Regs);
18 with HW.MMIO_Range;
19 pragma Elaborate_All (HW.MMIO_Range);
20 with HW.DbC_Config;
21
22 package HW.DbC
23 with
24    Abstract_State => (State, (DMA with External)),
25    Initializes    => State
26 is
27
28    procedure Init;
29
30    procedure Poll (Now : Boolean := False);
31
32    procedure Receive
33      (Buf : in out Buffer;
34       Len : in out Natural)
35    with
36       Post => Len <= Len'Old;
37
38    procedure Send
39      (Buf      : in     Buffer;
40       Len      : in out Natural;
41       Success  :    out Boolean)
42    with
43       Post => Len <= Len'Old;
44
45    ----------------------------------------------------------------------------
46
47 private
48
49    type Word2  is mod 2 **  2;
50    type Word3  is mod 2 **  3;
51    type Word4  is mod 2 **  4;
52    type Word5  is mod 2 **  5;
53    type Word10 is mod 2 ** 10;
54    type Word19 is mod 2 ** 19;
55    type Word20 is mod 2 ** 20;
56    type Word28 is mod 2 ** 28;
57
58    type Error is (
59       Success,
60       Communication_Error,
61       Driver_Error,
62       Stall_Error,
63       Data_Residue,
64       Bad_Descriptor,
65       Not_Enough_Bandwidth,
66       Unsupported_Size,
67       Unsupported_Count,
68       No_Space_Left,
69       Unknown_Device_Class,
70       Invalid_Data,
71       Invalid_Request,
72       Timeout,
73       Class_Prohibited,
74       Initialization_Error,
75       Controller_Error,
76       No_USB2_Address,
77       Device_Not_Supported,
78       Unknown_Error);
79
80    ----------------------------------------------------------------------------
81
82    Max_DMA_Xfers : constant   := 64;
83    Max_Bulk_Size : constant   := 4096;
84    Highest_Address : constant := 16#0000_ffff_ffff_ffff#;
85
86    Endpoint_Count : constant  := 3;
87    -- Endpoint 1 (the control endpoint) is handled by hardware
88    -- Endpoint 2 is the bulk out endpoint
89    -- Endpoint 3 is the bulk in endpoint
90    subtype Endpoint_Range is Positive range 2 .. Endpoint_Count;
91
92    type Global_Transfer_Id is range 0 .. Max_DMA_Xfers - 1;
93    -- DMA space for the last transfer is reserved for the kernel.
94    subtype Transfer_Id is
95       Global_Transfer_Id range 0 .. Global_Transfer_Id'Last - 1;
96
97    ----------------------------------------------------------------------------
98
99    MMIO_Size : constant := DbC_Config.XHCI_SIZE;
100    type MMIO_Index is range 0 .. MMIO_Size / 4 - 1;
101    type MMIO_Array is array (MMIO_Index) of Word32
102    with
103       Atomic_Components,
104       Size => MMIO_Size * 8;
105    pragma Warnings (Off, "atomic synchronization set");
106    package MMIO is new MMIO_Range
107      (Base_Addr   => DbC_Config.XHCI_BASE,
108       Element_T   => Word32,
109       Index_T     => MMIO_Index,
110       Array_T     => MMIO_Array);
111    pragma Warnings (On, "atomic synchronization set");
112
113    type Cap_Registers is
114      (Capability_Registers_Length,
115       XHCI_Extended_Caps);
116    package Cap_S_Regs is new Sub_Regs (Cap_Registers);
117    Cap_Reg_Descs : constant Cap_S_Regs.Array_T :=
118      (Capability_Registers_Length      => (16#00#,  7,  0),
119       XHCI_Extended_Caps               => (16#10#, 31, 16));
120    package Cap_Regs is new MMIO_Regs (MMIO, 0, Cap_S_Regs, Cap_Reg_Descs);
121
122    type Op_Registers is
123      (Run_Stop,
124       Host_Controller_Reset,
125       HC_Halted,
126       Controller_Not_Ready);
127    package Op_S_Regs is new Sub_Regs (Op_Registers);
128    Op_Reg_Descs : constant Op_S_Regs.Array_T :=
129      (Run_Stop                         => (16#00#,  0,  0),
130       Host_Controller_Reset            => (16#00#,  1,  1),
131       HC_Halted                        => (16#04#,  0,  0),
132       Controller_Not_Ready             => (16#04#, 11, 11));
133    package Op_Regs is new MMIO_Regs (MMIO, 0, Op_S_Regs, Op_Reg_Descs);
134
135    type xCap_Registers is
136      (Capability_ID,
137       Next_xCap);
138    package xCap_S_Regs is new Sub_Regs (xCap_Registers);
139    xCap_Reg_Descs : constant xCap_S_Regs.Array_T :=
140      (Capability_ID                    => (16#00#,  7,  0),
141       Next_xCap                        => (16#00#, 15,  8));
142    package xCap_Regs is new MMIO_Regs (MMIO, 0, xCap_S_Regs, xCap_Reg_Descs);
143    procedure Find_Next_xCap (Cap_Id : in Word8; Success : out Boolean);
144
145    type Legacy_Support_Registers is
146      (HC_BIOS_Owned_Semaphore,
147       HC_OS_Owned_Semaphore);
148    package Legacy_Support_S_Regs is new Sub_Regs (Legacy_Support_Registers);
149    Legacy_Support_Reg_Descs : constant Legacy_Support_S_Regs.Array_T :=
150      (HC_BIOS_Owned_Semaphore => (16#00#, 16, 16),
151       HC_OS_Owned_Semaphore   => (16#00#, 24, 24));
152    package Legacy_Support_Regs is new MMIO_Regs
153      (DbC.MMIO, 0, Legacy_Support_S_Regs, Legacy_Support_Reg_Descs);
154
155    type Registers is
156      (Doorbell_Target,
157       ERST_Size,
158       ERST_Base_Lo,
159       ERST_Base_Hi,
160       ER_Dequeue_Ptr_Lo,
161       ER_Dequeue_Ptr_Hi,
162       DBC_CONTROL,
163       DbC_Run,
164       Link_Status_Event_Enable,
165       Halt_OUT_TR,
166       Halt_IN_TR,
167       DbC_Run_Change,
168       Debug_Max_Burst_Size,
169       Device_Address,
170       DbC_Enable,
171       DBC_STATUS,
172       Event_Ring_Not_Empty,
173       DbC_System_Bus_Reset,
174       Debug_Port_Number,
175       DBC_PORTSC,
176       Current_Connect_Status,
177       Port_Enable_Disable,
178       Port_Reset,
179       Port_Link_State,
180       Port_Speed,
181       Connect_Status_Change,
182       Port_Reset_Change,
183       Port_Link_Status_Change,
184       Port_Config_Error_Change,
185       Context_Pointer_Lo,
186       Context_Pointer_Hi,
187       DbC_Protocol,
188       Vendor_ID,
189       Product_ID,
190       Device_Revision);
191    package S_Regs is new Sub_Regs (Registers);
192    Reg_Descs : constant S_Regs.Array_T :=
193      (Doorbell_Target                  => (16#04#, 15,  8),
194       ERST_Size                        => (16#08#, 15,  0),
195       ERST_Base_Lo                     => (16#10#, 31,  0),
196       ERST_Base_Hi                     => (16#14#, 31,  0),
197       ER_Dequeue_Ptr_Lo                => (16#18#, 31,  0),
198       ER_Dequeue_Ptr_Hi                => (16#1c#, 31,  0),
199       DBC_CONTROL                      => (16#20#, 31,  0),
200       DbC_Run                          => (16#20#,  0,  0),
201       Link_Status_Event_Enable         => (16#20#,  1,  1),
202       Halt_OUT_TR                      => (16#20#,  2,  2),
203       Halt_IN_TR                       => (16#20#,  3,  3),
204       DbC_Run_Change                   => (16#20#,  4,  4),
205       Debug_Max_Burst_Size             => (16#20#, 23, 16),
206       Device_Address                   => (16#20#, 30, 24),
207       DbC_Enable                       => (16#20#, 31, 31),
208       DBC_STATUS                       => (16#24#, 31,  0),
209       Event_Ring_Not_Empty             => (16#24#,  0,  0),
210       DbC_System_Bus_Reset             => (16#24#,  1,  1),
211       Debug_Port_Number                => (16#24#, 31, 24),
212       DBC_PORTSC                       => (16#28#, 31,  0),
213       Current_Connect_Status           => (16#28#,  0,  0),
214       Port_Enable_Disable              => (16#28#,  1,  1),
215       Port_Reset                       => (16#28#,  4,  4),
216       Port_Link_State                  => (16#28#,  8,  5),
217       Port_Speed                       => (16#28#, 13, 10),
218       Connect_Status_Change            => (16#28#, 17, 17),
219       Port_Reset_Change                => (16#28#, 21, 21),
220       Port_Link_Status_Change          => (16#28#, 22, 22),
221       Port_Config_Error_Change         => (16#28#, 23, 23),
222       Context_Pointer_Lo               => (16#30#, 31,  0),
223       Context_Pointer_Hi               => (16#34#, 31,  0),
224       DbC_Protocol                     => (16#38#,  7,  0),
225       Vendor_ID                        => (16#38#, 31, 16),
226       Product_ID                       => (16#3c#, 15,  0),
227       Device_Revision                  => (16#3c#, 31, 16));
228    package Regs is new MMIO_Regs (MMIO, 0, S_Regs, Reg_Descs);
229
230    procedure Ring_Doorbell (EP : Endpoint_Range)
231    with
232       Pre => Regs.Byte_Offset /= 0;
233
234 end HW.DbC;
235
236 --  vim: set ts=8 sts=3 sw=3 et: