Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / obp / dev / ide / ide.fth
CommitLineData
920dae64
AT
1\ ========== Copyright Header Begin ==========================================
2\
3\ Hypervisor Software File: ide.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: @(#)ide.fth 1.21 06/07/14
43purpose:
44copyright: Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
45copyright: Use is subject to license terms.
46
47hex
48
49headerless
50
51" ide" name
52" ide" device-type
53
542 encode-int " #address-cells" property
55
560 instance value cmd-regs
570 instance value ctrl-regs
580 instance value interface \ which interface
590 instance value disk-id \ which drive
600 instance value port
610 instance value lun
620 value secondary? \ secondary interface present?
630 value reg-enable
64
650 value present
66: ata! ( data reg -- ) cmd-regs + rb! ;
67: ata@ ( reg -- data ) cmd-regs + rb@ ;
68
69: ctrl! ( data -- ) ctrl-regs + rb! ;
70: ctrl@ ( -- data ) ctrl-regs + rb@ ;
71
72: data! ( data -- ) wbflip cmd-regs rw! ;
73: data@ ( -- data ) cmd-regs rw@ wbflip ;
74: err@ ( -- data ) h# 1 ata@ ;
75: cmd! ( data -- ) h# 7 ata! ;
76: stat@ ( -- data ) h# 7 ata@ ;
77: astat@ ( -- data ) h# 2 ctrl@ ; \ Alternate status reg
78
79: .rd-ide-block ( regs addr bytes -- ) bounds do data@ i w! 2 +loop drop ;
80: .wr-ide-block ( regs addr bytes -- ) bounds do i w@ data! 2 +loop drop ;
81
82instance defer xfer-fn
83: (read) ( -- ) ['] .rd-ide-block is xfer-fn ;
84: (write) ( -- ) ['] .wr-ide-block is xfer-fn ;
85
86\ Checking IDE interrupts is device/vendor specific..
87defer ide-irq? ( -- flag? ) ' false is ide-irq?
88
89\
90\ These bits must be set for commands to work.
91\
92h# E0 constant cmd-reg-bits
93\ h# A0 constant cmd-reg-bits
94
95headers
96
97d# 5000 constant reset-bsy-timeout
98
99headerless
1000 instance value blocksize
101
102create reg-array
103 0 ,
104 0 ,
105 0 ,
106 0 ,
107
108: .inform ( str,len -- ) type space ;
109: .drive " drive" .inform ;
110: .master " Master" .inform ;
111: .slave " Slave" .inform ;
112: .interface " interface" .inform ;
113: .primary " Primary" .inform ;
114: .secondary " Secondary" .inform ;
115: .number " number" .inform ;
116: .invalid-ide " Invalid IDE" .inform ;
117: .diag-msg ." Failed Diagnostic" cr ;
118
1190 instance value error?
1200 instance value timeout?
121instance defer check-bits
122
123\ Define a simple usec counter
124[ifndef] have-usec-fcode?
125d# 200 value looptime
126
127: us ( n -- ) looptime * 0 ?do loop ;
128
129: calibrate-us ( -- )
130 d# 3.000.000 dup is looptime ( n )
131 get-msecs looptime 0 ?do loop get-msecs swap - ( n ms )
132 d# 1000 * / 1 max is looptime
133;
134
135calibrate-us
136[then]
137
138: xfer-wait-status ( timeout check-acf -- ok? )
139 false is timeout? ( timeout check-acf )
140 is check-bits 0 ?do ( )
141 stat@ check-bits if unloop true exit then
142 d# 10 us ( )
143 loop false ( failed )
144 true is timeout? ( failed )
145;
146
147: wait-status ( timeout check-acf -- ok? )
148 false is timeout? ( timeout check-acf )
149 is check-bits 0 ?do ( )
150 stat@ check-bits if unloop true exit then
151 1 ms ( )
152 loop false ( failed )
153 true is timeout? ( failed )
154;
155
156: alt-wait-status ( timeout check-acf -- ok? )
157 false is timeout? ( timeout check-acf )
158 is check-bits 0 ?do ( )
159 astat@ check-bits if unloop true exit then
160 1 ms ( )
161 loop false ( failed )
162 true is timeout? ( failed )
163;
164
165
166: bitset? ( data n -- set? ) tuck and = ;
167: .check-busy ( status -- set? ) h# 80 bitset? ;
168: .check-!busy ( status -- set? ) .check-busy 0= ;
169: .check-ready ( status -- set? ) h# 40 bitset? ;
170: .check-data ( status -- set? ) h# 8 bitset? ;
171: .check-data&!busy ( status -- set? ) dup h# 8 bitset? swap .check-!busy and ;
172
173: wait-!busy? ( t -- ok? ) ['] .check-!busy wait-status ;
174: wait-busy? ( t -- ok? ) ['] .check-busy wait-status ;
175: wait-ready? ( t -- ok? ) ['] .check-ready wait-status ;
176: wait-data? ( t -- ok? ) ['] .check-data wait-status ;
177: wait-data&!busy? ( t -- ok? ) ['] .check-data&!busy wait-status ;
178: xfer-wait-!busy? ( t -- ok? ) ['] .check-!busy xfer-wait-status ;
179
180: alt-wait-!busy? ( t -- ok? ) ['] .check-!busy alt-wait-status ;
181: alt-wait-ready? ( t -- ok? ) ['] .check-ready alt-wait-status ;
182: alt-wait-data? ( t -- ok? ) ['] .check-data alt-wait-status ;
183
184: decode-unit,lun ( target lun -- m/s p/s )
185 to lun ( target )
186 dup 1 and ( target m/s )
187 swap 1 rshift ( m/s p/s )
188;
189
190\ Our Addressing scheme works like this:
191\ ide/disk@D[,pP][,L]
192\ where D = Device 0-3, bit 1 = Interface, 0 = Device
193\ P = Port and L = Lun
194\ anything else is invalid.
195\
196
197\ By default set-port does nothing.
198: (set-port) ( port# -- okay? ) drop false ;
199
200[ifdef] M1575-SATA?
201\ On M1575-derived soutbridges you need to use config space to access some
202\ important SATA registers.
203: config-b@ ( offset -- data ) my-space + " config-b@" $call-parent ;
204: config-b! ( data offset -- ) my-space + " config-b!" $call-parent ;
205
206\ This is only guaranteed to work with M1575-derived soutbridges
207: (set-m1575-port) ( port# -- okay? )
208 dup d# 16 < if
209 \ Save the port in case we ever need to use it again.
210 dup to port
211 \ Switch to regs for this PHY
212 interface 1 << disk-id or h# 80 config-b!
213 \ Set PM Port #
214 h# 9a config-b!
215 true exit
216 then
217 drop false
218;
219[then]
220
221
222external
223defer set-port ' (set-port) to set-port
224
225: set-address ( target lun -- OK? )
226 decode-unit,lun ( m/s p/s )
227 dup 0 1 between ( m/s p/s valid )
228 if ( m/s p/s )
229 dup 0<> secondary? 0= and if ( m/s p/s )
230 " No" .inform ( m/s p/s )
231 .secondary .interface ( m/s p/s )
232 2drop false exit ( false )
233 then ( -- false )
234 dup is interface ( m/s )
235 if 2 else 0 then ( m/s offset )
236 reg-array swap ( m/s array offset )
237 2dup na+ @ is cmd-regs ( m/s array offset )
238 1+ na+ @ is ctrl-regs ( m/s )
239 dup 0 1 between ( m/s valid? )
240 if ( m/s )
241 is disk-id ( -- )
242 true ( -1 )
243 else ( target )
244 .Invalid-IDE .drive .number ( -- )
245 . cr false ( 0 )
246 then ( 0 | 1 )
247 else ( m/s p/s )
248 .Invalid-IDE .interface .number ( m/s )
249 . cr drop false ( 0 )
250 then
251;
252
253headerless
254\
255\ For the ATA interface the data in the command block is
256\ a copy of the contents of the registers and I just copy then into the
257\ correct places to run the command.
258\
2590 instance value timeout
260
261fload ${BP}/dev/ide/pktdata.fth
262fload ${BP}/dev/ide/ata/support.fth \ Load ATA interface
263fload ${BP}/dev/ide/atapi/support.fth \ Load ATAPI interface
264
265headerless
266: #emit ( n -- ) ascii 0 + emit ;
267
268h# 200 buffer: id-buf
269: Model-# ( -- )
270 ." Model: " id-buf d# 54 + dup c@ if d# 40 type else drop ." <Unknown>" then
271;
272
273h# 12 buffer: id-pkt
274h# 12 buffer: id-cmd
275
276: .not-present ( -- false ) 4 spaces ." Not Present" false ;
277
278: (reset) ( check? -- ok? )
279 6 2 ctrl!
280 1 ms
281 if 1 wait-busy? else true then
282 2 2 ctrl!
283;