Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / obp / dev / sun4v-devices / vdisk / methods.fth
CommitLineData
920dae64
AT
1\ ========== Copyright Header Begin ==========================================
2\
3\ Hypervisor Software File: methods.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: @(#)methods.fth 1.5 07/04/10
43purpose: Virtual Disk driver methods
44copyright: Copyright 2007 Sun Microsystems, Inc. All Rights Reserved
45copyright: Use is subject to license terms.
46
47external
48
49d# 512 constant block-size
50
51: dma-alloc ( size -- vaddr ) pagesize swap 0 claim ;
52: dma-free ( vaddr size -- ) swap release ;
53: dma-sync ( virt-addr dev-addr size -- ) 3drop ;
54: dma-map-out ( vaddr devaddr n -- ) 3drop ;
55: dma-map-in ( vaddr size cache? -- devaddr )
56 2drop
57;
58
59headerless
60
61/vdisk-attr-msg /vdsk-descr-msg max value /vdsk-descr-buf \ Size of the descr
62 \ buffer is max of attr and descr
63 \ structures.
64h# 8000 value /max-transfer \ Maximum transfer size is 32k bytes
65
66fload ${BP}/dev/sun4v-devices/ldc/methods.fth
67
68\ If the vDisk client does not use the VTOC service, it must specify a value
69\ of 0xff for the slice field for read and write transactions so that the
70\ server knows that the offset specified is the absolute offset relative to
71\ the start of a disk. See VIO specification for details.
72
73h# ff constant use-absolute-disk-offset
74
75vdev-disk-client to current-vio-dev
760 value debug-vdisk? \ Debug message enabler
77vd-disk-type-unk value vd-disk-type \ Stores type of virtual disk, unknown, disk or slice
781 value use-block-read?
79
808 value vdsk-sid \ Variable to hold sequence ID
81d# 200 value vd-retries \ Variable to hold # of retries
820 value vdsk-descr-buf \ Variable to hold vdisk descriptor buffer
83
840 value offset-low \ Low Offset to start of partition
850 value offset-high \ High Offset to start of partition
860 value label-package \ Stores ihandle for label package
870 value deblocker \ Stores ihandle for deblocker package
880 value ldc-up? \ flag, Set if LDC is up
890 value vdsk-seq \ Sequence# for the next request
900 value cur-vdsk-seq \ Sequence# of the current request
91
92: init-deblocker ( -- okay? )
93 " " " deblocker" $open-package to deblocker
94 deblocker if
95 true
96 else
97 cmn-error[ " Can't open deblocker package" ]cmn-end false
98 then
99;
100
101: init-label-package ( -- okay? )
102 0 to offset-high 0 to offset-low
103 my-args " disk-label" $open-package dup to label-package
104 if
105 0 0 " offset" label-package $call-method to offset-high to offset-low
106 true
107 else
108 cmn-error[ " Can't open disk label package" ]cmn-end false
109 then
110;
111
112\ The service domain may be down or rebooting... Keep retrying for 5 minutes
113: open-vdisk-ldc ( -- error? )
114 get-msecs d# 300.000 + \ 5 minutes later
115 begin ( finish-time )
116 get-msecs over < ( finish-time keep-trying? )
117 while ( finish-time )
118 vd-ldcid ldc-mode-unreliable ldc-open if ( finish-time )
119 true to ldc-up? ( finish-time )
120 drop false exit ( false )
121 then ( finish-time )
122 cmn-warn[
123 " Timeout connecting to virtual disk server... retrying"
124 ]cmn-end
125 d# 5000 ms ( finish-time )
126 repeat
127 cmn-warn[ " Unable to connect to virtual disk server" ]cmn-end
128 drop true ( true )
129;
130
131: close-vdisk-ldc ( -- )
132 ldc-close 0 to ldc-up?
133;
134
135\ Retry a few times if EWOULDBLOCK, print out warning message if didn't get EOK.
136\ Only update seqid upon successful return because Solaris counter part
137\ doesn't like new seqid if OBP higher level SW do retries
138: send-to-ldc ( buf len -- #bytes )
139 0 vd-retries 0 do ( buf len status )
140 drop 2dup ( buf len buf len )
141 ldc-write ( buf len #bytes status )
142 dup HV-EOK <> if ( buf len #bytes status )
143 dup HV-EWOULDBLOCK <> if ( buf len #bytes status )
144 dup LDC-NOTUP = if ( buf len #bytes status )
145 cmn-warn[ " Sending packet to LDC but LDC is Not Up!" ]cmn-end
146 2drop 2drop 0 unloop exit ( 0 )
147 then
148 cmn-warn[ " Sending packet to LDC, status: %d" ]cmn-end
149 3drop 0 unloop exit ( 0 )
150 then
151 else ( buf len #bytes status )
152 cur-vdsk-seq 1+ to vdsk-seq
153 drop nip nip unloop exit ( #bytes )
154 then
155 nip ( buf len status )
156 \ Every 20 loops, roughly 20 seconds (ldc-write can take @ 1s),
157 \ print a retrying message
158 i 1+ d# 20 mod 0= if
159 cmn-warn[
160 " Timeout sending package to LDC ... retrying"
161 ]cmn-end
162 then
163 loop ( buf len status )
164 3drop 0
165 cmn-warn[ " Sending packet to LDC timed out!" ]cmn-end
166;
167
168
169: receive-from-ldc ( buf len -- #bytes )
170 0 vd-retries 0 do ( buf len status )
171 drop 2dup ldc-read ( buf len #bytes status )
172 dup HV-EOK <> if ( buf len #bytes status )
173 dup HV-EWOULDBLOCK <> if ( buf len #bytes status )
174 dup LDC-NOTUP = if ( buf len #bytes status )
175 cmn-warn[
176 " Receiving packet from LDC but LDC is Not Up!"
177 ]cmn-end
178 2drop 2drop 0 unloop exit ( 0 )
179 then
180 cmn-warn[ " Receiving packet from LDC, status: %d" ]cmn-end
181 3drop 0 unloop exit ( 0 )
182 then
183 else ( buf len #bytes status )
184 \ Treat EOK with length = 0 same as EWOULDBLOCK at LDC layer
185 \ in which case just retry
186 over if ( buf len #bytes status )
187 drop nip nip unloop exit ( #bytes )
188 then
189 then ( buf len #bytes status )
190 nip ( buf len status )
191 \ Every 20 loops, roughly 20 seconds (ldc-read can take @ 1s),
192 \ print a retrying message
193 i 1+ d# 20 mod 0= if
194 cmn-warn[
195 " Timeout receiving packet from LDC ... retrying"
196 ]cmn-end
197 then
198 loop ( buf len status )
199 3drop 0
200 cmn-warn[ " Receiving packet from LDC timed out!" ]cmn-end
201;
202
203' receive-from-ldc is retrieve-packet
204
205\ Set up vio-msg-tag, sid and seq
206: set-descr-req-header ( -- )
207 vdsk-descr-buf /vdsk-descr-msg erase ( )
208
209 vio-msg-type-data vio-subtype-info vio-desc-data ( type stype env )
210 vdsk-descr-buf set-vio-msg-tag ( )
211 vdsk-sid vdsk-descr-buf tuck >vio-sid l! ( buf )
212
213 vd-disk-type over >vdsk-slice c! ( buf )
214 vdsk-seq swap 2dup >vdsk-seq x! ( seq buf )
215 >vdsk-reqid x! ( )
216 vdsk-seq to cur-vdsk-seq
217;
218
219: send-descr-req ( -- ok? )
220 vdsk-descr-buf /vdsk-descr-msg send-to-ldc ( len )
221 /vdsk-descr-msg = ( ok? )
222;
223
224\ Send VDS in-band descriptor ring request
225: send-descr-read-req ( size offset cadr ck# -- ok? )
226 set-descr-req-header ( size offset cadr ck# )
227 2swap over swap ( cadr ck# size size offset )
228 block-size / ( cadr ck# size size boffset )
229 vdsk-descr-buf tuck >vdsk-addr x! ( cadr ck# size size buf )
230 tuck >vdsk-nbytes x! ( cadr ck# size buf )
231 vdsi-bread over >vdsk-operation c! ( cadr ck# size buf )
232 vdsk-#cookies over >vdsk-#cookies l! ( cadr ck# size buf )
233 >vdsk-cookie fill-in-vio-cookie ( )
234 send-descr-req
235;
236
237: vdsk-ack-msg? ( -- yes? )
238 vdsk-descr-buf get-vio-msg-tag ( env stype type )
239 vio-desc-data vio-subtype-ack vio-msg-type-data ( desc subtype msg-type )
240 vio-tag-match? 0= if ( )
241 false exit ( false )
242 then
243
244 vdsk-descr-buf >vdsk-seq x@ ( seq )
245
246 cur-vdsk-seq = if ( )
247 \ Status follows the definition in /usr/include/sys/errno.h
248 vdsk-descr-buf >vdsk-status l@ 0= ( yes? )
249 else
250 cmn-warn[ " vdisk response packet out of sequence" ]cmn-end
251 false ( false )
252 then
253;
254
255\ Get an ACK for our request
256\ The receive-from-ldc times out in @ 3 minute. Try one additional
257\ time in case do not get descr-ack the first time around.
258: get-descr-ack? ( -- yes? )
259 2 0 do ( )
260 vdsk-descr-buf /vdsk-descr-msg receive-from-ldc ( rlen )
261 /vdsk-descr-msg = if ( )
262 vdsk-ack-msg? if ( )
263 true unloop exit ( true )
264 then
265 then
266 loop false ( false )
267;
268
269: disk-read ( size addr offset -- #bytes )
270 debug-vdisk? if 3dup ." disk-read: offset addr size: " u. u. u. cr then
271 >r >r dup dup r> swap r> -rot ( size size offset addr size)
272 ldc-add-map-table-entries ( size size offset cadr ck# )
273 debug-vdisk? if 2dup ." #cookie cookie-addr " u. u. cr then
274 ( size size offset cadr ck# )
275 send-descr-read-req if ( #bytes )
276 get-descr-ack? 0= if ( #bytes )
277 drop 0 ( 0 )
278 then
279 else ( #bytes )
280 cmn-warn[ " Can't send vdisk read request!" ]cmn-end
281 drop 0 ( 0 )
282 then ( #bytes|0 )
283;
284
285\ Fill in version negotiation pkt content and send out
286: send-vdsk-ver-msg ( -- ok? )
287 vdsk-descr-buf /vio-ver-msg erase ( )
288
289 \ vdsk session id is only updated once during version negotiation
290 vdsk-sid 1+ dup to vdsk-sid ( sid )
291 vdsk-descr-buf >vio-sid l! ( )
292
293 vio-msg-type-ctrl vio-subtype-info vio-ver-info ( msg-type sub-type ver )
294 vdsk-descr-buf set-vio-msg-tag ( )
295
296 vdev-disk-client vdisk-minor vdisk-major ( dev-type minor major )
297 vdsk-descr-buf set-vio-msg-ver ( )
298
299 vdsk-descr-buf /vio-ver-msg ( buf len )
300 send-to-ldc ( #bytes )
301
302 /vio-ver-msg = ( ok? )
303;
304
305' send-vdsk-ver-msg is send-vio-ver-msg
306
307\ The ack parameter may be ack or nack
308: send-vdsk-ack-msg ( buf ack -- ok? )
309 over >vio-subtype c! ( buf )
310 vdsk-sid over >vio-sid l! ( buf )
311 /vio-ver-msg send-to-ldc ( len )
312 /vio-ver-msg =
313;
314
315' send-vdsk-ack-msg is send-vio-ack-msg
316
317: vdsk-compatible-ver? ( buf -- yes? )
318 dup >vio-ver-major w@ vdisk-major = ( buf flag1 )
319 swap >vio-ver-minor w@ vdisk-minor = ( flag1 flag2 )
320 and ( yes? )
321;
322
323' vdsk-compatible-ver? is vio-compatible-ver?
324
325\ Send our attributes
326: send-vdsk-attr ( -- ok? )
327 vdsk-descr-buf /vdisk-attr-msg erase ( )
328 vio-msg-type-ctrl vio-subtype-info vio-attr-info ( msf-type subtype attr )
329 vdsk-descr-buf set-vio-msg-tag ( )
330 vdsk-sid vdsk-descr-buf >vio-sid l! ( )
331
332 vdsk-descr-buf /max-transfer block-size / over >vdisk-mtu x! ( buf )
333 block-size over >vdisk-bsize l! ( buf )
334 vio-desc-mode swap >vdisk-xfer-mode c! ( )
335
336 vdsk-descr-buf /vdisk-attr-msg send-to-ldc ( #bytes )
337 /vdisk-attr-msg = ( ok? )
338;
339' send-vdsk-attr is send-vio-attr
340
341: send-vdsk-rdx ( buf -- ok? )
342 dup /vdisk-attr-msg erase ( buf )
343 >r vio-msg-type-ctrl vio-subtype-info vio-rdx ( msg-type subtype rdx ) ( r: buf )
344 r@ set-vio-msg-tag ( ) ( r: buf )
345 vdsk-sid r@ >vio-sid l! ( )
346 r> /vdisk-attr-msg send-to-ldc ( #bytes )
347 /vdisk-attr-msg = ( ok? )
348;
349
350' send-vdsk-rdx is send-vio-rdx
351
352\ Inspect VDS attributes, if vdisk-type is type-disk then set slice to use
353\ an absolute disk offset
354: (update-vd-disk-type ( buf -- )
355 >vdisk-type c@ vd-disk-type-disk = if ( )
356 use-absolute-disk-offset to vd-disk-type ( )
357 then
358;
359
360' (update-vd-disk-type is update-vd-disk-type
361
362\ Stages:
363\ Version negotiation -> Vdisk Attr info -> Dring info -> RDX
364: init-vdsk-conn ( -- ok? )
365 vdsk-descr-buf version-negotiation if ( )
366 vdsk-descr-buf /vdisk-attr-msg vio-exchange-attr if ( )
367 true exit ( true )
368 then
369 then
370 cmn-warn[ " Communication error with Virtual Disk Server!" ]cmn-end
371 false ( false )
372;
373
374\ The disk writes are not supported, just return 0 bytes written
375: disk-write ( size raddr offset -- #bytes )
376 3drop 0
377;
378
379headerless
380: r/w-blocks ( addr block# #blocks read? -- #read/#written )
381 >r block-size * -rot ( size addr block# ) ( r: read? )
382 block-size * ( size addr offset ) ( r: read? )
383 r> if ( size addr offset )
384 disk-read ( #bytes )
385 else ( size addr offset )
386 disk-write ( #bytes )
387 then ( #bytes )
388 block-size / ( #read|#written )
389;
390
391\ Allocate vdisk descriptor buffer
392: allocate-vdsk-descr-buf
393 8 /vdsk-descr-buf 0 claim to vdsk-descr-buf ( )
394;
395
396\ Release and reset vdisk descriptor buffer
397: deallocate-vdsk-descr-buf
398 /vdsk-descr-buf vdsk-descr-buf release ( )
399 0 to vdsk-descr-buf
400;
401
402external
403\ These three methods are called by the deblocker.
404
405: max-transfer ( -- #bytes ) /max-transfer ;
406: read-blocks ( addr block# #blocks -- #read ) true r/w-blocks ;
407: write-blocks ( addr block# #blocks -- #written ) false r/w-blocks ;
408
409: #blocks ( -- true | n false ) true ;
410
411: open ( -- flag )
412 open-vdisk-ldc if
413 false exit ( false )
414 then
415
416 allocate-vdsk-descr-buf ( )
417
418 init-deblocker 0= if
419 deallocate-vdsk-descr-buf ( )
420 close-vdisk-ldc ( )
421 false exit ( false )
422 then
423 debug-vdisk? if ." deblocker opened." cr then ( )
424
425 init-vdsk-conn 0= if ( )
426 deallocate-vdsk-descr-buf ( )
427 deblocker close-package ( )
428 close-vdisk-ldc ( )
429 false exit ( false )
430 then
431
432 init-label-package 0= if ( )
433 deallocate-vdsk-descr-buf ( )
434 deblocker close-package ( )
435 close-vdisk-ldc ( )
436 false exit ( false )
437 then
438 true ( true )
439 debug-vdisk? if ." label pkg opened." cr then ( true )
440;
441
442: close ( -- )
443 deallocate-vdsk-descr-buf ( )
444
445 label-package ?dup if ( )
446 close-package ( )
447 then
448 deblocker ?dup if ( )
449 close-package ( )
450 then
451 ldc-up? if ( )
452 close-vdisk-ldc
453 then
454;
455
456: seek ( offset.low offset.high -- okay? )
457 offset-low offset-high d+ " seek" deblocker $call-method ( okay? )
458;
459
460: read ( addr len -- actual-len )
461 " read" deblocker $call-method ( actual-len )
462;
463
464: write ( addr len -- actual-len )
465 " write" deblocker $call-method ( actual-len )
466;
467
468: load ( addr -- size )
469 " load" label-package $call-method ( size )
470;
471
472: size ( -- d.size )
473 " size" label-package $call-method ( d.size )
474;
475
476headerless