Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / devices / common / console.cc
// ========== Copyright Header Begin ==========================================
//
// OpenSPARC T2 Processor File: console.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 ============================================
#include <fcntl.h>
#include <termio.h>
#include "console.h"
bool console::get_pty(char **name, int *sfd, int *mfd){
if ((*mfd = open("/dev/ptmx", O_RDWR|O_NDELAY)) == -1) {
fprintf(stderr,"get_pty: Cannot find a pseudo tty.\n");
return false;
}
if (grantpt(*mfd) < 0) {
fprintf(stderr,"get_pty: Could not grant access to slave pseudo tty\n");
perror("grantpt");
close(*mfd);
return false;
}
if (unlockpt(*mfd) < 0) {
fprintf(stderr,"get_pty: Unable to unlock pseudo tty.\n");
perror("unlockpt");
close(*mfd);
return false;
}
*name = strdup(ptsname(*mfd));
*sfd = open(*name, O_RDWR | O_NOCTTY);
if (*sfd < 0) {
fprintf(stderr,"get_pty: Unable to open slave side for %d\n", *mfd);
close(*mfd);
return false;
}
if (ioctl(*sfd, I_PUSH, "ptem") < 0) {
fprintf(stderr,"get_pty: Ioctl I_PUSH ptem failed\n");
perror("ioctl i_push ptem");
close(*mfd);
return false;
}
if (ioctl(*sfd, I_PUSH, "ldterm") < 0) {
fprintf(stderr,"serial: Ioctl I_PUSH ldterm failed\n");
perror("ioctl i_push ldterm");
close(*mfd);
return false;
}
chmod(*name,S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
struct termio tty;
ioctl(*sfd, TCGETA, &tty);
tty.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
tty.c_cc[VMIN] = 1;
tty.c_cc[VTIME] = 0;
ioctl(*sfd, TCSETA, &tty);
return true;
}
void console::term_read_ports(fd_set readfds){
unsigned char buf[256];
for(termMapIter = termMap.begin(); termMapIter!= termMap.end(); termMapIter++){
if (FD_ISSET(termMapIter->second->mport_fd, &readfds)) {
int nbytes;
unsigned char ch;
int index = 0;
while ((nbytes = read(termMapIter->second->mport_fd, &ch, 1)) == 1){
buf[index++] = ch;
buf[index] = 0;
termMapIter->second->cbFun(termMapIter->second->cbData, buf, termMapIter->first);
index = 0;
}
}
}
}
//return a unique port identifier and the tty name for tip connection in tty_name
int console::getTerminal(char * title, int numScrolLines, inputCallbk cbFun, void * cbData, char ** tty_name, bool pop_win){
console::title = strdup(title);
term_lines = numScrolLines;
term * t = new term();
int retVal;
if(!get_pty(&t->tty_name, &t->port_fd, &t->mport_fd)){
delete t;
return -1;
}
t->cbFun = cbFun;
t->cbData = cbData;
pthread_mutex_lock(&termMutex);
termMap[currentPortNum++] = t;
retVal = currentPortNum - 1;
pthread_mutex_unlock(&termMutex);
if(pop_win)
t->pop_term(display, fn, bg, fg, title, numScrolLines, exec);
*tty_name = strdup(t->tty_name);
return retVal;
}
void console::term_select(){
fd_set readFd;
int n;
struct timeval tval;
//time out every 1 second, to check if additional consoles have been added.
tval.tv_sec = 1;
tval.tv_usec = 0;
for(;;){
FD_ZERO(&readFd);
for(termMapIter = termMap.begin(); termMapIter!= termMap.end(); termMapIter++)
FD_SET(termMapIter->second->mport_fd, &readFd);
n = select(FD_SETSIZE, &readFd, (fd_set *)0,(fd_set *)0, &tval);
switch (n) {
case -1: /* error */
break;
case 0: /* timeout */
break;
default: /* input available */
term_read_ports(readFd);
break;
}
}
}
void * callTermThread(void * arg){
console * t = (console*)arg;
t->term_select();
return (void*)0;
}