Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / obp / dev / usb / requests.fth
CommitLineData
920dae64
AT
1\ ========== Copyright Header Begin ==========================================
2\
3\ Hypervisor Software File: requests.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: @(#)requests.fth 1.13 02/12/19
43purpose:
44copyright: Copyright 1997-2000 Sun Microsystems, Inc. All Rights Reserved
45
46: request-blank ( -- addr ) /request get-chunk ;
47
48: descript-form ( len -- addr )
49 request-blank
50 get-descript-req over request-type w!
51 swap over req-len le-w!
52;
53
54: get-dev-descript-form ( len -- addr )
55 descript-form
56 device-descript over req-value 1+ c!
57;
58
59: get-config-descript-form ( len -- addr )
60 descript-form
61 config-descript over req-value 1+ c! \ need index as well
62;
63
64: set-address-form ( usb-addr -- addr )
65 request-blank
66 set-address-req over request-type w!
67 swap over req-value le-w!
68;
69
70
71: add-setup-transfer ( p-adr p-len endp-d -- )
72 2 setup-bits rot t>endq
73;
74
75\ XXX should have a toggle in the stack diagram; see execute-1-interrupt.
76\ XXX the adding code can be better factored and cleaned up
77\ dir is 0 for data from target to host, 1 for data from host to target
78: (add-data-transfer) ( buf-adr buf-len dir endp-d -- )
79 3 \ toggle
80 rot if out-bits else in-bits then
81 rot t>endq
82;
83
84: add-data-transfer ( buf-adr buf-len dir endp-d -- )
85 rot ?dup if
86 -rot (add-data-transfer)
87 else 2drop drop \ 0 len transfer not needed here
88 then
89;
90
91\ dir is 0 for out-ack, 1 for in-ack (opposite of add-data-transfer)
92: add-ack-transfer ( dir endp-d -- )
93 >r >r
94 0 0 3 \ status transfer
95 r> if in-bits else out-bits then
96 r> t>endq
97;
98
99: add-isoc-transfer ( frame# badr blen endp -- )
100 over if
101 isoct>endq
102 else 2drop 2drop \ 0 len transfer not needed here
103 then
104;
105
106: enque-control ( endp-d -- )
107 control-off next-frame
108 control-id e>q
109 control-on control-filled
110;
111
112\ Need to clear hccontrol bit. on next frame, hccontrolcurrent is adjusted
113\ so it does not point to the one being removed (ohci 5.2.7.1.2 says use 0).
114\ adjust pointers in nearby endpoint d's to point around the one being
115\ removed. then turn on the q in hccontrol again.
116: deque-control ( endp-d -- )
117 chip-base hc-control rl@ >r
118 control-off next-frame
119 eq>
120 0 chip-base hc-control-current rl! \ make sure it's not looking at this 1
121 control-filled \ make it start over on control q
122 r> chip-base hc-control rl!
123;
124
125: enque-interrupt ( endp-d q# -- )
126 periodic-off next-frame
127 e>q
128 periodic-on
129;
130
131: deque-interrupt ( endp-d -- )
132 chip-base hc-control rl@ >r
133 periodic-off next-frame
134 eq>
135 r> chip-base hc-control rl!
136;
137
138: enque-bulk ( endp-d -- )
139 bulk-off next-frame
140 bulk-id e>q
141 bulk-on bulk-filled
142;
143
144: deque-bulk ( endp-d -- )
145 chip-base hc-control rl@ >r
146 bulk-off next-frame
147 eq>
148 r> chip-base hc-control rl!
149;
150
151: enque-isoc ( endp-d -- )
152 isoc-off next-frame
153 isoc-id e>q
154 isoc-on periodic-on
155;
156
157: deque-isoc ( -- )
158 chip-base hc-control rl@ >r
159 isoc-off next-frame
160 eq>
161 r> chip-base hc-control rl!
162;
163
164' take-done-q to bless-done-q \ for polled at probe time;
165 \ could use quit-take-done-q
166
167\ ping-pongs once to check both done-q's if needed. Leaves the code pointing
168\ to the done q with the done transfer waiting that it found, if it found one.
169\ XXX If other code guarantees this starts on a clean q, ping-pong should be
170\ first.
171\ The endpoint starts with the pointer for the distributor set to a clean
172\ queue, and the regular code looking at a clean queue, so I think the ping-
173\ pong can be done first. Results in a slightly better response time.
174\ there's a wrinkle in connection with the interrupt transfers and isoc
175\ transfers.
176: done-waiting? ( endpoint -- done-waiting? )
177 bless-done-q
178 dup code-done-q @ ?dup if
179 nip
180 else
181 dup ping-pong
182 code-done-q @
183 then
184;
185
186d# 5000 value time-limit \ 5 sec timeout, usb 7.1.4.3; global ok
187
188: more-time? ( limit -- limit-not-hit? )
189 get-msecs - 0>
190;
191
192\ 0 if timed-out.
193: wait-for-reply ( endpoint -- done-q | 0 )
194 get-msecs time-limit +
195 begin
196 over done-waiting? dup if
197 dup
198 else over more-time? 0= if true then
199 then
200 until
201 nip nip
202;
203
204: wait-till-stopped ( endpoint -- stopped | 0 ) \ 0 if timed-out
205 get-msecs time-limit +
206 begin
207 over stopped? dup if
208 dup
209 else over more-time? 0= if true then
210 then
211 until
212 nip nip
213;
214
215\ true if only one more reply outstanding. partly a check that all the
216\ transfer-d's are accounted for and none left in limbo (endpoint-d shows
217\ empty, but no reply on the done-q yet).
218: last-reply? ( endpoint -- last? )
219 transfer-count @ 1- 0=
220;
221
222\ Move the transfer-d's from done-q to the stack.
223: take-transfer-d's ( endpoint -- q-head )
224 dup code-done-q @
225 0 rot code-done-q ! \ this done-q can be reused now.
226;
227
228\ Assumes that the transfer-d's are put on the q in the same order
229\ as on the controller done-q.
230\ code is condition code of last reply or error code of recent reply
231\ code is present only if bad-or-last? is non-false.
232: bad-or-last-reply? ( transfer-d endpoint -- [code] bad-or-last? )
233 2dup dump-following-transfer-d's
234 swap >r last-reply? if
235 r@ condition-code true
236 else
237 r@ condition-code ?dup
238 then
239 r> dump-transfer
240;
241
242\ XXX if timeout, need to dump the transfer somehow
243\ Look for a done transfer. Keep looking until one shows up, or timeout.
244\ Dump any earlier done transfers.
245\ Check if it is the last one. If it is, return its condition code.
246\ If it is not the last one, check it for an error, and return that if
247\ non-zero. If it isn't the last one, and has no error, keep looking.
248
249\ Not used for enable-int-transactions. Should never time out.
250
251\ 0 if we got the last reply, there was no timeout, and there was
252\ no error. Otherwise, there was a timeout, or there was an error.
253\ The done transfer-d's are dumped.
254: wait-for-last-reply ( endpoint-d -- reply-code )
255 begin dup wait-for-reply ?dup if
256 over bad-or-last-reply?
257 else \ timed-out
258 time-out-error true
259 then
260 until
261 nip
262;
263
264: 1-try-wait ( endpoint-d -- reply-code )
265 time-limit ( endpoint-d time-limit )
266 2 is time-limit
267 swap wait-for-last-reply ( time-limit reply-code )
268 swap is time-limit ( reply-code )
269;
270
271\ Look at the packet status words; report the first error
272: packet-statuses ( transfer-d -- error-code )
273 0 swap \ assume good
274 8 0 do
275 i over packet-condition-code
276 ?dup if -rot nip leave then
277 loop
278 drop
279;
280
281: isoc-transfer-bad? ( transfer-d -- error-code )
282 dup condition-code ?dup if
283 nip
284 else
285 packet-statuses
286 then
287;
288
289\ Reverse the q of transfer-d's onto the stack.
290: get-transfer-d's ( q-head -- q-head trans1 ... transn )
291 begin
292 dup next-transfer le-l@
293 ?dup 0=
294 until
295;
296
297\ Look at the transfer-d's on the done-q in reverse order (in order that
298\ they went on the done-q). Check each one for bad isoc status. Dump
299\ the transfer-d's.
300: check-isoc-packets ( done-q-head -- error-code )
301 0 >r \ assume good
302 dup >r ( R: 0 done-head )
303 get-transfer-d's ( done-head trans1 ... transn ) ( R: 0 q-head )
304 begin
305 dup isoc-transfer-bad? ?dup if
306 r> r> ?dup if
307 >r >r drop
308 else
309 swap >r >r
310 then
311 then
312 dup dump-isoc-transfer
313 r@ =
314 until
315 r> drop
316 r>
317;
318
319: wait-for-last-isoc-reply ( endp-d -- reply-code )
320 dup wait-till-stopped if \ endpoint done
321 bless-done-q
322 \ can't be any replies on current done q, so ping-pong:
323 dup ping-pong take-transfer-d's ( done-q-head )
324 check-isoc-packets \ look for error codes, dump transfer-d's
325 else
326 drop time-out-error
327 then
328;
329
330: dump-done-q ( endpoint-d -- )
331 dup code-done-q @ if
332 dup code-done-q @ tuck swap
333 dump-following-transfer-d's dump-transfer
334 else drop
335 then
336;
337
338
339\ XXX needs change to return a nak for execute-1-interrupt?
3402 constant usb-ack
3416 constant usb-nak
342e constant usb-stall
343
344\ hw-err? is anything other than usb ack, nak, or stall
345: translate-code ( reply-code -- hw-err? | stat 0 )
346 ?dup if
347 dup stall-error = if drop usb-stall 0 then
348 else usb-ack 0
349 then
350;
351
352
353\ How do we process the transfers in order? Does it matter?
354\ Right now the done transfers are put on the chip done q in reverse order,
355\ earlier done ones are pushed towards the tail of the q (it's a "stack").
356\ They are moved to the endpoint done q's in the same order (they are
357\ "stacks"). The distributor code is simpler and faster this way, which
358\ is a good thing, since it executes on the 10 ms tick timer.
359
360\ Could give each transfer descriptor a sequence number, and keep the last
361\ number in the endpoint. Then could look at each done transfer in order
362\ of the sequence.
363
364\ Doesn't look like we need sequence numbers:
365\ Can we assume that if transfer 2 shows up on a done q, that transfer 1
366\ went through ok? And is on some q already (or already disposed of by the
367\ code)? At least can assume that 1 is somewhere. Looks like can assume
368\ that 1 went ok, except for isoc transfers.
369
370\ For general transfers, any code other than no-error will cause endpoint to
371\ halt. isoc transfers will never halt.
372
373\ isoc transfers have error codes in the transfer descriptor fields as well
374\ as the completion code field. The completion code may be no-error, while
375\ some packet status words may have error codes.
376
377\ So, when the code takes a done q, it can reverse the transfer d's to get
378\ them in sequence of completion, or just dump all but the latest executed.
379
380\ So for a non-isoc, non-repeated interrupt, interface method, wait until
381\ either the last transfer is finished, or some transfer gets an error.
382\ If last transfer is ok, report good back to caller. Otherwise, report
383\ error of some sort.