/* * dev_pic.h - PIC (Programmable Interrupt Controler) generic device API definition. * * Authors 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-MKH; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #ifndef _DEV_PIC_H_ #define _DEV_PIC_H_ #include #include /***************************************************************************************** * Generic Programmable Interrupt Controler definition * * The PIC generic device describes the the programmable hardware infrastructure used * to route a given IRQ to a given core, in a given cluster, and to help the interrupt * handler to select and execute the relevant ISR (Interrupt Service Routine). * It handles the four following types of interrupts: * * 1) EXT_IRQ (External IRQ) generated by the external (shared) peripherals. * 2) INT_IRQ (Internal IRQ) generated by the internal (replicated) peripherals. * 3) TIM_IRQ (Timer IRQ) generated by the timers (one timer per core). * 4) IPI_IRQ (Inter Processor IRQ) generated by software (one IPI per core). * * In supported manycores architectures, the PIC device contains two types * of hardware components: * - the IOPIC is an external component, handling all external peripherals IRQs. * - The LAPIC is an internal component, replicated in each cluster, handling local * peripherals IRQS, Timer IRQs and IPIs (inter-processor-interupts). * * The "source" device for each input IRQ to the external IOPIC component, is defined * in the "arch_info" file, and registered in the "iopic_input" global variable * at kernel initialization. * * The "source" device for each input IRQ to the replicated LAPIC components, is defined * in the "arch_info" file, and stored in the "lapic_input" global variable * at kernel initialization. * * The PIC device defines generic commands that can be used by each kernel instance, * - to create in local cluster the PIC implementation specific interupt vector(s), * - to bind a given IRQ (internal or external IRQ to a given core in the local cluster, * - to configure and activate the TICK timer for a given core in the local cluster, * - to allows the software to send an IPI to any core in any cluster. * This API is detailed below, and must be implemented by all PIC implementations. * * In each cluster, a PIC implementation specific structure can be linked to the * cluster manager or to the core descriptors to register the interrupt vectors * used by the kernel to select the relevant ISR when an interrupt is received * by a given core in a given cluster. * This PIC device does not execute itself I/O operations. It is just acting as a * configurable interrupt router for I/O operation executed by other peripherals. * Therefore, ALMOS-MKH does not use the PIC device waiting queue, does not creates * a server thread for the PIC device, and does not register the command in the calling * thread descriptor, but call directly the relevant driver function. ****************************************************************************************/ /**** Forward declarations ****/ struct chdev_s; /***************************************************************************************** * This defines the specific extension for the PIC chdev descriptor. * It contains the function pointers for all functions that mus be implemented * by all implementation specific drivers. ****************************************************************************************/ typedef void (bind_irq_t) ( lid_t lid , struct chdev_s * src_chdev ); typedef void (enable_irq_t) ( lid_t lid , xptr_t src_chdev_xp ); typedef void (disable_irq_t) ( lid_t lid , xptr_t src_chdev_xp ); typedef void (enable_timer_t) ( uint32_t period ); typedef void (enable_ipi_t) ( void ); typedef void (send_ipi_t) ( cxy_t cxy , lid_t lid ); typedef void (ack_ipi_t) ( void ); typedef void (extend_init_t) ( uint32_t * lapic_base ); typedef struct pic_extend_s { bind_irq_t * bind_irq; /*! pointer on the driver "bind_irq" function */ enable_irq_t * enable_irq; /*! pointer on the driver "enable_irq" function */ disable_irq_t * disable_irq; /*! pointer on the driver "disable_irq" function */ enable_timer_t * enable_timer; /*! pointer on the driver "enable_timer" function */ enable_ipi_t * enable_ipi; /*! pointer on the driver "enable_ipi" function */ send_ipi_t * send_ipi; /*! pointer on the driver "send_ipi" function */ ack_ipi_t * ack_ipi; /*! pointer on the driver "ack_ipi" function */ extend_init_t * extend_init; /*! pointer on the driver "init_extend" function */ } pic_extend_t; /***************************************************************************************** * This structure defines the input IRQS for the external IOPIC controller, that is used * by external peripherals (IOC, NIC, TXT, etc.) to signal completion of an I/O operation. * It describes the hardware wiring of IRQs between external peripherals and the IOPIC, * as each entry contains the input IRQ index in IOPIC. * For a multi-channels/multi_IRQ peripheral, there is one chdev per IRQ. * This structure is replicated in each cluster. It is allocated as a global variable * in the kernel_init.c file. *****************************************************************************************/ typedef struct iopic_input_s { uint32_t ioc[CONFIG_MAX_IOC_CHANNELS]; uint32_t txt_rx[CONFIG_MAX_TXT_CHANNELS]; uint32_t txt_tx[CONFIG_MAX_TXT_CHANNELS]; uint32_t nic_rx[CONFIG_MAX_NIC_CHANNELS]; uint32_t nic_tx[CONFIG_MAX_NIC_CHANNELS]; uint32_t iob; } iopic_input_t; /****************************************************************************************** * This structure defines the input IRQS for the internal LAPIC controllers, that are used * by internal peripherals IRQS (DMA, MMC) to signal completion of an I/O operation. * It describes the hardware wiring of IRQs between internal peripherals and ICU, * as each entry contains the input IRQ index in the LAPIC component. * For a multi-channels peripheral, there is one chdev and one IRQ per channel. * This structure is replicated in each cluster. It is allocated as a global variable * in the kernel_init.c file. *****************************************************************************************/ typedef struct lapic_input_s { uint32_t dma[CONFIG_MAX_DMA_CHANNELS]; uint32_t mmc; // MMC is single channel } lapic_input_t; /***************************************************************************************** * This enum defines the various implementations of the PIC device. * This array must be kept consistent with the define in arch_info.h file ****************************************************************************************/ enum pic_impl_e { IMPL_PIC_SCL = 0, IMPL_PIC_I86 = 1, } pic_impl_t; /***************************************************************************************** * This function makes two initialisations : * - It initializes the PIC specific fields of the chdev descriptor. * - it initializes the implementation specific PIC hardware registers. * It is executed once in cluster containing the PIC chdev, during kernel initialisation. * The calling core goes to sleep in case of failure. ***************************************************************************************** * @ pic : local pointer on PIC device descriptor. ****************************************************************************************/ void dev_pic_init( struct chdev_s * pic ); /***************************************************************************************** * This function completes the PIC infrastructure initialisation in each cluster. * It allocates memory for the local PIC extensions in the core descriptors and/or * in the cluster manager, as required by the specific PIC implementation. * This function is called by CPO in all clusters, during kernel initialisation phase. * The calling core goes to sleep in case of failure. ***************************************************************************************** * @ lapic_base : local pointer on LAPIC component segment base. ****************************************************************************************/ void dev_pic_extend_init( uint32_t * lapic_base ); /***************************************************************************************** * This function configure the PIC device to route the IRQ generated by a local chdev, * defined by the argument, to a local core identified by the argument. * This is a static binding, defined during kernel init: IRQ can be enabled/disabled, * but the binding cannot be released. It can be used for both internal & external IRQs. * The configuration is actually done by the - implementation specific - driver, * and this function just call the relevant driver. * WARNING : the IRQ must be explicitely enabled by the dev_pic_enable_irq() function. ***************************************************************************************** * @ lid : target core local index. * @ src_chdev : local pointer on source chdev descriptor. ****************************************************************************************/ void dev_pic_bind_irq( lid_t lid, struct chdev_s * src_chdev ); /***************************************************************************************** * This function enables the IRQ generated by a remote chdev, defined by the * argument. It can be called by any thread running in any cluster, * and can be used for both internal & external IRQs. ***************************************************************************************** * @ lid : target core local index (in cluster containing the source chdev). * @ src_chdev_xp : extended pointer on source chdev descriptor. ****************************************************************************************/ void dev_pic_enable_irq( lid_t lid, xptr_t src_chdev_xp ); /***************************************************************************************** * This function disables remote IRQ generated by a remote chdev, defined by the * argument. It can be called by any thread running in any cluster, * and can be used for both INT_IRq & EXT_IRQ. ***************************************************************************************** * @ lid : target core local index (in cluster containing the source chdev). * @ src_chdev_xp : extended pointer on sour chdev descriptor. ****************************************************************************************/ void dev_pic_disable_irq( lid_t lid, xptr_t src_chdev_xp ); /***************************************************************************************** * This function activates the TIM_IRQ for the calling core. * The argument is a number of milli-seconds between two successive IRQs. * It is converted to a number of cycles by the PIC driver implementation. ***************************************************************************************** * @ period : number of milliseconds. ****************************************************************************************/ void dev_pic_enable_timer( uint32_t period ); /***************************************************************************************** * This function activates the IPI_IRQ for the calling core. ****************************************************************************************/ void dev_pic_enable_ipi( void ); /***************************************************************************************** * This function allows the calling thread to send an IPI to any core in any cluster. * The target core is identified by the & arguments. ***************************************************************************************** * @ cxy : target core cluster. * @ lid : target core local index. ****************************************************************************************/ void dev_pic_send_ipi( cxy_t cxy, lid_t lid ); /***************************************************************************************** * This function acknowledges the IPI identified by the calling core local index, * in the local LAPIC component. ****************************************************************************************/ void dev_pic_ack_ipi( void ); /***************************************************************************************** * This debug function displays the content of the iopic_input structure, * that register the input IRQS for the external IOPIC controller. ****************************************************************************************/ void dev_pic_inputs_display( void ); #endif /* _DEV_PIC_H_ */