summaryrefslogblamecommitdiffstats
path: root/c/src/lib/libbsp/i960/rxgen960/console/serial.c
blob: a9e9dd2dd9f6ef9aa97c61774493f1dec995680a (plain) (tree)










































































































































































































































































































































































                                                                                                        
/*
 *  $Id$
 */

#include "serial.h"
#include "rtems.h"


typedef unsigned char uchar ;           /* Abbreviations */
typedef unsigned short ushort ;
typedef unsigned long ulong ;
int DBGConsole_make_sync = 0;
#define CONSOLE_CHANNELS	1 

#define MAX_CONSOLE 4
static int consoles[MAX_CONSOLE]; 
static int active_consoles = 0;
static struct{
	rtems_id sem;
	int rx;
	int cnt;
	char in_line[128];
}cons_input[MAX_CONSOLE];



/* This uses the message out and in buffers as serial emulator.
	Pretty stupid eh? 
*/

#define uart1	((volatile unsigned char *)0x1318)
#define uart1_rx	((volatile unsigned int *)0x1310)

#define NUM_UARTS 1
static volatile unsigned int * uart = { uart1 };
static volatile unsigned int * uart_rx = { uart1_rx };


extern void	display_msg(void);
/*extern int	sprintf();*/



int
console_uartinit(unsigned int BAUDRate)
{
#ifdef CONSOLE_CHANNELS
	void cons_isr();
	rpmu_attach_inmsg0(cons_isr);
#endif
	return(0);
}

	
/* Introduce a new console channel */
console_new(char * name)
{
#ifdef CONSOLE_CHANNELS
	unsigned int x, stat;
	x = 0xfe000000 | (name[0] << 16) | (name[1] << 8) | name[2];
	do {
		stat = *uart;
	} while (DBGConsole_make_sync && (stat != 0));
	*uart = x;
	x = ( name[3] << 24) | ( name[4] << 16) | ( name[5] << 8) |  name[6] ;
	do {
		stat = *uart;
	} while (DBGConsole_make_sync && (stat != 0));
	*uart = x;
	active_consoles += 1;
	rtems_task_ident( RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &consoles[active_consoles] );
#endif
}
	


    /***********************************************************************
     ***  Transmit character to host.
     *** put the console ID in upper byte
     *** 
     ***********************************************************************/

int console_sps_putc(int cc)
{
	register unsigned char	stat;
	int rtid, i;
	unsigned int ch;
	unsigned int level;
#ifdef CONSOLE_CHANNELS
	rtems_task_ident( RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &rtid );
	ch = cc & 0xff;
	for(i=1; i <= active_consoles; i++){
		if( rtid == consoles[i]){
			ch |= (i ) << 24 ;
			break;
		}
	}
#else
	ch = cc;
#endif

	/*
	 *  Pause until there is room in the UART transmit
	 *  buffer.
	 */

        if (ch == -1)
          return ch;

wait:
	do {
		stat = *uart;
	} while (DBGConsole_make_sync && (stat != 0));
	rtems_interrupt_disable(level);
	if( (*uart != 0) && DBGConsole_make_sync){
		rtems_interrupt_enable(level);
		goto wait;
	}

	/*
	 *  Transmit data. (Junk)
	 */

	*uart = ch;
	rtems_interrupt_enable(level);
	return cc;

}


    /*
      * putnum -- print a 32 bit number in hex
      */
     int
     putnum (num)
     unsigned int num;
     {
       char  buffer[9];
       int   count;
       int   digit;
     
       for (count = 7 ; count >= 0 ; count--) {
         digit = (num >> (count * 4)) & 0xf;
     
         if (digit <= 9)
           console_sps_putc( (char) ('0' + digit));
         else
           console_sps_putc( (char) ('A' - 10 + digit));
       }
     }

    /*
      * putmem -- print the specified memory block
      */
     void
     putmem (addr, num)
     char *addr;
     unsigned int num;
     {
       int i = 0;
       int j = 0;
       int val = 0;
       int digit = 0;
      
       console_sps_putc(13);
       console_sps_putc(10);
       putnum((unsigned int) addr);
       console_sps_putc(':');
       console_sps_putc(' ');
       while(num)
       {
         val = *addr;

         for (j = 0; j < 2; j++)
         {
           digit = (val & 0xf0) >> 4;
           val <<= 4;

           if (digit < 10) 
           {
             console_sps_putc(digit + '0');
           }
           else
           {
             console_sps_putc(digit - 10 + 'A');
           }
         }
         console_sps_putc(' ');

         num--;
         addr++;
         if (++i == 16)
         {
           console_sps_putc(13);
           console_sps_putc(10);
           putnum((unsigned int) addr);
           console_sps_putc(':');
           console_sps_putc(' ');
           i = 0;
         }
       }
       console_sps_putc(13);
       console_sps_putc(10);
     }

    /*
      * putcmem -- print the specified pci config memory block
      */
     void
     putcmem (addr, num)
     unsigned char *addr;
     unsigned int num;
     {
       int i = 0;
       int j = 0;
       unsigned short val = 0;
       int digit = 0;
       unsigned int *satucmd = (unsigned int *) 0x1298;
       unsigned int *soccar = (unsigned int *) 0x12a8;
       unsigned int *soccdp = (unsigned int *) 0x12b0;
      
       *satucmd = 4;

       console_sps_putc(13);
       console_sps_putc(10);
       putnum((unsigned int) addr);
       console_sps_putc(':');
       console_sps_putc(' ');
       while(num)
       {
         *soccar =  (unsigned int) addr;
         val = *soccdp;

         for (j = 0; j < 4; j++)
         {
           digit = (val & 0xf000) >> 12;
           val <<= 4;

           if (digit < 10) 
           {
             console_sps_putc(digit + '0');
           }
           else
           {
             console_sps_putc(digit - 10 + 'A');
           }
         }
         console_sps_putc(' ');

         num -= 2;
         addr += 2;
         if (++i == 8)
         {
           console_sps_putc(13);
           console_sps_putc(10);
           putnum((unsigned int) addr);
           console_sps_putc(':');
           console_sps_putc(' ');
           i = 0;
         }
       }
       console_sps_putc(13);
       console_sps_putc(10);
     }

    /***********************************************************************
     ***  Read character from host.
     ***********************************************************************/
