/* * soclib_mty.c - soclib_mty driver definition (used in TSAR-LETI architecture). * * Author Alain Greiner (2016,2017,2018) * * Copyright (c) UPMC Sorbonne Universites * * This file is part of ALMOS-MKH. * * ALMOS-MKH is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2.0 of the License. * * ALMOS-MKH is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with ALMOS-kernel; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include /**************************************************************************************** * This driver supports the "backup" TTY controler implemented in cluster 0 * of the TSAR-LETI architecture, that is actually an over-simplified version * of the vci_tty_tsar component: * * 1) This hardware component handles only ONE TTY physical channel, that must * be virtualized by the driver to support several kernel TXT devices. * 2) For received characters, the hardware support one RX_IRQ, and one bit * in the MTY_STATUS register to signal that the MTY_READ register is full. * 3) For transmitted characters, the hardware does NOT provide a TX_IRQ, * and does NOT provide status information about the MTY_WRITE register, * but implement a low-level flow control mechanism: the response to the * VCI write request in MTY_WRITE register is blocked until this register * can be actually written... * * It implements the generic TXT device API: * - transfer one single character from TTY to command "buffer" if to_mem is non-zero. * - transfer "count" characters from command "buffer" to TTY if "to_mem is zero. * * It handles asynchronous control characters (^C / ^Z), that are translated to signals * transmited to the TXT owner process (foreground process). * * This driver implements one TX_FIFO for the transmited characters, writen by the "cmd" * function, and read by the "isr" function). * This driver implements one RX_FIFO for the received characters, writen by the "isr" * function, and read by the "cmd" function). ***************************************************************************************/ /**************************************************************************************** * SOCLIB_MTY registers offsets and masks ***************************************************************************************/ #define MTY_WRITE 0 #define MTY_STATUS 1 #define MTY_READ 2 #define MTY_CONFIG 3 /**************************************************************************************** * masks for MTY_STATUS and MTY_CONFIG registers ***************************************************************************************/ #define MTY_STATUS_RX_FULL 1 // TTY_READ_REG full if 1 #define MTY_CONFIG_RX_ENABLE 1 // RX_IRQ enable if 1 /**************************************************************************************** * This structure is used for both the RX_FIFO and the TX_FIFO. ***************************************************************************************/ #define MTY_FIFO_DEPTH 128 typedef struct mty_fifo_s { char data[MTY_FIFO_DEPTH]; // one char per slot unsigned int ptr; // next free slot index unsigned int ptw; // next full slot index unsigned int sts; // number of full slots } mty_fifo_t; /**************************************************************************************** * This function masks the TTY_RX IRQ. **************************************************************************************** * @ chdev : pointer on the TXT chdev descriptor. ***************************************************************************************/ void soclib_mty_init( chdev_t * chdev ); /**************************************************************************************** * This function implements both the TXT_READ & TXT_WRITE commands registered in the * client thread descriptor (in the txt_cmd field), even if ALMOS-MKH defines two * different chdevs (and consequently two diffeerent server threads) for the RX and TX * directions. The client thread is identified by the argument. * These functions are supposed to be called by the server thread associated at a * given TXT channel for a given direction (TX or RX). * Depending on the command type, it access the TX_FIFO or RX_FIFO, and blocks the TXT * device server thread on the THREAD_BLOCKED_DEV_ISR, if the RX_FIFO is empty (for a * READ), or if the TX_FIFO is full for a WRITE). * The actual transfer between the FIFOs and the TTY device registers is done by the ISR. * **************************************************************************************** * @ thread_xp : extended pointer on client thread descriptor. ***************************************************************************************/ void soclib_mty_cmd( xptr_t thread_xp ); /**************************************************************************************** * This function implements the TXT_SYNC_WRITE command registered in the txt_aux_t * structure. As the MTY hardware component does not provide any status information, * it relies on the "blocking write" mechanism to the MTY_REGISTER for flow-control. * It is used by the kernel do display debug messages on TXT0 terminal, without * interference with another TXT access to another terminal done by the same thread. **************************************************************************************** * @ thread_xp : pointer on the txt_aux_t structure containing the arguments. ***************************************************************************************/ void soclib_mty_aux( void * args ); /**************************************************************************************** * This ISR is executed to handle both TX and RX transfers: * It is also in charge of multiplexing / demultiplexing the characters between * one single physical channel, and several virtual channels. * There is one couple of TX_FIFO / RX_FIFO per virtual channel, and each FIFO can be * located in a different cluster (in the same cluster as the associated chdev). * * For both TX and TX, a character on the physical channel is encoded as two bytes: * The first byte contains the virtual channel index. The second byte contains * the ascii character value. * * - For RX, this ISR is called to move one character from the MTY_READ register to * the relevant RX_FIFO when the MTY_RX_IRQ is activated (when the MTY_STATUS_RX_FULL * bit, and the MTY_CONFIG_RX_ENABLE bit are both set), indicating that the MTY_READ * register is full and can be read. As there is one single physical channel, * there is one single MTY_RX_IRQ, that is routed to one single core that dispatch * each received character to the relevant (likely remote) RX_FIFO. * This core is supposed to be located in the same cluster as the MTY peripheral. * * - For TX, there is no TX_IRQ handled by the MTY controller, and no status bit. * Therefore, this ISR is called to move one character from one TX_FIFO to the * MTY_WRITE register at each TICK event, and relies on the "blocking write" * mechanism to the MTY_REGISTER for flow-control. * As there is one single physical channel, this ISR is executed by one single core * that scan the (likely remote) TX_FIFOs associated to all virtual channels, * and transmit the first found character, with a round_robin policy between channels. * This core is supposed to be located in the same cluster as the MTY peripheral. * * The RX_IRQ is always enabled to catch the control characters (^C / ^D / ^Z), * that are not copied in the RX_FIFO, but directly analysed by the ISR * and signaled to the TXT owner process (foreground process). **************************************************************************************** * @ chdev : local pointer on TXT chdev descriptor. ***************************************************************************************/ void soclib_mty_isr( chdev_t * chdev );