Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / obp / dev / usb-devices / kbd / usbutils.fth
CommitLineData
920dae64
AT
1\ ========== Copyright Header Begin ==========================================
2\
3\ Hypervisor Software File: usbutils.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 ============================================
42\ id: @(#)usbutils.fth 1.33 04/09/22
43\ purpose:
44\ copyright: Copyright 2004 Sun Microsystems, Inc. All Rights Reserved
45\ copyright: Use is subject to license terms.
46
47external
48
49\ XXX Must use set-report(output) request.
50\ : set-leds ( which-leds? -- )
51\ ;
52
53\ Nothing here yet because we're not sure if bell will be supported in
54\ USB keyboards.
55\ XXX called from ring-bell in keyboard.fth
56: ring-keyboard-bell ( -- ?? )
57;
58
59\ Do a set-protocol to get to boot mode.
60\ Interface Protocol == 0 (Keyboard).
61
62: set-kbd-bootmode ( -- hw-err? | stat 0 )
63 h# 21 set-prtcl-buff^v >ctrl-pkt-breqtype c! \ class request
64 h# b set-prtcl-buff^v >ctrl-pkt-brequest c! \ 0xb=set protocol
65 0 set-prtcl-buff^v >ctrl-pkt-wvalue le-w! \ 0=boot protocol
66 my-interface set-prtcl-buff^v >ctrl-pkt-windex le-w!
67 0 set-prtcl-buff^v >ctrl-pkt-wlength le-w! \ 0=no data
68
69 my-speed
70 1 \ dir; no, don't xfer data from device to mem
71 0max-packet \ max-pkt
72 0 \ buf-adr; no data coming back
73 0 \ buf-len; no data coming back
74 set-prtcl-buff^v \ pkt-adr
75 /ctrl-pkt \ pkt-len
76 my-endpt \ endpt
77 my-addr \ usb-adr
78 ( low-speed? dir max-pkt buf-adr buf-len rqst-adr rqst-len end-pt usb-adr )
79
80 execute-control ( hw-err? | stat 0 )
81;
82
83: get-kbd-protocol ( -- hw-err? | stat 0 )
84 h# a1 set-prtcl-buff^v >ctrl-pkt-breqtype c! \ class request
85 h# 3 set-prtcl-buff^v >ctrl-pkt-brequest c! \ 0x3=get protocol
86 0 set-prtcl-buff^v >ctrl-pkt-wvalue le-w!
87 my-interface set-prtcl-buff^v >ctrl-pkt-windex le-w!
88 1 set-prtcl-buff^v >ctrl-pkt-wlength le-w! \ 1=#bytes data
89
90 my-speed
91 0 \ dir; yes, do xfer data from device to mem
92 0max-packet \ max-pkt
93 1-byte^v \ buf-adr for data coming back
94 0 over c! \ clear 1 data byte
95 1 \ len of data coming back
96 set-prtcl-buff^v \ pkt-adr
97 /ctrl-pkt \ pkt-len
98 my-endpt \ endpt
99 my-addr \ usb-adr
100 ( low-speed? dir max-pkt buf-adr buf-len rqst-adr rqst-len end-pt usb-adr )
101
102 execute-control ( hw-err? | stat 0 )
103;
104
105: set-kbd-idle ( -- hw-err? | stat 0 )
106 h# 21 set-prtcl-buff^v >ctrl-pkt-breqtype c! \ class request
107 h# a set-prtcl-buff^v >ctrl-pkt-brequest c! \ 0xa=set idle
108 h# 7d00 set-prtcl-buff^v >ctrl-pkt-wvalue le-w! \ idle=125x4 ms.
109 my-interface set-prtcl-buff^v >ctrl-pkt-windex le-w!
110 0 set-prtcl-buff^v >ctrl-pkt-wlength le-w! \ 0=no data
111
112 my-speed
113 1 \ dir; no, don't xfer data from device to mem
114 0max-packet \ max-pkt
115 0 \ buf-adr; no data coming back
116 0 \ buf-len; no data coming back
117 set-prtcl-buff^v \ pkt-adr
118 /ctrl-pkt \ pkt-len
119 my-endpt \ endpt
120 my-addr \ usb-adr
121 ( low-speed? dir max-pkt buf-adr buf-len rqst-adr rqst-len end-pt usb-adr )
122
123 execute-control ( hw-err? | stat 0 )
124;
125
126: get-kbd-idle ( -- hw-err? | stat 0 )
127 h# a1 set-prtcl-buff^v >ctrl-pkt-breqtype c! \ class request
128 2 set-prtcl-buff^v >ctrl-pkt-brequest c! \ 2=get idle
129 0 set-prtcl-buff^v >ctrl-pkt-wvalue le-w!
130 my-interface set-prtcl-buff^v >ctrl-pkt-windex le-w!
131 1 set-prtcl-buff^v >ctrl-pkt-wlength le-w! \ 1=#bytes data
132
133 my-speed
134 0 \ dir; yes, do xfer data from device to mem
135 0max-packet \ max-pkt
136 1-byte^v \ buf-adr for data coming back
137 0 over c! \ clear 1 byte of data
138 1 \ len of data coming back
139 set-prtcl-buff^v \ pkt-adr
140 /ctrl-pkt \ pkt-len
141 my-endpt \ endpt
142 my-addr \ usb-adr
143 ( low-speed? dir max-pkt buf-adr buf-len rqst-adr rqst-len end-pt usb-adr )
144
145 execute-control ( hw-err? | stat 0 )
146;
147
148
149\ We've received a stall status when checking the interrupt status with
150\ the HA. Make a certain number of attempts to unstall, and then throw
151\ when the last attempt is unsuccessful.
152
153: issue-unstall ( -- hw-err? | stat 0 )
154 unstall-cnt 9 > if
155 \ poop maybe we should attempt to reset the device, then reconfigure
156 \ it for boot mode and set the ticker again, and keep track of *that*
157 \ process for x number of times...
158 ." USB console device could not be unstalled..." cr
159 true throw
160 else
161 \ issue the unstall via execute-control
162 1 std-pkt-buff^v >ctrl-pkt-breqtype c! \ 0x1= clear feature
163 1 std-pkt-buff^v >ctrl-pkt-brequest c! \ 0x1=CLEAR_FEATURE
164 0 std-pkt-buff^v >ctrl-pkt-wvalue le-w! \ 0=ENDPOINT_STALL
165 my-int-endpt std-pkt-buff^v >ctrl-pkt-windex le-w!
166 0 std-pkt-buff^v >ctrl-pkt-wlength le-w! \ 0=no data
167
168 my-speed
169 1 \ dir=no xfer data usb->mem
170 /ctrl-pkt \ max-pkt = len of outgoing request
171 0 0 \ buf-adr, buf-len
172 get-descr-buff^v \ request-adr
173 /ctrl-pkt \ request-len
174 my-endpt \ endpoint
175 my-addr \ usb-adr
176 ( speed dir max-pkt buf-adr buf-len rqst-adr rqst-len end-pt usb-adr )
177
178 execute-control ( hw-err? | stat 0 )
179
180 unstall-cnt 1+ to unstall-cnt
181 then
182;
183
184
185: attempt-unstall ( -- ack|nak|stall )
186 issue-unstall ( hw-err?|stat 0 )
187 0<> if
188 true throw \ hw-err during unstall attempt
189 then
190;
191
192
193\ headers \ XXX for debugging
194
1955 constant no-response-error
196
1970 value no-response-cnt
198
199: possible-no-response ( hw-err -- hw-err )
200 dup no-response-error = if
201 no-response-cnt 1+ to no-response-cnt
202 then
203;
204
205defer maybe-message
206
207: .no-response ( -- )
208 ['] noop to maybe-message \ publish once only
209 ." USB keyboard not responding, please power cycle." cr
210;
211
212' .no-response to maybe-message
213
214: not-responding? ( -- not-there? )
215 no-response-cnt d# 10 >=
216;
217
218: dummy-keys ( -- Stop-a? )
219 keybuff-curr^v /key-info-buff erase
220 eval-key-data
221;
222
223\ Send off to the HA/parent to see if a keyboard packet is present,
224\ and if so then send the data off to the key evaluation routine.
225\ Check for hardware status errors, and also check for usb NAK (no
226\ packets waiting) and STALL (indicating a usb function problem).
227
228: poll-usb ( -- stopA? )
229 not-responding? if \ essentially no recovery
230 maybe-message
231 dummy-keys exit \ dummy to clear other code
232 then
233 keybuff-curr^v our-ha-token @ int-transaction-status ( hw-err?|stat 0)
234 ?dup if ( hw-err )
235 possible-no-response drop
236 dummy-keys exit \ dummy to clear other code
237 then ( stat )
238
239 0 to no-response-cnt \ still responding
240
241 case
242 h# 6 of \ nak
243 false
244 endof ( no-Stop-a )
245
246 h# e of \ stall
247 \ poop turn-off tick timer?
248 \ poop turn-off host timer?
249 begin
250 attempt-unstall ( ack|nack|stall )
251 \ unstall attempt has built-in "max count"
252 \ loop check; does throw when at max count
253 2 = if ( ) \ ack rcvd from unstall
254 true ( loop-exit-flag )
255 else \ nack or stall from unstall attempt
256 false ( loop-noexit-flag )
257 then
258 until ( )
259 \ poop turn-on tick timer?
260 \ poop turn-on host timer?
261 false ( no-Stop-A )
262 endof
263
264 2 of \ ack
265 eval-key-data ( Stop-A? )
266 endof ( Stop-A? )
267 endcase
268;
269
270
271\ If keyboard "interrupts" were already running then turn them off.
272
273: makesure-kbdints-off ( -- )
274 our-ha-token @ dup -1 <> if ( token )
275 disable-int-transactions to ha-toggle ( )
276 -1 our-ha-token ! ( )
277 else
278 drop ( )
279 then
280;
281
282
283\ For "reset", turn off repeat-interrupt-request if it's already on and
284\ set the token to -1 to indicate interrupts are off. Set up the device
285\ to be a "boot" device, and initialize software variables. Then send 1
286\ interrupt request and look at its status to see if the keyboard is
287\ (still) there. If there and everything is ok then turn on the repeated
288\ interrupts, and link our tick timer to check the the status
289\ periodically.
290\ [ For the Sun keyboards, reset was in the probe.fth file. ]
291
292: init-kbd ( -- )
293 makesure-kbdints-off ( )
294 ['] set-kbd-bootmode do-ctrl/err-loop ( )
295 ['] set-kbd-idle do-ctrl/err-loop
296 clear-keyboard ( )
297;
298
299\ from parent device node if an interface, from my node if combined device
300: set-my-0max-packet ( -- )
301 " 0max-packet" get-inherited-property ( true | adr len false )
302 if
303 ." Unable to get 0max-packet for usb keyboard." cr
304 true throw
305 else
306 decode-int to 0max-packet
307 2drop
308 then
309;
310
311\ low-speed property from my node only, else is regular speed
312: set-my-speed ( -- )
313 " low-speed" get-my-property ( true | adr len false )
314 if \ regular speed
315 false
316 else \ low speed
317 2drop true
318 then
319 to my-speed
320;
321
322: set-my-addr ( -- )
323 " assigned-address" get-inherited-property ( true | addr len false )
324 if
325 ." Unable to get assigned address for usb keyboard." cr
326 true throw
327 else
328 decode-int to my-addr 2drop
329 then
330;
331
332: $>endpt ( addr len -- n ) \ this better work, no throw
333 base @ >r hex
334 dup if
335 $number if \ XXX dreadfully wrong, no enpt #
336 cr ." missing endpoint#"
337 1 \ XXX probably wrong here
338 then
339 else 2drop 1 \ default to endpt 1
340 then
341 r> base !
342;
343
344: $>packet ( addr len -- n )
345 base @ >r hex
346 dup if
347 $number if \ XXX dreadfully wrong, no max-pkt#
348 cr ." missing max-packet#"
349 8 \ Sun default
350 then
351 else 2drop 8 \ Sun default; seriously wrong
352 then
353 r> base !
354;
355
356\ read endpoints and max-packets
357: set-my-endpts ( -- )
358 " endpoints" get-inherited-property ( true | addr len false )
359 if
360 ." Unable to get endpoints for usb keyboard." cr
361 true throw
362 else
363 decode-string 2swap 2drop
364 ascii , left-parse-string 2drop \ always 0, for my-endpt ( control )
365 ascii , left-parse-string 2drop \ could use for 0max-packet
366 ascii , left-parse-string \ assume this is the interrupt endpt
367 $>endpt h# f and \ XXX dumping direction for now
368 to my-int-endpt
369 ascii , left-parse-string \ its max-packet
370 $>packet to my-int-max-packet
371 2drop ( ) \ dump any other endpts for now
372 then
373;
374
375: set-my-interface ( -- )
376 " interface#" get-my-property \ must be in my node
377 if \ seriously wrong
378 0 \ Sun default
379 else
380 decode-int
381 nip nip
382 then
383 to my-interface
384;
385
386\ The country layout is determined in the open routine, and the
387\ keymap presence/correctness is determined at that time also.
388\ True is returned if everything is OK, otherwise false is returned.
389
390\ 0 instance value kbd-driver
391: install-device ( -- everything-ok? )
392 -1 our-ha-token ! 1 to ha-toggle
393
394 set-my-0max-packet set-my-speed
395 set-my-addr set-my-endpts
396 set-my-interface
397
398 init-kbd
399
400\ forced-keyboard-mode? or ( ok? )
401
402 8 \ ms
403 our-toggle \ toggle
404 my-speed
405 0 \ dir = xfer from USB to host (us)
406 my-int-max-packet
407 8 \ buf-len; max length for data being returned
408 my-int-endpt \ endpoint
409 my-addr \ usb-adr
410 ( ms toggle low-speed? dir max-pkt buf-len endpoint usb-adr )
411
412 enable-int-transactions ( HAtoken )
413
414 dup if ( HAtoken )
415 our-ha-token ! true ( yes-ok )
416 else ( not-ok )
417 \ A returned token of 0 indicates that the HA wouldn't honor our
418 \ request, meaning that one of the parameters is probably bogus.
419 ." HostAdapter didn't honor keyboard enable-int-transactions." cr
420 drop true throw
421 then
422;
423
424: alloc-vaddr-buffs ( -- )
425 /ctrl-pkt dma-alloc to set-prtcl-buff^v
426 /ctrl-pkt dma-alloc to get-descr-buff^v
427 /hid-descriptor dma-alloc to hid-descr-buff^v
428 /key-info-buff dma-alloc to keybuff-curr^v
429 /ctrl-pkt dma-alloc to std-pkt-buff^v
430 1 dma-alloc to 1-byte^v
431;
432
433
434: dealloc-vaddr-buffs ( -- )
435 set-prtcl-buff^v /ctrl-pkt dma-free
436 get-descr-buff^v /ctrl-pkt dma-free
437 hid-descr-buff^v /hid-descriptor dma-free
438 keybuff-curr^v /key-info-buff dma-free
439 std-pkt-buff^v /ctrl-pkt dma-free
440 1-byte^v 1 dma-free
441;