/////////////////////////////////////////////////////////////////////////////////// // File : tty_driver.c // Date : 23/05/2013 // Author : alain greiner // Copyright (c) UPMC-LIP6 /////////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include #if !defined(SEG_TTY_BASE) # error: You must define SEG_TTY_BASE in the hard_config.h file #endif //////////////////////////////////////////////////////////////////////////////////// // global variables //////////////////////////////////////////////////////////////////////////////////// __attribute__((section(".kdata"))) unsigned int _tty_rx_buf[NB_TTY_CHANNELS]; __attribute__((section(".kdata"))) unsigned int _tty_rx_full[NB_TTY_CHANNELS]; //////////////////////////////////////////////////////////////////////////////////// // access functions //////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////// unsigned int _tty_get_register( unsigned int channel, unsigned int index ) { unsigned int* vaddr = (unsigned int*)SEG_TTY_BASE + channel*TTY_SPAN + index; return _io_extended_read( vaddr ); } ///////////////////////////////////////////// void _tty_set_register( unsigned int channel, unsigned int index, unsigned int value ) { unsigned int* vaddr = (unsigned int*)SEG_TTY_BASE + channel*TTY_SPAN + index; _io_extended_write( vaddr, value ); } ////////////////////////////////////// void _tty_init( unsigned int channel ) { _tty_rx_full[channel] = 0; } //////////////////////////////////////// void _tty_rx_isr( unsigned int irq_type, // HWI / WTI unsigned int irq_id, // index returned by XCU unsigned int channel ) // TTY channel { unsigned int gpid = _get_procid(); unsigned int cluster_xy = gpid >> P_WIDTH; // get TTY status unsigned int status = _tty_get_register( channel, TTY_STATUS ); // check both TTY status and kernel buffer status: // does nothing if kernel buffer full or tty_buffer empty if ( ((status & 0x1) == 0) || (_tty_rx_full[channel] != 0) ) return; // reset WTI in XCU if WTI type if ( irq_type == IRQ_TYPE_WTI ) { unsigned int value; _xcu_get_wti_value( cluster_xy, irq_id, &value ); } // transfer character to kernel buffer and acknowledge TTY IRQ _tty_rx_buf[channel] = _tty_get_register( channel, TTY_READ ); // set kernel buffer status asm volatile( "sync" ); _tty_rx_full[channel] = 1; #if GIET_DEBUG_IRQS // we don't take the TTY lock to avoid deadlock unsigned int x = cluster_xy >> Y_WIDTH; unsigned int y = cluster_xy & ((1<