예제 #1
0
/**
 * version of printf that works better in exception context.
 *
 * @param format
 *
 * XXX If this function weren't in cvmx-interrupt.c, we'd use the SDK version.
 */
void cvmx_safe_printf(const char *format, ...)
{
    char buffer[256];
    char *ptr = buffer;
    int count;
    va_list args;

    va_start(args, format);
#ifndef __U_BOOT__
    count = vsnprintf(buffer, sizeof(buffer), format, args);
#else
    count = vsprintf(buffer, format, args);
#endif
    va_end(args);

    while (count-- > 0)
    {
        cvmx_uart_lsr_t lsrval;

        /* Spin until there is room */
        do
        {
            lsrval.u64 = cvmx_read_csr(CVMX_MIO_UARTX_LSR(0));
#if !defined(CONFIG_OCTEON_SIM_SPEED)
            if (lsrval.s.temt == 0)
                cvmx_wait(10000);   /* Just to reduce the load on the system */
#endif
        }
        while (lsrval.s.temt == 0);

        if (*ptr == '\n')
            cvmx_write_csr(CVMX_MIO_UARTX_THR(0), '\r');
        cvmx_write_csr(CVMX_MIO_UARTX_THR(0), *ptr++);
    }
}
예제 #2
0
파일: cvmx-interrupt.c 프로젝트: odit/rv042
/**
 * version of printf that works better in exception context.
 *
 * @param format
 */
static void safe_printf(const char *format, ...)
{
    static char buffer[256];
    va_list args;
    va_start(args, format);
    int count = vsnprintf(buffer, sizeof(buffer), format, args);
    va_end(args);

    char *ptr = buffer;
    while (count-- > 0)
    {
        cvmx_uart_lsr_t lsrval;

        /* Spin until there is room */
        do
        {
            lsrval.u64 = cvmx_read_csr(CVMX_MIO_UARTX_LSR(0));
            if (lsrval.s.temt == 0)
                cvmx_wait(10000);   /* Just to reduce the load on the system */
        }
        while (lsrval.s.temt == 0);

        if (*ptr == '\n')
            cvmx_write_csr(CVMX_MIO_UARTX_THR(0), '\r');
        cvmx_write_csr(CVMX_MIO_UARTX_THR(0), *ptr++);
    }
}
예제 #3
0
파일: ewx_uart.c 프로젝트: zliu/libewx
/**
 * Get a single byte from serial port.
 *
 * @param uart_index Uart to read from (0 or 1)
 * @return The byte read
 */
inline uint8_t uart_read_byte_wait( int uart_index )
{
	/* Read and return the data. Will not be returned if there is
	no data */
	if( !pci_console )
	{
		cvmx_uart_lsr_t lsrval;
		while ( 1 )
		{
			lsrval.u64 = cvmx_read_csr( CVMX_MIO_UARTX_LSR( uart_index ) );
			if ( lsrval.s.dr )
			{
				return cvmx_read_csr( CVMX_MIO_UARTX_RBR( uart_index ) );
			}
			return getchar();
		}
	}
	else
	{
		char c;
		while ( 1 )
		{
			if ( !pci_cons_desc_addr )
			{
				return 0;
			}
			octeon_pci_console_read(pci_cons_desc_addr, 0,	&c, 1, 1);
			return c;
		}
	}
}
예제 #4
0
파일: ewx_uart.c 프로젝트: zliu/libewx
int uart_read_byte_nowait( int uart_index )
{
	/* Read and return the data. Zero will be returned if there is
	no data */
	if( !pci_console )
	{
		cvmx_uart_lsr_t lsrval;
		lsrval.u64 = cvmx_read_csr( CVMX_MIO_UARTX_LSR( uart_index ) );
		if ( lsrval.s.dr )
		{
			return cvmx_read_csr( CVMX_MIO_UARTX_RBR( uart_index ) );
		}
		else
		{
			return -1;
		}
	}
	else
	{
		char c;
		if ( !pci_cons_desc_addr )
		{
			return 0;
		}
		octeon_pci_console_read(pci_cons_desc_addr, 0,	&c, 1, 1);
		return c;
	}
}
예제 #5
0
static int octeon_serial_tstc(void)
{
    cvmx_uart_lsr_t lsrval;
    uint8_t uart_index = GET_UART_INDEX(gd->arch.console_uart);
    uint8_t node = GET_UART_NODE(gd->arch.console_uart);

    octeon_board_poll();
    WATCHDOG_RESET();

    lsrval.u64 = cvmx_read_csr_node(node,
                                    CVMX_MIO_UARTX_LSR(uart_index));
    return lsrval.s.dr;
}
예제 #6
0
파일: ewx_uart.c 프로젝트: zliu/libewx
/**
 * Wait for the TX buffer to be empty
 *
 * @param uart_index Uart to check
 */
