Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / obp / dev / network / ophir / core.fth
CommitLineData
920dae64
AT
1\ ========== Copyright Header Begin ==========================================
2\
3\ Hypervisor Software File: core.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: @(#)core.fth 1.2 06/05/11
43purpose: Intel Ophir/82571 Core routines
44copyright: Copyright 2006 Sun Microsystems, Inc. All Rights Reserved
45copyright: Use is subject to license terms.
46
47headerless
480 instance value restart?
49defer restart-net ['] true to restart-net
50\ ============================================================================
51\ Data structures
52\ ----------------------------------------------------------------------------
53
54\ RX descriptor
55struct
56 /x field >rx-buf \ Pointer to data buffer
57 /w field >rx-length \ Length of data buffer
58 /w field >rx-csum \ Checksum
59 /c field >rx-status
60 /c field >rx-error
61 /w field >rx-special \ Special - unused (needed for VLAN)
62constant /rxd
63
64\ RX Status bits
65h# 01 constant rxstat.dd \ Descriptor done
66h# 02 constant rxstat.eop \ End of packet
67h# 04 constant rxstat.ixsm \ Ignore checksum indication
68 \ Ignore bits 3-7.
69\ RX Error bits
70h# 01 constant rxerr.ce \ CRC or alignment error
71h# 02 constant rxerr.se \ Symbol error (TBI)
72h# 04 constant rxerr.seq \ Sequence error (TBI)
73\ Ignore other errors - applicable to
74\ offload features.
75
76\ Miscellaneous rx constants and pointers
77h# 40 constant #rxds \ Number of rx descriptors
78#rxds /rxd * constant /rxd-ring \ Size of rx descriptor table
790 value rxd-base \ Base of descriptor table
800 value rxd-end \ End of descriptor table in bytes.
810 value rxd-tail \ Shadow of hardware tail pointer.
820 value rxd-dma-base \ Hardware address of descriptor array.
83d# 2048 constant /rx-buf \ Size of one rx buffer
84/rx-buf #rxds *
85constant /rx-buf-array \ Total amount of memory allocated for
86 \ rx buffers.
870 value rx-buf-base \ Base of rx buffer array
88
89\ TX descriptor
90struct
91 /x field >tx-buf \ Pointer to data buffer
92 /w field >tx-length \ Length of data buffer
93 /c field >tx-cso \ Checksum offset (optional)
94 /c field >tx-cmd \ Command
95 /c field >tx-status
96 /c field >tx-css \ Checksum Start field (optional)
97 /w field >tx-special \ Special - unused (needed for VLAN)
98constant /txd
99
100\ TX command bits
101h# 01 constant txcmd.eop \ End of packet
102h# 02 constant txcmd.ifcs \ Insert Frame checksum
103h# 08 constant txcmd.rs \ Report status
104 \ All other bits ignored
105
106\ TX status bits
107h# 01 constant txstat.dd \ Descriptor done.
108h# 02 constant txstat.ec \ Excess collisions
109h# 04 constant txstat.lc \ Late collision
110
111\ TX constants and pointers
112h# 8 constant #txds \ Number of tx descriptors
113 \ (8 is the smallest possible)
114#txds /txd * constant /tx-ring \ Size of tx descriptor table
1150 value txd-base \ Base of descriptor table
1160 value txd-end \ End of descriptor table in bytes
1170 value txd-current \ Currently being transmitted buffer
1180 value txd-tail \ Shadow of hardware tail pointer
1190 value txd-dma-base \ Hardware address of descriptor array
120
121d# 2048 constant /tx-buf \ Size of one tx buffer
122/tx-buf #txds *
123 constant /tx-buf-array \ Total amount of memory
124 \ allocated for tx buffers.
1250 value tx-buf-base \ Base of tx buffer array
126
127\
128\ Memory layout: starting from cpu-dma-blk (which is therefore the same
129\ as rxd-base)
130\ Base Size Comments
131\ ========== ===== ========
132\ rxd-base /rxd-ring rx descriptors
133\ rx-buf-base /rx-buf-array rx data buffers
134\ txd-base /tx-ring tx descriptors
135\ tx-buf-base /tx-buf-array tx buffers
136\
137\ Set value of /dma-blk for "map-buffers"
138\
139/rxd-ring /rx-buf-array + ( /rx-data )
140/tx-ring /tx-buf-array + ( /rx-data /tx-data )
141+ /rxd + is /dma-blk \ Add /rxd to allow for alignment rounding.
142
143: rxd>d# ( desc -- index )
144 rxd-base - /rxd /
145;
146
147\ Write a value to the rx tail register
148: rx-tail! ( desc -- )
149 rxd>d# h# 2818 reg!
150;
151
152: txd>d# ( desc -- index )
153 txd-base - /txd /
154;
155
156\ Write a value to the tx tail register
157: tx-tail! ( desc -- )
158 txd-base - /txd / h# 3818 reg!
159;
160
161\
162\ Initialize the rx and tx descriptor rings and buffers.
163\ We aren't telling the hardware about these yet.
164\
165: .rx-ring ( -- )
166 ." Head: " h# 2810 reg@ .x
167 ." Tail: " h# 2818 reg@ .x cr
168 rxd-base #rxds 0 do
169 dup i /rxd * + ( adr desc )
170 dup local-x@ .x /x + local-x@ .x cr
171 loop
172 drop
173;
174
175: .tx-ring ( -- )
176 ." Head: " h# 3810 reg@ .x
177 ." Tail: " h# 3818 reg@ .x cr
178 txd-base #txds 0 do
179 dup i /txd * +
180 dup local-x@ .x /x + local-x@ .x cr
181 loop
182 drop
183;
184
185: init-rings ( base -- )
186 dup >r ( base ) ( r: base )
187 /rxd round-up ( desc-base ) \ Align descriptor base
188 dup is rxd-base
189 \ Tail starts off as first descriptor (head will be second)
190 \ That is, all buffers start off belonging to the chip,
191 \ except the tail itself.
192 dup is rxd-tail ( desc )
193 cpu>io-adr is rxd-dma-base ( )
194
195 rxd-base /rxd-ring + dup is rx-buf-base is rxd-end
196 #rxds 0 do
197 i /rx-buf * rx-buf-base + cpu>io-adr ( dma-adr )
198 i /rxd * rxd-base + tuck ( desc-adr dma-adr desc-adr )
199 \ Write the buffer address to the descriptor
200 >rx-buf local-x! ( desc-adr )
201 \ Clear the flags (buffer belongs to hw)
202 0 swap >rx-length local-x! ( )
203 loop
204
205 rx-buf-base /rx-buf-array + is txd-base
206 txd-base is txd-tail
207 txd-base /tx-ring + dup is tx-buf-base is txd-end
208 txd-base cpu>io-adr is txd-dma-base
209 #txds 0 do
210 i /tx-buf * tx-buf-base + cpu>io-adr ( dma-adr )
211 i /txd * txd-base + tuck ( desc dma-adr desc )
212 \ Write the buffer address to the descriptor
213 >tx-buf local-x! ( desc )
214 \ Clear the rest of the descriptor
215 0 over >tx-length local-x! ( desc )
216 \ Initialize command register.
217 txcmd.rs txcmd.eop or txcmd.ifcs or swap >tx-cmd local-c!
218 loop
219 \ Sync it all back to mem.
220 r> dup cpu>io-adr /dma-blk dma-sync ( ) ( r: )
221;
222
223\ ============================================================================
224\ Receive routines.
225\ ----------------------------------------------------------------------------
226
227\ Move to the next rx descriptor in the ring (ie
228\ wrap if needed).
229: next-rxd ( desc -- next-desc )
230 /rxd +
231 dup rxd-end >= if
232 drop rxd-base
233 then
234;
235
236: sync-rxd ( desc -- ) dup cpu>io-adr /rxd dma-sync ;
237: sync-rx-buf ( desc -- ) >rx-buf local@ dup io>cpu-adr swap /rx-buf dma-sync ;
238
239: return-buffer ( handle -- )
240 \ Clear status
241 0 over >rx-status local-c! ( desc )
242 0 over >rx-length local-w!
243 dup sync-rx-buf
244 dup rx-tail! ( desc )
245 is rxd-tail ( )
246;
247
248: receive-ready? ( -- pkt-waiting? )
249 rxd-tail next-rxd
250 dup sync-rxd ( desc )
251 >rx-status local-c@ ( status )
252 rxstat.dd and 0<> ( pkt-waiting? )
253;
254
255: receive ( -- pkt-handle pkt pktlen )
256 rxd-tail next-rxd ( desc )
257 dup >rx-buf local-x@ io>cpu-adr ( desc pkt )
258 over >rx-length local-w@ ( desc pkt len desc )
259;
260
261\ ============================================================================
262\ Main transmit routines
263\ ----------------------------------------------------------------------------
264
265\ Move to the next tx descriptor in the ring (ie
266\ wrap if needed).
267: next-txd ( desc -- next-desc )
268 /txd +
269 dup txd-end >= if
270 drop txd-base
271 then
272;
273
274: sync-tx-buf ( desc -- )
275 \ Might as well sync the descriptor here also.
276 dup dup cpu>io-adr /txd dma-sync
277 >tx-buf local-x@ dup io>cpu-adr swap /tx-buf dma-sync
278;
279
280: transmit-complete? ( desc -- complete? )
281 >tx-status local-c@ txstat.dd and 0<>
282;
283
284\ Wait for up to 4 seconds for the transmit to complete.
285: send-wait ( desc -- ok? )
286 d# 4000 get-msecs + ( desc tout )
287 begin
288 dup get-msecs >= while ( desc tout )
289 over transmit-complete? if
290 2drop true exit
291 then
292 repeat ( desc tout )
293 2drop
294 " Timeout waiting for transmit completion" diag-type-cr
295 true to restart?
296 false
297;
298
299: transmit ( buf len -- ok? )
300 txd-tail >r ( buf len ) ( r: desc )
301 dup r@ >tx-length local-w! \ Set length
302 r@ >tx-buf local-x@ io>cpu-adr swap cmove ( ) \ Copy data
303 0 r@ >tx-status local-c!
304 r@ sync-tx-buf
305
306 \ Increment shadow tail pointer.
307 r> dup next-txd dup to txd-tail ( desc desc' ) ( r: )
308 \ Write updated tail pointer to hardware (starts transmit)
309 tx-tail! ( desc )
310 \ Wait for the transmit to complete.
311 send-wait ( ok? )
312 \ At this point, errors we can see are:
313 \ Timeout waiting for send to complete - maybe need to restart net
314 \ Excess collisions.
315 \ Late collision.
316;
317
318: get-tx-buffer ( -- adr )
319 txd-tail >tx-buf local@ io>cpu-adr
320;
321
322\ ============================================================================
323\ Initialization routines
324\ ----------------------------------------------------------------------------
325
326\ Control register: address 0x0000
327: ctrl@ ( -- value ) 0 reg@ ;
328: ctrl! ( value -- ) 0 reg! ;
3291 d# 26 << constant ctrl.rst
3301 d# 05 << constant ctrl.asde
3311 d# 06 << constant ctrl.slu
332
333\ Receive address registers:
334\ Low: 5400 + 8*i
335\ Hi: 5404 + 8*i
336
337\ Set receive address low register[i]
338: ral! ( val i -- )
339 8 * h# 5400 + reg!
340;
341\ Set the i'th receive address hi register[i]
342: rah! ( val i -- )
343 8 * h# 5404 + reg!
344;
345: ra! ( val i -- )
346 8 * h# 5400 + regx!
347;
348
349
350: reset-chip ( -- )
351 ctrl.rst ctrl!
352 10 ms
353 \ Assume reset has completed.
354;
355
356: clear-multicast-table ( -- )
357 h# 5400 h# 5200 do
358 0 i reg!
359 /l +loop
360;
361
362
363\ Set the mac address in the receive address 0 registers.
364\ Clear the remaining registers and the multicast table array.
365
366: set-mac-address ( -- )
367 clear-multicast-table
368 mac-address drop ( mac-adr-ptr )
369 dup w@ wbflip
370 over 2 + w@ wbflip wljoin 0 ral! ( mac-adr-ptr )
371 4 + w@ wbflip h# 8000.0000 or 0 rah!
372 \ Clear remaining receive address registers.
373 d# 16 1 do
374 0 i ral!
375 0 i rah!
376 loop
377;
378
379: set-promis-mode ( -- )
380 h# 18 h# 0100 reg-bset \ Set upe and mpe
381;
382
383: init-mac-mode ( -- )
384 mac-mode case
385 promiscuous of set-promis-mode endof
386 endcase
387;
388
389: init-receive ( -- )
390 set-mac-address
391 0 h# 2820 reg! \ Clear receive delay timer
392 0 h# 282c reg! \ Clear receive absolute timer reg
393 /rxd-ring h# 2808 reg! \ Set receive descriptor length reg
394 \ Set the rx descriptor base address
395 rxd-base cpu>io-adr xlsplit h# 2804 reg! ( base.lo ) \ hi
396 h# 2800 reg! \ lo
397 rxd-tail rx-tail! \ Set tail (precalculated in init-rings)
398 \ Give all the buffers to the chip: the tail pointer has already
399 \ been initialized by init-rings - set the head to be the next descriptor.
400 rxd-tail next-rxd
401 rxd>d# h# 2810 reg!
402 h# 0001.0101 h# 2828 reg! \ rx descriptor control
403 \ Receive control:
404 \ Enable: 0000.0002 On.
405 \ Store bad packets: 0000.0004 Off.
406 \ Promiscuous bits: 0000.0018 Off.
407 \ Long packet enable: 0000.0020 Off.
408 \ Loopback mode: 0000.00c0 No loopback
409 \ RDMTS 0000.0300 Don't care. 0 is ok.
410 \ Multicast offset: 0000.3000 Don't care. 0 is ok.
411 \ Accept broadcast: 0000.8000 On.
412 \ Receive buf size: 0003.0000 0 == 2048 byte buffers.
413 \ Vlan Filter: 0004.0000 Off
414 \ CFI bits: 0018.0000 Off.
415 \ Discard pause frames: 0040.0000 On.
416 \ Pass mac control: 0080.0000 Off.
417 \ BSEX: 0200.0000 Off. None of that thank you!
418 \ Strip crc: 0400.0000 Off.
419 \
420 h# 0040.8002 h# 0100 reg-bset \ Now receiving!
421 init-mac-mode
422;
423
424: init-transmit ( -- )
425 \ Set transmit descriptor base address
426 txd-base cpu>io-adr xlsplit h# 3804 reg! ( base.lo ) \ hi
427 h# 3800 reg! ( ) \ lo
428 /tx-ring h# 3808 reg! \ Transmit descriptor ring length
429 \ Start the head and tail pointers pointing to the same value
430 \ (doesn't matter which it is).
431 txd-tail tx-tail! \ Transmit descriptor tail
432 txd-tail txd>d# h# 3810 reg! \ Transmit descriptor head
433 h# 60200a h# 0410 reg! \ Inter-packet gap register.
434 \ Transmit control:
435 \ Enable: 0000.0002 On
436 \ Pad short packets: 0000.0004 On (per manual)
437 \ Collision threshold: 0000.00f0 Value = 0xf (recommended)
438 \ Collision distance: 0020.0000 0x40 bytes (half-duplex)
439 \ Software xoff 0040.0000 Off
440 \ Retransmit on late col: 0100.0000 Off
441 h# 0004.00fe h# 400 reg!
442;
443
444: init-chip ( -- )
445 ctrl.slu ctrl.asde or ctrl! \ Set control register - enable PHY
446 0 h# 00c8 reg! \ Clear all interrupt cause set bits
447 h# ffff.ffff h# 00d8 reg! \ Mask all interrupts.
448 0 h# 0178 reg! \ Clear txcw
449 cpu-dma-base init-rings \ Initialize the memory structures
450 init-receive
451 init-transmit
452;
453
454: net-on ( -- ok? )
455 reset-chip
456 init-chip
457 true
458;
459
460: net-off ( -- )
461 2 h# 100 reg-bclear \ Disable rx
462 2 h# 400 reg-bclear \ Disable tx
463 reset-chip
464;