// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: SS_Serial.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 ============================================
SS_Serial::SS_Serial( SS_AddressMap
* map
, SS_Paddr lo
, SS_Paddr hi
)/*{{{*/
line_status(LINE_TX_EMPTY
| LINE_TX_HOLD
),
map
->add(lo
,hi
,this,SS_AddressMap::REL
,SS_Serial::access
);
SS_Serial::~SS_Serial()/*{{{*/
int SS_Serial::connect( const char* term
)/*{{{*/
struct sockaddr_in server
, client
;
int client_size
= sizeof(client
);
if ((fd
= socket(AF_INET
,SOCK_STREAM
,0)) < 0)
if (setsockopt(fd
,SOL_SOCKET
,SO_REUSEADDR
,(uint8_t*)&on
,sizeof(on
)) < 0)
server
.sin_family
= AF_INET
;
server
.sin_addr
.s_addr
= INADDR_ANY
;
server
.sin_port
= htons(0);
while (bind(fd
,(struct sockaddr
*)&server
,sizeof(server
)) < 0)
int length
= sizeof(server
);
if (getsockname(fd
,(struct sockaddr
*)&server
,&length
) == -1)
gethostname(hostname
,256);
sprintf(command
,term
,hostname
,ntohs(server
.sin_port
));
if ((serial_rd
= accept(fd
,(struct sockaddr
*)&client
,&client_size
)) < 0)
// Put the accepted socket in non-blocking mode
int fl
= fcntl(serial_rd
,F_GETFL
);
if (fcntl(serial_rd
,F_SETFL
,fl
|O_NONBLOCK
) < 0)
serial_wr
= dup(serial_rd
);
int SS_Serial::file_io( const char* input
, const char* output
)/*{{{*/
mode_t mode
= S_IFREG
|S_IRUSR
|S_IWUSR
|S_IRGRP
;
int flag
= O_WRONLY
|O_CREAT
|O_TRUNC
;
if ((serial_wr
= open(output
,flag
,mode
)) < 0)
if ((serial_rd
= open(input
,O_RDONLY
)) < 0)
void SS_Serial::access( void* obj
, uint_t sid
, SS_Access::Type type
, SS_Paddr pa
, uint_t size
, uint64_t* data
)/*{{{*/
SS_Serial
* self
= (SS_Serial
*)obj
;
*data
= self
->buffer
[self
->buffer_ptr
++];
if (self
->buffer_len
== 0)
int n
= read(self
->serial_rd
,self
->buffer
,BUFFER_SIZE
);
self
->buffer_len
= (n
> 0) ? n
: 0;
self
->line_status
|= LINE_DATA_READY
;
self
->line_status
&= ~LINE_DATA_READY
;
if (self
->buffer_len
== 0)
int n
= read(self
->serial_rd
,self
->buffer
,BUFFER_SIZE
);
self
->buffer_len
= (n
> 0) ? n
: 0;
self
->line_status
|= LINE_DATA_READY
;
*data
= self
->line_status
;
write(self
->serial_wr
,&c
,1);
self
->line_status
= *data
| LINE_TX_EMPTY
| LINE_TX_HOLD
;
fprintf(stderr
,"Serial: Unsupported access type\n");