void uart_wait_idle( int uart_index )
{
	cvmx_uart_lsr_t lsrval;

	// Spin until there is room
	do
	{
		lsrval.u64 = cvmx_read_csr( CVMX_MIO_UARTX_LSR( uart_index ) );
		if ( lsrval.s.temt == 0 )
		{
			cvmx_wait( 10000 );   // Just to reduce the load on the system
		}
	}
	while ( lsrval.s.temt == 0 );
}
예제 #7
0
/**
 * Put a single byte to uart port.
 *
 * @param uart_index Uart to write to (0 or 1)
 * @param ch         Byte to write
 */
static inline void uart_write_byte(int uart, uint8_t ch)
{
    cvmx_uart_lsr_t lsrval;
    uint8_t uart_index = GET_UART_INDEX(uart);
    uint8_t node = GET_UART_NODE(uart);

    /* Spin until there is room */
    do {
        lsrval.u64 = cvmx_read_csr_node(node,
                                        CVMX_MIO_UARTX_LSR(uart_index));
    } while (lsrval.s.thre == 0);

    WATCHDOG_RESET();
    /* Write the byte */
    cvmx_write_csr_node(node, CVMX_MIO_UARTX_THR(uart_index), ch);
}
예제 #8
0
/**
 * Get a single byte from serial port.
 *
 * @param uart_index Uart to read from (0 or 1)
 * @return The byte read
 */
static inline uint8_t uart_read_byte(int uart)
{
    cvmx_uart_lsr_t lsrval;
    uint8_t uart_index = GET_UART_INDEX(uart);
    uint8_t node = GET_UART_NODE(uart);

    /* Spin until data is available */
    do {
        lsrval.u64 = cvmx_read_csr_node(node,
                                        CVMX_MIO_UARTX_LSR(uart_index));
        WATCHDOG_RESET();
        octeon_board_poll();
    } while (!lsrval.s.dr);

    /* Read and return the data */
    return cvmx_read_csr_node(node, CVMX_MIO_UARTX_RBR(uart_index));
}
예제 #9
0
파일: ewx_uart.c 프로젝트: zliu/libewx
/**
 * Put a single byte to uart port.
 *
 * @param uart_index Uart to write to (0 or 1)
 * @param ch         Byte to write
 */
inline void uart_write_byte( int uart_index, uint8_t ch )
{
	if ( !pci_console )
	{
		cvmx_uart_lsr_t lsrval;

		// Spin until there is room
		do
		{
			lsrval.u64 = cvmx_read_csr( CVMX_MIO_UARTX_LSR( uart_index ) );
			if ( lsrval.s.thre == 0 )
			{
				cvmx_wait( 10000 );   /* Just to reduce the load on the system */
			}
		}
		while ( lsrval.s.thre == 0 );

		// Write the byte
		cvmx_write_csr( CVMX_MIO_UARTX_THR( uart_index ), ch );
		return;
	}
	else
	{
		char r = '\r';
		if ( pci_cons_desc_addr )
		{
    	    if (ch == '\n')
				octeon_pci_console_write(pci_cons_desc_addr, 0,  &r, 1, OCT_PCI_CON_FLAG_NONBLOCK);
			octeon_pci_console_write(pci_cons_desc_addr, 0,  (char *)&ch, 1, OCT_PCI_CON_FLAG_NONBLOCK);
		}
		else
		{
			printf( "pci_console read error\n" );
		}
	}
}
예제 #10
0
/**
 * Function that does the real work of setting up the Octeon uart.
 * Takes all parameters as arguments, so it does not require gd
 * structure to be set up.
 *
 * @param uart_index Index of uart to configure
 * @param cpu_clock_hertz
 *                   CPU clock frequency in Hz
 * @param baudrate   Baudrate to configure
 *
 * @return 0 on success
 *         !0 on error
 */
