Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / obp / dev / usb2 / hcd / ohci / edtd.fth
CommitLineData
920dae64
AT
1\ ========== Copyright Header Begin ==========================================
2\
3\ Hypervisor Software File: edtd.fth
4\
5\ Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
6\
7\ - Do no alter or remove copyright notices
8\
9\ - Redistribution and use of this software in source and binary forms, with
10\ or without modification, are permitted provided that the following
11\ conditions are met:
12\
13\ - Redistribution of source code must retain the above copyright notice,
14\ this list of conditions and the following disclaimer.
15\
16\ - Redistribution in binary form must reproduce the above copyright notice,
17\ this list of conditions and the following disclaimer in the
18\ documentation and/or other materials provided with the distribution.
19\
20\ Neither the name of Sun Microsystems, Inc. or the names of contributors
21\ may be used to endorse or promote products derived from this software
22\ without specific prior written permission.
23\
24\ This software is provided "AS IS," without a warranty of any kind.
25\ ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
26\ INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
27\ PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
28\ MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
29\ ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
30\ DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
31\ OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
32\ FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
33\ DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
34\ ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
35\ SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
36\
37\ You acknowledge that this software is not designed, licensed or
38\ intended for use in the design, construction, operation or maintenance of
39\ any nuclear facility.
40\
41\ ========== Copyright Header End ============================================
42id: @(#)edtd.fth 1.1 07/01/24
43purpose: Data structures and manuipulation routines for OHCI USB Controller
44\ See license at end of file
45
46hex
47headers
48
49\ XXX Isochronous is not supported in the current version of the OHCI driver
50
51\ ---------------------------------------------------------------------------
52\ Data structures for this implementation of the OHCI USB Driver include:
53\ - hcca 256 bytes defined by OCHI Spec for USB HC
54\ - ed-control pointer to the control ED list
55\ - ed-bulk pointer to the bulk ED list
56\ - intr internal array of interrupts (to complement the hcca)
57\ ---------------------------------------------------------------------------
58
59\ ---------------------------------------------------------------------------
60\ HcHCCA as defined by the OHCI Spec; 256-byte aligned
61\ ---------------------------------------------------------------------------
62
630 value intr \ Software interrupt buffer
640 value hcca \ Virtual address of HcHCCA
650 value hcca-unaligned \ Unaligned virtual address of HcHCCA
660 value hcca-phys \ Physical address of HcHCCA
67
68\ HCCA
69d# 32 constant #intr
70
71struct ( hcca )
72#intr 4 * field >hcca-intr \ Physical addresses of interrupt EDs
732 field >hcca-frame
742 field >hcca-pad
754 field >hcca-done \ Physical addresses of done EDs
76d# 120 field >hcca-reserved
77constant /hcca
78
79: hcca! ( padr idx -- ) 4 * hcca + le-l! ;
80
81: init-hcca ( -- )
82 \ Allocate hcca
83 /hcca aligned256-alloc
84 dup to hcca \ Aligned address
85 swap to hcca-unaligned \ Unaligned address
86 /hcca true dma-map-in to hcca-phys \ Physical address
87
88 \ Initialize hcca
89 hcca /hcca erase
90 hcca hcca-phys /hcca dma-sync
91;
92
93\ ---------------------------------------------------------------------------
94\ Internal interrupt list per >hcca-intr entry
95\
96\ XXX I can see how this can be expanded to >intr-head32ms, >intr-tail32ms,
97\ XXX and so on, to support the various poll intervals. See comment on
98\ XXX interrupt scheduling below.
99\ ---------------------------------------------------------------------------
100struct \ An entry of intr
101 4 field >intr-head \ Virtual address of interrupt head
102 4 field >intr-tail \ Virtual address of interrupt tail
103 4 field >iso-head \ Virtual address of isochronous head
104 4 field >iso-tail \ Virtual address of isochronous tail
105dup constant /intr-entry
106#intr * constant /intr
107
108: init-intr ( -- )
109 /intr alloc-mem dup to intr \ Allocate intr
110 /intr erase \ Initialize intr
111;
112
113: 'intr ( idx -- adr ) /intr-entry * intr + ;
114: intr-head@ ( idx -- adr ) 'intr >intr-head l@ ;
115: intr-head! ( adr idx -- ) 'intr >intr-head l! ;
116: intr-tail@ ( idx -- adr ) 'intr >intr-tail l@ ;
117: intr-tail! ( adr idx -- ) 'intr >intr-tail l! ;
118: iso-head@ ( idx -- adr ) 'intr >iso-head l@ ;
119: iso-head! ( adr idx -- ) 'intr >iso-head l! ;
120: iso-tail@ ( idx -- adr ) 'intr >iso-tail l@ ;
121: iso-tail! ( adr idx -- ) 'intr >iso-tail l! ;
122
123\ ---------------------------------------------------------------------------
124\ Endpoint descriptor (ED) as defined by the OHCI Spec; 16-byte aligned
125\ ---------------------------------------------------------------------------
126
127\ XXX If we add ed-control-tail & ed-bulk-tail, then insert-* does not have
128\ XXX to disable the function, we need to skip tail until insert is done.
129
1300 value ed-control \ Virtual address of head of control ED list
1310 value ed-bulk \ Virtual address of head of bulk ED list
132
133struct \ Beginning of ED
1344 field >hced-control \ ED control info
1354 field >hced-tdtail \ Physical address of TD tail
1364 field >hced-tdhead \ Physical address of TD head
1374 field >hced-next \ Physical address of next ED
138dup constant /hced
139 \ Driver specific fields
1404 field >ed-phys \ Physical address of HC ED
1414 field >ed-next \ Pointer to the next endpoint
1424 field >ed-prev \ Pointer to the previous endpoint
1434 field >ed-unaligned \ Unaligned virtual address of the ED
1444 field >ed-size \ Size of EDs+TDs
145d# 32 round-up \ Multiple of 32 bytes
146 \ 32 bytes because there are cases where
147 \ EDs and TDs are allocated together
148dup constant /ed \ Size of each ed
149#intr * constant /eds \ Size of all eds allocated at a time
150
151\ >hced-control constants
1520000 constant ED_DIR_TD
1530800 constant ED_DIR_OUT
1541000 constant ED_DIR_IN
1551800 constant ED_DIR_MASK
156
1570000 constant ED_SPEED_FULL
1582000 constant ED_SPEED_LO
1592000 constant ED_SPEED_MASK
160
1610000 constant ED_SKIP_OFF
1624000 constant ED_SKIP_ON
1634000 constant ED_SKIP_MASK
164
1650000 constant ED_FORMAT_G
1668000 constant ED_FORMAT_I
1678000 constant ED_FORMAT_MASK
168
1690000 constant ED_TOGGLE_DATA0
1700002 constant ED_TOGGLE_DATA1
1710002 constant ED_TOGGLE_MASK
172
1730001 constant ED_HALTED
174
175: ed-data>di-data ( n -- n' ) ED_TOGGLE_MASK and if 1 else 0 then ;
176: di-data>ed-data ( n -- n' ) if ED_TOGGLE_DATA1 else ED_TOGGLE_DATA0 then ;
177
178: (set-skip) ( ed skip-bit -- )
179 >r
180 dup >hced-control dup le-l@
181 ED_SKIP_MASK invert and r> or
182 swap le-l!
183 dup >ed-phys l@ /hced dma-sync
184;
185: ed-set-skip ( ed -- ) ED_SKIP_ON (set-skip) ;
186: ed-unset-skip ( ed -- ) ED_SKIP_OFF (set-skip) ;
187
188\ ---------------------------------------------------------------------------
189\ Transfer Descriptor (TD) as defined by the OHCI Spec:
190\ general TDs are 16-byte aligned; isochronous TDs are 32-byte aligned.
191\ ---------------------------------------------------------------------------
192
193struct \ Beginning of General TD fields
1944 field >hctd-control \ TD control info
1954 field >hctd-cbp \ Physical address of current buffer pointer
1964 field >hctd-next \ physical address of next TD
1974 field >hctd-be \ physical address of buffer end
198dup constant /gtd
199 \ Isochronous TD fields
2002 field >hctd-offset0 \ Offset 0 / PSW 0
2012 field >hctd-offset1 \ Offset 1 / PSW 1
2022 field >hctd-offset2 \ Offset 2 / PSW 2
2032 field >hctd-offset3 \ Offset 3 / PSW 3
2042 field >hctd-offset4 \ Offset 4 / PSW 4
2052 field >hctd-offset5 \ Offset 5 / PSW 5
2062 field >hctd-offset6 \ Offset 6 / PSW 6
2072 field >hctd-offset7 \ Offset 7 / PSW 7
208dup constant /itd
209 \ Driver specific fields
2104 field >td-phys \ Physical address of HC TD
2114 field >td-next \ Virtual address of next TD
2124 field >td-cbp \ Virtual address of current buffer pointer
2134 field >td-pcbp \ Physical address of current buffer pointer
2144 field >td-/cbp-all \ Buffer length (size of the entire buffer)
215 \ For bulk and intr TDs
216d# 32 round-up \ Multiple of 32 bytes
217constant /td
218
219\ >hctd-control constants
2200004.0000 constant TD_ROUND_ON
2210000.0000 constant TD_ROUND_ERR
2220004.0000 constant TD_ROUND_MASK
223
2240000.0000 constant TD_DIR_SETUP
2250008.0000 constant TD_DIR_OUT
2260010.0000 constant TD_DIR_IN
2270018.0000 constant TD_DIR_MASK
228
22900c0.0000 constant TD_INTR_MIN
23000e0.0000 constant TD_INTR_OFF
23100e0.0000 constant TD_INTR_MASK
232
2330000.0000 constant TD_TOGGLE_USE_ED
2340200.0000 constant TD_TOGGLE_USE_LSB0
2350300.0000 constant TD_TOGGLE_USE_LSB1
2360100.0000 constant TD_TOGGLE_MASK
2370c00.0000 constant TD_ERR_CNT_MASK
238
2390000.0000 constant TD_CC_NOERROR
2401000.0000 constant TD_CC_CRC
2412000.0000 constant TD_CC_BITSTUFFING
2423000.0000 constant TD_CC_DATATOGGLEMISMATCH
2434000.0000 constant TD_CC_STALL
2445000.0000 constant TD_CC_DEVICENOTRESPONDING
2456000.0000 constant TD_CC_PIDCHECKFAILURE
2467000.0000 constant TD_CC_UNEXPECTEDPID
2478000.0000 constant TD_CC_DATAOVERRUN
2489000.0000 constant TD_CC_DATAUNDERRUN
249c000.0000 constant TD_CC_BUFFEROVERRUN
250d000.0000 constant TD_CC_BUFFERUNDERRUN
251f000.0000 constant TD_CC_NOTACCESSED
252f000.0000 constant TD_CC_MASK
253
254: td-data>di-data ( n -- n' ) TD_TOGGLE_MASK and if 1 else 0 then ;
255: di-data>td-data ( n -- n' ) if TD_TOGGLE_USE_LSB1 else TD_TOGGLE_USE_LSB0 then ;
256
257\ ---------------------------------------------------------------------------
258
259: init-struct ( -- )
260 init-struct
261 0 to ed-control 0 to ed-bulk
262 init-hcca
263 init-intr
264;
265
266\ ---------------------------------------------------------------------------
267\ ED and TDs for bulk, control and interrupt operations.
268\ ED and its list of TDs are allocated as needed.
269\ ---------------------------------------------------------------------------
270
271: init-ed ( ed.u,v,p len -- )
272 2 pick >ed-size l! ( ed.u,v,p )
273 over >ed-phys l! ( ed,u,v )
274 >ed-unaligned l! ( )
275;
276
277: link-tds ( td.v td.p #tds -- )
278 1- 0 ?do ( td.v td.p )
279 2dup swap >td-phys l! ( td.v td.p )
280 /td + tuck over >hctd-next le-l! ( td.p' td.v )
281 dup /td + tuck swap ( td.p td.v' td.v' td.v )
282 >td-next l! ( td.p td.v )
283 swap ( td.v td.p )
284 loop
285 swap >td-phys l! ( )
286;
287: link-edtd ( td.p #tds ed -- )
288 >r ( td.p #tds ) ( R: ed )
289 1- /td * over + ( td.p ptail ) ( R: ed )
290 r@ >hced-tdtail le-l! ( td.p ) ( R: ed )
291 r> >hced-tdhead le-l! ( )
292;
293: link-edtds ( td.v td.p #tds ed -- )
294 >r 2dup r> link-edtd ( td.v td.p #tds ) \ Link ED to TD
295 link-tds ( ) \ Link TDs
296;
297: alloc-edtds ( #tds -- ed td )
298 dup >r /td * /ed + dup >r ( len ) ( R: #tds len )
299 aligned32-alloc-map-in ( ed.u,v,p ) ( R: #tds len )
300 over r@ erase ( ed.u,v,p ) ( R: #tds len )
301 3dup r> init-ed ( ed.u,v,p ) ( R: #tds )
302 rot drop ( ed.v,p ) ( R: #tds )
303 over /ed + dup -rot ( ed td ed.p td.v ) ( R: #tds )
304 swap /ed + ( ed td td.v td.p ) ( R: #tds )
305 r> 4 pick link-edtds ( ed td )
306;
307: free-edtds ( ed -- )
308 >r ( R: ed )
309 r@ >ed-unaligned l@ ( ed.u ) ( R: ed )
310 r@ dup >ed-phys l@ ( ed.u,v,p ) ( R: ed )
311 r> >ed-size l@ ( ed.u,v,p size )
312 aligned32-free-map-out ( )
313;
314: sync-edtds ( ed -- )
315 dup >ed-phys l@ ( ed.v,p )
316 over >ed-size l@ ( ed.v,p len )
317 dma-sync ( )
318;
319: map-out-cbp ( td -- )
320 dup >td-cbp l@ over >td-pcbp l@ rot >td-/cbp-all l@ hcd-map-out
321;
322
323\ ---------------------------------------------------------------------------
324\ Control scheduling
325\ ---------------------------------------------------------------------------
326
327: fixup-ed-next-prev ( ed -- ed )
328 dup >ed-prev l@ ?dup if over >ed-next l@ swap >ed-next l! then
329 dup >ed-next l@ ?dup if over >ed-prev l@ swap >ed-prev l! then
330;
331
332: insert-ed ( new-ed old-ed -- )
333 ?dup 0= if drop exit then \ No old-ed, done
334 2dup >ed-prev l! \ old-ed's prev is new-ed
335 2dup swap >ed-next l! \ new-ed's next is old-ed
336 >ed-phys l@ swap >hced-next le-l! \ new-ed's hced-next is old-ed's phys
337;
338
339: insert-control-ed ( ed -- )
340 dup ed-control insert-ed
341 to ed-control
342;
343: remove-control-ed ( ed -- )
344 fixup-ed-next-prev ( ed )
345 dup ed-control = if >ed-next l@ to ed-control else drop then
346;
347
348\ ---------------------------------------------------------------------------
349\ Bulk scheduling
350\ ---------------------------------------------------------------------------
351
352: insert-bulk-ed ( ed -- )
353 dup ed-bulk insert-ed
354 to ed-bulk
355;
356: remove-bulk-ed ( ed -- )
357 fixup-ed-next-prev ( ed )
358 dup ed-bulk = if >ed-next l@ to ed-bulk else drop then
359;
360
361\ ---------------------------------------------------------------------------
362\ Interrupt scheduling
363\ Schedule interrupt at the rate min(interval,2**x).
364\
365\ XXX Need to determines which scheduling queue for that rate has the smallest
366\ committed bandwidth.
367\
368\ XXX To really implement the various poll intervals, the simplistic way is
369\ XXX to have 32 dummy EDs for 1ms interval; 16 dummy EDs for 2ms interval;
370\ XXX 8 dummy EDs for 4ms interval; 4 dummy EDs for 8ms interval;
371\ XXX 2 dummy EDs for 16ms interval; and, 1 dummy ED for 32ms interval.
372\ XXX Then you link to the end of the lists of EDs for each interval. Ughhh!
373\
374\ XXX For now, just implement fixed poll interval.
375\
376\ XXX On further thought, since we're polling the intr pipeline from the
377\ XXX device driver, the driver driver can poll the intr at the interval
378\ XXX specified. And thus, the need to fully implement poll intervals at
379\ XXX the HCD level is redundant.
380\ ---------------------------------------------------------------------------
381
3824 constant intr-interval
383
384: (insert-intr-ed) ( ed idx -- )
385 dup >r ( ed idx ) ( R: idx )
386 intr-tail@ ?dup 0= if ( ed ) ( R: idx )
387 dup r@ intr-head! ( ed ) ( R: idx )
388 dup >ed-phys l@ r@ hcca! ( ed ) ( R: idx )
389 else ( ed ted ) ( R: idx )
390 2dup >ed-next l! ( ed ted ) ( R: idx )
391 over >ed-phys l@ over >hced-next le-l! ( ed ted ) ( R: idx )
392 over >ed-prev l! ( ed ) ( R: idx )
393 then
394 r@ iso-head@ over >ed-next l! ( ed ) ( R: idx )
395 r> intr-tail! ( )
396;
397: insert-intr-ed ( ed interval -- )
398 drop
399 #intr 0 do dup i (insert-intr-ed) intr-interval +loop drop
400;
401
402: (remove-intr-ed) ( ed idx -- )
403 >r ( ed ) ( R: idx )
404 fixup-ed-next-prev ( ed ) ( R: idx )
405 r@ intr-head@ over = if ( ed ) ( R: idx )
406 dup >ed-next l@ dup r@ intr-head! ( ed ped ) ( R: idx )
407 dup if >ed-phys l@ then r@ hcca!
408 ( ed ) ( R: idx )
409 then
410 r@ intr-tail@ over = if ( ed ) ( R: idx )
411 dup >ed-prev l@ r@ intr-tail! ( ed ) ( R: idx )
412 then
413 r> 2drop
414;
415: remove-intr-ed ( ed -- )
416 #intr 0 do dup i (remove-intr-ed) intr-interval +loop drop
417;
418
419\ ---------------------------------------------------------------------------
420\ Wait for an ED to be done and process any errors.
421\
422\ When done? returns no error found yet, the caller should should if errors
423\ were found in the TDs.
424\ ---------------------------------------------------------------------------
425
426defer process-hc-status
427
4280 value timeout
429
430: .td-error ( cc -- )
431 case
432 TD_CC_CRC of " CRC" USB_ERR_CRC endof
433 TD_CC_BITSTUFFING of " Bit Stuffing" USB_ERR_BITSTUFFING endof
434 TD_CC_DATATOGGLEMISMATCH of " Data Toggle Mismatch" USB_ERR_DATATOGGLEMISMATCH endof
435 TD_CC_STALL of " Stall" USB_ERR_STALL endof
436 TD_CC_DEVICENOTRESPONDING of " Device Not Responding" USB_ERR_DEVICENOTRESPONDING endof
437 TD_CC_PIDCHECKFAILURE of " PID Check Failure" USB_ERR_PIDCHECKFAILURE endof
438 TD_CC_UNEXPECTEDPID of " Unexpected PID" USB_ERR_UNEXPECTEDPIC endof
439 TD_CC_DATAOVERRUN of " Data Overrun" USB_ERR_DATAOVERRUN endof
440 TD_CC_DATAUNDERRUN of " Data Underrun" USB_ERR_DATAUNDERRUN endof
441 TD_CC_BUFFEROVERRUN of " Buffer Overrun" USB_ERR_BUFFEROVERRUN endof
442 TD_CC_BUFFERUNDERRUN of " Buffer Underrun" USB_ERR_BUFFERUNDERRUN endof
443 TD_CC_NOTACCESSED of " Not Accessed" USB_ERR_NOTACCESSED endof
444 ( default ) " Unknown Error" rot USB_ERR_UNKNOWN swap
445 endcase
446 set-usb-error
447;
448
449: error? ( td -- usberr )
450 begin
451 dup >td-next l@ if \ Process a real TD
452 dup >hctd-control le-l@ TD_CC_MASK and ?dup if
453 .td-error drop 0 \ Error found in TD
454 else
455 >td-next l@ \ TD's ok, examine the next TD
456 then
457 else \ Don't need to process last dummy TD
458 drop 0
459 then
460 ?dup 0= until
461 usb-error
462;
463
464: ed-done? ( ed -- done? )
465 dup >hced-tdhead le-l@ dup ED_HALTED and ( ed head halted? )
466 swap h# ffff.fff0 and ( ed halted? head )
467 rot >hced-tdtail le-l@ h# ffff.fff0 and = ( halted? head=tail? )
468 or ( done? )
469;
470
471: done? ( ed -- error? )
472 begin
473 process-hc-status
474 dup sync-edtds
475 dup ed-done? ?dup 0= if
476 1 ms
477 timeout 1- dup to timeout 0=
478 then
479 until
480 ed-done? 0= if " Timeout" USB_ERR_TIMEOUT set-usb-error then
481 usb-error
482;
483
484: get-actual ( td -- actual )
485 dup >hctd-cbp le-l@ ?dup if
486 swap >td-pcbp l@ -
487 else
488 dup >hctd-be le-l@ swap >td-pcbp l@ - 1+
489 then
490;
491
492headers
493
494\ LICENSE_BEGIN
495\ Copyright (c) 2006 FirmWorks
496\
497\ Permission is hereby granted, free of charge, to any person obtaining
498\ a copy of this software and associated documentation files (the
499\ "Software"), to deal in the Software without restriction, including
500\ without limitation the rights to use, copy, modify, merge, publish,
501\ distribute, sublicense, and/or sell copies of the Software, and to
502\ permit persons to whom the Software is furnished to do so, subject to
503\ the following conditions:
504\
505\ The above copyright notice and this permission notice shall be
506\ included in all copies or substantial portions of the Software.
507\
508\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
509\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
510\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
511\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
512\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
513\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
514\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
515\
516\ LICENSE_END