/*
|
/*
|
* $Id: serial.c,v 1.2 2001-09-27 11:59:58 chris Exp $
|
* $Id: serial.c,v 1.2 2001-09-27 11:59:58 chris Exp $
|
*/
|
*/
|
|
|
#include "serial.h"
|
#include "serial.h"
|
#include "rtems.h"
|
#include "rtems.h"
|
|
|
|
|
typedef unsigned char uchar ; /* Abbreviations */
|
typedef unsigned char uchar ; /* Abbreviations */
|
typedef unsigned short ushort ;
|
typedef unsigned short ushort ;
|
typedef unsigned long ulong ;
|
typedef unsigned long ulong ;
|
int DBGConsole_make_sync = 0;
|
int DBGConsole_make_sync = 0;
|
#define CONSOLE_CHANNELS 1
|
#define CONSOLE_CHANNELS 1
|
|
|
#define MAX_CONSOLE 4
|
#define MAX_CONSOLE 4
|
static int consoles[MAX_CONSOLE];
|
static int consoles[MAX_CONSOLE];
|
static int active_consoles = 0;
|
static int active_consoles = 0;
|
static struct{
|
static struct{
|
rtems_id sem;
|
rtems_id sem;
|
int rx;
|
int rx;
|
int cnt;
|
int cnt;
|
char in_line[128];
|
char in_line[128];
|
}cons_input[MAX_CONSOLE];
|
}cons_input[MAX_CONSOLE];
|
|
|
|
|
|
|
/* This uses the message out and in buffers as serial emulator.
|
/* This uses the message out and in buffers as serial emulator.
|
Pretty stupid eh?
|
Pretty stupid eh?
|
*/
|
*/
|
|
|
#define uart1 ((volatile unsigned char *)0x1318)
|
#define uart1 ((volatile unsigned char *)0x1318)
|
#define uart1_rx ((volatile unsigned int *)0x1310)
|
#define uart1_rx ((volatile unsigned int *)0x1310)
|
|
|
#define NUM_UARTS 1
|
#define NUM_UARTS 1
|
static volatile unsigned int * uart = { uart1 };
|
static volatile unsigned int * uart = { uart1 };
|
static volatile unsigned int * uart_rx = { uart1_rx };
|
static volatile unsigned int * uart_rx = { uart1_rx };
|
|
|
|
|
extern void display_msg(void);
|
extern void display_msg(void);
|
/*extern int sprintf();*/
|
/*extern int sprintf();*/
|
|
|
|
|
|
|
int
|
int
|
console_uartinit(unsigned int BAUDRate)
|
console_uartinit(unsigned int BAUDRate)
|
{
|
{
|
#ifdef CONSOLE_CHANNELS
|
#ifdef CONSOLE_CHANNELS
|
void cons_isr();
|
void cons_isr();
|
rpmu_attach_inmsg0(cons_isr);
|
rpmu_attach_inmsg0(cons_isr);
|
#endif
|
#endif
|
return(0);
|
return(0);
|
}
|
}
|
|
|
|
|
/* Introduce a new console channel */
|
/* Introduce a new console channel */
|
console_new(char * name)
|
console_new(char * name)
|
{
|
{
|
#ifdef CONSOLE_CHANNELS
|
#ifdef CONSOLE_CHANNELS
|
unsigned int x, stat;
|
unsigned int x, stat;
|
x = 0xfe000000 | (name[0] << 16) | (name[1] << 8) | name[2];
|
x = 0xfe000000 | (name[0] << 16) | (name[1] << 8) | name[2];
|
do {
|
do {
|
stat = *uart;
|
stat = *uart;
|
} while (DBGConsole_make_sync && (stat != 0));
|
} while (DBGConsole_make_sync && (stat != 0));
|
*uart = x;
|
*uart = x;
|
x = ( name[3] << 24) | ( name[4] << 16) | ( name[5] << 8) | name[6] ;
|
x = ( name[3] << 24) | ( name[4] << 16) | ( name[5] << 8) | name[6] ;
|
do {
|
do {
|
stat = *uart;
|
stat = *uart;
|
} while (DBGConsole_make_sync && (stat != 0));
|
} while (DBGConsole_make_sync && (stat != 0));
|
*uart = x;
|
*uart = x;
|
active_consoles += 1;
|
active_consoles += 1;
|
rtems_task_ident( RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &consoles[active_consoles] );
|
rtems_task_ident( RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &consoles[active_consoles] );
|
#endif
|
#endif
|
}
|
}
|
|
|
|
|
|
|
/***********************************************************************
|
/***********************************************************************
|
*** Transmit character to host.
|
*** Transmit character to host.
|
*** put the console ID in upper byte
|
*** put the console ID in upper byte
|
***
|
***
|
***********************************************************************/
|
***********************************************************************/
|
|
|
int console_sps_putc(int cc)
|
int console_sps_putc(int cc)
|
{
|
{
|
register unsigned char stat;
|
register unsigned char stat;
|
int rtid, i;
|
int rtid, i;
|
unsigned int ch;
|
unsigned int ch;
|
unsigned int level;
|
unsigned int level;
|
#ifdef CONSOLE_CHANNELS
|
#ifdef CONSOLE_CHANNELS
|
rtems_task_ident( RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &rtid );
|
rtems_task_ident( RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &rtid );
|
ch = cc & 0xff;
|
ch = cc & 0xff;
|
for(i=1; i <= active_consoles; i++){
|
for(i=1; i <= active_consoles; i++){
|
if( rtid == consoles[i]){
|
if( rtid == consoles[i]){
|
ch |= (i ) << 24 ;
|
ch |= (i ) << 24 ;
|
break;
|
break;
|
}
|
}
|
}
|
}
|
#else
|
#else
|
ch = cc;
|
ch = cc;
|
#endif
|
#endif
|
|
|
/*
|
/*
|
* Pause until there is room in the UART transmit
|
* Pause until there is room in the UART transmit
|
* buffer.
|
* buffer.
|
*/
|
*/
|
|
|
if (ch == -1)
|
if (ch == -1)
|
return ch;
|
return ch;
|
|
|
wait:
|
wait:
|
do {
|
do {
|
stat = *uart;
|
stat = *uart;
|
} while (DBGConsole_make_sync && (stat != 0));
|
} while (DBGConsole_make_sync && (stat != 0));
|
rtems_interrupt_disable(level);
|
rtems_interrupt_disable(level);
|
if( (*uart != 0) && DBGConsole_make_sync){
|
if( (*uart != 0) && DBGConsole_make_sync){
|
rtems_interrupt_enable(level);
|
rtems_interrupt_enable(level);
|
goto wait;
|
goto wait;
|
}
|
}
|
|
|
/*
|
/*
|
* Transmit data. (Junk)
|
* Transmit data. (Junk)
|
*/
|
*/
|
|
|
*uart = ch;
|
*uart = ch;
|
rtems_interrupt_enable(level);
|
rtems_interrupt_enable(level);
|
return cc;
|
return cc;
|
|
|
}
|
}
|
|
|
|
|
/*
|
/*
|
* putnum -- print a 32 bit number in hex
|
* putnum -- print a 32 bit number in hex
|
*/
|
*/
|
int
|
int
|
putnum (num)
|
putnum (num)
|
unsigned int num;
|
unsigned int num;
|
{
|
{
|
char buffer[9];
|
char buffer[9];
|
int count;
|
int count;
|
int digit;
|
int digit;
|
|
|
for (count = 7 ; count >= 0 ; count--) {
|
for (count = 7 ; count >= 0 ; count--) {
|
digit = (num >> (count * 4)) & 0xf;
|
digit = (num >> (count * 4)) & 0xf;
|
|
|
if (digit <= 9)
|
if (digit <= 9)
|
console_sps_putc( (char) ('0' + digit));
|
console_sps_putc( (char) ('0' + digit));
|
else
|
else
|
console_sps_putc( (char) ('A' - 10 + digit));
|
console_sps_putc( (char) ('A' - 10 + digit));
|
}
|
}
|
}
|
}
|
|
|
/*
|
/*
|
* putmem -- print the specified memory block
|
* putmem -- print the specified memory block
|
*/
|
*/
|
void
|
void
|
putmem (addr, num)
|
putmem (addr, num)
|
char *addr;
|
char *addr;
|
unsigned int num;
|
unsigned int num;
|
{
|
{
|
int i = 0;
|
int i = 0;
|
int j = 0;
|
int j = 0;
|
int val = 0;
|
int val = 0;
|
int digit = 0;
|
int digit = 0;
|
|
|
console_sps_putc(13);
|
console_sps_putc(13);
|
console_sps_putc(10);
|
console_sps_putc(10);
|
putnum((unsigned int) addr);
|
putnum((unsigned int) addr);
|
console_sps_putc(':');
|
console_sps_putc(':');
|
console_sps_putc(' ');
|
console_sps_putc(' ');
|
while(num)
|
while(num)
|
{
|
{
|
val = *addr;
|
val = *addr;
|
|
|
for (j = 0; j < 2; j++)
|
for (j = 0; j < 2; j++)
|
{
|
{
|
digit = (val & 0xf0) >> 4;
|
digit = (val & 0xf0) >> 4;
|
val <<= 4;
|
val <<= 4;
|
|
|
if (digit < 10)
|
if (digit < 10)
|
{
|
{
|
console_sps_putc(digit + '0');
|
console_sps_putc(digit + '0');
|
}
|
}
|
else
|
else
|
{
|
{
|
console_sps_putc(digit - 10 + 'A');
|
console_sps_putc(digit - 10 + 'A');
|
}
|
}
|
}
|
}
|
console_sps_putc(' ');
|
console_sps_putc(' ');
|
|
|
num--;
|
num--;
|
addr++;
|
addr++;
|
if (++i == 16)
|
if (++i == 16)
|
{
|
{
|
console_sps_putc(13);
|
console_sps_putc(13);
|
console_sps_putc(10);
|
console_sps_putc(10);
|
putnum((unsigned int) addr);
|
putnum((unsigned int) addr);
|
console_sps_putc(':');
|
console_sps_putc(':');
|
console_sps_putc(' ');
|
console_sps_putc(' ');
|
i = 0;
|
i = 0;
|
}
|
}
|
}
|
}
|
console_sps_putc(13);
|
console_sps_putc(13);
|
console_sps_putc(10);
|
console_sps_putc(10);
|
}
|
}
|
|
|
/*
|
/*
|
* putcmem -- print the specified pci config memory block
|
* putcmem -- print the specified pci config memory block
|
*/
|
*/
|
void
|
void
|
putcmem (addr, num)
|
putcmem (addr, num)
|
unsigned char *addr;
|
unsigned char *addr;
|
unsigned int num;
|
unsigned int num;
|
{
|
{
|
int i = 0;
|
int i = 0;
|
int j = 0;
|
int j = 0;
|
unsigned short val = 0;
|
unsigned short val = 0;
|
int digit = 0;
|
int digit = 0;
|
unsigned int *satucmd = (unsigned int *) 0x1298;
|
unsigned int *satucmd = (unsigned int *) 0x1298;
|
unsigned int *soccar = (unsigned int *) 0x12a8;
|
unsigned int *soccar = (unsigned int *) 0x12a8;
|
unsigned int *soccdp = (unsigned int *) 0x12b0;
|
unsigned int *soccdp = (unsigned int *) 0x12b0;
|
|
|
*satucmd = 4;
|
*satucmd = 4;
|
|
|
console_sps_putc(13);
|
console_sps_putc(13);
|
console_sps_putc(10);
|
console_sps_putc(10);
|
putnum((unsigned int) addr);
|
putnum((unsigned int) addr);
|
console_sps_putc(':');
|
console_sps_putc(':');
|
console_sps_putc(' ');
|
console_sps_putc(' ');
|
while(num)
|
while(num)
|
{
|
{
|
*soccar = (unsigned int) addr;
|
*soccar = (unsigned int) addr;
|
val = *soccdp;
|
val = *soccdp;
|
|
|
for (j = 0; j < 4; j++)
|
for (j = 0; j < 4; j++)
|
{
|
{
|
digit = (val & 0xf000) >> 12;
|
digit = (val & 0xf000) >> 12;
|
val <<= 4;
|
val <<= 4;
|
|
|
if (digit < 10)
|
if (digit < 10)
|
{
|
{
|
console_sps_putc(digit + '0');
|
console_sps_putc(digit + '0');
|
}
|
}
|
else
|
else
|
{
|
{
|
console_sps_putc(digit - 10 + 'A');
|
console_sps_putc(digit - 10 + 'A');
|
}
|
}
|
}
|
}
|
console_sps_putc(' ');
|
console_sps_putc(' ');
|
|
|
num -= 2;
|
num -= 2;
|
addr += 2;
|
addr += 2;
|
if (++i == 8)
|
if (++i == 8)
|
{
|
{
|
console_sps_putc(13);
|
console_sps_putc(13);
|
console_sps_putc(10);
|
console_sps_putc(10);
|
putnum((unsigned int) addr);
|
putnum((unsigned int) addr);
|
console_sps_putc(':');
|
console_sps_putc(':');
|
console_sps_putc(' ');
|
console_sps_putc(' ');
|
i = 0;
|
i = 0;
|
}
|
}
|
}
|
}
|
console_sps_putc(13);
|
console_sps_putc(13);
|
console_sps_putc(10);
|
console_sps_putc(10);
|
}
|
}
|
|
|
/***********************************************************************
|
/***********************************************************************
|
*** Read character from host.
|
*** Read character from host.
|
***********************************************************************/
|
***********************************************************************/
|
#ifdef CONSOLE_CHANNELS
|
#ifdef CONSOLE_CHANNELS
|
int console_sps_getc()
|
int console_sps_getc()
|
{
|
{
|
|
|
int consinx;
|
int consinx;
|
int rtid, i;
|
int rtid, i;
|
unsigned int level, level2;
|
unsigned int level, level2;
|
char ch;
|
char ch;
|
consinx = 0;
|
consinx = 0;
|
rtems_task_ident( RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &rtid );
|
rtems_task_ident( RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &rtid );
|
for(i=1; i <= active_consoles; i++){
|
for(i=1; i <= active_consoles; i++){
|
if( rtid == consoles[i]){
|
if( rtid == consoles[i]){
|
consinx = i ;
|
consinx = i ;
|
break;
|
break;
|
}
|
}
|
}
|
}
|
if( i > active_consoles)
|
if( i > active_consoles)
|
consinx = 0;
|
consinx = 0;
|
if( cons_input[consinx].sem == 0){
|
if( cons_input[consinx].sem == 0){
|
rtems_name sname;
|
rtems_name sname;
|
sname = rtems_build_name('S','U','X',(char)(consinx + '0'));
|
sname = rtems_build_name('S','U','X',(char)(consinx + '0'));
|
rtems_semaphore_create(sname, 0, RTEMS_DEFAULT_ATTRIBUTES, 0, &cons_input[consinx].sem);
|
rtems_semaphore_create(sname, 0, RTEMS_DEFAULT_ATTRIBUTES, 0, &cons_input[consinx].sem);
|
cons_input[consinx].rx = 0;
|
cons_input[consinx].rx = 0;
|
}
|
}
|
while( cons_input[consinx].cnt == cons_input[consinx].rx){
|
while( cons_input[consinx].cnt == cons_input[consinx].rx){
|
rtems_semaphore_obtain(cons_input[consinx].sem, RTEMS_WAIT, 0);
|
rtems_semaphore_obtain(cons_input[consinx].sem, RTEMS_WAIT, 0);
|
/* rtems_task_wake_after( RTEMS_YIELD_PROCESSOR);*/
|
/* rtems_task_wake_after( RTEMS_YIELD_PROCESSOR);*/
|
}
|
}
|
rtems_interrupt_disable(level);
|
rtems_interrupt_disable(level);
|
i = cons_input[consinx].rx;
|
i = cons_input[consinx].rx;
|
ch = cons_input[consinx].in_line[i];
|
ch = cons_input[consinx].in_line[i];
|
i++;
|
i++;
|
if( i >= sizeof( cons_input[consinx].in_line))
|
if( i >= sizeof( cons_input[consinx].in_line))
|
i = 0;
|
i = 0;
|
cons_input[consinx].rx = i;
|
cons_input[consinx].rx = i;
|
rtems_interrupt_enable(level);
|
rtems_interrupt_enable(level);
|
return ch;
|
return ch;
|
}
|
}
|
|
|
|
|
void cons_isr()
|
void cons_isr()
|
{
|
{
|
unsigned int i, chin, consinx, st;
|
unsigned int i, chin, consinx, st;
|
chin = *uart_rx;
|
chin = *uart_rx;
|
consinx = chin >> 24;
|
consinx = chin >> 24;
|
if( consinx > active_consoles)
|
if( consinx > active_consoles)
|
goto release;
|
goto release;
|
i = cons_input[consinx].cnt;
|
i = cons_input[consinx].cnt;
|
cons_input[consinx].in_line[i] = chin & 0xff;
|
cons_input[consinx].in_line[i] = chin & 0xff;
|
i++;
|
i++;
|
if( i >= sizeof( cons_input[consinx].in_line))
|
if( i >= sizeof( cons_input[consinx].in_line))
|
i = 0;
|
i = 0;
|
cons_input[consinx].cnt = i;
|
cons_input[consinx].cnt = i;
|
st = rtems_semaphore_release( cons_input[consinx].sem);
|
st = rtems_semaphore_release( cons_input[consinx].sem);
|
release:
|
release:
|
*uart_rx = 0;
|
*uart_rx = 0;
|
}
|
}
|
|
|
#else
|
#else
|
volatile int console_foo = 0;
|
volatile int console_foo = 0;
|
int console_sps_getc()
|
int console_sps_getc()
|
{
|
{
|
volatile unsigned int stat;
|
volatile unsigned int stat;
|
register int ch;
|
register int ch;
|
|
|
stat = *uart_rx;
|
stat = *uart_rx;
|
while (stat == 0)
|
while (stat == 0)
|
{
|
{
|
rtems_task_wake_after( RTEMS_YIELD_PROCESSOR );
|
rtems_task_wake_after( RTEMS_YIELD_PROCESSOR );
|
stat = *uart_rx;
|
stat = *uart_rx;
|
console_foo++;
|
console_foo++;
|
}
|
}
|
*uart_rx = 0;
|
*uart_rx = 0;
|
|
|
ch = stat;
|
ch = stat;
|
|
|
return ch;
|
return ch;
|
}
|
}
|
#endif
|
#endif
|
|
|
/***********************************************************************
|
/***********************************************************************
|
*** check character from host.
|
*** check character from host.
|
***********************************************************************/
|
***********************************************************************/
|
|
|
int console_sps_kbhit()
|
int console_sps_kbhit()
|
{
|
{
|
register unsigned short stat;
|
register unsigned short stat;
|
|
|
stat = *uart;
|
stat = *uart;
|
return ( stat != 0);
|
return ( stat != 0);
|
}
|
}
|
|
|
|
|
|
|
|
|
|
|