Index: trunk/hal/tsar_mips32/drivers/soclib_pic.h
===================================================================
--- trunk/hal/tsar_mips32/drivers/soclib_pic.h	(revision 75)
+++ trunk/hal/tsar_mips32/drivers/soclib_pic.h	(revision 188)
@@ -2,5 +2,5 @@
  * soclib_pic.c - soclib PIC driver definition.
  *
- * Author  Alain Greiner (2016)
+ * Author  Alain Greiner (2016,2017)
  *
  * Copyright (c) UPMC Sorbonne Universites
@@ -22,62 +22,277 @@
  */
 
-#ifndef _SOCLIB_IOPIC_H_
-#define _SOCLIB_IOPIC_H_
+#ifndef _SOCLIB_PIC_H_
+#define _SOCLIB_PIC_H_
 
 #include <hal_types.h>
 
-/******************************************************************************************
- *  PIC register offsets (per input IRQ)
- *****************************************************************************************/
-
-#define IOPIC_ADDRESS           0
-#define IOPIC_EXTEND            1
-#define IOPIC_STATUS            2
-#define IOPIC_MASK              3
-#define IOPIC_SPAN              4
-
-/******************************************************************************************
- * This blocking function desactivates all input IRQs in PIC controler.
- * It must be called by a local thread.
- ******************************************************************************************
+/****  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 
+
+/******************************************************************************************
+ * 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];
+    struct chdev_s * wti_vector[SOCLIB_MAX_WTI];
+}
+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( chdev_t * chdev );
-
-/******************************************************************************************
- * This blocking function returns the status for a given input IRQ in the remote
- * PIC controler. It can be called by any thread running on any cluster.
- ******************************************************************************************
- * @ dev_xp    : extended pointer on the PIC device descriptor.
- * @ irq_id    : input IRQ index.
- * @ status    : pointer on local buffer for returned status.
- *****************************************************************************************/
-void   soclib_pic_get_status( xptr_t     dev_xp,
-                              uint32_t   irq_id,
-                              uint32_t * status );
-
-/******************************************************************************************
- * This blocking function unmask an input IRQ in a remote PIC controler, and bind it
- * with a WTI mailbox, by registering the WTI mailbox extended pointer.
+void   soclib_pic_init( chdev_t * 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 <src_chdev> argument, to a local core identified by the <lid> 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,
+                          chdev_t * src_chdev );
+
+/******************************************************************************************
+ * This function enable a HWI/WTI IRQ identified by the <src_chdev> argument,
+ * that contains information on the IRQ type (HWI/WTI), and IRQ index. 
+ * It access the relevant XCU mask register, but does not access IOPIC.
+ ******************************************************************************************
+ * @ lid        : target core local index.
+ * @ src_chdev  : local pointer on source chdev descriptor.
+ *****************************************************************************************/
+void soclib_pic_enable_irq( lid_t     lid,
+                            chdev_t * src_chdev );
+
+/******************************************************************************************
+ * This function disable a HWI/WTI IRQ identified by the <src_chdev> argument, 
+ * that contains information on the IRQ type (HWI/WTI), and IRQ index.
+ * It access the relevant XCU mask register, but does not access IOPIC.
+ ******************************************************************************************
+ * @ lid        : target core local index.
+ * @ src_chdev  : local pointer on source chdev descriptor.
+ *****************************************************************************************/
+void soclib_pic_disable_irq( lid_t     lid,
+                             chdev_t * src_chdev );
+
+/******************************************************************************************
+ * This function activates the TICK timer for the calling core.
+ * The <period> argument define the number of cycles between IRQs.
+ ******************************************************************************************
+ * @ period      : number of cycles between IRQs.
+ *****************************************************************************************/
+void soclib_pic_enable_timer( uint32_t period );
+
+/******************************************************************************************
+ * 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.
  ******************************************************************************************
- * @ dev_xp    : extended pointer on the PIC device descriptor.
- * @ irq_id    : input IRQ index.
- * @ xp_wti    : extended pointer on the WTI mailbox.
- *****************************************************************************************/
-void   soclib_pic_bind_irq( xptr_t    dev_xp,
-                            uint32_t  irq_id,
-                            xptr_t    wti_xp );
-
-/******************************************************************************************
- * This blocking function mask an input IRQ in a remote PIC controler.
- * It can be called by any thread running on any cluster.
- ******************************************************************************************
- * @ dev_xp    : extended pointer on the PIC device descriptor.
- * @ irq_id    : input IRQ index. 
- *****************************************************************************************/
-void   soclib_pic_unbind_irq( xptr_t    dev_xp,
-                              uint32_t  irq_id );
-
-
-#endif	/* _SOCLIB_IOPIC_H_ */
+ * @ cxy        : target core cluster.
+ * @ lid        : target core local index.
+ *****************************************************************************************/
+void soclib_pic_send_ipi( cxy_t    cxy,
+                          lid_t    lid );
+
+
+
+
+
+
+/******************************************************************************************
+ *                    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 a local pointer on the local XCU base segment.
+ *****************************************************************************************/
+uint32_t * soclib_pic_xcu_base();
+
+/******************************************************************************************
+ * This function acknowledge a PTI IRQ generated by the local XCU for a core 
+ * identified by the <lid> argument.
+ *****************************************************************************************/
+uint32_t soclib_pic_ack_timer( lid_t lid );
+
+/******************************************************************************************
+ * This function returns in the <hwi_status>, <wti_status>, <pti_status> buffers
+ * the local XCU status for a given core identidied by the <lid> 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 soclip_pic_irq_handler();
+
+
+
+
+
+
+
+#endif	/* _SOCLIB_PIC_H_ */
