Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / sam-t2 / sam / devices / common / console.cc
CommitLineData
920dae64
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: console.cc
4// Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
5// DO NOT ALTER OR REMOVE COPYRIGHT NOTICES.
6//
7// The above named program is free software; you can redistribute it and/or
8// modify it under the terms of the GNU General Public
9// License version 2 as published by the Free Software Foundation.
10//
11// The above named program is distributed in the hope that it will be
12// useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14// General Public License for more details.
15//
16// You should have received a copy of the GNU General Public
17// License along with this work; if not, write to the Free Software
18// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
19//
20// ========== Copyright Header End ============================================
21#include <fcntl.h>
22#include <termio.h>
23#include "console.h"
24
25
26bool console::get_pty(char **name, int *sfd, int *mfd){
27 if ((*mfd = open("/dev/ptmx", O_RDWR|O_NDELAY)) == -1) {
28 fprintf(stderr,"get_pty: Cannot find a pseudo tty.\n");
29 return false;
30 }
31
32 if (grantpt(*mfd) < 0) {
33 fprintf(stderr,"get_pty: Could not grant access to slave pseudo tty\n");
34 perror("grantpt");
35 close(*mfd);
36 return false;
37 }
38
39 if (unlockpt(*mfd) < 0) {
40 fprintf(stderr,"get_pty: Unable to unlock pseudo tty.\n");
41 perror("unlockpt");
42 close(*mfd);
43 return false;
44 }
45
46 *name = strdup(ptsname(*mfd));
47 *sfd = open(*name, O_RDWR | O_NOCTTY);
48
49 if (*sfd < 0) {
50 fprintf(stderr,"get_pty: Unable to open slave side for %d\n", *mfd);
51 close(*mfd);
52 return false;
53 }
54
55 if (ioctl(*sfd, I_PUSH, "ptem") < 0) {
56 fprintf(stderr,"get_pty: Ioctl I_PUSH ptem failed\n");
57 perror("ioctl i_push ptem");
58 close(*mfd);
59 return false;
60 }
61
62 if (ioctl(*sfd, I_PUSH, "ldterm") < 0) {
63 fprintf(stderr,"serial: Ioctl I_PUSH ldterm failed\n");
64 perror("ioctl i_push ldterm");
65 close(*mfd);
66 return false;
67 }
68
69 chmod(*name,S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
70
71 struct termio tty;
72
73 ioctl(*sfd, TCGETA, &tty);
74 tty.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL);
75 tty.c_cc[VMIN] = 1;
76 tty.c_cc[VTIME] = 0;
77 ioctl(*sfd, TCSETA, &tty);
78
79 return true;
80}
81
82void console::term_read_ports(fd_set readfds){
83 unsigned char buf[256];
84
85 for(termMapIter = termMap.begin(); termMapIter!= termMap.end(); termMapIter++){
86 if (FD_ISSET(termMapIter->second->mport_fd, &readfds)) {
87 int nbytes;
88 unsigned char ch;
89 int index = 0;
90
91 while ((nbytes = read(termMapIter->second->mport_fd, &ch, 1)) == 1){
92 buf[index++] = ch;
93 buf[index] = 0;
94 termMapIter->second->cbFun(termMapIter->second->cbData, buf, termMapIter->first);
95 index = 0;
96 }
97 }
98 }
99}
100//return a unique port identifier and the tty name for tip connection in tty_name
101int console::getTerminal(char * title, int numScrolLines, inputCallbk cbFun, void * cbData, char ** tty_name, bool pop_win){
102
103 console::title = strdup(title);
104 term_lines = numScrolLines;
105
106 term * t = new term();
107 int retVal;
108 if(!get_pty(&t->tty_name, &t->port_fd, &t->mport_fd)){
109 delete t;
110 return -1;
111 }
112 t->cbFun = cbFun;
113 t->cbData = cbData;
114
115 pthread_mutex_lock(&termMutex);
116 termMap[currentPortNum++] = t;
117 retVal = currentPortNum - 1;
118 pthread_mutex_unlock(&termMutex);
119
120 if(pop_win)
121 t->pop_term(display, fn, bg, fg, title, numScrolLines, exec);
122
123 *tty_name = strdup(t->tty_name);
124 return retVal;
125}
126
127void console::term_select(){
128
129 fd_set readFd;
130 int n;
131 struct timeval tval;
132 //time out every 1 second, to check if additional consoles have been added.
133 tval.tv_sec = 1;
134 tval.tv_usec = 0;
135
136 for(;;){
137 FD_ZERO(&readFd);
138
139 for(termMapIter = termMap.begin(); termMapIter!= termMap.end(); termMapIter++)
140 FD_SET(termMapIter->second->mport_fd, &readFd);
141
142 n = select(FD_SETSIZE, &readFd, (fd_set *)0,(fd_set *)0, &tval);
143
144 switch (n) {
145 case -1: /* error */
146 break;
147 case 0: /* timeout */
148 break;
149 default: /* input available */
150 term_read_ports(readFd);
151 break;
152 }
153 }
154
155}
156
157
158
159void * callTermThread(void * arg){
160 console * t = (console*)arg;
161 t->term_select();
162 return (void*)0;
163}