* Copyright (c) 1992 The Regents of the University of California.
* This code is derived from software contributed to Berkeley by
* Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
* %sccs.include.redist.c%
* from: $Hdr: cons.c,v 4.300 91/06/09 06:34:41 root Rel41 $ SONY
* @(#)bmcons.c 7.3 (Berkeley) %G%
#include <machine/fix_machine_type.h>
#include <news3400/hbdev/rsreg.h>
#include <news3400/sio/sccparam.h>
#define CN_ON (RXE|TXE|RTS|DTR)
* Local variables for the driver
int cnrint(), cnxint(), cnsint();
* Open console. Turn on console if this is the first use of it.
cnopen(dev
, flag
, mode
, p
)
register struct tty
*tp
= &cn_tty
[0];
if (tp
->t_state
& TS_XCLUDE
&& p
->p_ucred
->cr_uid
!= 0)
* If this is first open, initialze tty state to default.
if ((tp
->t_state
& TS_ISOPEN
) == 0) {
tp
->t_iflag
= TTYDEF_IFLAG
;
tp
->t_oflag
= TTYDEF_OFLAG
;
tp
->t_cflag
= TTYDEF_CFLAG
;
tp
->t_lflag
= TTYDEF_LFLAG
;
tp
->t_ispeed
= tp
->t_ospeed
= TTYDEF_SPEED
;
cnparam(tp
, &tp
->t_termios
);
* Wait receiver and status interrupt
(void) cnmctl(CN_ON
, DMSET
);
tp
->t_state
|= TS_CARR_ON
;
return ((*linesw
[tp
->t_line
].l_open
)(dev
, tp
));
register struct tty
*tp
= &cn_tty
[0];
(*linesw
[tp
->t_line
].l_close
)(tp
);
(void) cnmctl(CN_BRK
, DMBIC
);
register struct tty
*tp
= &cn_tty
[0];
return ((*linesw
[tp
->t_line
].l_read
)(tp
, uio
, flag
));
register struct tty
*tp
= &cn_tty
[0];
return ((*linesw
[tp
->t_line
].l_write
)(tp
, uio
, flag
));
* console receiver interrupt.
register struct tty
*tp
= &cn_tty
[0];
if ((tp
->t_state
& TS_ISOPEN
) == 0) {
wakeup((caddr_t
)&tp
->t_rawq
);
* Loop fetching characters from the silo for console
* until there are no more in the silo.
rint
= linesw
[tp
->t_line
].l_rint
;
cnioctl(dev
, cmd
, data
, flag
)
register struct tty
*tp
= &cn_tty
[0];
error
= (*linesw
[tp
->t_line
].l_ioctl
)(tp
, cmd
, data
, flag
);
error
= ttioctl(tp
, cmd
, data
, flag
);
(void) cnmctl(CN_BRK
, DMBIS
);
(void) cnmctl(CN_BRK
, DMBIC
);
(void) cnmctl(CN_DTR
|CN_RTS
, DMBIS
);
(void) cnmctl(CN_DTR
|CN_RTS
, DMBIC
);
(void) cnmctl(dmtocn(*(int *)data
), DMSET
);
(void) cnmctl(dmtocn(*(int *)data
), DMBIS
);
(void) cnmctl(dmtocn(*(int *)data
), DMBIC
);
*(int *)data
= cntodm(cnmctl(0, DMGET
));
if (bits
& DML_LE
) b
|= CN_TXE
|CN_RXE
;
if (bits
& DML_DTR
) b
|= CN_DTR
;
if (bits
& DML_RTS
) b
|= CN_RTS
;
if (bits
& DML_CTS
) b
|= CN_CTS
;
if (bits
& DML_CAR
) b
|= CN_DCD
;
if (bits
& DML_RNG
) b
|= CN_RI
;
if (bits
& DML_DSR
) b
|= CN_DSR
;
if (bits
& (CN_TXE
|CN_RXE
)) b
|= DML_LE
;
if (bits
& CN_DTR
) b
|= DML_DTR
;
if (bits
& CN_RTS
) b
|= DML_RTS
;
if (bits
& CN_CTS
) b
|= DML_CTS
;
if (bits
& CN_DCD
) b
|= DML_CAR
;
if (bits
& CN_RI
) b
|= DML_RNG
;
if (bits
& CN_DSR
) b
|= DML_DSR
;
* Set parameters from open or stty into the console hardware
register struct termios
*t
;
register int cflag
= t
->c_cflag
;
* Block interrupts so parameters will be set
* before the line interrupts.
(void) cnmctl(CN_OFF
, DMSET
);
~(CHAR_SIZE
|PARITY
|EVEN
|STOPBIT
|BAUD_RATE
|NOCHECK
);
if ((cflag
& CREAD
) == 0)
case CS6
: param
|= C6BIT
; break;
case CS7
: param
|= C7BIT
; break;
case CS8
: param
|= C8BIT
; break;
if ((cflag
& PARODD
) == 0)
if ((tp
->t_iflag
& INPCK
) == 0)
* console transmitter interrupt.
register struct tty
*tp
= &cn_tty
[0];
if (tp
->t_state
& TS_FLUSH
)
tp
->t_state
&= ~TS_FLUSH
;
ndflush(&tp
->t_outq
, count
);
(*linesw
[tp
->t_line
].l_start
)(tp
);
* Start (restart) transmission on the console.
* Must hold interrupts in following code to prevent
* state of the tp from changing.
* If it's currently active, or delaying, no need to do anything.
if (tp
->t_state
& (TS_TIMEOUT
|TS_BUSY
|TS_TTSTOP
))
* If ther are still characters in the IOP,
* just reenable transmit.
* If there are sleepers, and output has drained below low
* water mark, wake up the sleepers.
if (tp
->t_outq
.c_cc
<= tp
->t_lowat
) {
if (tp
->t_state
& TS_ASLEEP
) {
tp
->t_state
&= ~TS_ASLEEP
;
wakeup((caddr_t
)&tp
->t_outq
);
* Now restart transmission unless the output queue is
if (tp
->t_outq
.c_cc
== 0)
if (tp
->t_flags
& (RAW
|LITOUT
))
nch
= ndqb(&tp
->t_outq
, 0);
nch
= ndqb(&tp
->t_outq
, 0200);
* If first thing on queue is a delay process it.
timeout(ttrstrt
, (caddr_t
)tp
, (nch
&0x7f)+6);
tp
->t_state
|= TS_TIMEOUT
;
* If characters to transmit, restart transmission.
* Stop output on a line, e.g. for ^S/^Q or output flush.
* Block input/output interrupts while messing with state.
if (tp
->t_state
& TS_BUSY
) {
if ((tp
->t_state
& TS_TTSTOP
) == 0) {
bits
&= (RXE
|TXE
|RTS
|DTR
|XBREAK
);
mbits
= mbits
& ~(RXE
|TXE
|RTS
|DTR
|XBREAK
) | bits
;
* console status interrupt
register struct tty
*tp
= &cn_tty
[0];
if (stat
& OVERRUN_ERROR
)
printf("console: fifo overflow\n");
(*linesw
[tp
->t_line
].l_rint
)
(tp
->t_flags
& RAW
? '\0' : tp
->t_cc
[VINTR
], tp
);
* console control interrupt
* Machine dependent functions
#include <news3400/newsipc/newsipc.h>
#include <news3400/mrx/h/cio.h>
#include <news3400/mrx/h/console.h>
#define ipc_phys(x) K0_TT0(x)
#define ipc_log(x) TT0_K0(x)
#define ipc_phys(x) (caddr_t)((int)(x) & ~0x80000000)
#define ipc_log(x) (caddr_t)((int)(x) | 0x80000000)
extern char *ext_fnt_addr
[];
extern char *ext_fnt24_addr
[];
struct cons_ctrl_req req
;
port_cnrecv
= port_create("@cnrecv", cnrint
, -1);
port_cnxmit
= port_create("@cnxmit", cnxint
, -1);
port_cnctrl
= port_create("@cnctrl", NULL
, 0);
port_cnstat
= port_create("@cnstat", cnsint
, -1);
port_cnfont
= port_create("@cnfont", cnfont
, -1);
/* use NULL action port */
port_cnrecv_iop
= object_query("cons_input");
port_cnxmit_iop
= object_query("cons_output");
port_cnctrl_iop
= object_query("cons_ctrl");
port_cnstat_iop
= object_query("cons_stat");
req
.cons_func
= CIO_ASKDEVICE
;
msg_send(port_cnctrl_iop
, port_cnctrl
, &req
, sizeof(req
), 0);
msg_recv(port_cnctrl
, NULL
, &reply
, NULL
, 0);
tty00_is_console
= *reply
;
req
.cons_func
= CIO_SET16FNT
;
req
.cons_addr
= (char *)ipc_phys(ext_fnt_addr
);
msg_send(port_cnctrl_iop
, port_cnctrl
, &req
, sizeof(req
), 0);
msg_recv(port_cnctrl
, NULL
, NULL
, NULL
, 0);
req
.cons_func
= CIO_SET24FNT
;
req
.cons_addr
= (char *)ipc_phys(ext_fnt24_addr
);
msg_send(port_cnctrl_iop
, port_cnctrl
, &req
, sizeof(req
), 0);
msg_recv(port_cnctrl
, NULL
, NULL
, NULL
, 0);
msg_send(port_cnrecv_iop
, port_cnrecv
, &len
, sizeof(len
), 0);
msg_recv(port
, NULL
, &buf
, &len
, 0);
_cnrint((char *)MACH_CACHED_TO_UNCACHED(buf
), len
);
msg_recv(port
, NULL
, &len
, NULL
, 0);
msg_send(port_cnctrl_iop
, 0, &func
, sizeof(func
), 0);
msg_send(port_cnxmit_iop
, port_cnxmit
, tp
->t_outq
.c_cf
,
func
= flush
? CIO_FLUSH
: CIO_STOP
;
msg_send(port_cnctrl_iop
, 0, &func
, sizeof(func
), 0);
msg_recv(port
, NULL
, &stat
, NULL
, 0);
msg_send(port_cnstat_iop
, port_cnstat
, NULL
, 0, 0);
struct cons_ctrl_req req
;
req
.cons_func
= CIO_GETPARAMS
;
/* message length 8 means 2 * sizeof(int) : func and status */
msg_send(port_cnctrl_iop
, port_cnctrl
, &req
, 8, 0);
msg_recv(port_cnctrl
, NULL
, &reply
, NULL
, 0);
struct cons_ctrl_req req
;
req
.cons_func
= CIO_SETPARAMS
;
/* message length 8 means 2 * sizeof(int) : func and status */
msg_send(port_cnctrl_iop
, 0, &req
, 8, 0);
msg_recv(port
, NULL
, &func
, NULL
, 0);
#include <news3400/hbdev/rsreg.h>
#include <news3400/iop/framebuf.h>
#include <news3400/fb/fbdefs.h>
lastcount
= vt100_write(0, tp
->t_outq
.c_cf
, n
);
return (bitmap_get_param());