// ========== Copyright Header Begin ==========================================
// OpenSPARC T2 Processor File: 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 ============================================
static const char *serial_4v_help
= "\
tip based SAM N2 console module (for Legion's virtual console device)\n\
sysconf serial_4v <instance_name> base=<start_addr> size=<map size> [log[=<filename>]] [pop] [fg=<color>] [bg=<color>] [font=<font>] [dnkxoe] [raw] [-a] [T=<title>] [e=<command>]\n\
'base' is the start address of memory mapped address, of the device CSRs\n\
'size' is the size of the CSR space\n\
'log' enables logging of console o/p to a file. The default log file is <instance_name>.log\n\
'raw' - optional boolean parameter, if specified enables unbuffered logging of console o/p, if logging is enabled\n\
The log file is opened in append mode if -a is not specified\n\
'pop' is boolean arg which if present will open an xterm window for console o/p\n\
'e, e, command\' is optional argument to set command instead of /bin/tip\n\
'T, T, title\' is optional argument to set xterm title instead of instance name\n\
'fg, bg, font, T' are optional arguments to set foreground, background and font of the xterm window\n\
'dnkxoe' - do not kill xterm on exit, default - window killed\n\
For UI help type <instance name>\n\
For module specific info type \"modinfo <instance name>\"";
Module
*Module::create(const char *_modname
, const char *_instance_name
){
return new serial4v(_modname
, _instance_name
);
const char * serial4v::get_help(){
return Module::get_help_string();
Module::get_help_string(){
serial4v::serial4v(const char * modname
,const char * instance_name
)
Module(modname
,instance_name
),
pthread_mutex_init(&mutty
,0);
line_status
= DS_LSTAT_TX_EMPTY
| DS_LSTAT_TX_HOLD
;
in
.count
= in
.head
= in
.tail
= 0;
font
= strdup("-dec-terminal-medium-r-normal-*-14-140-*-75-c-80-iso8859-1");
exec
= strdup("/bin/tip");
kill_xterm_on_exit
= true;
mmi_register_instance_cmd(getInstance(),serial_4v_help
,serial_4v_ui_cmd
);
bool serial4v::parse_arg(const char * arg
){
}else if(!strcmp("dnkxoe",arg
)){
kill_xterm_on_exit
= false;
}else if(!strcmp("raw",arg
)){
}else if(!strcmp("-a",arg
)){
}else if(!strncmp("log",arg
,3)){
debug_more("%s: console log enabled. Log file %s",getName(),logfile
);
debug_more("%s: console log enabled. Log file %s.log",getName(),getName());
}else if(argval("base",arg
,&start_pa
)){
debug_more("%s: base_pa %llx\n",getName(), start_pa
);
}else if(argval("size",arg
,&size
)){
debug_more("%s: size %llx, end_pa %llx\n",getName(), size
, start_pa
+ size
- 1);
}else if(argval("bg",arg
,&bg
)){
debug_more("%s: bg - %s\n",getName(), bg
);
}else if(argval("fg",arg
,&fg
)){
debug_more("%s: fg - %s\n",getName(), fg
);
}else if(argval("font",arg
,&font
)){
debug_more("%s: font - %s\n",getName(), font
);
}else if(argval("T",arg
,&title
)){
debug_more("%s: T - %s\n",getName(), title
);
}else if(argval("e",arg
,&exec
)){
debug_more("%s: e - %s\n",getName(), exec
);
bool serial4v::check_args(){
debug_err("%s:must specify start address\n",getName());
debug_err("%s:must specify size of address mapping\n",getName());
void serial4v::init_done(){
title
= (const char*)malloc(strlen(getName() + 1));
strcpy((char*)title
,getName());
if(fg
) Console
->setFg(fg
);
if(bg
) Console
->setBg(bg
);
if(font
) Console
->setFont(font
);
if(exec
) Console
->setExec(exec
);
if(title
) Console
->setTitle(title
);
portCon
= Console
->getTerminal((char*)title
,10000,getConsoleIp
, this, &portConName
, pop
);
fprintf(stderr
,"%s : to connect to console: tip %s\n",getName(),portConName
);
Console
->setId(getName());
char * logname
= (char*)malloc( strlen( getName() ) + strlen(".log") + 1 );
strcpy(logname
,getName());
logfile
= strdup(logname
);
Console
->log(portCon
,true,logfile
,raw
,append
);
if(mmi_map_physio(start_pa
, size
, (void *) this, serial4v_physio_access
) != 0) {
debug_err("%s fatal error: unaable to map IO space\n");
void serial4v::getConsoleIp(void *data
,unsigned char *ip
, int port
){
serial4v
* self
= (serial4v
*)data
;
pthread_mutex_lock(&self
->mutty
);
if(self
->in
.count
< self
->in
.size
){
self
->in
.bufp
[self
->in
.tail
] = *ip
;
if(self
->in
.tail
>= self
->in
.size
)
self
->line_status
|= DS_LSTAT_DATA_READY
;
if(!(self
->line_status
& DS_LSTAT_OVERRUN
))
self
->debug_err("%s: buffer overrun",self
->getName());
self
->line_status
|= DS_LSTAT_OVERRUN
;
pthread_mutex_unlock(&self
->mutty
);
void serial4v::serial4v_ld (uint64_t paddr
, uint64_t *buf
, int size
){
reg
= (ds_reg_t
) (paddr
& 0xfff) ;
pthread_mutex_lock(&mutty
);
line_status
&= ~DS_LSTAT_DATA_READY
;
line_status
&= ~DS_LSTAT_DATA_READY
;
pthread_mutex_unlock(&mutty
);
pthread_mutex_lock(&mutty
);
pthread_mutex_unlock(&mutty
);
debug_err("%s: rd access to unimplemented register 0x%x\n",getName());
void serial4v::serial4v_st(uint64_t pa
, uint64_t *buf
, int sz
){
reg
= (ds_reg_t
) (pa
& 0xfff);
debug_err("%s:writing 0x%llx to console. Truncate to 8 bits\n",getName());
Console
->writeTerminal(portCon
, &chr
, 1);
pthread_mutex_lock(&mutty
);
line_status
= (val
& 0xff) | DS_LSTAT_TX_EMPTY
| DS_LSTAT_TX_HOLD
;
pthread_mutex_unlock(&mutty
);
debug_err("%s: wr access to unimplemented register 0x%x\n",getName());
int serial4v::serial4v_physio_access(uint32_t cpuid
, void* obj
, uint64_t paddr
,
mmi_bool_t wr
, uint32_t size
, uint64_t* buf
, uint8_t bytemask
){
serial4v
* s
= (serial4v
*) obj
;
s
->serial4v_st(paddr
,buf
,size
);
s
->serial4v_ld(paddr
,buf
,size
);
int serial_4v_ui_cmd(void * obj
, int argc
, char * argv
[]){
serial4v
* i
= (serial4v
*)obj
;
i
->handle_ui(argc
, argv
);
void serial4v::handle_ui(int argc
, char * argv
[]){
}else if(!strcmp(argv
[1],"send")){
const int bufSize
= 1024 * 10;
// no error checking for command string to be longer than 10KB
for(int i
= 2; i
< argc
; i
++){
buf
[strlen(buf
) - 1] = '\n';
for(int i
= 0; i
< strlen(buf
); i
++)
getConsoleIp((void*)this,(uint8_t *)(buf
+ i
),-1);
for(int i
= 0; i
< strlen(buf
); i
++)
getConsoleIp((void*)this,(uint8_t *)(buf
+ i
),-1);
}else if(!strcmp(argv
[1],"sendfile")){
while(fread(&chr
,1,1,fp
))
getConsoleIp((void*)this,&chr
,-1);
fprintf(stderr
,"%s restore: error opening file <%s>\n",getName(),argv
[2]);
fprintf(stderr
,"%s sendfile: no filename specified\n",getName());
}else if(!strcmp(argv
[1],"dump")){
fprintf(stderr
,"%s dump: error opening file <%s>\n",getName(),argv
[2]);
}else if(!strcmp(argv
[1],"restore")){
fprintf(stderr
,"%s restore: error opening file <%s>\n",getName(),argv
[2]);
fprintf(stderr
,"%s restore: no restore filename specified\n",getName());
}else if(!strcmp(argv
[1],"debug")){
debug_level
= atoi(argv
[2]);
fprintf(stderr
,"%s: set debug level to %d\n",getName(),debug_level
);
fprintf(stderr
,"%s: current debug level %d\n",getName(),debug_level
);
}else if(!strcmp(argv
[1],"pop")){
Console
->pop_term(portCon
);
}else if(!strcmp(argv
[1],"kill")){
Console
->kill_term(portCon
);
}else if(!strcmp(argv
[1],"fg")){
fprintf(stderr
," fg : %s\n", fg
);
}else if(!strcmp(argv
[1],"bg")){
fprintf(stderr
," bg : %s\n", bg
);
}else if(!strcmp(argv
[1],"font")){
if(font
) free((void*)font
);
fprintf(stderr
," font : %s\n", font
);
}else if(!strcmp(argv
[1],"T")){
if(title
) free((void*)title
);
Console
->setTitle(title
);
fprintf(stderr
," title : %s\n", title
);
}else if(!strcmp(argv
[1],"e")){
if(exec
) free((void*)exec
);
fprintf(stderr
," exec : %s\n", exec
);
debug_err("%s: unsupported UI command <%s>\n",getName(),argv
[1]);