1/*
2 * Copyright (c) 2009, 2012, ETH Zurich. All rights reserved.
3 *
4 * This file is distributed under the terms in the attached LICENSE file.
5 * If you do not find this file, copies can be found by writing to:
6 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group.
7 */
8
9/*
10 * ehci.dev
11 *
12 * DESCRIPTION: Enhanced Host Controller Interface description
13 *
14 * Numbers in comments refer to the Intel Enhanced Host Controller
15 * Interface Specification for Universal Serial Bus, March 12, 2002,
16 * Revision: 1.0 
17 */
18
19device ehci msbfirst (addr cap, addr op) "EHCI USB Controller" {
20
21    /* 
22     * Section 2.2 
23     * Host controller capabilty registers 
24     */
25    
26    // 2.2.1 
27    // The correct value for 'op' is actually 'cap' plus this number. 
28    register caplength ro addr(cap, 0x00) "Capability Registers Length" 
29    type(uint8);
30
31    // 2.2.2
32    register hciversion ro addr(cap, 0x02) "Host Controller Interface Version Number" 
33    type(uint16);
34
35    // 2.2.3
36    register hcsparams ro addr(cap, 0x04) "Structural parameters" {
37    _        8;
38    dpn      4  "Debug port number";
39    _        3;
40    p_indicator  1      "Port indicator";
41    n_cc     4  "Number of campanion controller";
42    n_pcc    4      "Number of ports per companion controller";
43    prr      1      "Port routing rules";
44    _        2;
45    ppc      1      "Port power control";
46    n_ports  4      "Num. physical downstream ports on this controller";
47   }; 
48    
49    // 2.2.4
50    register hccparams ro addr(cap, 0x08) "Capability parameters" {
51    _        16;
52    eecp     8     "EHCI extended capabilities pointer"; 
53    ist      4     "Isochronous scheduling threshold";
54    _        1;
55    aspc     1     "Asynchronous sechedule park capability";
56    pflf     1     "Programmable frame list flag";
57    bit64ac    1     "Extended 64 bit addressing capability";
58    };
59    
60    // section 2.2.5 Companion port route descriptor 
61    register hcspportroute ro addr(cap, 0x0C) "Companion port route descr." {
62    attr    60  "Port array";
63    _   4;
64    };
65
66    /* 
67     * Section 2.3
68     * Host controller operational registers
69     */
70 
71    constants itc_val "Interrupt threshold control" {
72    itc_val_rsvd  = 0x00  "Reserved";
73    uframe_1      = 0x01  "1 Micro frame";
74    uframes_2     = 0x02  "2 Micro frames";
75    uframes_4     = 0x04  "4 Micro frames";
76    uframes_8     = 0x08  "8 Micro frames (default, equates to 1 ms)";
77    uframes_16    = 0x10  "16 Micro frames (2 ms)";
78    uframes_32    = 0x20  "32 Micro frames (4 ms)";
79    uframes_64    = 0x40  "64 Micro frames (8 ms)";
80    };
81    
82    constants frame_val "Frame list size" {
83    elem_1024    = 0b00   "1024 Elements (4096 bytes, default)";
84    elem_512     = 0b01   "512 Elements (2048 bytes)";
85    elem_256     = 0b10   "256 Elements (1024 bytes)";
86    frame_rsvd   = 0b11   "Reserved";
87    };
88    
89    // 2.3.1
90    register usbcmd rw addr(op, 0x00) "USB command" {
91    _       8    mbz;
92    itc     8    type(itc_val) "Interrupt threshold control";
93    _       4    mbz;
94    aspme   1    rw     "Asynchronous schedule park mode enable";
95    _       1    mbz;
96    aspmc   2    rw     "Asynchronous schedule park mode count";
97    lhcr    1    rw     "Light host controller reset";
98    iaad    1    rw     "Interrupt on async advance doorbell";
99    ase     1    rw     "Asynchronous schedule enable";
100    pse     1    rw     "Periodic schedule enable";
101    fls     2    type(frame_val)  "Frame list size";
102    hcr     1    rw     "Host controller reset";
103    rs      1    rw     "Run stop for scheduling";
104    };
105
106    // 2.3.2
107    register usbsts rw addr(op, 0x04) "USB status" {
108    _        16   mbz;
109    ass      1    ro   "Asynchronous schedule status";
110    pss      1    ro   "Periodic schedule status";
111    rec      1    ro   "Reclamation";
112    hch      1    ro   "Host controller halted see Run/Stop";   
113    _        6    mbz;
114    iaa      1    rwc  "Interrupt on Async advance";
115    hse      1    rwc  "Host system error";
116    flr      1    rwc  "Frame list rollover";
117    pcd      1    rwc  "Port change detect";
118    usbei    1    rwc  "USB error interrupt";
119    usbi     1    rwc  "USB interrupt";
120    };
121
122    // 2.3.3
123    register usbintr rw addr(op, 0x08) "USB interrupt enable" {
124    _       26 mbz;
125    iaae   1  "Interrupt on async advance enable";
126    hsee   1  "Host system error enable";
127    flre   1  "Frame list rollover enable";
128    pcie   1  "Port change interrupt enable";
129    usbeie 1  "USB error interrupt enable";
130    usbie  1  "USB interrupt enable";
131    };
132
133    // 2.3.4
134    register frindex rw addr(op, 0x0C) "Frame index" {
135    _    18  mbz;
136    fi   14     "Frame index";
137    };
138
139    // 2.3.5 
140    // NOTE: Only enabled if 64 bit address capability is enabled 
141    register ctrldssegment rw addr(op, 0x10) "Control data structure segment" {
142    data 32 rw "MSB [63:32] bits of EHCI data strctures";
143    };
144
145    // 2.3.6 
146    register periodiclistbase rw addr(op, 0x14) "Periodic frame list base addr" {
147    addr   20   rw    "Base address (must be 4k aligned)";
148    _      12   mbz; 
149    };
150    
151    // 2.3.7
152    register asynclistaddr rw addr(op, 0x18) "Current async. list addr." {
153    lpl    27   rw   "Link pointer low";
154    _      5    mbz;
155    };
156    
157    // 2.3.8 
158    register configflag rw addr(op, 0x40) "Configure flag" {
159    _     31   mbz;
160    cf    1    rw   "Configure flag";
161    };
162    
163    // 2.3.9
164    constants test_mode_val "Test modes" {
165    disabled  =  0b0000   "Test mode not enabled";
166    test_j_st =  0b0001   "Test J_STATE";
167    test_k_st =  0b0010   "Test K_STATE";
168    se0_nak   =  0b0011   "Test SE0_NAK";
169    test_pack =  0b0100   "Test packet";
170    force_ena =  0b0101   "Force enable";
171    };
172    
173    constants indi_val "Port indicator values" {
174    off                = 0b00  "Port indicators are off";
175    amber              = 0b01  "Amber";
176    green              = 0b10  "Green";
177    indi_val_undef     = 0b11  "Undefined";
178    };     
179    
180    constants lstatus_val "USB line status" {
181    se0           =  0b00   "Not low speed device, perform EHCI reset";
182    j_state       =  0b10   "Not low speed device, perform EHCI reset";
183    k_state       =  0b01   "Low speed device, release ownership of port";
184    lstatus_undef =  0b11   "Not low speed device, perform EHCI reset"; 
185    };
186
187    regarray portsc rw addr(op, 0x44)[16] "Port status and control" {
188    _            9 mbz;
189    wkoc_e       1      "Wake on over-current enable";
190    wkdscnnt_e   1      "Wake on disconnect enable";
191    wkcnnt_e     1      "Wake on connect enable";
192    ptc          4 type(test_mode_val) "Port test control";
193    pic          2 type(indi_val)      "Port indicator control";
194    po           1      "Port owner";
195    pp           1      "Port power";
196    ls           2 type(lstatus_val)   "Line status value";
197    _            1 mbz;
198    pr           1      "Port reset";
199    sus          1      "Port suspend";
200    fpr          1      "Force port resume";
201    occ          1 rwc  "Over current change";
202    oca          1 ro   "Over current active";
203    pec          1 rwc  "Port enable/disbale change";
204    ped          1      "Port enabled/disabled";
205    csc          1 rwc  "Connect status change";
206    ccs          1 ro   "Current connect status";
207    };
208/*
209    //
210    // In-memory data structures
211    //
212
213    // 3.1
214    constants lptype width(2) "Link pointer type" {
215    lp_itd  = 0b00  "Isochronous transfer descriptor";
216    lp_qh   = 0b01  "Queue head";
217    lp_sitd = 0b10  "Split transaction isochronous trans. desc.";
218    lp_fstn = 0b11  "Frame span traversal node";
219    };
220
221    datatype lp msbfirst(32) "Link pointer" {
222    p   27      "Frame list link pointer";
223    _   2 mbz;
224    typ 2 type(lptype) "Pointer type";
225    t   1       "Pointer value invalid";
226    };
227
228    // 3.3
229    datatype itd msbfirst(32) "Isochronous transfer descriptor" {
230    next    32 type(lp) "Next descriptor";
231    sc0 32 type(itsc)   "Transaction 0 Status/control";
232    sc1 32 type(itsc)   "Transaction 1 Status/control";
233    sc2 32 type(itsc)   "Transaction 2 Status/control";
234    sc3 32 type(itsc)   "Transaction 3 Status/control";
235    sc4 32 type(itsc)   "Transaction 4 Status/control";
236    sc5 32 type(itsc)   "Transaction 5 Status/control";
237    sc6 32 type(itsc)   "Transaction 6 Status/control";
238    sc7 32 type(itsc)   "Transaction 7 Status/control";
239    bp0 32 type(itbp0)  "Buffer pointer 0";
240    bp1 32 type(itbp1)  "Buffer pointer 1";
241    bp2     32 type(itbp2)  "Buffer pointer 2";
242    bp3 32 type(itbp3)  "Buffer pointer 3";
243    bp4 32 type(itbp3)  "Buffer pointer 4";
244    bp5 32 type(itbp3)  "Buffer pointer 5";
245    bp6 32 type(itbp3)  "Buffer pointer 6";
246    };
247
248    // 3.3.2
249    datatype itsc msbfirst(32) "Isochronous transaction status/control" {
250    // Status
251    active  1       "Active";
252    dbe 1       "Data buffer error";
253    bd  1       "Babble detected";
254    xacterr 1       "Transaction error";
255    // Control
256    length  12      "Transaction length";
257    ioc 1       "Interrupt on complete";
258    pg  3       "Page select (0-6)";
259    offset  12      "Offset from state of buffer";
260    };
261
262    // 3.3.3
263    datatype itbp0 msbfirst(32) "iTD buffer pointer page 0" {
264    p   20      "Buffer pointer (4k aligned)";
265    epn 4       "Endpoint number";
266    _   1 mbz;
267    da  7       "Device address";
268    };
269    datatype itdp1 msbfirst(32) "iTD buffer pointer page 1" {
270    p   20      "Buffer pointer (4k aligned)";
271    dir 1       "In (1) or out (0) PID";
272    mps 11      "Maximum packet size";
273    };
274    datatype itdp2 msbfirst(32) "iTD buffer pointer page 2" {
275    p   20      "Buffer pointer (4k aligned)";
276    _   10 mbz;
277    multi   2       "Num. transactions/micro-frame + 1 (0=rsvd)";
278    };
279    datatype itdp3 msbfirst(32) "iTD buffer pointer page 3" {
280    p   20      "Buffer pointer (4k aligned)";
281    _   12 mbz;
282    };
283
284    // 3.4
285    datatype sitd msbfirst(32) "Split isochronous transfer descriptor" {
286    next    32 type(lp) "Next descriptor";
287    cap 32 type(sitcap) "Endpoint capabilities/characteristics";
288    msc 32 type(sitmsc) "Micro-frame schedule control";
289    tsc 32 type(sittsc) "Transfer status and control";
290    bpl0    32 type(sitbpl0) "Buffer page pointer 0";
291    bpl1    32 type(sitbpl1) "Buffer page pointer 1";
292    bp  32 type(sitblp) "Back link";
293    };
294
295    // 3.4.2
296    datatype sitcap msbfirst(32) "siTD endpoint capabilities/characteristics" {
297    dir 1       "In (1) or out (0) PID";
298    port    7       "Port number";
299    _   1 mbz;
300    hub 7       "Hub address";
301    _   4 mbz;
302    epn 4       "Endpoint number";
303    _   1 mbz;
304    da  7       "Device address";
305    };
306    datatype sitmsc msbfirst(32) "siTD micro-frame schedule control" {
307    _   16 mbz;
308    scm 8       "Split completion mask";
309    ssm 8       "Split start mask";
310    };
311
312    // 3.4.3 
313    datatype sittsc msbfirst(32) "siTD transfer status and control" {
314    ioc 1       "Interrupt on complete";
315    p   1       "Page select";
316    _   4 mbz;
317    total   10      "Total bytes to transfer";
318    cpm 8       "Microframe complete-split progress mask";
319    active  1       "Status active";
320    err 1       "ERR response rcvd from transaction translator";
321    dbe 1       "Data buffer error";
322    babble  1       "Babble detected";
323    xacterr 1       "Transaction error";
324    mmf 1       "Missed micro-frame";
325    sts 1       "Split transaction state";
326    _   1 mbz;
327    };
328
329    // 3.4.4 
330    constants xpos width(2) "Transaction position" {
331    tp_all  = 0b00      "Entire payload";
332    tp_begin = 0b01     "First data payload";
333    tp_mid  = 0b10      "Middle payload";
334    tp_end = 0b11       "Final payload";
335    };
336    datatype sitbpl0 msbfirst(32) "siTD buffer page pointer list page 0" {
337    p   20      "Buffer pointer (4k aligned)";
338    offset  12      "Current offset";
339    };
340    datatype sitbpl1 msbfirst(32) "siTD buffer page pointer list page 1" {
341    p   20      "Buffer pointer (4k aligned)";
342    _   7 mbz;
343    tp  2 type(xpos)    "Transaction position";
344    tc  3       "Transaction count";
345    };
346
347    // 3.4.5
348    datatype sitblp msbfirst(32) "siTD back link pointer" {
349    bp  27      "Back pointer";
350    _   4 mbz;
351    t   1       "Terminate (0 -> bp is valid)";
352    };
353
354    // 3.5
355    datatype qtd msbfirst(32) "Queue element transfer descriptor" {
356    next    32 type(lp) "Next element";
357    altnext 32 type(lp) "Alternate next pointer";
358    token   32 type(qttok)  "Token";
359    bp0 32 type(qtbp0)  "Buffer pointer 0";
360    bp1 32 type(qtbp1)  "Buffer pointer 1";
361    bp2 32 type(qtbp1)  "Buffer pointer 2";
362    bp3 32 type(qtbp1)  "Buffer pointer 3";
363    bp4 32 type(qtbp1)  "Buffer pointer 4";
364    };
365
366    // 3.5.3
367    constants pid "PID token encoding" {
368    pid_out     = 0b00  "Generates OUT token (E1H)";
369    pid_in      = 0b01  "Generates IN token (69H)";
370    pid_setup   = 0b10  "Generates SETUP token (2DH)";
371    pid_rsvd    = 0b11  "Reserved";
372    };
373    
374    datatype qttok msbfirst(32) "qTD Token" {
375    toggle  1       "Data toggle";
376    tbt 15      "Total bytes to transfer";
377    ioc 1       "Interrupt on complete";
378    cp  3       "Current page";
379    cerr    2       "Error counter";
380    pidc    2 type(pid) "PID code token";
381    active  1       "Status active";
382    halted  1       "Serious error at endpoint";
383    dbe 1       "Data buffer error";
384    babble  1       "Babble detected";
385    xacterr 1       "Transaction error";
386    mmf 1       "Missed micro-frame";
387    sts 1       "Split transaction state";
388    ping    1       "Ping state";
389    };
390
391    // 3.5.4
392    datatype qtbp0 msbfirst(32) "Queue element buffer pointer page 0" {
393    p   20      "Buffer pointer (4k aligned)";
394    offset  12      "Current offset";
395    };
396    datatype qtbp1 msbfirst(32) "Queue element buffer pointer page 1" {
397    p   20      "Buffer pointer (4k aligned)";
398    _   12 mbz;
399    };
400
401    // 3.6
402    datatype qh msbfirst(32) "Queue head" {
403    hlp 32 type(lp) "Horizontal link pointer";
404    cap1    32 type(qhcap1) "Endpoint capabilities/characteristics 1";
405    cap2    32 type(qhcap2) "Endpoint capabilities/characteristics 2";
406    current 32 type(lp) "Current element";
407    next    32 type(lp) "Next element";
408    altnext 32 type(qhlp)   "Alternate next pointer";
409    token   32 type(qttok)  "Token";
410    bp0 32 type(qtbp0)  "Buffer pointer 0";
411    bp1 32 type(qhbp1)  "Buffer pointer 1";
412    bp2 32 type(qhbp2)  "Buffer pointer 2";
413    bp3 32 type(qtbp1)  "Buffer pointer 3";
414    bp4 32 type(qtbp1)  "Buffer pointer 4";
415    };  
416
417    // 3.6.2 
418    constants speed width(2) "Endpoint speed" {
419    fullspeed   = 0b00 "Full-speed (12Mbs)";
420    lowspeed    = 0b01 "Low-speed (1.5Mbs)";
421    highspeed   = 0b10 "High-speed (480 Mb/s)";
422    };
423
424    datatype qhcap1 msbfirst(32) "Endpoint capabilities: queue head word 1"{
425    rl  4       "NAK count reload";
426    c   1       "Control endpoint flag";
427    mpl 11      "Maximum packet length";
428    h   1       "Head of reclamation list flag";
429    dtc 1       "Data toggle control";
430    eps 2 type(speed)   "Endpoint speed";
431    epn 4       "Endpoint number";
432    i   1       "Inactivate on next transaction";
433    da  7       "Device address";
434    };
435
436    datatype qhcap2 msbfirst(32) "Endpoint capabilities: queue head word 2"{
437    mult    2       "High-bandwidth pipe multiplier";
438    port    7       "Port number";
439    hub 7       "Hub address";
440    scm 8       "Split completion mask";
441    ism 8       "Interrupt schedule mask";
442    };
443
444    // 3.6.3 
445    datatype qhlpa msbfirst(32) "Alternate queue head link pointer" {
446    p   27      "Frame list link pointer";
447    nakcnt  4       "NACK counter";
448    t   1       "Pointer value invalid";
449    };
450
451    datatype qhbp1 msbfirst(32) "Queue head buffer pointer page 1" {
452    p   20      "Buffer pointer (4k aligned)";
453    _   4 mbz;
454    cpm 8       "Split-transaction complete-split progress";
455    };
456
457    datatype qhbp2 msbfirst(32) "Queue head buffer pointer page 2" {
458    p   20      "Buffer pointer (4k aligned)";
459    sb  7       "S-bytes";
460    ft  5       "Split-transaction frame tag";
461    };
462
463    // 3.7
464    datatype fstm msbfirst(32) "Periodic Frame Span Traversal Node" {
465    normal  32 type(lp) "Normal path link pointer"; 
466    back    32 type(lp) "Back path link pointer";
467    };*/
468};
469
470