#ifdef CONSOLE_CHANNELS
int console_sps_getc()
{
	
	int consinx;
	int rtid, i;
	unsigned int level, level2;
	char ch;
	consinx = 0;
	rtems_task_ident( RTEMS_SELF, RTEMS_SEARCH_ALL_NODES, &rtid );
	for(i=1; i <= active_consoles; i++){
		if( rtid == consoles[i]){
			consinx = i ;
			break;
		}
	}
	if( i > active_consoles)
		consinx = 0;
	if( cons_input[consinx].sem == 0){
		rtems_name sname;
		sname = rtems_build_name('S','U','X',(char)(consinx + '0'));
		rtems_semaphore_create(sname, 0, RTEMS_DEFAULT_ATTRIBUTES, 0, &cons_input[consinx].sem);
		cons_input[consinx].rx = 0;
	}
	while( cons_input[consinx].cnt == cons_input[consinx].rx){
		rtems_semaphore_obtain(cons_input[consinx].sem, RTEMS_WAIT, 0);
/*	rtems_task_wake_after( RTEMS_YIELD_PROCESSOR);*/
}
	rtems_interrupt_disable(level);
	i = cons_input[consinx].rx;
	ch = cons_input[consinx].in_line[i];
	i++;
	if( i >= sizeof( cons_input[consinx].in_line))
		i = 0;
	cons_input[consinx].rx = i;
	rtems_interrupt_enable(level);
	return ch;
}
	

void cons_isr()
{
	unsigned int i, chin,  consinx, st;
	chin = *uart_rx;
	consinx = chin >> 24;
	if( consinx > active_consoles)
		goto release;
	i = cons_input[consinx].cnt;
	cons_input[consinx].in_line[i] = chin & 0xff;
	i++;
	if( i >= sizeof( cons_input[consinx].in_line))
		i = 0;
	cons_input[consinx].cnt = i;
	st = rtems_semaphore_release( cons_input[consinx].sem);
release:
	*uart_rx = 0;
}
	
#else
volatile int console_foo = 0;
int console_sps_getc()
{
	volatile unsigned int	stat;
	register int	ch;

	stat = *uart_rx;
	while (stat == 0)
        {
                rtems_task_wake_after( RTEMS_YIELD_PROCESSOR );
		stat = *uart_rx;
		console_foo++;
        }
	*uart_rx = 0;

	ch = stat;

	return ch;
}
#endif

    /***********************************************************************
     ***  check character from host.
     ***********************************************************************/

int console_sps_kbhit()
{
        register unsigned short stat;

        stat = *uart;
        return ( stat != 0);
}