int octeon_uart_setup2(int uart, int cpu_clock_hertz, int baudrate)
{
    uint16_t divisor;
    cvmx_uart_fcr_t fcrval;
    cvmx_uart_mcr_t mcrval;
    cvmx_uart_lcr_t lcrval;
    uint8_t uart_index = GET_UART_INDEX(uart);
    uint8_t node = GET_UART_NODE(uart);
#if !CONFIG_OCTEON_SIM_SPEED
    uint64_t read_cycle;
#endif

    fcrval.u64 = 0;
    fcrval.s.en = 1;	/* enable the FIFO's */
    fcrval.s.rxfr = 1;	/* reset the RX fifo */
    fcrval.s.txfr = 1;	/* reset the TX fifo */

    divisor = compute_divisor(cpu_clock_hertz, baudrate);

    cvmx_write_csr_node(node, CVMX_MIO_UARTX_FCR(uart_index), fcrval.u64);

    mcrval.u64 = 0;
#if CONFIG_OCTEON_SIM_SETUP
    if (uart_index == 1)
        mcrval.s.afce = 1;	/* enable auto flow control for
					 * simulator. Needed for gdb
					 * regression callfuncs.exp.
					 */
    else
        mcrval.s.afce = 0;	/* disable auto flow control so board
					 * can power on without serial port
					 * connected
					 */
#else
    mcrval.s.afce = 0;	/* disable auto flow control so board can power
				 * on without serial port connected
				 */
#endif
    mcrval.s.rts = 1;	/* looks like this must be set for auto flow
				 * control to work
				 */

    cvmx_read_csr_node(node, CVMX_MIO_UARTX_LSR(uart_index));

    lcrval.u64 = 0;
    lcrval.s.cls = CVMX_UART_BITS8;
    lcrval.s.stop = 0;	/* stop bit included? */
    lcrval.s.pen = 0;	/* no parity? */
    lcrval.s.eps = 1;	/* even parity? */
    lcrval.s.dlab = 1;	/* temporary to program the divisor */
    cvmx_write_csr_node(node, CVMX_MIO_UARTX_LCR(uart_index), lcrval.u64);

    cvmx_write_csr_node(node, CVMX_MIO_UARTX_DLL(uart_index), divisor & 0xff);
    cvmx_write_csr_node(node, CVMX_MIO_UARTX_DLH(uart_index), (divisor >> 8) & 0xff);

    /* divisor is programmed now, set this back to normal */
    lcrval.s.dlab = 0;
    cvmx_write_csr_node(node, CVMX_MIO_UARTX_LCR(uart_index), lcrval.u64);

#if !CONFIG_OCTEON_SIM_SPEED
    /* spec says need to wait after you program the divisor */
    read_cycle = octeon_get_cycles() + (2 * divisor * 16) + 10000;
    while (octeon_get_cycles() < read_cycle) {
        /* Spin */
    }
#endif

    /* Don't enable flow control until after baud rate is configured. - we
     * don't want to allow characters in until after the baud rate is
     * fully configured
     */
    cvmx_write_csr_node(node, CVMX_MIO_UARTX_MCR(uart_index), mcrval.u64);
    return 0;

}