/* * soclib_pic.h - soclib PIC driver definition. * * Author Alain Greiner (2016,2017) * * 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 */ #ifndef _SOCLIB_PIC_H_ #define _SOCLIB_PIC_H_ #include /**** Forward declarations ****/ struct chdev_s; /***************************************************************************************** * This file defines the driver for the SOCLIB PIC device. * * The SOCLIB PIC infrastructure contains two types of components: * * - The IOPIC external controller handles the external IRQs generated by the external * peripherals. The IOPIC controller provides two services: * 1) It translate each IRQ hardware signal to a write transactions to a specific * mailbox, for a given core in a giveb cluster, as explained below. * 2) It allows the kernel to selectively enable/disable any external IRQ * identified by its index. * * - The XCU internal controller implement the generic local interrupt controller * (LAPIC), replicated in all clusters containing at least one core. * In each cluster, it concentrates all IRQs destinated to one given core, * and helps the interrupt handler to select the ISR (Interrupt Service Routine) * that must be executed by the target core. It defines three types of IRQs: * 1) HWI : The HardWare Interrupts are generated by local internal peripherals. * They are connected to the local XCU, to be routed to a given local core. * 2) WTI : The Write Triggered Interrupts are actually mailboxes implemented in the * local XCU. They are used to implement software IPIs (Inter-Processor-Interrupts), * or to register the write transactions generated by the IOPIC controller. * 3) PTI : The Programmable Timer Interrupts are actually timers generating periodic * interrupts controled by softare, contained in the local XCU, and routed to * a local core. * The numbers of interrupts of each type in a given cluster are defined in the * XCU_CONFIG register of the XCU component, and cannot be larger than the * SOCLIB_MAX_HWI, SOCLIB_MAX_WTI, SOCLIB_MAX_PTI constants defined below. * The XCU controller provides three main services: * 1) It allows the kernel to selectively enable/disable any IRQ (identified by its type * and index) for a given core. It is the kernel responsibility to enable a given IRQ * for a single core as a given IRQ event should be handled by only one core. * 2) It makes a global OR between all enabled IRQs for a given core, to interrupt * the core when at least one enabled IRQ is active. * 3) It is capable to return the highest priority active IRQ of each type. * For each type, the lowest index have the highest priority. * * To select the ISR to be executed for a given HWI or WTI interrupt, the SOCLIB PIC * infrastructure implements for each core two interrupts vectors, called hwi_vector[] * and wti_vector[]. Each entry contains a pointer on the local chdev descriptor that * is the "source" of the interrupt, and contains itself a link to the ISR to be executed. * These interrupt vectors are stored in the core descriptor extension. * For the PTI interrupts, there is one PTI per core, and the ISR is simply defined * by the soclib_pic_timer_isr() function. * * There is no specific chdev to describe the current state of a given XCU controller. * To store the informations attached to a given XCU (namely the WTI allocator), the * SOCLIB PIC implementation attach a specific PIC extension to the cluster manager, * called XCU descriptor. *****************************************************************************************/ #define SOCLIB_TYPE_HWI 0 #define SOCLIB_TYPE_WTI 1 #define SOCLIB_TYPE_PTI 2 #define SOCLIB_MAX_HWI 16 #define SOCLIB_MAX_WTI 16 #define SOCLIB_MAX_PTI 16 #define SOCLIB_CYCLES_PER_MS 60 // SystemC virtual prototype at 60 KHz /****************************************************************************************** * This define the registers offsets for the external SOCLIB_IOPIC component. * There is 4 addressable registers for each external input IRQ. *****************************************************************************************/ #define IOPIC_ADDRESS 0 #define IOPIC_EXTEND 1 #define IOPIC_STATUS 2 #define IOPIC_MASK 3 #define IOPIC_SPAN 4 /****************************************************************************************** * This define the registers offsets for the internal SOCLIB_XCU components. * There is an XCU component in each cluster. *****************************************************************************************/ #define XCU_WTI_REG 0 #define XCU_PTI_PER 1 #define XCU_PTI_VAL 2 #define XCU_PTI_ACK 3 #define XCU_MSK_PTI 4 #define XCU_MSK_PTI_ENABLE 5 #define XCU_MSK_PTI_DISABLE 6 #define XCU_PTI_ACTIVE 6 #define XCU_MSK_HWI 8 #define XCU_MSK_HWI_ENABLE 9 #define XCU_MSK_HWI_DISABLE 10 #define XCU_HWI_ACTIVE 10 #define XCU_MSK_WTI 12 #define XCU_MSK_WTI_ENABLE 13 #define XCU_MSK_WTI_DISABLE 14 #define XCU_WTI_ACTIVE 14 #define XCU_PRIO 15 #define XCU_CONFIG 16 /****************************************************************************************** * This structure defines the core descriptor extension used by the SOCLIB PIC * implementation to store the two HWI / WTI interrupts vectors in the core descriptor. * Each entry contains a local pointer on the chdev that is the source of the IRQ. * A non allocated entry contains the NULL value. *****************************************************************************************/ typedef struct soclib_pic_core_s { struct chdev_s * hwi_vector[SOCLIB_MAX_HWI]; /* HWI interrupt vector */ struct chdev_s * wti_vector[SOCLIB_MAX_WTI]; /* WTI interrupt vector */ } soclib_pic_core_t; /****************************************************************************************** * This structure defines the cluster manager extension used by the SOCLIB PIC * implementation to register the local XCU base address, the number of HWI/WTI/PTI, * and the WTI allocator. The WTI allocator is very simple, because an allocated WTI * mailbox is never released. *****************************************************************************************/ typedef struct soclib_pic_cluster_s { uint32_t * xcu_base; /*! local pointer on xcu segment base */ uint32_t hwi_nr; /*! actual number of HWI inputs in XCU */ uint32_t wti_nr; /*! actual number of HWI inputs in XCU */ uint32_t pti_nr; /*! actual number of HWI inputs in XCU */ uint32_t first_free_wti; /*! simple allocator : first free WTI slot index */ } soclib_pic_cluster_t; /****************************************************************************************** * Generic PIC API *****************************************************************************************/ /****************************************************************************************** * This blocking function disables all input IRQs in the IOPIC controller, and * disables all HWIs, WTIs, and PTIs in the XCU (LAPIC) controllers, for all cores, * in all clusters. * It must be called by a thread running in the cluster containing the PIC chdev. ****************************************************************************************** * @ chdev : pointer on PIC chdev descriptor. *****************************************************************************************/ void soclib_pic_init( struct chdev_s * pic ); /***************************************************************************************** * This function allocates memory from local cluster for the SOCLIB PIC core extensions * of all cores contained in the cluster, initializes the two HWI, WTI interrupt vectors * as empty, and registers - for each core - the pointer in core descriptor. * Then it allocates memory from local cluster for the SOCLIB PIC cluster extension, * to implement the XCU WTI allocator, and registers the pointer in cluster manager. * It access the local XCU component to get actual number of HWI / WTI / PTI. ***************************************************************************************** * @ xcu_base : local pointer on XCU controller segment base. ****************************************************************************************/ void soclib_pic_extend_init( uint32_t * xcu_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. * If the source chdev is external (IOC, TXT, NIC, IOB): * - it get a WTI mailbox from the XCU. * - it enables this WTI in XCU. * - it updates the target core WTI interrupt vector. * - it link the WTI to the relevant input IRQ in IOPIC. * If the source chdev is internal (MMC, DMA): * - it enables the HWI in XCU. * - it updates the target core HWI interrupt vector. * It must be called by a thread running in local cluster. ****************************************************************************************** * @ lid : target core local index. * @ src_chdev : local pointer on source chdev descriptor. *****************************************************************************************/ void soclib_pic_bind_irq( lid_t lid, struct chdev_s * src_chdev ); /****************************************************************************************** * This function enables a remote HWI/WTI IRQ, identified by the argument, * that contains information on the IRQ type (HWI/WTI), and IRQ index. * It access the remote XCU mask register, but does not access IOPIC. ****************************************************************************************** * @ lid : target core local index (in cluster containing the source chdev). * @ src_chdev_xp : extended pointer on source chdev descriptor. *****************************************************************************************/ void soclib_pic_enable_irq( lid_t lid, xptr_t src_chdev_xp ); /****************************************************************************************** * This function disables a remote HWI/WTI IRQ, identified by the argument, * that contains information on the IRQ type (HWI/WTI), and IRQ index. * It access the remote XCU mask register, but does not access IOPIC. ****************************************************************************************** * @ lid : target core local index (in cluster containing the source chdev). * @ src_chdev_xp : extended pointer on source chdev descriptor. *****************************************************************************************/ void soclib_pic_disable_irq( lid_t lid, xptr_t src_chdev_xp ); /****************************************************************************************** * This function activates the PTI timer for the calling core. * The argument define the number of cycles between IRQs. ****************************************************************************************** * @ period : number of ticks between IRQs. *****************************************************************************************/ void soclib_pic_enable_timer( uint32_t period ); /****************************************************************************************** * This function activates the WTI[lid] in the local cluster, where lid is the calling * core local index. *****************************************************************************************/ void soclib_pic_enable_ipi(); /****************************************************************************************** * This function allows the calling thread to send an IPI to any core in any cluster. * It can be called by any thread running on any cluster. ****************************************************************************************** * @ cxy : target core cluster. * @ lid : target core local index. *****************************************************************************************/ void soclib_pic_send_ipi( cxy_t cxy, lid_t lid ); /****************************************************************************************** * This function acknowleges the WTI[lid] in the local cluster, where lid is the calling * core local index. *****************************************************************************************/ void soclib_pic_ack_ipi(); /****************************************************************************************** * Private PIC API for TSAR. *****************************************************************************************/ /****************************************************************************************** * This function returns the first free WTI mailbox from the XCU descriptor. * cluster extension containing the current XCU state. It does not access the * hardware XCU component. This WTI allocator is very simple, because an allocated * WTI is never released. The first WTIs are preallocated for IPI (wpi_id == lid). * This allocator does not use a lock, because there is no risk of concurrent access. * If there is no free slot, it means that the total number of external IRQs is too * large for the number of cores in the architecture, and the core goes to sleep. *****************************************************************************************/ uint32_t soclib_pic_wti_alloc(); /****************************************************************************************** * This function returns the local pointer on the local XCU base segment. *****************************************************************************************/ uint32_t * soclib_pic_xcu_base(); /****************************************************************************************** * This function returns the local pointer on a remote XCU base segment. * It is used by the soclip_pic_enable_irq() and soclib_pic_disable_irq() functions. ****************************************************************************************** * @ cxy : target cluster identifier. *****************************************************************************************/ uint32_t * soclib_pic_remote_xcu_base( cxy_t cxy ); /****************************************************************************************** * This function returns in the , , buffers * the local XCU status for a given core identidied by the argument. *****************************************************************************************/ void soclib_pic_xcu_status( lid_t lid, uint32_t * hwi_status, uint32_t * wti_status, uint32_t * pti_status ); /****************************************************************************************** * This SOCLIB PIC specific is the call-back function is the interrupt handler. *****************************************************************************************/ void soclib_pic_irq_handler(); #endif /* _SOCLIB_PIC_H_ */