| [5] | 1 | /* | 
|---|
|  | 2 | * chdev.h - channel device (chdev) descriptor definition. | 
|---|
|  | 3 | * | 
|---|
|  | 4 | * Authors  Alain Greiner    (2016) | 
|---|
|  | 5 | * | 
|---|
|  | 6 | * Copyright (c) UPMC Sorbonne Universites | 
|---|
|  | 7 | * | 
|---|
|  | 8 | * This file is part of ALMOS-MKH | 
|---|
|  | 9 | * | 
|---|
|  | 10 | * ALMOS-MKH is free software; you can redistribute it and/or modify it | 
|---|
|  | 11 | * under the terms of the GNU General Public License as published by | 
|---|
|  | 12 | * the Free Software Foundation; version 2.0 of the License. | 
|---|
|  | 13 | * | 
|---|
|  | 14 | * ALMOS-MKH is distributed in the hope that it will be useful, but | 
|---|
|  | 15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
|  | 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
|---|
|  | 17 | * General Public License for more details. | 
|---|
|  | 18 | * | 
|---|
|  | 19 | * You should have received a copy of the GNU General Public License | 
|---|
|  | 20 | * along with ALMOS-MKH; if not, write to the Free Software Foundation, | 
|---|
|  | 21 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 
|---|
|  | 22 | */ | 
|---|
|  | 23 |  | 
|---|
|  | 24 | #ifndef _CHDEV_H_ | 
|---|
|  | 25 | #define _CHDEV_H_ | 
|---|
|  | 26 |  | 
|---|
| [14] | 27 | #include <kernel_config.h> | 
|---|
| [5] | 28 | #include <hal_types.h> | 
|---|
|  | 29 | #include <xlist.h> | 
|---|
|  | 30 | #include <metafs.h> | 
|---|
|  | 31 | #include <remote_spinlock.h> | 
|---|
|  | 32 | #include <dev_ioc.h> | 
|---|
|  | 33 | #include <dev_nic.h> | 
|---|
|  | 34 | #include <dev_pic.h> | 
|---|
|  | 35 | #include <dev_fbf.h> | 
|---|
|  | 36 |  | 
|---|
|  | 37 | /****************************************************************************************** | 
|---|
|  | 38 | *       Channel Device descriptor definition | 
|---|
|  | 39 | * | 
|---|
|  | 40 | * This file defines the kernel representation of a generic (i.e. implementation | 
|---|
|  | 41 | * independant) Channel Device descriptor (in brief "chdev"). | 
|---|
| [23] | 42 | * ALMOS-MKH supports multi-channels peripherals, and defines one separated chdev | 
|---|
|  | 43 | * descriptor for each channel (and for each RX/TX direction for the NIC device). | 
|---|
| [5] | 44 | * Each chdev contains a waiting queue, registering the "client threads" requests, | 
|---|
|  | 45 | * and an associated "server thread", handling these requests. | 
|---|
|  | 46 | * These descriptors are physically distributed on all clusters to minimize contention. | 
|---|
|  | 47 | * Therefore a given I/O operation involve generally three clusters: | 
|---|
|  | 48 | * - the client cluster, containing the client thread, | 
|---|
| [204] | 49 | * - the server cluster, containing the chdev and the server thread, | 
|---|
|  | 50 | * - the I/O cluster, containing the physical device. | 
|---|
| [5] | 51 | *****************************************************************************************/ | 
|---|
|  | 52 |  | 
|---|
|  | 53 | /****  Forward declarations  ****/ | 
|---|
|  | 54 |  | 
|---|
|  | 55 | struct  chdev_s; | 
|---|
|  | 56 | struct  thread_s; | 
|---|
|  | 57 | struct  boot_info_s; | 
|---|
|  | 58 |  | 
|---|
|  | 59 | /****************************************************************************************** | 
|---|
|  | 60 | * These macros extract the functionality and the implementation from the peripheral type. | 
|---|
|  | 61 | *****************************************************************************************/ | 
|---|
|  | 62 |  | 
|---|
|  | 63 | #define FUNC_FROM_TYPE( type )    ((uint32_t)(type>>16)) | 
|---|
|  | 64 | #define IMPL_FROM_TYPE( type )    ((uint32_t)(type & 0x0000FFFF)) | 
|---|
|  | 65 |  | 
|---|
|  | 66 | /****************************************************************************************** | 
|---|
| [204] | 67 | * This define the generic prototypes for the two functions that must be defined | 
|---|
| [5] | 68 | * by all drivers implementing a generic device: | 
|---|
|  | 69 | * - "cmd"     : start an I/O operation. | 
|---|
|  | 70 | * - "isr"     : complete an I/O operation. | 
|---|
| [204] | 71 | * The "cmd" and "isr" are registered in the generic chdev descriptor at kernel init, | 
|---|
| [5] | 72 | * and are called to start and complete an I/O operation. | 
|---|
|  | 73 | *****************************************************************************************/ | 
|---|
|  | 74 |  | 
|---|
|  | 75 | typedef void (dev_ini_t) ( xptr_t dev ); | 
|---|
|  | 76 | typedef void (dev_cmd_t) ( xptr_t thread ); | 
|---|
|  | 77 | typedef void (dev_isr_t) ( struct chdev_s * dev ); | 
|---|
|  | 78 |  | 
|---|
|  | 79 | /****************************************************************************************** | 
|---|
|  | 80 | * This enum defines the supported generic device types. | 
|---|
|  | 81 | * These types are functionnal types: all (architecture specific) implementations | 
|---|
|  | 82 | * provide the same set of operations and the same driver API. | 
|---|
|  | 83 | * This enum must be consistent with the enum in files arch_info.h, and arch_class.py. | 
|---|
| [204] | 84 | * | 
|---|
|  | 85 | * WARNING : The ICU device exist in boot_info to specify the base address of the | 
|---|
|  | 86 | *           distributed LAPIC controler, but it does not exist as a chdev in the kernel, | 
|---|
|  | 87 | *           as it is hidden in the driver associated to the PIC device. | 
|---|
| [5] | 88 | *****************************************************************************************/ | 
|---|
|  | 89 |  | 
|---|
|  | 90 | enum dev_func_type | 
|---|
|  | 91 | { | 
|---|
|  | 92 | DEV_FUNC_RAM   =  0, | 
|---|
|  | 93 | DEV_FUNC_ROM   =  1, | 
|---|
|  | 94 | DEV_FUNC_FBF   =  2, | 
|---|
|  | 95 | DEV_FUNC_IOB   =  3, | 
|---|
|  | 96 | DEV_FUNC_IOC   =  4, | 
|---|
|  | 97 | DEV_FUNC_MMC   =  5, | 
|---|
|  | 98 | DEV_FUNC_DMA   =  6, | 
|---|
|  | 99 | DEV_FUNC_NIC   =  7, | 
|---|
|  | 100 | DEV_FUNC_TIM   =  8, | 
|---|
|  | 101 | DEV_FUNC_TXT   =  9, | 
|---|
| [204] | 102 | DEV_FUNC_ICU   = 10, | 
|---|
| [5] | 103 | DEV_FUNC_PIC   = 11, | 
|---|
|  | 104 |  | 
|---|
|  | 105 | DEV_FUNC_NR    = 12, | 
|---|
|  | 106 | }; | 
|---|
|  | 107 |  | 
|---|
|  | 108 | /****************************************************************************************** | 
|---|
|  | 109 | * This structure defines a chdev descriptor. | 
|---|
| [23] | 110 | * For multi-channels device, there is one chdev descriptor per channel. | 
|---|
| [5] | 111 | * This structure is NOT replicated, and can be located in any cluster. | 
|---|
|  | 112 | * One kernel thread, in charge of handling the commands registered in the waiting queue | 
|---|
|  | 113 | * of client threads is associated to each chdev descriptor (not for ICU, PIC, IOB). | 
|---|
|  | 114 | * For each device type ***, the specific extensions are defined in the "dev_***.h" file. | 
|---|
|  | 115 | *****************************************************************************************/ | 
|---|
|  | 116 |  | 
|---|
|  | 117 | typedef struct chdev_s | 
|---|
|  | 118 | { | 
|---|
|  | 119 | uint32_t             func;        /*! peripheral functionnal type                    */ | 
|---|
|  | 120 | uint32_t             impl;        /*! peripheral inplementation subtype              */ | 
|---|
|  | 121 | uint32_t             channel;     /*! channel index                                  */ | 
|---|
|  | 122 | bool_t               is_rx;       /*! relevant for NIC peripheral channels only      */ | 
|---|
| [188] | 123 | xptr_t               base;        /*! extended pointer on channel device segment     */ | 
|---|
| [23] | 124 | char                 name[16];    /*! name (required by DEVFS)                       */ | 
|---|
| [5] | 125 |  | 
|---|
|  | 126 | dev_cmd_t          * cmd;         /*! local pointer on driver command function       */ | 
|---|
|  | 127 | dev_isr_t          * isr;         /*! local pointer on driver ISR function           */ | 
|---|
|  | 128 | struct thread_s    * server;      /*! local pointer on associated server thread      */ | 
|---|
|  | 129 |  | 
|---|
|  | 130 | uint32_t             irq_type;    /*! associated IRQ type in local ICU               */ | 
|---|
|  | 131 | uint32_t             irq_id;      /*! associated IRQ index in local ICU              */ | 
|---|
|  | 132 |  | 
|---|
|  | 133 | metafs_t             node;        /*! Metafs node associated with this device        */ | 
|---|
|  | 134 |  | 
|---|
|  | 135 | remote_spinlock_t    wait_lock;   /*! lock protecting exclusive access to queue      */ | 
|---|
|  | 136 | xlist_entry_t        wait_root;   /*! root of waiting threads queue                  */ | 
|---|
|  | 137 |  | 
|---|
|  | 138 | union | 
|---|
|  | 139 | { | 
|---|
|  | 140 | ioc_extend_t     ioc;         /*! IOC specific extension                         */ | 
|---|
|  | 141 | nic_extend_t     nic;         /*! NIC specific extension                         */ | 
|---|
|  | 142 | pic_extend_t     pic;         /*! PIC specific extension                         */ | 
|---|
|  | 143 | fbf_extend_t     fbf;         /*! FBF specific extension                         */ | 
|---|
|  | 144 | } | 
|---|
|  | 145 | ext; | 
|---|
|  | 146 | } | 
|---|
|  | 147 | chdev_t; | 
|---|
|  | 148 |  | 
|---|
|  | 149 | /****************************************************************************************** | 
|---|
|  | 150 | * This structure defines the channel_devices descriptors directory. | 
|---|
|  | 151 | * Each entry in this structure contains an extended pointer on a chdev descriptor. | 
|---|
|  | 152 | * There is one entry per channel OR per cluster, depending on peripheral type. | 
|---|
|  | 153 | * This structure is replicated in each cluster, and is initialised during kernel init. | 
|---|
|  | 154 | * It is used for fast access to a device descriptor, from type and channel for an | 
|---|
|  | 155 | * external peripheral, or from type and cluster for a hared internal peripheral. | 
|---|
|  | 156 | * - a "shared" chdev can be accessed by any thread running in any cluster. | 
|---|
|  | 157 | * - a "private" chdev can only be accessed by a thread running in local cluster. | 
|---|
|  | 158 | *****************************************************************************************/ | 
|---|
|  | 159 |  | 
|---|
|  | 160 | typedef struct chdev_directory_s | 
|---|
|  | 161 | { | 
|---|
|  | 162 | xptr_t   iob;                                // external / single channel / shared | 
|---|
|  | 163 | xptr_t   pic;                                // external / single channel / shared | 
|---|
|  | 164 |  | 
|---|
|  | 165 | xptr_t   txt[CONFIG_MAX_TXT_CHANNELS];       // external / multi-channels / shared | 
|---|
|  | 166 | xptr_t   ioc[CONFIG_MAX_IOC_CHANNELS];       // external / multi-channels / shared | 
|---|
|  | 167 | xptr_t   fbf[CONFIG_MAX_FBF_CHANNELS];       // external / multi-channels / shared | 
|---|
|  | 168 | xptr_t   nic_rx[CONFIG_MAX_NIC_CHANNELS];    // external / multi-channels / shared | 
|---|
|  | 169 | xptr_t   nic_tx[CONFIG_MAX_NIC_CHANNELS];    // external / multi-channels / shared | 
|---|
|  | 170 |  | 
|---|
|  | 171 | xptr_t   mmc[CONFIG_MAX_CLUSTERS];           // internal / single channel / shared | 
|---|
|  | 172 |  | 
|---|
|  | 173 | xptr_t   dma[CONFIG_MAX_DMA_CHANNELS];       // internal / multi-channels / private | 
|---|
|  | 174 | } | 
|---|
|  | 175 | chdev_directory_t; | 
|---|
|  | 176 |  | 
|---|
|  | 177 | /****************************************************************************************** | 
|---|
|  | 178 | * This function display relevant values for a chdev descriptor. | 
|---|
|  | 179 | ****************************************************************************************** | 
|---|
|  | 180 | * @ chdev   : pointer on chdev. | 
|---|
|  | 181 | *****************************************************************************************/ | 
|---|
|  | 182 | void chdev_print( chdev_t * chdev ); | 
|---|
|  | 183 |  | 
|---|
|  | 184 | /****************************************************************************************** | 
|---|
|  | 185 | * This function returns a printable string for a device functionnal types. | 
|---|
|  | 186 | ****************************************************************************************** | 
|---|
|  | 187 | * @ func_type  : functionnal type. | 
|---|
| [16] | 188 | * @ return pointer on string. | 
|---|
| [5] | 189 | *****************************************************************************************/ | 
|---|
|  | 190 | char * chdev_func_str( uint32_t func_type ); | 
|---|
|  | 191 |  | 
|---|
|  | 192 | /****************************************************************************************** | 
|---|
|  | 193 | * This  function allocates memory and initializes a chdev descriptor in local cluster, | 
|---|
|  | 194 | * from arguments values.  It should be called by a local thread. | 
|---|
|  | 195 | * The device specific fields are initialised later. | 
|---|
|  | 196 | ****************************************************************************************** | 
|---|
|  | 197 | * @ func      : functionnal type. | 
|---|
|  | 198 | * @ impl      : implementation type. | 
|---|
|  | 199 | * @ channel   : channel index / for multi-channels peripherals. | 
|---|
|  | 200 | * @ is_rx     : for NIC peripheral / NIC RX if true / NIC TX if false. | 
|---|
|  | 201 | * @ base      : extended pointer on peripheral segment base. | 
|---|
|  | 202 | * @ return a local pointer on created chdev / return NULL if failure. | 
|---|
|  | 203 | *****************************************************************************************/ | 
|---|
|  | 204 | chdev_t * chdev_create( uint32_t    func, | 
|---|
|  | 205 | uint32_t    impl, | 
|---|
|  | 206 | uint32_t    channel, | 
|---|
|  | 207 | bool_t      is_rx, | 
|---|
|  | 208 | xptr_t      base ); | 
|---|
|  | 209 |  | 
|---|
|  | 210 | /****************************************************************************************** | 
|---|
|  | 211 | * This function registers a local client thread in the waiting queue of a remote | 
|---|
|  | 212 | * chdev descriptor, activates (i.e. unblock) the server thread associated to chdev, | 
|---|
|  | 213 | * and blocks itself on the THREAD_BLOCKED_IO condition. | 
|---|
|  | 214 | ****************************************************************************************** | 
|---|
|  | 215 | * @ chdev_xp  : extended pointer on remote chdev descriptor. | 
|---|
|  | 216 | * @ thread    : local pointer on client thread. | 
|---|
|  | 217 | *****************************************************************************************/ | 
|---|
|  | 218 | void chdev_register_command( xptr_t            chdev_xp, | 
|---|
|  | 219 | struct thread_s * thread ); | 
|---|
|  | 220 |  | 
|---|
|  | 221 | /****************************************************************************************** | 
|---|
|  | 222 | * This function is executed by the server thread associated to a chdev descriptor. | 
|---|
|  | 223 | * It executes an infinite loop to handle sequencially all commands registered by the | 
|---|
|  | 224 | * client threads in the device waiting queue, until the queue is empty. | 
|---|
|  | 225 | * The driver CMD function being blocking, these functions return only when the command | 
|---|
|  | 226 | * is completed. These functions can use either a busy waiting policy, or a descheduling | 
|---|
|  | 227 | * policy, blocking on the THREAD_BLOCKED_IO_ISR condition, and reactivated by the ISR. | 
|---|
|  | 228 | * When the waiting queue is empty, the server thread blocks on the THREAD_BLOCKED_IO_CMD | 
|---|
|  | 229 | * condition and deschedule. It is re-activated by a client thread registering a command. | 
|---|
|  | 230 | ****************************************************************************************** | 
|---|
|  | 231 | * @ chdev   : local pointer on device descriptor. | 
|---|
|  | 232 | *****************************************************************************************/ | 
|---|
|  | 233 | void chdev_sequencial_server( chdev_t * chdev ); | 
|---|
|  | 234 |  | 
|---|
| [317] | 235 | /****************************************************************************************** | 
|---|
|  | 236 | * This function displays the local copy of the external chdevs directory. | 
|---|
|  | 237 | * (global variable replicated in all clusters) | 
|---|
|  | 238 | *****************************************************************************************/ | 
|---|
|  | 239 | void chdev_dir_display(); | 
|---|
| [5] | 240 |  | 
|---|
| [317] | 241 |  | 
|---|
|  | 242 |  | 
|---|
| [5] | 243 | #endif  /* _CHDEV_H_ */ | 
|---|