/* * $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); }