// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: term.cc
// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
// The above named program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License version 2 as published by the Free Software Foundation.
// The above named program is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
// You should have received a copy of the GNU General Public
// License along with this work; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
// ========== Copyright Header End ============================================
* Copyright (C) 2001 Sun Microsystems, Inc.
#pragma ident "@(#)1.16 07/11/19 term.cc"
#include "blaze_globals.h"
//extern FILE *serial_file;
extern serialInterface
* systemConsole
;
typedef void (*serial_send
)(void *, char *, int );
FILE *serial_output_file
;
static struct term terms
[NUM_PORTS
];
/////////////////////////////////////////////////
static bool_t
get_pty(char *name
, int *sfd
, int *mfd
)
if ((*mfd
= open("/dev/ptmx", O_RDWR
|O_NDELAY
)) == -1) {
ui
->error("serial: Cannot find a pseudo tty.\n");
ui
->error("serial: Could not grant access to slave pseudo tty\n");
if (unlockpt(*mfd
) < 0) {
ui
->error("serial: Unable to unlock pseudo tty.\n");
strcpy(name
, ptsname(*mfd
));
*sfd
= open(name
, O_RDWR
);
ui
->error("serial: Unable to open slave side for %d\n", *mfd
);
if (ioctl(*sfd
, I_PUSH
, "ptem") < 0) {
ui
->error("serial: Ioctl I_PUSH ptem failed\n");
ui
->perror("ioctl i_push ptem");
if (ioctl(*sfd
, I_PUSH
, "ldterm") < 0) {
ui
->error("serial: Ioctl I_PUSH ldterm failed\n");
ui
->perror("ioctl i_push ldterm");
static int xterm_pid
= -1;
int term_console (char *pty_dev
, char *display
)
if ((pid
= vfork()) == 0) {
execl("/usr/openwin/bin/xterm", "/usr/openwin/bin/xterm", "-display", display
,
"-T", "blaze-sim-console", "-n", "blz-sim-con", "-sb", "-sl", "10000",
"-e", "/bin/tip", pty_dev
, NULL
);
ui
->perror("/usr/openwin/bin/xterm for blaze console");
void term_console_destroy ()
ui
->verbose("\nkilling console window (pid %d)\n", xterm_pid
);
int deadpid
= wait(NULL
);
int term_init(FILE *fp
, serial_send fn
, void *cbData
,char **tty_name
)
terms
[portnum
].initialized
= FALSE
;
if (!get_pty(pty_name
, &terms
[portnum
].port_fd
,
&terms
[portnum
].mport_fd
)) {
ui
->error("TERM : get_pty failed\n");
S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IWGRP
| S_IROTH
|
terms
[portnum
].port_name
= strdup(pty_name
);
terms
[portnum
].input
= fn
;
terms
[portnum
].cbData
= cbData
;
terms
[portnum
].initialized
= TRUE
;
terms
[portnum
].serial_output_file
= fp
;
*tty_name
= strdup(pty_name
);
terms
[portnum
].serial_output_file
= fp
;
terms
[portnum
].port_name
= NULL
;
terms
[portnum
].input
= fn
;
terms
[portnum
].cbData
= cbData
;
terms
[portnum
].initialized
= TRUE
;
terms
[portnum
].mport_fd
= -1;
terms
[portnum
].port_fd
= -1;
*tty_name
= strdup("Op redirected !!");
void term_write(unsigned char *c
, int port
)
FILE *fp
= terms
[port
].serial_output_file
;
if(*c
== 0xd || *c
== '\0')
term_redirect_add (c
[0]);
write(terms
[port
].mport_fd
, c
, 1);
term_redirect_add (c
[0]) ;
static void term_read_ports(fd_set readfds
)
for (i
= 0; i
< NUM_PORTS
; i
++) {
if (FD_ISSET(terms
[i
].mport_fd
, &readfds
)) {
while ((nbytes
= read(terms
[i
].mport_fd
, &ch
, 1)) == 1) {
terms
[i
].input(terms
[i
].cbData
,chstr
,i
);
void term_fake_input (uint8_t *cmd
, int l
, int port
)
systemConsole
->chars_send((char *)cmd
, systemConsole
->portH
);
extern volatile bool config_is_done
;
// volatile is needed, otherwise the compiler eliminates the
// while loop as dead-code for opt version
// spin loop until the sysconf modules are loaded and initialized
// not doing this results in a race condition where the select call is
// made before the terms[i] struct is initialzed. The effect is, no
// console input possible.
// the variable config_is_done is set to true after the init_done() has
// been called for all the sysconf modules.
// better approaches are possible but would need to much work and cleanup.
for (i
= 0; i
<= portnum
; i
++) {
if (terms
[i
].initialized
&& terms
[i
].mport_fd
!= -1) {
FD_SET(terms
[i
].mport_fd
, &readfds
);
n
= select(FD_SETSIZE
, &readfds
, (fd_set
*)NULL
,
default: /* input available */
term_read_ports(readfds
);