Branch
Hash :
1a08f436
Author :
Date :
2010-08-25T09:23:17
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320
\ ========== Copyright Header Begin ==========================================
\
\ Hypervisor Software File: io.fth
\
\ Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
\
\ - Do no alter or remove copyright notices
\
\ - Redistribution and use of this software in source and binary forms, with
\ or without modification, are permitted provided that the following
\ conditions are met:
\
\ - Redistribution of source code must retain the above copyright notice,
\ this list of conditions and the following disclaimer.
\
\ - Redistribution in binary form must reproduce the above copyright notice,
\ this list of conditions and the following disclaimer in the
\ documentation and/or other materials provided with the distribution.
\
\ Neither the name of Sun Microsystems, Inc. or the names of contributors
\ may be used to endorse or promote products derived from this software
\ without specific prior written permission.
\
\ This software is provided "AS IS," without a warranty of any kind.
\ ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
\ INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
\ PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
\ MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
\ ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
\ DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
\ OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
\ FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
\ DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
\ ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
\ SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
\
\ You acknowledge that this software is not designed, licensed or
\ intended for use in the design, construction, operation or maintenance of
\ any nuclear facility.
\
\ ========== Copyright Header End ============================================
id: @(#)io.fth 1.11 05/02/02
purpose:
copyright: Copyright 2005 Sun Microsystems, Inc. All Rights Reserved
copyright: Use is subject to license terms.
headers
d# 90 constant ubufsize
ubufsize buffer: ubuf
0 value getptr
0 value putptr
0 value endptr
h# 10 constant msr-cts
variable ttylock
: initubuf ( -- )
ubuf is getptr
ubuf is putptr
ubuf ubufsize + is endptr
;
\ put key into uart buffer, ignoring overun
: bput ( key -- ) \ put key into buffer
putptr endptr >= if ubuf is putptr then
putptr c! putptr 1+ is putptr
;
\ clear the uart buffer for put task
: bputclr ( -- ) getptr is putptr ;
\ Fetch a key from buffer
: bget ( -- key )
getptr endptr >= if ubuf is getptr then
getptr c@ getptr 1+ is getptr
;
\ return TRUE if uart buffer is empty.
: ubuf-empty? ( -- flag ) getptr putptr = ;
headerless
: usea ( -- ) uartbase to uart ;
: useb ( -- ) uartbase to uart ;
create init-table
h# 00 c, h# 01 c, \ Interrupt Enable Register = disable all interrupts
h# 00 c, h# 04 c, \ Modem Control Register = disable all Modem fcns
h# 00 c, h# 02 c, \ FIFO Control Register = 0
h# 01 c, h# 02 c, \ FIFO Control Register = 1
h# 83 c, h# 03 c, \ Line Control Register = 83
h# 60 c, h# 00 c, \ Divisor Latch Register LSB
h# 00 c, h# 01 c, \ Divisor Latch Register MSB
h# 03 c, h# 03 c, \ Line Control Register = 03
\ h# 00 c, h# 04 c, \ Modem Control Register unchanged
\ h# 10 c, h# 04 c, \ Modem Control Register = enable Loopback Mode
h# 08 c, h# 04 c, \ Modem Control Register = IRQ enable
here init-table - constant #table-size
: uart! ( c offset -- ) uart + c! ;
: uart@ ( offset -- c ) uart + c@ ;
\ read SIO modem status register
: msr@ ( -- byte ) h# 06 uart@ ;
\ bsc is ready if CTS is asserted
: hw-bsc-ready? ( -- ready? ) msr@ msr-cts and ;
defer bsc-ready? ( -- ready? ) \ depends on flow control
' true is bsc-ready? \ default is no flow control
\ Receive Buffer Register RO
: rbr@ ( -- c ) 0 uart@ ;
\ Transmit Holding Register WO
: thr! ( c -- ) 0 uart! ;
0 value IER-reg \ IER contents at entry
\ Interrupt Enable Register
: ier! ( c -- ) 1 uart! ;
: ier@ ( -- c ) 1 uart@ ;
: disable_tx_int ( -- )
ier@ dup to IER-reg h# fd and ier!
;
: restore_tx_int ( -- )
IER-reg ier!
;
variable LSR-reg \ LSR shadow
\ Line Status Register RO
: lsr@ ( -- c ) 5 uart@ dup LSR-reg c@ or LSR-reg c! ;
: inituart ( -- )
initubuf
\ One time init stuff goes here.
init-table #table-size bounds ?do
i c@ i 1+ c@ uart!
2 +loop
;
\ Test for "break" character received.
: ubreak? ( -- flag ) lsr@ drop LSR-reg c@ h# 10 and ;
: uemit? ( -- flag )
bsc-ready? if
lsr@ h# 20 and
else
1 ms
0
then
;
: uemit ( char -- ) begin uemit? until thr! ;
: (ukey?) ( -- flag ) lsr@ h# 01 and ;
: (ukey) ( -- key ) begin (ukey?) until rbr@ ;
\ Wait for characters to finish transmitting
: uwait ( -- ) begin lsr@ h# 40 and until ;
\ This is called from Solaris under certain circumstances
\ such as early boot and panics.
\ In order to prevent MP systems registering spurious interrupts on
\ the CPU(s) not in OBP, or to prevent corruption of console I/O by
\ OBP and the console driver writing at the same time at the start of
\ panic handling, disable the THRE (tx) interrupt during the write.
\ Restore the state of the interrupt before waiting for the last
\ character to finish transmitting, this will ensure that Solaris
\ will see a tx interrupt in the case that it is waiting for one ie
\ OBP was called with data in the FIFO.
: uwrite ( adr len -- #written )
ttylock on
disable_tx_int
tuck bounds ?do ( len )
i c@ uemit ( len )
loop ( len )
restore_tx_int ( len )
uwait ( len )
ttylock off ( len )
;
: uread ( -- )
ttylock on
begin (ukey?) while (ukey) bput repeat
ttylock off
;
: ukey? ( -- flag ) uread ubuf-empty? 0= ;
: ukey ( -- char ) begin ukey? until bget ;
: clear-break ( -- )
ukey? drop bputclr
0 LSR-reg c!
;
headerless
d# 24.000.000 constant xtal-clk
d# 13 d# 16 * constant chip-div
: fifo! ( data -- ) h# 02 uart! ;
: lcr! ( data -- ) h# 03 uart! ;
: mcr! ( data -- ) h# 8 or h# 04 uart! ;
: mcr@ ( -- data ) h# 04 uart@ ;
struct
1 field LCR-reg \ Line Control
1 field MCR-reg \ Modem Control
drop
variable shadow-regs
\ Set the s/w version of the Line Control Register
: set-bits ( data addr -- ) tuck c@ or swap c! ;
: set-lcr ( data -- ) shadow-regs LCR-reg set-bits ;
: set-mcr ( data -- ) shadow-regs MCR-reg set-bits ;
: hold-uart ( -- )
h# 00 fifo! \ Disable and clear FIFOs
;
: release-uart ( -- )
5 uart@ drop \ clear error bits in LSR
shadow-regs ( addr )
dup LCR-reg c@ lcr! \ Write LCR (and select bank 0)
MCR-reg c@ mcr! \ write MCR reg
h# 01 fifo! \ FIFOs enabled
1 ms \ Allow device to stabilize.
; \ This delay is necessary to prevent
\ garbage characters from being sent out on
\ the first transmit resulting in a framing
\ error. For some reason this device needs
\ a moment to stabilize.
: set-baud ( baud -- )
chip-div * ( baud' )
xtal-clk d# 8 << ( baud' clk' )
swap / d# 8 >> ( divisor )
wbsplit ( lo hi )
h# 83 lcr! ( lo hi ) \ select Bank 1
h# 01 uart! ( lo ) \ Write Hi Div
h# 00 uart! ( -- ) \ Write Lo Div
h# 03 lcr! ( -- ) \ select Bank 0
;
: set-dtr-rts ( on? -- )
mcr@ swap
if 3 or
else 3 invert and
then
set-mcr
;
: set-databits ( #bits -- )
case
5 of h# 00 endof \ 5 bits data
6 of h# 01 endof \ 6 bits data
7 of h# 02 endof \ 7 bits data
8 of h# 03 endof \ 8 bits data
endcase ( data )
shadow-regs LCR-reg c! ( -- )
;
: set-parity ( parity -- )
case
p.mark of h# 28 endof \ mark
p.even of h# 18 endof \ even
p.odd of h# 08 endof \ odd
p.none of h# 0 endof \ none
p.space of h# 38 endof \ space
endcase ( data )
set-lcr ( )
;
: set-stopbits ( #stp -- )
1- if h# 04 set-lcr then
;
: no-flow-ctrl ( -- )
['] true is bsc-ready?
;
: hard-flow-ctrl ( -- )
['] hw-bsc-ready? is bsc-ready?
;
\ XXX needs work looking at the input chars as they arrive:
: soft-flow-ctrl ( -- )
." XXXX unimp: su16550 handshake" cr
['] true is bsc-ready?
;
: set-handshake ( hs -- )
case
hs.none of no-flow-ctrl endof
hs.hw of hard-flow-ctrl endof
hs.sw of soft-flow-ctrl endof
endcase
;
headers
\ mode parameter is switching between 232 and 433 (sp?)
: config-serial ( hs stp prty dbits baud dtr-rts-on? mode -- )
hold-uart ( hs stp prty dbits baud dtr-rts-on? mode )
rs-mode-select ( hs stp prty dbits baud dtr-rts-on? )
set-dtr-rts ( hs stp prty dbits baud )
set-baud ( hs stp prty dbits )
set-databits ( hs stp prty )
set-parity ( hs stp )
set-stopbits ( hs )
set-handshake ( )
release-uart ( )
;
headerless