| [258] | 1 | /////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 2 | // File     : sys_handler.c | 
|---|
 | 3 | // Date     : 01/04/2012 | 
|---|
 | 4 | // Author   : alain greiner and joel porquet | 
|---|
 | 5 | // Copyright (c) UPMC-LIP6 | 
|---|
 | 6 | /////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 7 |  | 
|---|
 | 8 | #include <sys_handler.h> | 
|---|
 | 9 | #include <tty_driver.h> | 
|---|
 | 10 | #include <tim_driver.h> | 
|---|
 | 11 | #include <nic_driver.h> | 
|---|
| [440] | 12 | #include <mmc_driver.h> | 
|---|
| [519] | 13 | #include <mwr_driver.h> | 
|---|
| [440] | 14 | #include <cma_driver.h> | 
|---|
| [258] | 15 | #include <ctx_handler.h> | 
|---|
 | 16 | #include <fat32.h> | 
|---|
 | 17 | #include <utils.h> | 
|---|
| [478] | 18 | #include <kernel_malloc.h> | 
|---|
| [459] | 19 | #include <tty0.h> | 
|---|
| [396] | 20 | #include <vmem.h> | 
|---|
| [322] | 21 | #include <hard_config.h> | 
|---|
| [258] | 22 | #include <giet_config.h> | 
|---|
 | 23 | #include <mapping_info.h> | 
|---|
| [547] | 24 | #include <irq_handler.h> | 
|---|
| [519] | 25 | #include <io.h> | 
|---|
| [258] | 26 |  | 
|---|
| [322] | 27 | #if !defined(SEG_BOOT_MAPPING_BASE)  | 
|---|
 | 28 | # error: You must define SEG_BOOT_MAPPING_BASE in the hard_config.h file | 
|---|
 | 29 | #endif | 
|---|
 | 30 |  | 
|---|
| [449] | 31 | #if !defined(NB_TTY_CHANNELS)  | 
|---|
 | 32 | # error: You must define NB_TTY_CHANNELS in the hard_config.h file | 
|---|
 | 33 | #endif | 
|---|
 | 34 |  | 
|---|
| [459] | 35 | #if (NB_TTY_CHANNELS < 1) | 
|---|
 | 36 | # error: NB_TTY_CHANNELS cannot be smaller than 1! | 
|---|
 | 37 | #endif | 
|---|
 | 38 |  | 
|---|
| [449] | 39 | #if !defined(NB_TIM_CHANNELS)  | 
|---|
 | 40 | # error: You must define NB_TIM_CHANNELS in the hard_config.h file | 
|---|
 | 41 | #endif | 
|---|
 | 42 |  | 
|---|
 | 43 | #if !defined(NB_NIC_CHANNELS)  | 
|---|
 | 44 | # error: You must define NB_NIC_CHANNELS in the hard_config.h file | 
|---|
 | 45 | #endif | 
|---|
 | 46 |  | 
|---|
 | 47 | #if !defined(NB_CMA_CHANNELS)  | 
|---|
 | 48 | # error: You must define NB_CMA_CHANNELS in the hard_config.h file | 
|---|
 | 49 | #endif | 
|---|
 | 50 |  | 
|---|
| [478] | 51 | #if !defined(GIET_NO_HARD_CC) | 
|---|
 | 52 | # error: You must define GIET_NO_HARD_CC in the giet_config.h file | 
|---|
| [449] | 53 | #endif | 
|---|
 | 54 |  | 
|---|
| [478] | 55 | #if !defined ( GIET_NIC_MAC4 ) | 
|---|
 | 56 | # error: You must define GIET_NIC_MAC4 in the giet_config.h file | 
|---|
| [449] | 57 | #endif | 
|---|
 | 58 |  | 
|---|
| [478] | 59 | #if !defined ( GIET_NIC_MAC2 ) | 
|---|
 | 60 | # error: You must define GIET_NIC_MAC2 in the giet_config.h file | 
|---|
| [449] | 61 | #endif | 
|---|
 | 62 |  | 
|---|
| [258] | 63 | //////////////////////////////////////////////////////////////////////////// | 
|---|
| [528] | 64 | //        Extern variables | 
|---|
| [519] | 65 | //////////////////////////////////////////////////////////////////////////// | 
|---|
 | 66 |  | 
|---|
| [528] | 67 | // allocated in tty0.c file. | 
|---|
 | 68 | extern sqt_lock_t _tty0_sqt_lock; | 
|---|
| [519] | 69 |  | 
|---|
| [528] | 70 | // allocated in mwr_driver.c file. | 
|---|
 | 71 | extern simple_lock_t  _coproc_lock[X_SIZE*Y_SIZE]; | 
|---|
| [556] | 72 | extern unsigned int   _coproc_type[X_SIZE*Y_SIZE]; | 
|---|
 | 73 | extern unsigned int   _coproc_info[X_SIZE*Y_SIZE]; | 
|---|
 | 74 | extern unsigned int   _coproc_mode[X_SIZE*Y_SIZE]; | 
|---|
 | 75 | extern unsigned int   _coproc_error[X_SIZE*Y_SIZE]; | 
|---|
 | 76 | extern unsigned int   _coproc_gtid[X_SIZE*Y_SIZE]; | 
|---|
| [519] | 77 |  | 
|---|
| [556] | 78 |  | 
|---|
| [528] | 79 | // allocated in tty_driver.c file. | 
|---|
 | 80 | extern unsigned int _tty_rx_full[NB_TTY_CHANNELS]; | 
|---|
 | 81 | extern unsigned int _tty_rx_buf[NB_TTY_CHANNELS]; | 
|---|
 | 82 |  | 
|---|
| [629] | 83 | // allocated in kernel_init.c file | 
|---|
 | 84 | extern static_scheduler_t* _schedulers[X_SIZE][Y_SIZE][NB_PROCS_MAX];  | 
|---|
 | 85 |  | 
|---|
| [519] | 86 | //////////////////////////////////////////////////////////////////////////// | 
|---|
| [440] | 87 | //     Channel allocators for peripherals | 
|---|
 | 88 | //     (TTY[0] is reserved for kernel) | 
|---|
 | 89 | //////////////////////////////////////////////////////////////////////////// | 
|---|
 | 90 |  | 
|---|
| [494] | 91 | __attribute__((section(".kdata"))) | 
|---|
| [478] | 92 | unsigned int _tty_channel_allocator    = 1; | 
|---|
| [494] | 93 |  | 
|---|
 | 94 | __attribute__((section(".kdata"))) | 
|---|
| [478] | 95 | unsigned int _tim_channel_allocator    = 0; | 
|---|
| [494] | 96 |  | 
|---|
 | 97 | __attribute__((section(".kdata"))) | 
|---|
| [478] | 98 | unsigned int _cma_channel_allocator    = 0; | 
|---|
| [494] | 99 |  | 
|---|
 | 100 | __attribute__((section(".kdata"))) | 
|---|
| [449] | 101 | unsigned int _nic_rx_channel_allocator = 0; | 
|---|
| [494] | 102 |  | 
|---|
 | 103 | __attribute__((section(".kdata"))) | 
|---|
| [449] | 104 | unsigned int _nic_tx_channel_allocator = 0; | 
|---|
| [440] | 105 |  | 
|---|
 | 106 | //////////////////////////////////////////////////////////////////////////// | 
|---|
| [614] | 107 | //     NIC_RX and NIC_TX kernel chbuf arrays  | 
|---|
| [449] | 108 | //////////////////////////////////////////////////////////////////////////// | 
|---|
 | 109 |  | 
|---|
| [494] | 110 | __attribute__((section(".kdata"))) | 
|---|
| [614] | 111 | ker_chbuf_t  _nic_ker_rx_chbuf[NB_NIC_CHANNELS] __attribute__((aligned(64))); | 
|---|
| [459] | 112 |  | 
|---|
| [494] | 113 | __attribute__((section(".kdata"))) | 
|---|
| [614] | 114 | ker_chbuf_t  _nic_ker_tx_chbuf[NB_NIC_CHANNELS] __attribute__((aligned(64))); | 
|---|
| [459] | 115 |  | 
|---|
| [478] | 116 | //////////////////////////////////////////////////////////////////////////// | 
|---|
 | 117 | // FBF related chbuf descriptors array, indexed by the CMA channel index. | 
|---|
 | 118 | // Physical addresses of these chbuf descriptors required for L2 cache sync. | 
|---|
| [614] | 119 | // FBF status | 
|---|
| [478] | 120 | //////////////////////////////////////////////////////////////////////////// | 
|---|
| [459] | 121 |  | 
|---|
| [494] | 122 | __attribute__((section(".kdata"))) | 
|---|
| [478] | 123 | fbf_chbuf_t _fbf_chbuf[NB_CMA_CHANNELS] __attribute__((aligned(64))); | 
|---|
| [459] | 124 |  | 
|---|
| [494] | 125 | __attribute__((section(".kdata"))) | 
|---|
| [478] | 126 | unsigned long long _fbf_chbuf_paddr[NB_CMA_CHANNELS]; | 
|---|
 | 127 |  | 
|---|
| [614] | 128 | __attribute__((section(".kdata"))) | 
|---|
 | 129 | buffer_status_t _fbf_status[NB_CMA_CHANNELS] __attribute__((aligned(64))); | 
|---|
 | 130 |  | 
|---|
| [449] | 131 | //////////////////////////////////////////////////////////////////////////// | 
|---|
| [258] | 132 | //    Initialize the syscall vector with syscall handlers | 
|---|
 | 133 | // Note: This array must be synchronised with the define in file stdio.h | 
|---|
 | 134 | //////////////////////////////////////////////////////////////////////////// | 
|---|
| [494] | 135 |  | 
|---|
 | 136 | __attribute__((section(".kdata"))) | 
|---|
| [258] | 137 | const void * _syscall_vector[64] =  | 
|---|
 | 138 | { | 
|---|
| [556] | 139 |     &_sys_proc_xyp,                  /* 0x00 */ | 
|---|
 | 140 |     &_get_proctime,                  /* 0x01 */ | 
|---|
 | 141 |     &_sys_tty_write,                 /* 0x02 */ | 
|---|
 | 142 |     &_sys_tty_read,                  /* 0x03 */ | 
|---|
 | 143 |     &_sys_tty_alloc,                 /* 0x04 */ | 
|---|
 | 144 |     &_sys_tty_get_lock,              /* 0x05 */ | 
|---|
 | 145 |     &_sys_tty_release_lock,          /* 0x06 */ | 
|---|
 | 146 |     &_sys_heap_info,                 /* 0x07 */ | 
|---|
 | 147 |     &_sys_local_task_id,             /* 0x08 */ | 
|---|
 | 148 |     &_sys_global_task_id,            /* 0x09 */  | 
|---|
 | 149 |     &_sys_fbf_cma_alloc,             /* 0x0A */ | 
|---|
| [614] | 150 |     &_sys_fbf_cma_init_buf,          /* 0x0B */ | 
|---|
 | 151 |     &_sys_fbf_cma_start,             /* 0x0C */ | 
|---|
 | 152 |     &_sys_fbf_cma_display,           /* 0x0D */ | 
|---|
 | 153 |     &_sys_fbf_cma_stop,              /* 0x0E */ | 
|---|
 | 154 |     &_sys_task_exit,                 /* 0x0F */ | 
|---|
| [258] | 155 |  | 
|---|
| [614] | 156 |     &_sys_procs_number,              /* 0x10 */ | 
|---|
 | 157 |     &_sys_fbf_sync_write,            /* 0x11 */ | 
|---|
 | 158 |     &_sys_fbf_sync_read,             /* 0x12 */ | 
|---|
 | 159 |     &_sys_thread_id,                 /* 0x13 */ | 
|---|
| [556] | 160 |     &_sys_tim_alloc,                 /* 0x14 */ | 
|---|
 | 161 |     &_sys_tim_start,                 /* 0x15 */  | 
|---|
 | 162 |     &_sys_tim_stop,                  /* 0x16 */ | 
|---|
| [629] | 163 |     &_sys_kill_application,          /* 0x17 */ | 
|---|
 | 164 |     &_sys_exec_application,          /* 0x18 */    | 
|---|
| [556] | 165 |     &_sys_context_switch,            /* 0x19 */ | 
|---|
 | 166 |     &_sys_vseg_get_vbase,            /* 0x1A */ | 
|---|
 | 167 |     &_sys_vseg_get_length,           /* 0x1B */ | 
|---|
 | 168 |     &_sys_xy_from_ptr,               /* 0x1C */ | 
|---|
 | 169 |     &_sys_ukn,                       /* 0x1D */ | 
|---|
 | 170 |     &_sys_ukn,                       /* 0x1E */ | 
|---|
 | 171 |     &_sys_ukn,                       /* 0x1F */ | 
|---|
| [258] | 172 |  | 
|---|
| [592] | 173 |     &_fat_open,                      /* 0x20 */ | 
|---|
 | 174 |     &_fat_read,                      /* 0x21 */ | 
|---|
 | 175 |     &_fat_write,                     /* 0x22 */ | 
|---|
 | 176 |     &_fat_lseek,                     /* 0x23 */ | 
|---|
 | 177 |     &_fat_file_info,                 /* 0x24 */ | 
|---|
| [556] | 178 |     &_fat_close,                     /* 0x25 */ | 
|---|
| [592] | 179 |     &_fat_remove,                    /* 0x26 */ | 
|---|
 | 180 |     &_fat_rename,                    /* 0x27 */ | 
|---|
 | 181 |     &_fat_mkdir,                     /* 0x28 */ | 
|---|
| [661] | 182 |     &_fat_opendir,                   /* 0x29 */ | 
|---|
 | 183 |     &_fat_closedir,                  /* 0x2A */ | 
|---|
 | 184 |     &_fat_readdir,                   /* 0x2B */ | 
|---|
 | 185 |     &_sys_ukn,                       /* 0x2C */ | 
|---|
| [556] | 186 |     &_sys_ukn,                       /* 0x2D */ | 
|---|
 | 187 |     &_sys_ukn,                       /* 0x2E */ | 
|---|
 | 188 |     &_sys_ukn,                       /* 0x2F */ | 
|---|
| [258] | 189 |  | 
|---|
| [556] | 190 |     &_sys_nic_alloc,                 /* 0x30 */ | 
|---|
 | 191 |     &_sys_nic_start,                 /* 0x31 */ | 
|---|
 | 192 |     &_sys_nic_move,                  /* 0x32 */ | 
|---|
 | 193 |     &_sys_nic_stop,                  /* 0x33 */ | 
|---|
 | 194 |     &_sys_nic_stats,                 /* 0x34 */ | 
|---|
 | 195 |     &_sys_nic_clear,                 /* 0x35 */  | 
|---|
 | 196 |     &_sys_ukn,                       /* 0x36 */ | 
|---|
 | 197 |     &_sys_ukn,                       /* 0x37 */ | 
|---|
 | 198 |     &_sys_ukn,                       /* 0x38 */    | 
|---|
 | 199 |     &_sys_ukn,                       /* 0x39 */ | 
|---|
 | 200 |     &_sys_ukn,                       /* 0x3A */ | 
|---|
 | 201 |     &_sys_coproc_completed,          /* 0x3B */ | 
|---|
 | 202 |     &_sys_coproc_alloc,              /* 0x3C */ | 
|---|
 | 203 |     &_sys_coproc_channel_init,       /* 0x3D */ | 
|---|
 | 204 |     &_sys_coproc_run,                /* 0x3E */ | 
|---|
 | 205 |     &_sys_coproc_release,            /* 0x3F */ | 
|---|
| [258] | 206 | }; | 
|---|
 | 207 |  | 
|---|
| [459] | 208 |  | 
|---|
| [258] | 209 | ////////////////////////////////////////////////////////////////////////////// | 
|---|
| [648] | 210 | //           Applications related syscall handlers  | 
|---|
 | 211 | ////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 212 |  | 
|---|
 | 213 | /////////////////////////////////////// | 
|---|
 | 214 | int _sys_kill_application( char* name ) | 
|---|
 | 215 | { | 
|---|
 | 216 |     mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; | 
|---|
 | 217 |     mapping_vspace_t * vspace  = _get_vspace_base(header); | 
|---|
 | 218 |     mapping_task_t   * task    = _get_task_base(header); | 
|---|
 | 219 |  | 
|---|
 | 220 |     unsigned int vspace_id; | 
|---|
 | 221 |     unsigned int task_id; | 
|---|
 | 222 |     unsigned int y_size = header->y_size; | 
|---|
 | 223 |  | 
|---|
 | 224 | #if GIET_DEBUG_EXEC | 
|---|
 | 225 | if ( _get_proctime() > GIET_DEBUG_EXEC ) | 
|---|
 | 226 | _printf("\n[DEBUG EXEC] enters _sys_kill_application() for %s\n", name ); | 
|---|
 | 227 | #endif | 
|---|
 | 228 |  | 
|---|
 | 229 |     // scan vspaces | 
|---|
 | 230 |     for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++)  | 
|---|
 | 231 |     { | 
|---|
 | 232 |         if ( _strcmp( vspace[vspace_id].name, name ) == 0 )  | 
|---|
 | 233 |         { | 
|---|
 | 234 |             // check if pplication can be killed | 
|---|
 | 235 |             if ( vspace[vspace_id].active ) return -2; | 
|---|
 | 236 |  | 
|---|
 | 237 |             // scan tasks in vspace | 
|---|
 | 238 |             for (task_id = vspace[vspace_id].task_offset;  | 
|---|
 | 239 |                  task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks);  | 
|---|
 | 240 |                  task_id++)  | 
|---|
 | 241 |             { | 
|---|
 | 242 |                 unsigned int cid   = task[task_id].clusterid; | 
|---|
 | 243 |                 unsigned int x     = cid / y_size; | 
|---|
 | 244 |                 unsigned int y     = cid % y_size; | 
|---|
 | 245 |                 unsigned int p     = task[task_id].proclocid; | 
|---|
 | 246 |                 unsigned int ltid  = task[task_id].ltid; | 
|---|
 | 247 |  | 
|---|
 | 248 |                 // get scheduler pointer for processor running the task | 
|---|
 | 249 |                 static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p]; | 
|---|
 | 250 |  | 
|---|
 | 251 |                 // release private TTY peripheral if required | 
|---|
 | 252 |                 if ( psched->context[ltid][CTX_TTY_ID] < NB_TTY_CHANNELS )  | 
|---|
 | 253 |                 { | 
|---|
 | 254 |                     psched->context[ltid][CTX_TTY_ID] = 0xFFFFFFFF; | 
|---|
 | 255 |                     _atomic_increment( &_tty_channel_allocator , 0xFFFFFFFF ); | 
|---|
 | 256 |                 } | 
|---|
 | 257 |  | 
|---|
 | 258 |                 // set NORUN_MASK_TASK bit | 
|---|
 | 259 |                 unsigned int*       ptr     = &psched->context[ltid][CTX_NORUN_ID]; | 
|---|
 | 260 |                 _atomic_or( ptr , NORUN_MASK_TASK ); | 
|---|
 | 261 |             }  | 
|---|
 | 262 |  | 
|---|
 | 263 | #if GIET_DEBUG_EXEC  | 
|---|
 | 264 | if ( _get_proctime() > GIET_DEBUG_EXEC ) | 
|---|
 | 265 | _printf("\n[DEBUG EXEC] exit _sys_kill_application() : %s desactivated\n", name ); | 
|---|
 | 266 | #endif | 
|---|
 | 267 |  | 
|---|
 | 268 |             return 0; | 
|---|
 | 269 |         } | 
|---|
 | 270 |     }  | 
|---|
 | 271 |  | 
|---|
 | 272 | #if GIET_DEBUG_EXEC  | 
|---|
 | 273 | if ( _get_proctime() > GIET_DEBUG_EXEC ) | 
|---|
 | 274 | _printf("\n[DEBUG EXEC] exit _sys_kill_application() : %s not found\n", name ); | 
|---|
 | 275 | #endif | 
|---|
 | 276 |  | 
|---|
 | 277 |     return -1;    // not found  | 
|---|
 | 278 |  | 
|---|
 | 279 | }  // end _sys_kill_application() | 
|---|
 | 280 |      | 
|---|
 | 281 | /////////////////////////////////////// | 
|---|
 | 282 | int _sys_exec_application( char* name ) | 
|---|
 | 283 | { | 
|---|
 | 284 |     mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; | 
|---|
 | 285 |     mapping_vspace_t * vspace  = _get_vspace_base(header); | 
|---|
 | 286 |     mapping_task_t   * task    = _get_task_base(header); | 
|---|
 | 287 |     mapping_vseg_t   * vseg    = _get_vseg_base(header); | 
|---|
 | 288 |  | 
|---|
 | 289 |     unsigned int vspace_id; | 
|---|
 | 290 |     unsigned int task_id; | 
|---|
 | 291 |     unsigned int vseg_id; | 
|---|
 | 292 |  | 
|---|
 | 293 |     unsigned int y_size = header->y_size; | 
|---|
 | 294 |  | 
|---|
 | 295 | #if GIET_DEBUG_EXEC  | 
|---|
 | 296 | if ( _get_proctime() > GIET_DEBUG_EXEC ) | 
|---|
 | 297 | _printf("\n[DEBUG EXEC] enters _sys_exec_application() at cycle %d for %s\n", | 
|---|
 | 298 |          _get_proctime() , name ); | 
|---|
 | 299 | #endif | 
|---|
 | 300 |  | 
|---|
 | 301 |     // scan vspaces | 
|---|
 | 302 |     for (vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++)  | 
|---|
 | 303 |     { | 
|---|
 | 304 |         if ( _strcmp( vspace[vspace_id].name, name ) == 0 )  | 
|---|
 | 305 |         { | 
|---|
 | 306 |             // scan tasks in vspace | 
|---|
 | 307 |             for (task_id = vspace[vspace_id].task_offset;  | 
|---|
 | 308 |                  task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks);  | 
|---|
 | 309 |                  task_id++)  | 
|---|
 | 310 |             { | 
|---|
 | 311 |                 unsigned int cid   = task[task_id].clusterid; | 
|---|
 | 312 |                 unsigned int x     = cid / y_size; | 
|---|
 | 313 |                 unsigned int y     = cid % y_size; | 
|---|
 | 314 |                 unsigned int p     = task[task_id].proclocid; | 
|---|
 | 315 |                 unsigned int ltid  = task[task_id].ltid; | 
|---|
 | 316 |  | 
|---|
 | 317 |                 // get scheduler pointer for the processor running the task | 
|---|
 | 318 |                 static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p]; | 
|---|
 | 319 |  | 
|---|
 | 320 |                 // sp_value : initial stack pointer  | 
|---|
 | 321 |                 vseg_id = task[task_id].stack_vseg_id; | 
|---|
 | 322 |                 unsigned int sp_value = vseg[vseg_id].vbase + vseg[vseg_id].length; | 
|---|
 | 323 |  | 
|---|
 | 324 |                 // epc value : task entry point | 
|---|
 | 325 |                 unsigned int  epc_value = psched->context[ltid][CTX_ENTRY_ID]; | 
|---|
 | 326 |  | 
|---|
 | 327 |                 // ra_value : initial return address | 
|---|
 | 328 |                 unsigned int ra_value = (unsigned int)(&_ctx_eret); | 
|---|
 | 329 |  | 
|---|
 | 330 |                 // initialise task context: RA / SR / EPC / SP / NORUN slots | 
|---|
 | 331 |                 psched->context[ltid][CTX_RA_ID]    = ra_value; | 
|---|
 | 332 |                 psched->context[ltid][CTX_SR_ID]    = GIET_SR_INIT_VALUE; | 
|---|
 | 333 |                 psched->context[ltid][CTX_SP_ID]    = sp_value; | 
|---|
 | 334 |                 psched->context[ltid][CTX_EPC_ID]   = epc_value; | 
|---|
 | 335 |                 psched->context[ltid][CTX_NORUN_ID] = 0; | 
|---|
 | 336 |  | 
|---|
 | 337 | #if GIET_DEBUG_EXEC  | 
|---|
 | 338 | if ( _get_proctime() > GIET_DEBUG_EXEC ) | 
|---|
 | 339 | _printf("\n[DEBUG EXEC] _sys_exec_application() start task %d on P[%d,%d,%d]\n" | 
|---|
 | 340 |         " - ctx_ra    = %x\n" | 
|---|
 | 341 |         " - ctx_sp    = %x\n" | 
|---|
 | 342 |         " - ctx_epc   = %x\n", | 
|---|
 | 343 |         task_id , x , y , p , ra_value , sp_value , epc_value ); | 
|---|
 | 344 | #endif | 
|---|
 | 345 |             }  | 
|---|
 | 346 |  | 
|---|
 | 347 | #if GIET_DEBUG_EXEC  | 
|---|
 | 348 | if ( _get_proctime() > GIET_DEBUG_EXEC ) | 
|---|
 | 349 | _printf("\n[DEBUG EXEC] exit _sys_exec_application() at cycle %d : %s activated\n", | 
|---|
 | 350 |         _get_proctime() , name ); | 
|---|
 | 351 | #endif | 
|---|
 | 352 |  | 
|---|
 | 353 |             return 0;   // application found and activated | 
|---|
 | 354 |         } | 
|---|
 | 355 |     } | 
|---|
 | 356 |  | 
|---|
 | 357 | #if GIET_DEBUG_EXEC  | 
|---|
 | 358 | if ( _get_proctime() > GIET_DEBUG_EXEC ) | 
|---|
 | 359 | _printf("\n[DEBUG EXEC] exit _sys_exec_application() at cycle %d : %s not found\n", | 
|---|
 | 360 |          _get_proctime() , name ); | 
|---|
 | 361 | #endif | 
|---|
 | 362 |  | 
|---|
 | 363 |     return -1;    // not found  | 
|---|
 | 364 |  | 
|---|
 | 365 | }  // end _sys_exec_application() | 
|---|
 | 366 |      | 
|---|
 | 367 |  | 
|---|
 | 368 | ////////////////////////////////////////////////////////////////////////////// | 
|---|
| [519] | 369 | //           Coprocessors related syscall handlers  | 
|---|
 | 370 | ////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 371 |  | 
|---|
 | 372 | ////////////////////////////////////////////////// | 
|---|
 | 373 | int _sys_coproc_alloc( unsigned int   coproc_type, | 
|---|
| [556] | 374 |                        unsigned int*  coproc_info ) | 
|---|
| [519] | 375 | { | 
|---|
 | 376 |     // In this implementation, the allocation policy is constrained: | 
|---|
 | 377 |     // the coprocessor must be in the same cluster as the calling task, | 
|---|
| [556] | 378 |     // and there is at most one coprocessor per cluster | 
|---|
| [519] | 379 |  | 
|---|
 | 380 |     mapping_header_t  * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; | 
|---|
 | 381 |     mapping_cluster_t * cluster = _get_cluster_base(header); | 
|---|
 | 382 |     mapping_periph_t  * periph  = _get_periph_base(header); | 
|---|
 | 383 |  | 
|---|
 | 384 |     // get cluster coordinates and cluster global index  | 
|---|
 | 385 |     unsigned int procid     = _get_procid(); | 
|---|
 | 386 |     unsigned int x          = procid >> (Y_WIDTH + P_WIDTH); | 
|---|
 | 387 |     unsigned int y          = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1); | 
|---|
| [556] | 388 |     unsigned int cluster_id = x * Y_SIZE + y; | 
|---|
| [519] | 389 |   | 
|---|
 | 390 |     // search coprocessor in cluster | 
|---|
 | 391 |     mapping_periph_t*  found = NULL; | 
|---|
 | 392 |     unsigned int min   = cluster[cluster_id].periph_offset; | 
|---|
 | 393 |     unsigned int max   = min + cluster[cluster_id].periphs; | 
|---|
 | 394 |     unsigned int periph_id; | 
|---|
 | 395 |     for ( periph_id = min ; periph_id < max ; periph_id++ ) | 
|---|
 | 396 |     { | 
|---|
 | 397 |         if ( (periph[periph_id].type == PERIPH_TYPE_MWR) && | 
|---|
 | 398 |              (periph[periph_id].subtype == coproc_type) ) | 
|---|
 | 399 |         { | 
|---|
 | 400 |             found = &periph[periph_id]; | 
|---|
 | 401 |             break; | 
|---|
 | 402 |         } | 
|---|
 | 403 |     }  | 
|---|
 | 404 |  | 
|---|
 | 405 |     if ( found != NULL ) | 
|---|
 | 406 |     { | 
|---|
 | 407 |         // get the lock (at most one coproc per cluster) | 
|---|
 | 408 |         _simple_lock_acquire( &_coproc_lock[cluster_id] ); | 
|---|
| [556] | 409 |  | 
|---|
 | 410 |         // register coproc characteristics in kernel arrays | 
|---|
 | 411 |         _coproc_type[cluster_id] = coproc_type; | 
|---|
 | 412 |         _coproc_info[cluster_id] = (found->arg0 & 0xFF)     | | 
|---|
 | 413 |                                    (found->arg1 & 0xFF)<<8  | | 
|---|
 | 414 |                                    (found->arg2 & 0xFF)<<16 | | 
|---|
 | 415 |                                    (found->arg3 & 0xFF)<<24 ; | 
|---|
 | 416 |  | 
|---|
| [519] | 417 |         // returns coprocessor info | 
|---|
| [556] | 418 |         *coproc_info = _coproc_info[cluster_id]; | 
|---|
| [519] | 419 |  | 
|---|
| [556] | 420 |         // register coprocessor coordinates in task context | 
|---|
 | 421 |         unsigned int cluster_xy = (x<<Y_WIDTH) + y; | 
|---|
 | 422 |         _set_context_slot( CTX_COPROC_ID , cluster_xy ); | 
|---|
 | 423 |  | 
|---|
| [519] | 424 | #if GIET_DEBUG_COPROC | 
|---|
 | 425 | _printf("\n[GIET DEBUG COPROC] _sys_coproc_alloc() in cluster[%d,%d]\n" | 
|---|
 | 426 |         "  coproc_info = %x / cluster_xy = %x\n", | 
|---|
| [556] | 427 |         x , y , *coproc_info , cluster_xy ); | 
|---|
| [519] | 428 | #endif | 
|---|
 | 429 |         return 0; | 
|---|
 | 430 |     } | 
|---|
 | 431 |     else | 
|---|
 | 432 |     { | 
|---|
 | 433 |          _printf("\n[GIET_ERROR] in _sys_coproc_alloc(): no coprocessor " | 
|---|
 | 434 |                  " with type %d available in cluster[%d,%d]\n", | 
|---|
 | 435 |                  coproc_type , x , y ); | 
|---|
 | 436 |         return -1; | 
|---|
 | 437 |     } | 
|---|
 | 438 | }  // end _sys_coproc_alloc() | 
|---|
 | 439 |  | 
|---|
| [556] | 440 | //////////////////////////////////////////////////////// | 
|---|
 | 441 | int _sys_coproc_release( unsigned int coproc_reg_index ) | 
|---|
| [519] | 442 | { | 
|---|
| [556] | 443 |     // processor coordinates | 
|---|
| [519] | 444 |     unsigned int procid = _get_procid(); | 
|---|
 | 445 |     unsigned int x      = procid >> (Y_WIDTH + P_WIDTH); | 
|---|
 | 446 |     unsigned int y      = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1); | 
|---|
| [556] | 447 |     unsigned int p      = procid & ((1<<P_WIDTH)-1); | 
|---|
 | 448 |      | 
|---|
 | 449 |     // get coprocessor coordinates | 
|---|
 | 450 |     unsigned int cluster_xy = _get_context_slot( CTX_COPROC_ID ); | 
|---|
 | 451 |     if ( cluster_xy > 0xFF ) | 
|---|
| [519] | 452 |     { | 
|---|
| [556] | 453 |          _printf("\n[GIET_ERROR] in _sys_coproc_release(): " | 
|---|
 | 454 |                  "no coprocessor allocated to task running on P[%d,%d,%d]\n", | 
|---|
 | 455 |                  x , y , p );  | 
|---|
| [519] | 456 |          return -1; | 
|---|
 | 457 |     } | 
|---|
 | 458 |  | 
|---|
| [556] | 459 |     unsigned int cx         = cluster_xy >> Y_WIDTH; | 
|---|
 | 460 |     unsigned int cy         = cluster_xy & ((1<<Y_WIDTH)-1); | 
|---|
 | 461 |     unsigned int cluster_id = cx * Y_SIZE + cy; | 
|---|
 | 462 |     unsigned int info       = _coproc_info[cluster_id]; | 
|---|
 | 463 |     unsigned int nb_to      = info & 0xFF; | 
|---|
 | 464 |     unsigned int nb_from    = (info>>8) & 0xFF; | 
|---|
 | 465 |     unsigned int channel; | 
|---|
| [519] | 466 |  | 
|---|
| [556] | 467 |     // stops coprocessor and communication channels | 
|---|
 | 468 |     _mwr_set_coproc_register( cluster_xy , coproc_reg_index , 0 ); | 
|---|
 | 469 |     for ( channel = 0 ; channel < (nb_from + nb_to) ; channel++ ) | 
|---|
 | 470 |     { | 
|---|
 | 471 |         _mwr_set_channel_register( cluster_xy , channel , MWR_CHANNEL_RUNNING , 0 ); | 
|---|
 | 472 |     } | 
|---|
| [519] | 473 |  | 
|---|
| [556] | 474 |     // deallocates coprocessor coordinates in task context | 
|---|
 | 475 |     _set_context_slot( CTX_COPROC_ID , 0xFFFFFFFF ); | 
|---|
 | 476 |  | 
|---|
 | 477 |     // release coprocessor lock | 
|---|
 | 478 |     _simple_lock_release( &_coproc_lock[cluster_id] ); | 
|---|
 | 479 |  | 
|---|
| [519] | 480 | #if GIET_DEBUG_COPROC | 
|---|
 | 481 | _printf("\n[GIET DEBUG COPROC] _sys_coproc_release() in cluster[%d,%d]\n", | 
|---|
| [556] | 482 |         cx, cy ); | 
|---|
| [519] | 483 | #endif | 
|---|
 | 484 |  | 
|---|
 | 485 |     return 0; | 
|---|
 | 486 | }  // end _sys_coproc_release() | 
|---|
 | 487 |  | 
|---|
| [556] | 488 | ////////////////////////////////////////////////////////////// | 
|---|
 | 489 | int _sys_coproc_channel_init( unsigned int            channel, | 
|---|
| [519] | 490 |                               giet_coproc_channel_t*  desc ) | 
|---|
 | 491 | { | 
|---|
| [556] | 492 |     // processor coordinates | 
|---|
| [519] | 493 |     unsigned int procid = _get_procid(); | 
|---|
 | 494 |     unsigned int x      = procid >> (Y_WIDTH + P_WIDTH); | 
|---|
 | 495 |     unsigned int y      = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1); | 
|---|
| [556] | 496 |     unsigned int p      = procid & ((1<<P_WIDTH)-1); | 
|---|
 | 497 |      | 
|---|
 | 498 |     // get coprocessor coordinates | 
|---|
 | 499 |     unsigned int cluster_xy = _get_context_slot( CTX_COPROC_ID ); | 
|---|
 | 500 |     if ( cluster_xy > 0xFF ) | 
|---|
| [519] | 501 |     { | 
|---|
 | 502 |          _printf("\n[GIET_ERROR] in _sys_coproc_channel_init(): " | 
|---|
| [556] | 503 |                  "no coprocessor allocated to task running on P[%d,%d,%d]\n", | 
|---|
 | 504 |                  x , y , p );  | 
|---|
| [519] | 505 |          return -1; | 
|---|
 | 506 |     } | 
|---|
 | 507 |  | 
|---|
 | 508 |     // check channel mode | 
|---|
 | 509 |     unsigned mode = desc->channel_mode; | 
|---|
 | 510 |     if ( (mode != MODE_MWMR) &&  | 
|---|
 | 511 |          (mode != MODE_DMA_IRQ) &&  | 
|---|
 | 512 |          (mode != MODE_DMA_NO_IRQ) ) | 
|---|
 | 513 |     { | 
|---|
| [556] | 514 |          _printf("\n[GIET_ERROR] in _sys_coproc_channel_init(): " | 
|---|
| [519] | 515 |                  " illegal mode\n"); | 
|---|
 | 516 |          return -1; | 
|---|
 | 517 |     } | 
|---|
 | 518 |  | 
|---|
 | 519 |     // get memory buffer size | 
|---|
 | 520 |     unsigned int size = desc->buffer_size; | 
|---|
 | 521 |   | 
|---|
| [528] | 522 |     // physical addresses | 
|---|
| [519] | 523 |     unsigned long long buffer_paddr; | 
|---|
 | 524 |     unsigned int       buffer_lsb; | 
|---|
 | 525 |     unsigned int       buffer_msb; | 
|---|
| [556] | 526 |     unsigned long long mwmr_paddr = 0; | 
|---|
| [519] | 527 |     unsigned int       mwmr_lsb; | 
|---|
 | 528 |     unsigned int       mwmr_msb; | 
|---|
| [556] | 529 |     unsigned long long lock_paddr = 0; | 
|---|
| [519] | 530 |     unsigned int       lock_lsb; | 
|---|
 | 531 |     unsigned int       lock_msb; | 
|---|
 | 532 |  | 
|---|
| [528] | 533 |     unsigned int       flags;     // unused | 
|---|
 | 534 |  | 
|---|
| [519] | 535 |     // compute memory buffer physical address | 
|---|
| [528] | 536 |     buffer_paddr = _v2p_translate( desc->buffer_vaddr , &flags ); | 
|---|
 | 537 |     buffer_lsb   = (unsigned int)buffer_paddr; | 
|---|
 | 538 |     buffer_msb   = (unsigned int)(buffer_paddr>>32);  | 
|---|
| [519] | 539 |  | 
|---|
 | 540 |     // call MWMR_DMA driver | 
|---|
| [556] | 541 |     _mwr_set_channel_register( cluster_xy, channel, MWR_CHANNEL_MODE, mode );  | 
|---|
 | 542 |     _mwr_set_channel_register( cluster_xy, channel, MWR_CHANNEL_SIZE, size );  | 
|---|
 | 543 |     _mwr_set_channel_register( cluster_xy, channel, MWR_CHANNEL_BUFFER_LSB, buffer_lsb );  | 
|---|
 | 544 |     _mwr_set_channel_register( cluster_xy, channel, MWR_CHANNEL_BUFFER_MSB, buffer_msb );  | 
|---|
| [519] | 545 |                         | 
|---|
 | 546 |     if ( mode == MODE_MWMR ) | 
|---|
 | 547 |     { | 
|---|
| [528] | 548 |         // compute MWMR descriptor physical address | 
|---|
 | 549 |         mwmr_paddr = _v2p_translate( desc->mwmr_vaddr , &flags ); | 
|---|
| [519] | 550 |         mwmr_lsb = (unsigned int)mwmr_paddr; | 
|---|
 | 551 |         mwmr_msb = (unsigned int)(mwmr_paddr>>32);  | 
|---|
 | 552 |  | 
|---|
| [528] | 553 |         // call MWMR_DMA driver | 
|---|
| [556] | 554 |         _mwr_set_channel_register( cluster_xy, channel, MWR_CHANNEL_MWMR_LSB, mwmr_lsb );  | 
|---|
 | 555 |         _mwr_set_channel_register( cluster_xy, channel, MWR_CHANNEL_MWMR_MSB, mwmr_msb );  | 
|---|
| [528] | 556 |  | 
|---|
 | 557 |         // compute lock physical address | 
|---|
 | 558 |         lock_paddr = _v2p_translate( desc->lock_vaddr , &flags ); | 
|---|
| [519] | 559 |         lock_lsb = (unsigned int)lock_paddr; | 
|---|
 | 560 |         lock_msb = (unsigned int)(lock_paddr>>32);  | 
|---|
 | 561 |  | 
|---|
 | 562 |         // call MWMR_DMA driver | 
|---|
| [556] | 563 |         _mwr_set_channel_register( cluster_xy, channel, MWR_CHANNEL_LOCK_LSB, lock_lsb );  | 
|---|
 | 564 |         _mwr_set_channel_register( cluster_xy, channel, MWR_CHANNEL_LOCK_MSB, lock_msb );  | 
|---|
| [519] | 565 |     } | 
|---|
 | 566 |  | 
|---|
 | 567 | #if GIET_DEBUG_COPROC | 
|---|
| [556] | 568 | _printf("\n[GIET DEBUG COPROC] _sys_coproc_channel_init() for coproc[%d,%d]\n" | 
|---|
| [519] | 569 |         " channel =  %d / mode = %d / buffer_size = %d\n" | 
|---|
 | 570 |         " buffer_paddr = %l / mwmr_paddr = %l / lock_paddr = %l\n", | 
|---|
 | 571 |         x , y , channel , mode , size , | 
|---|
 | 572 |         buffer_paddr, mwmr_paddr, lock_paddr ); | 
|---|
 | 573 | #endif | 
|---|
 | 574 |          | 
|---|
 | 575 |     return 0; | 
|---|
 | 576 | } // end _sys_coproc_channel_init() | 
|---|
 | 577 |  | 
|---|
| [556] | 578 | //////////////////////////////////////////////////// | 
|---|
 | 579 | int _sys_coproc_run( unsigned int coproc_reg_index ) | 
|---|
| [519] | 580 | { | 
|---|
| [556] | 581 |     // processor coordinates | 
|---|
| [519] | 582 |     unsigned int procid = _get_procid(); | 
|---|
 | 583 |     unsigned int x      = procid >> (Y_WIDTH + P_WIDTH); | 
|---|
 | 584 |     unsigned int y      = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1); | 
|---|
| [556] | 585 |     unsigned int p      = procid & ((1<<P_WIDTH)-1); | 
|---|
 | 586 |      | 
|---|
 | 587 |     // get coprocessor coordinates | 
|---|
 | 588 |     unsigned int cluster_xy = _get_context_slot( CTX_COPROC_ID ); | 
|---|
 | 589 |     if ( cluster_xy > 0xFF ) | 
|---|
| [519] | 590 |     { | 
|---|
| [556] | 591 |          _printf("\n[GIET_ERROR] in _sys_coproc_run(): " | 
|---|
 | 592 |                  "no coprocessor allocated to task running on P[%d,%d,%d]\n", | 
|---|
 | 593 |                  x , y , p );  | 
|---|
| [519] | 594 |          return -1; | 
|---|
 | 595 |     } | 
|---|
 | 596 |  | 
|---|
| [556] | 597 |     unsigned int cx         = cluster_xy >> Y_WIDTH; | 
|---|
 | 598 |     unsigned int cy         = cluster_xy & ((1<<Y_WIDTH)-1); | 
|---|
 | 599 |     unsigned int cluster_id = cx * Y_SIZE + cy; | 
|---|
 | 600 |     unsigned int info       = _coproc_info[cluster_id]; | 
|---|
 | 601 |     unsigned int nb_to      = info & 0xFF; | 
|---|
 | 602 |     unsigned int nb_from    = (info>>8) & 0xFF; | 
|---|
 | 603 |     unsigned int mode       = 0xFFFFFFFF; | 
|---|
 | 604 |     unsigned int channel; | 
|---|
| [519] | 605 |  | 
|---|
| [556] | 606 |     // register coprocessor running mode  | 
|---|
 | 607 |     for ( channel = 0 ; channel < (nb_from + nb_to) ; channel++ ) | 
|---|
 | 608 |     { | 
|---|
 | 609 |         unsigned int temp; | 
|---|
 | 610 |         temp = _mwr_get_channel_register( cluster_xy , channel , MWR_CHANNEL_MODE ); | 
|---|
| [519] | 611 |  | 
|---|
| [556] | 612 |         if ( mode == 0xFFFFFFFF )  | 
|---|
 | 613 |         { | 
|---|
 | 614 |             mode = temp; | 
|---|
 | 615 |         } | 
|---|
 | 616 |         else if ( temp != mode ) | 
|---|
 | 617 |         { | 
|---|
 | 618 |             _printf("\n[GIET_ERROR] P[%d,%d,%d] in _sys_coproc_run() for coprocessor[%d,%d]\n" | 
|---|
 | 619 |                     "  all channels don't have the same mode\n", x , y , p , cx , cy ); | 
|---|
 | 620 |             return -1; | 
|---|
 | 621 |         } | 
|---|
 | 622 |     } | 
|---|
 | 623 |     _coproc_mode[cluster_id] = mode; | 
|---|
| [519] | 624 |  | 
|---|
| [556] | 625 |     // start all communication channels | 
|---|
 | 626 |     for ( channel = 0 ; channel < (nb_from + nb_to) ; channel++ ) | 
|---|
 | 627 |     { | 
|---|
 | 628 |         _mwr_set_channel_register( cluster_xy , channel , MWR_CHANNEL_RUNNING , 1 ); | 
|---|
 | 629 |     } | 
|---|
| [519] | 630 |  | 
|---|
| [556] | 631 |     ////////////////////////////////////////////////////////////////////////// | 
|---|
 | 632 |     if ( (mode == MODE_MWMR) || (mode == MODE_DMA_NO_IRQ) )  // no descheduling | 
|---|
| [519] | 633 |     { | 
|---|
| [556] | 634 |         // start coprocessor | 
|---|
 | 635 |         _mwr_set_coproc_register( cluster_xy , coproc_reg_index , 1 ); | 
|---|
 | 636 |  | 
|---|
 | 637 | #if GIET_DEBUG_COPROC | 
|---|
 | 638 | if ( mode == MODE_MWMR ) | 
|---|
 | 639 | _printf("\n[GIET DEBUG COPROC] _sys_coproc_run() P[%d,%d,%d] starts coprocessor[%d,%d]\n" | 
|---|
 | 640 |         "   MODE_MWMR at cycle %d\n", x , y , p , cx , cy , _get_proctime() ); | 
|---|
 | 641 | else | 
|---|
 | 642 | _printf("\n[GIET DEBUG COPROC] _sys_coproc_run() P[%d,%d,%d] starts coprocessor[%d,%d]\n" | 
|---|
 | 643 |         "   MODE_DMA_NO_IRQ at cycle %d\n", x , y , p , cx , cy , _get_proctime() ); | 
|---|
 | 644 | #endif | 
|---|
 | 645 |  | 
|---|
 | 646 |         return 0; | 
|---|
| [519] | 647 |     } | 
|---|
| [556] | 648 |     /////////////////////////////////////////////////////////////////////////// | 
|---|
 | 649 |     else                                // mode == MODE_DMA_IRQ => descheduling | 
|---|
 | 650 |     { | 
|---|
 | 651 |         // set _coproc_gtid  | 
|---|
 | 652 |         unsigned int ltid = _get_current_task_id(); | 
|---|
 | 653 |         _coproc_gtid[cluster_id] = (procid<<16) + ltid; | 
|---|
| [519] | 654 |  | 
|---|
| [556] | 655 |         // enters critical section | 
|---|
 | 656 |         unsigned int save_sr; | 
|---|
 | 657 |         _it_disable( &save_sr );  | 
|---|
 | 658 |  | 
|---|
| [629] | 659 |         // set NORUN_MASK_COPROC bit | 
|---|
 | 660 |         static_scheduler_t* psched  = (static_scheduler_t*)_schedulers[x][y][p]; | 
|---|
 | 661 |         unsigned int*       ptr     = &psched->context[ltid][CTX_NORUN_ID]; | 
|---|
 | 662 |         _atomic_or( ptr , NORUN_MASK_COPROC ); | 
|---|
| [556] | 663 |  | 
|---|
 | 664 |         // start coprocessor | 
|---|
 | 665 |         _mwr_set_coproc_register( cluster_xy , coproc_reg_index , 1 ); | 
|---|
 | 666 |  | 
|---|
| [519] | 667 | #if GIET_DEBUG_COPROC | 
|---|
| [556] | 668 | _printf("\n[GIET DEBUG COPROC] _sys_coproc_run() P[%d,%d,%d] starts coprocessor[%d,%d]\n" | 
|---|
 | 669 |         "   MODE_DMA_IRQ at cycle %d\n", x , y , p , cx , cy , _get_proctime() ); | 
|---|
| [519] | 670 | #endif | 
|---|
 | 671 |  | 
|---|
| [556] | 672 |         // deschedule task | 
|---|
 | 673 |         _ctx_switch();  | 
|---|
| [519] | 674 |  | 
|---|
| [556] | 675 | #if GIET_DEBUG_COPROC | 
|---|
 | 676 | _printf("\n[GIET DEBUG COPROC] _sys_coproc_run() P[%d,%d,%d] resume\n" | 
|---|
 | 677 |         "  coprocessor[%d,%d] completion at cycle %d\n",  | 
|---|
 | 678 |         x , y , p , cx , cy , _get_proctime() ); | 
|---|
 | 679 | #endif | 
|---|
 | 680 |  | 
|---|
 | 681 |         // restore SR | 
|---|
 | 682 |         _it_restore( &save_sr ); | 
|---|
 | 683 |  | 
|---|
 | 684 |         // return error computed by mwr_isr() | 
|---|
 | 685 |         return _coproc_error[cluster_id]; | 
|---|
 | 686 |     }  | 
|---|
 | 687 | } // end _sys_coproc_run() | 
|---|
 | 688 |  | 
|---|
 | 689 | /////////////////////////// | 
|---|
 | 690 | int _sys_coproc_completed() | 
|---|
| [519] | 691 | { | 
|---|
| [556] | 692 |     // processor coordinates | 
|---|
| [519] | 693 |     unsigned int procid = _get_procid(); | 
|---|
 | 694 |     unsigned int x      = procid >> (Y_WIDTH + P_WIDTH); | 
|---|
 | 695 |     unsigned int y      = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1); | 
|---|
| [556] | 696 |     unsigned int p      = procid & ((1<<P_WIDTH)-1); | 
|---|
 | 697 |      | 
|---|
 | 698 |     // get coprocessor coordinates | 
|---|
 | 699 |     unsigned int cluster_xy = _get_context_slot( CTX_COPROC_ID ); | 
|---|
 | 700 |     if ( cluster_xy > 0xFF ) | 
|---|
| [519] | 701 |     { | 
|---|
 | 702 |          _printf("\n[GIET_ERROR] in _sys_coproc_completed(): " | 
|---|
| [556] | 703 |                  "no coprocessor allocated to task running on P[%d,%d,%d]\n", | 
|---|
 | 704 |                  x , y , p );  | 
|---|
| [519] | 705 |          return -1; | 
|---|
 | 706 |     } | 
|---|
 | 707 |  | 
|---|
| [556] | 708 |     unsigned int cx         = cluster_xy >> Y_WIDTH; | 
|---|
 | 709 |     unsigned int cy         = cluster_xy & ((1<<Y_WIDTH)-1); | 
|---|
 | 710 |     unsigned int cluster_id = cx * Y_SIZE + cy; | 
|---|
 | 711 |     unsigned int mode       = _coproc_mode[cluster_id]; | 
|---|
| [519] | 712 |  | 
|---|
| [556] | 713 |     // analyse possible errors | 
|---|
 | 714 |     if ( mode == MODE_DMA_NO_IRQ ) | 
|---|
 | 715 |     { | 
|---|
 | 716 |         unsigned int info       = _coproc_info[cluster_id]; | 
|---|
 | 717 |         unsigned int nb_to      = info & 0xFF; | 
|---|
 | 718 |         unsigned int nb_from    = (info>>8) & 0xFF; | 
|---|
 | 719 |         unsigned int error      = 0; | 
|---|
 | 720 |         unsigned int channel; | 
|---|
 | 721 |         unsigned int status; | 
|---|
 | 722 |  | 
|---|
 | 723 |         // get status for all channels, and signal all reported errors | 
|---|
 | 724 |         for ( channel = 0 ; channel < (nb_to +nb_from) ; channel++ ) | 
|---|
 | 725 |         { | 
|---|
 | 726 |             do | 
|---|
 | 727 |             { | 
|---|
 | 728 |                 status = _mwr_get_channel_register( cluster_xy , channel , MWR_CHANNEL_STATUS ); | 
|---|
 | 729 |                 if ( status == MWR_CHANNEL_ERROR_DATA ) | 
|---|
 | 730 |                 { | 
|---|
 | 731 |                     _printf("\n[GIET_ERROR] in _sys_coproc_completed()" | 
|---|
 | 732 |                             " / channel %d / DATA_ERROR\n", channel ); | 
|---|
 | 733 |                     error = 1; | 
|---|
 | 734 |                     break; | 
|---|
 | 735 |                 } | 
|---|
 | 736 |                 else if ( status == MWR_CHANNEL_ERROR_LOCK ) | 
|---|
 | 737 |                 { | 
|---|
 | 738 |                     _printf("\n[GIET_ERROR] in _sys_coproc_completed()" | 
|---|
 | 739 |                             " / channel %d / LOCK_ERROR\n", channel ); | 
|---|
 | 740 |                     error = 1; | 
|---|
 | 741 |                     break; | 
|---|
 | 742 |                 } | 
|---|
 | 743 |                 else if ( status == MWR_CHANNEL_ERROR_DESC ) | 
|---|
 | 744 |                 { | 
|---|
 | 745 |                     _printf("\n[GIET_ERROR] in _sys_coproc_completed()" | 
|---|
 | 746 |                             " / channel %d / DESC_ERROR\n", channel ); | 
|---|
 | 747 |                     error = 1; | 
|---|
 | 748 |                     break; | 
|---|
 | 749 |                 } | 
|---|
 | 750 |             } while ( status == MWR_CHANNEL_BUSY ); | 
|---|
 | 751 |  | 
|---|
 | 752 |             // reset channel | 
|---|
 | 753 |             _mwr_set_channel_register( cluster_xy , channel , MWR_CHANNEL_RUNNING , 0 );  | 
|---|
 | 754 |  | 
|---|
 | 755 |         }  // end for channels | 
|---|
 | 756 |  | 
|---|
| [519] | 757 | #if GIET_DEBUG_COPROC | 
|---|
| [556] | 758 | _printf("\n[GIET DEBUG COPROC] _sys_coproc_completed() for coprocessor[%d,%d] error = %d\n",  | 
|---|
 | 759 |         cx , cy , error ); | 
|---|
| [519] | 760 | #endif | 
|---|
 | 761 |  | 
|---|
| [556] | 762 |         return error; | 
|---|
 | 763 |     } | 
|---|
 | 764 |     else  // mode == MODE_MWMR or MODE_DMA_IRQ | 
|---|
 | 765 |     { | 
|---|
 | 766 |         _printf("\n[GIET ERROR] sys_coproc_completed() should not be called for " | 
|---|
 | 767 |                 "coprocessor[%d,%d] running in MODE_MWMR or MODE_DMA_IRQ\n", cx , cy ); | 
|---|
 | 768 |         return 1; | 
|---|
 | 769 |     } | 
|---|
| [519] | 770 | } // end _sys_coproc_completed() | 
|---|
 | 771 |  | 
|---|
 | 772 |  | 
|---|
 | 773 | ////////////////////////////////////////////////////////////////////////////// | 
|---|
| [440] | 774 | //             TTY related syscall handlers  | 
|---|
| [258] | 775 | ////////////////////////////////////////////////////////////////////////////// | 
|---|
| [440] | 776 |  | 
|---|
 | 777 | //////////////////// | 
|---|
 | 778 | int _sys_tty_alloc() | 
|---|
| [258] | 779 | { | 
|---|
| [440] | 780 |     // get a new TTY terminal index | 
|---|
| [459] | 781 |     unsigned int channel = _atomic_increment( &_tty_channel_allocator, 1 ); | 
|---|
| [440] | 782 |  | 
|---|
 | 783 |     if ( channel >= NB_TTY_CHANNELS ) | 
|---|
 | 784 |     { | 
|---|
| [648] | 785 |         _atomic_increment( &_tty_channel_allocator , 0xFFFFFFFF ); | 
|---|
| [440] | 786 |         _printf("\n[GIET_ERROR] in _sys_tty_alloc() : not enough TTY channels\n"); | 
|---|
 | 787 |         return -1; | 
|---|
 | 788 |     } | 
|---|
| [547] | 789 |  | 
|---|
| [648] | 790 |     // reset kernel buffer for allocated TTY channel | 
|---|
 | 791 |     _tty_rx_full[channel] = 0; | 
|---|
 | 792 |  | 
|---|
| [547] | 793 |     // allocate a WTI mailbox to the calling proc if external IRQ | 
|---|
 | 794 |     unsigned int unused; | 
|---|
 | 795 |     if ( USE_PIC ) _ext_irq_alloc( ISR_TTY_RX , channel , &unused );  | 
|---|
 | 796 |     | 
|---|
 | 797 |     // update calling task index | 
|---|
 | 798 |     _set_context_slot( CTX_TTY_ID, channel ); | 
|---|
 | 799 |  | 
|---|
 | 800 |     return 0; | 
|---|
| [258] | 801 | } | 
|---|
 | 802 |  | 
|---|
| [440] | 803 | ///////////////////////////////////////////////// | 
|---|
 | 804 | int _sys_tty_write( const char*  buffer,     | 
|---|
 | 805 |                     unsigned int length,    // number of characters | 
|---|
 | 806 |                     unsigned int channel)   // channel index  | 
|---|
 | 807 | { | 
|---|
 | 808 |     unsigned int  nwritten; | 
|---|
 | 809 |  | 
|---|
 | 810 |     // compute and check tty channel | 
|---|
 | 811 |     if( channel == 0xFFFFFFFF )  channel = _get_context_slot(CTX_TTY_ID); | 
|---|
 | 812 |     if( channel >= NB_TTY_CHANNELS ) return -1; | 
|---|
 | 813 |  | 
|---|
 | 814 |     // write string to TTY channel | 
|---|
 | 815 |     for (nwritten = 0; nwritten < length; nwritten++)  | 
|---|
 | 816 |     { | 
|---|
 | 817 |         // check tty's status  | 
|---|
 | 818 |         if ( _tty_get_register( channel, TTY_STATUS ) & 0x2 )  break; | 
|---|
 | 819 |  | 
|---|
 | 820 |         // write one byte | 
|---|
 | 821 |         if (buffer[nwritten] == '\n')  | 
|---|
 | 822 |         { | 
|---|
 | 823 |             _tty_set_register( channel, TTY_WRITE, (unsigned int)'\r' ); | 
|---|
 | 824 |         } | 
|---|
 | 825 |         _tty_set_register( channel, TTY_WRITE, (unsigned int)buffer[nwritten] ); | 
|---|
 | 826 |     } | 
|---|
 | 827 |      | 
|---|
 | 828 |     return nwritten; | 
|---|
 | 829 | } | 
|---|
 | 830 |  | 
|---|
 | 831 | //////////////////////////////////////////////// | 
|---|
 | 832 | int _sys_tty_read( char*        buffer,  | 
|---|
 | 833 |                    unsigned int length,    // unused | 
|---|
 | 834 |                    unsigned int channel)   // channel index | 
|---|
 | 835 | { | 
|---|
 | 836 |     // compute and check tty channel | 
|---|
 | 837 |     if( channel == 0xFFFFFFFF )  channel = _get_context_slot(CTX_TTY_ID); | 
|---|
 | 838 |     if( channel >= NB_TTY_CHANNELS ) return -1; | 
|---|
 | 839 |  | 
|---|
 | 840 |     // read one character from TTY channel | 
|---|
 | 841 |     if (_tty_rx_full[channel] == 0)  | 
|---|
 | 842 |     { | 
|---|
 | 843 |         return 0; | 
|---|
 | 844 |     } | 
|---|
 | 845 |     else  | 
|---|
 | 846 |     { | 
|---|
 | 847 |         *buffer = _tty_rx_buf[channel]; | 
|---|
 | 848 |         _tty_rx_full[channel] = 0; | 
|---|
 | 849 |         return 1; | 
|---|
 | 850 |     } | 
|---|
 | 851 | } | 
|---|
 | 852 |  | 
|---|
 | 853 | /////////////////////////////////////////// | 
|---|
| [494] | 854 | int _sys_tty_get_lock( unsigned int   channel,       // unused | 
|---|
| [440] | 855 |                        unsigned int * save_sr_ptr ) | 
|---|
 | 856 | { | 
|---|
| [494] | 857 |     // check tty channel | 
|---|
 | 858 |     if( channel != 0 )  return 1; | 
|---|
| [440] | 859 |  | 
|---|
 | 860 |     _it_disable( save_sr_ptr ); | 
|---|
| [494] | 861 |     _sqt_lock_acquire( &_tty0_sqt_lock ); | 
|---|
| [440] | 862 |     return 0; | 
|---|
 | 863 | } | 
|---|
 | 864 |  | 
|---|
 | 865 | /////////////////////////////////////////////// | 
|---|
 | 866 | int _sys_tty_release_lock( unsigned int   channel, | 
|---|
 | 867 |                            unsigned int * save_sr_ptr ) | 
|---|
 | 868 | { | 
|---|
| [494] | 869 |     // check tty channel | 
|---|
 | 870 |     if( channel != 0 )  return 1; | 
|---|
| [440] | 871 |  | 
|---|
| [494] | 872 |     _sqt_lock_release( &_tty0_sqt_lock ); | 
|---|
| [440] | 873 |     _it_restore( save_sr_ptr ); | 
|---|
 | 874 |     return 0; | 
|---|
 | 875 | } | 
|---|
 | 876 |  | 
|---|
| [428] | 877 | ////////////////////////////////////////////////////////////////////////////// | 
|---|
| [440] | 878 | //             TIM related syscall handlers  | 
|---|
| [428] | 879 | ////////////////////////////////////////////////////////////////////////////// | 
|---|
| [440] | 880 |  | 
|---|
 | 881 | //////////////////// | 
|---|
 | 882 | int _sys_tim_alloc() | 
|---|
| [428] | 883 | { | 
|---|
| [440] | 884 |     // get a new timer index  | 
|---|
| [459] | 885 |     unsigned int channel = _atomic_increment( &_tim_channel_allocator, 1 ); | 
|---|
| [440] | 886 |  | 
|---|
 | 887 |     if ( channel >= NB_TIM_CHANNELS ) | 
|---|
 | 888 |     { | 
|---|
 | 889 |         _printf("\n[GIET_ERROR] in _sys_tim_alloc() : not enough TIM channels\n"); | 
|---|
 | 890 |         return -1; | 
|---|
 | 891 |     } | 
|---|
 | 892 |     else | 
|---|
 | 893 |     { | 
|---|
| [449] | 894 |         _set_context_slot( CTX_TIM_ID, channel ); | 
|---|
 | 895 |         return 0; | 
|---|
| [440] | 896 |     } | 
|---|
 | 897 | } | 
|---|
 | 898 |  | 
|---|
 | 899 | ///////////////////////////////////////// | 
|---|
 | 900 | int _sys_tim_start( unsigned int period ) | 
|---|
 | 901 | { | 
|---|
 | 902 |     // get timer index | 
|---|
 | 903 |     unsigned int channel = _get_context_slot( CTX_TIM_ID ); | 
|---|
 | 904 |     if ( channel >= NB_TIM_CHANNELS ) | 
|---|
 | 905 |     { | 
|---|
 | 906 |         _printf("\n[GIET_ERROR] in _sys_tim_start() : not enough TIM channels\n"); | 
|---|
 | 907 |         return -1; | 
|---|
 | 908 |     } | 
|---|
 | 909 |  | 
|---|
 | 910 |     // start timer | 
|---|
 | 911 |     _timer_start( channel, period ); | 
|---|
 | 912 |  | 
|---|
 | 913 |     return 0; | 
|---|
 | 914 | } | 
|---|
 | 915 |  | 
|---|
 | 916 | /////////////////// | 
|---|
 | 917 | int _sys_tim_stop() | 
|---|
 | 918 | { | 
|---|
 | 919 |     // get timer index | 
|---|
 | 920 |     unsigned int channel = _get_context_slot( CTX_TIM_ID ); | 
|---|
 | 921 |     if ( channel >= NB_TIM_CHANNELS ) | 
|---|
 | 922 |     { | 
|---|
 | 923 |         _printf("\n[GIET_ERROR] in _sys_tim_stop() : illegal timer index\n"); | 
|---|
 | 924 |         return -1; | 
|---|
 | 925 |     } | 
|---|
 | 926 |  | 
|---|
 | 927 |     // stop timer | 
|---|
 | 928 |     _timer_stop( channel ); | 
|---|
 | 929 |  | 
|---|
 | 930 |     return 0; | 
|---|
 | 931 | } | 
|---|
 | 932 |  | 
|---|
 | 933 | ////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 934 | //             NIC related syscall handlers  | 
|---|
 | 935 | ////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 936 |  | 
|---|
| [478] | 937 | #define NIC_CONTAINER_SIZE 4096 | 
|---|
 | 938 |  | 
|---|
| [494] | 939 | //////////////////////////////////////// | 
|---|
 | 940 | int _sys_nic_alloc( unsigned int is_rx, | 
|---|
 | 941 |                     unsigned int xmax, | 
|---|
 | 942 |                     unsigned int ymax ) | 
|---|
| [440] | 943 | { | 
|---|
| [494] | 944 |     // check xmax / ymax parameters | 
|---|
 | 945 |     if ( xmax > X_SIZE ) | 
|---|
 | 946 |     { | 
|---|
 | 947 |         _printf("\n[GIET_ERROR] in _sys_nic_alloc() xmax argument too large\n"); | 
|---|
 | 948 |         return -1; | 
|---|
 | 949 |     } | 
|---|
 | 950 |     if ( ymax > Y_SIZE ) | 
|---|
 | 951 |     { | 
|---|
 | 952 |         _printf("\n[GIET_ERROR] in _sys_nic_alloc() ymax argument too large\n"); | 
|---|
 | 953 |         return -1; | 
|---|
 | 954 |     } | 
|---|
| [459] | 955 |  | 
|---|
| [614] | 956 |     //////////////////////////////////////////////////////// | 
|---|
 | 957 |     // Step 1: get and register CMA and NIC channel index // | 
|---|
 | 958 |     //////////////////////////////////////////////////////// | 
|---|
 | 959 |  | 
|---|
| [494] | 960 |     // get a NIC_RX or NIC_TX channel index  | 
|---|
| [449] | 961 |     unsigned int nic_channel; | 
|---|
 | 962 |     unsigned int cma_channel; | 
|---|
| [440] | 963 |  | 
|---|
| [459] | 964 |     if ( is_rx ) nic_channel = _atomic_increment( &_nic_rx_channel_allocator, 1 ); | 
|---|
 | 965 |     else         nic_channel = _atomic_increment( &_nic_tx_channel_allocator, 1 ); | 
|---|
| [449] | 966 |  | 
|---|
 | 967 |     if ( (nic_channel >= NB_NIC_CHANNELS) ) | 
|---|
| [440] | 968 |     { | 
|---|
| [449] | 969 |         _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough NIC channels\n"); | 
|---|
| [440] | 970 |         return -1; | 
|---|
 | 971 |     } | 
|---|
| [449] | 972 |  | 
|---|
 | 973 |     // get a CMA channel index | 
|---|
| [459] | 974 |     cma_channel = _atomic_increment( &_cma_channel_allocator, 1 ); | 
|---|
| [449] | 975 |  | 
|---|
 | 976 |     if ( cma_channel >= NB_CMA_CHANNELS ) | 
|---|
 | 977 |     { | 
|---|
 | 978 |         _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough CMA channels\n"); | 
|---|
 | 979 |         return -1; | 
|---|
 | 980 |     } | 
|---|
| [459] | 981 |  | 
|---|
| [494] | 982 | #if GIET_DEBUG_NIC | 
|---|
 | 983 | unsigned int thread  = _get_context_slot( CTX_TRDID_ID ); | 
|---|
 | 984 | _printf("\n[GIET DEBUG NIC] Task %d enters sys_nic_alloc() at cycle %d\n" | 
|---|
| [547] | 985 |         "  nic_channel = %d / cma_channel = %d\n", | 
|---|
| [494] | 986 |         thread , _get_proctime() , nic_channel , cma_channel ); | 
|---|
 | 987 | #endif | 
|---|
 | 988 |  | 
|---|
| [449] | 989 |     // register nic_index and cma_index in task context | 
|---|
 | 990 |     if ( is_rx ) | 
|---|
 | 991 |     { | 
|---|
 | 992 |         _set_context_slot( CTX_NIC_RX_ID, nic_channel ); | 
|---|
 | 993 |         _set_context_slot( CTX_CMA_RX_ID, cma_channel ); | 
|---|
 | 994 |     } | 
|---|
| [440] | 995 |     else | 
|---|
 | 996 |     { | 
|---|
| [449] | 997 |         _set_context_slot( CTX_NIC_TX_ID, nic_channel ); | 
|---|
 | 998 |         _set_context_slot( CTX_CMA_TX_ID, cma_channel ); | 
|---|
| [440] | 999 |     } | 
|---|
 | 1000 |  | 
|---|
| [614] | 1001 |     ///////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 1002 |     // Step 2: loop on all the clusters                                            // | 
|---|
 | 1003 |     // Allocate the kernel containers and status, compute the container and the    // | 
|---|
 | 1004 |     // status physical addresses, fill and synchronize the kernel CHBUF descriptor // | 
|---|
 | 1005 |     ///////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 1006 |  | 
|---|
| [494] | 1007 |     // physical addresses to be registered in the CMA registers | 
|---|
| [459] | 1008 |     unsigned long long nic_chbuf_pbase;     // NIC chbuf physical address | 
|---|
 | 1009 |     unsigned long long ker_chbuf_pbase;     // kernel chbuf physical address | 
|---|
| [449] | 1010 |  | 
|---|
| [614] | 1011 |     // allocate one kernel container and one status variable per cluster in the | 
|---|
 | 1012 |     // (xmax / ymax) mesh | 
|---|
| [528] | 1013 |     unsigned int        cx;                 // cluster X coordinate | 
|---|
 | 1014 |     unsigned int        cy;                 // cluster Y coordinate | 
|---|
 | 1015 |     unsigned int        index;              // container index in chbuf | 
|---|
 | 1016 |     unsigned int        vaddr;              // virtual address | 
|---|
 | 1017 |     unsigned long long  cont_paddr;         // container physical address | 
|---|
| [614] | 1018 |     unsigned long long  sts_paddr;          // container status physical address | 
|---|
| [494] | 1019 |  | 
|---|
| [528] | 1020 |     unsigned int        flags;              // for _v2p_translate() | 
|---|
 | 1021 |  | 
|---|
| [494] | 1022 |     for ( cx = 0 ; cx < xmax ; cx++ ) | 
|---|
| [478] | 1023 |     { | 
|---|
| [494] | 1024 |         for ( cy = 0 ; cy < ymax ; cy++ ) | 
|---|
| [478] | 1025 |         { | 
|---|
 | 1026 |             // compute index in chbuf | 
|---|
| [494] | 1027 |             index = (cx * ymax) + cy;  | 
|---|
| [478] | 1028 |  | 
|---|
| [494] | 1029 |             // allocate the kernel container | 
|---|
| [478] | 1030 |             vaddr = (unsigned int)_remote_malloc( NIC_CONTAINER_SIZE, cx, cy ); | 
|---|
 | 1031 |  | 
|---|
| [494] | 1032 |             if ( vaddr == 0 )  // not enough kernel heap memory in cluster[cx,cy] | 
|---|
 | 1033 |             { | 
|---|
 | 1034 |                 _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough kenel heap" | 
|---|
 | 1035 |                         " in cluster[%d,%d]\n", cx, cy ); | 
|---|
 | 1036 |                 return -1; | 
|---|
 | 1037 |             } | 
|---|
 | 1038 |  | 
|---|
| [478] | 1039 |             // compute container physical address | 
|---|
| [528] | 1040 |             cont_paddr = _v2p_translate( vaddr , &flags ); | 
|---|
| [478] | 1041 |  | 
|---|
| [614] | 1042 |             // checking container address alignment | 
|---|
 | 1043 |             if ( cont_paddr & 0x3F ) | 
|---|
 | 1044 |             { | 
|---|
 | 1045 |                 _printf("\n[GIET ERROR] in _sys_nic_alloc() : container address of cluster[%d,%d] not aligned\n", | 
|---|
 | 1046 |                         cx, cy); | 
|---|
 | 1047 |                 return -1; | 
|---|
 | 1048 |             } | 
|---|
 | 1049 |  | 
|---|
 | 1050 | #if GIET_DEBUG_NIC | 
|---|
 | 1051 | _printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_alloc()\n" | 
|---|
 | 1052 |         " allocates in cluster[%d,%d]:\n" | 
|---|
 | 1053 |         " - container vaddr = %x / paddr = %l\n", | 
|---|
 | 1054 |         thread , cx , cy , vaddr, cont_paddr ); | 
|---|
 | 1055 | #endif | 
|---|
 | 1056 |  | 
|---|
 | 1057 |             // allocate the kernel container status | 
|---|
 | 1058 |             // it occupies 64 bytes but only last bit is useful (1 for full and 0 for empty) | 
|---|
 | 1059 |             vaddr = (unsigned int)_remote_malloc( 64, cx, cy ); | 
|---|
 | 1060 |  | 
|---|
 | 1061 |             if ( vaddr == 0 )  // not enough kernel heap memory in cluster[cx,cy] | 
|---|
 | 1062 |             { | 
|---|
 | 1063 |                 _printf("\n[GIET_ERROR] in _sys_nic_alloc() not enough kenel heap" | 
|---|
 | 1064 |                         " in cluster[%d,%d]\n", cx, cy ); | 
|---|
 | 1065 |                 return -1; | 
|---|
 | 1066 |             } | 
|---|
 | 1067 |  | 
|---|
 | 1068 |             // compute status physical address | 
|---|
 | 1069 |             sts_paddr = _v2p_translate( vaddr , &flags ); | 
|---|
 | 1070 |  | 
|---|
 | 1071 |             // checking status address alignment | 
|---|
 | 1072 |             if ( sts_paddr & 0x3F ) | 
|---|
 | 1073 |             { | 
|---|
 | 1074 |                 _printf("\n[GIET ERROR] in _sys_nic_alloc() : status address of cluster[%d,%d] not aligned\n", | 
|---|
 | 1075 |                         cx, cy); | 
|---|
 | 1076 |                 return -1; | 
|---|
 | 1077 |             } | 
|---|
 | 1078 |  | 
|---|
| [494] | 1079 |             // initialize chbuf entry | 
|---|
| [614] | 1080 |             // The buffer descriptor has the following structure: | 
|---|
 | 1081 |             // - the 26 LSB bits contain bits[6:31] of the buffer physical address | 
|---|
 | 1082 |             // - the 26 following bits contain bits[6:31] of the physical address where the | 
|---|
 | 1083 |             //   buffer status is located | 
|---|
 | 1084 |             // - the 12 MSB bits contain the common address extension of the buffer and its | 
|---|
 | 1085 |             //   status | 
|---|
 | 1086 |             if ( is_rx ) | 
|---|
 | 1087 |                 _nic_ker_rx_chbuf[nic_channel].buf_desc[index] = | 
|---|
 | 1088 |                     (unsigned long long) | 
|---|
 | 1089 |                     ((sts_paddr & 0xFFFFFFFFULL) >> 6) + | 
|---|
 | 1090 |                     (((cont_paddr & 0xFFFFFFFFFFFULL) >> 6) << 26); | 
|---|
 | 1091 |             else | 
|---|
 | 1092 |                 _nic_ker_tx_chbuf[nic_channel].buf_desc[index] = | 
|---|
 | 1093 |                     (unsigned long long) | 
|---|
 | 1094 |                     ((sts_paddr & 0xFFFFFFC0ULL) >> 6) + | 
|---|
 | 1095 |                     (((cont_paddr & 0xFFFFFFFFFC0ULL) >> 6) << 26); | 
|---|
| [478] | 1096 |  | 
|---|
 | 1097 | #if GIET_DEBUG_NIC | 
|---|
| [614] | 1098 | _printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_alloc()\n" | 
|---|
 | 1099 |         " - status vaddr = %x / paddr = %l\n" | 
|---|
 | 1100 |         " Buffer descriptor = %l\n", | 
|---|
 | 1101 |         thread, vaddr, sts_paddr, | 
|---|
 | 1102 |         (unsigned long long)((sts_paddr & 0xFFFFFFFFULL) >> 6) +  | 
|---|
 | 1103 |         (((cont_paddr & 0xFFFFFFFFFFFULL) >> 6) << 26) ); | 
|---|
| [478] | 1104 | #endif | 
|---|
 | 1105 |         } | 
|---|
 | 1106 |     } | 
|---|
 | 1107 |  | 
|---|
| [494] | 1108 |     // complete kernel chbuf initialisation | 
|---|
 | 1109 |     if ( is_rx ) | 
|---|
 | 1110 |     { | 
|---|
| [614] | 1111 |         _nic_ker_rx_chbuf[nic_channel].xmax = xmax; | 
|---|
 | 1112 |         _nic_ker_rx_chbuf[nic_channel].ymax = ymax; | 
|---|
| [494] | 1113 |     } | 
|---|
 | 1114 |     else | 
|---|
 | 1115 |     { | 
|---|
| [614] | 1116 |         _nic_ker_tx_chbuf[nic_channel].xmax = xmax; | 
|---|
 | 1117 |         _nic_ker_tx_chbuf[nic_channel].ymax = ymax; | 
|---|
| [494] | 1118 |     } | 
|---|
 | 1119 |  | 
|---|
| [449] | 1120 |     // compute the kernel chbuf descriptor physical address | 
|---|
| [614] | 1121 |     if ( is_rx ) vaddr = (unsigned int)( &_nic_ker_rx_chbuf[nic_channel] ); | 
|---|
 | 1122 |     else         vaddr = (unsigned int)( &_nic_ker_tx_chbuf[nic_channel] ); | 
|---|
| [440] | 1123 |  | 
|---|
| [528] | 1124 |     ker_chbuf_pbase = _v2p_translate( vaddr , &flags ); | 
|---|
 | 1125 |  | 
|---|
| [459] | 1126 | #if GIET_DEBUG_NIC | 
|---|
| [547] | 1127 | _printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_alloc() get kernel chbuf\n" | 
|---|
 | 1128 |         "  vaddr = %x / paddr = %l\n", | 
|---|
| [478] | 1129 |         thread , vaddr , ker_chbuf_pbase ); | 
|---|
| [459] | 1130 | #endif | 
|---|
| [440] | 1131 |  | 
|---|
| [459] | 1132 |     // sync the kernel chbuf in L2 after write in L2 | 
|---|
| [614] | 1133 |     _mmc_sync( ker_chbuf_pbase, sizeof( ker_chbuf_t ) ); | 
|---|
| [459] | 1134 |  | 
|---|
| [614] | 1135 |     /////////////////////////////////////////////////////////////// | 
|---|
 | 1136 |     // Step 3: compute the NIC chbuf descriptor physical address // | 
|---|
 | 1137 |     /////////////////////////////////////////////////////////////// | 
|---|
 | 1138 |  | 
|---|
 | 1139 |     unsigned int offset; | 
|---|
 | 1140 |     if ( is_rx ) offset = 0x4100; | 
|---|
 | 1141 |     else         offset = 0x4110; | 
|---|
 | 1142 |     nic_chbuf_pbase = (((unsigned long long)((X_IO << Y_WIDTH) + Y_IO))<<32) | | 
|---|
 | 1143 |                       (SEG_NIC_BASE + (nic_channel<<15) + offset); | 
|---|
 | 1144 |  | 
|---|
 | 1145 | #if GIET_DEBUG_NIC | 
|---|
 | 1146 | _printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_alloc() get NIC chbuf : paddr = %l\n", | 
|---|
 | 1147 |         thread , nic_chbuf_pbase ); | 
|---|
 | 1148 | #endif | 
|---|
 | 1149 |  | 
|---|
 | 1150 |     //////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 1151 |     // Step 4: initialize CMA registers defining the source & destination chbufs // | 
|---|
 | 1152 |     //////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 1153 |  | 
|---|
| [459] | 1154 |     if ( is_rx )               // NIC to kernel | 
|---|
 | 1155 |     { | 
|---|
 | 1156 |         _cma_set_register( cma_channel, CHBUF_SRC_DESC , (unsigned int)(nic_chbuf_pbase) ); | 
|---|
 | 1157 |         _cma_set_register( cma_channel, CHBUF_SRC_EXT  , (unsigned int)(nic_chbuf_pbase>>32) ); | 
|---|
 | 1158 |         _cma_set_register( cma_channel, CHBUF_SRC_NBUFS, 2 ); | 
|---|
 | 1159 |         _cma_set_register( cma_channel, CHBUF_DST_DESC , (unsigned int)(ker_chbuf_pbase) ); | 
|---|
 | 1160 |         _cma_set_register( cma_channel, CHBUF_DST_EXT  , (unsigned int)(ker_chbuf_pbase>>32) ); | 
|---|
| [494] | 1161 |         _cma_set_register( cma_channel, CHBUF_DST_NBUFS, xmax * ymax ); | 
|---|
| [459] | 1162 |     } | 
|---|
 | 1163 |     else                      // kernel to NIC | 
|---|
 | 1164 |     { | 
|---|
 | 1165 |         _cma_set_register( cma_channel, CHBUF_SRC_DESC , (unsigned int)(ker_chbuf_pbase) ); | 
|---|
 | 1166 |         _cma_set_register( cma_channel, CHBUF_SRC_EXT  , (unsigned int)(ker_chbuf_pbase>>32) ); | 
|---|
| [494] | 1167 |         _cma_set_register( cma_channel, CHBUF_SRC_NBUFS, xmax * ymax ); | 
|---|
| [459] | 1168 |         _cma_set_register( cma_channel, CHBUF_DST_DESC , (unsigned int)(nic_chbuf_pbase) ); | 
|---|
 | 1169 |         _cma_set_register( cma_channel, CHBUF_DST_EXT  , (unsigned int)(nic_chbuf_pbase>>32) ); | 
|---|
 | 1170 |         _cma_set_register( cma_channel, CHBUF_DST_NBUFS, 2 ); | 
|---|
 | 1171 |     } | 
|---|
 | 1172 |  | 
|---|
| [494] | 1173 | #if GIET_DEBUG_NIC | 
|---|
 | 1174 | _printf("\n[GIET DEBUG NIC] Task %d exit _sys_nic_alloc() at cycle %d\n", | 
|---|
 | 1175 |         thread, _get_proctime() ); | 
|---|
 | 1176 | #endif | 
|---|
 | 1177 |  | 
|---|
 | 1178 |     return nic_channel; | 
|---|
 | 1179 | } // end _sys_nic_alloc() | 
|---|
 | 1180 |  | 
|---|
 | 1181 |  | 
|---|
 | 1182 | //////////////////////////////////////// | 
|---|
 | 1183 | int _sys_nic_start( unsigned int is_rx, | 
|---|
 | 1184 |                     unsigned int channel ) | 
|---|
 | 1185 | { | 
|---|
 | 1186 |     unsigned int nic_channel; | 
|---|
 | 1187 |     unsigned int cma_channel; | 
|---|
 | 1188 |  | 
|---|
 | 1189 |     // get NIC channel index and CMA channel index from task context | 
|---|
 | 1190 |     if ( is_rx ) | 
|---|
 | 1191 |     { | 
|---|
 | 1192 |         nic_channel = _get_context_slot( CTX_NIC_RX_ID ); | 
|---|
 | 1193 |         cma_channel = _get_context_slot( CTX_CMA_RX_ID ); | 
|---|
 | 1194 |     } | 
|---|
 | 1195 |     else | 
|---|
 | 1196 |     { | 
|---|
 | 1197 |         nic_channel = _get_context_slot( CTX_NIC_TX_ID ); | 
|---|
 | 1198 |         cma_channel = _get_context_slot( CTX_CMA_TX_ID ); | 
|---|
 | 1199 |     } | 
|---|
 | 1200 |  | 
|---|
 | 1201 | #if GIET_DEBUG_NIC | 
|---|
 | 1202 | unsigned int thread  = _get_context_slot( CTX_TRDID_ID ); | 
|---|
| [547] | 1203 | _printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_start() at cycle %d\n" | 
|---|
 | 1204 |         "  get NIC channel = %d / CMA channel = %d\n", | 
|---|
| [494] | 1205 |         thread, _get_proctime(), nic_channel, cma_channel ); | 
|---|
 | 1206 | #endif | 
|---|
 | 1207 |  | 
|---|
 | 1208 |     // check NIC and CMA channels index | 
|---|
 | 1209 |     if ( nic_channel != channel ) | 
|---|
 | 1210 |     { | 
|---|
 | 1211 |         _printf("\n[GIET_ERROR] in _sys_nic_start(): illegal NIC channel\n"); | 
|---|
 | 1212 |         return -1; | 
|---|
 | 1213 |     } | 
|---|
 | 1214 |     if ( cma_channel >= NB_CMA_CHANNELS ) | 
|---|
 | 1215 |     { | 
|---|
 | 1216 |         _printf("\n[GIET_ERROR] in _sys_nic_start(): illegal CMA channel\n"); | 
|---|
 | 1217 |         return -1; | 
|---|
 | 1218 |     } | 
|---|
 | 1219 |  | 
|---|
| [449] | 1220 |     // start CMA transfer | 
|---|
| [478] | 1221 |     _cma_set_register( cma_channel, CHBUF_BUF_SIZE , NIC_CONTAINER_SIZE ); | 
|---|
| [505] | 1222 |     _cma_set_register( cma_channel, CHBUF_PERIOD   , 0 );     // OUT_OF_ORDER  | 
|---|
| [449] | 1223 |     _cma_set_register( cma_channel, CHBUF_RUN      , 1 ); | 
|---|
 | 1224 |  | 
|---|
 | 1225 |     // activates NIC channel | 
|---|
| [614] | 1226 |     _nic_channel_start( nic_channel, is_rx, GIET_NIC_MAC4, GIET_NIC_MAC2 ); | 
|---|
| [459] | 1227 |  | 
|---|
 | 1228 | #if GIET_DEBUG_NIC | 
|---|
| [614] | 1229 |     _printf("\n[GIET DEBUG NIC] Task %d exit _sys_nic_start() at cycle %d\n", | 
|---|
 | 1230 |             thread , _get_proctime() ); | 
|---|
| [459] | 1231 | #endif | 
|---|
 | 1232 |  | 
|---|
| [449] | 1233 |     return 0; | 
|---|
| [505] | 1234 | }  // end _sys_nic_start() | 
|---|
| [449] | 1235 |  | 
|---|
| [494] | 1236 |  | 
|---|
| [449] | 1237 | ////////////////////////////////////// | 
|---|
 | 1238 | int _sys_nic_move( unsigned int is_rx, | 
|---|
| [459] | 1239 |                    unsigned int channel, | 
|---|
| [449] | 1240 |                    void*        buffer ) | 
|---|
 | 1241 | { | 
|---|
 | 1242 |  | 
|---|
| [459] | 1243 | #if GIET_DEBUG_NIC | 
|---|
 | 1244 | unsigned int thread  = _get_context_slot( CTX_TRDID_ID ); | 
|---|
| [478] | 1245 | _printf("\n[GIET DEBUG NIC] Task %d enters _sys_nic_move() at cycle %d\n", | 
|---|
 | 1246 |         thread , _get_proctime() ); | 
|---|
| [459] | 1247 | #endif | 
|---|
 | 1248 |  | 
|---|
| [494] | 1249 |     // check NIC channel index | 
|---|
 | 1250 |     if ( channel >= NB_NIC_CHANNELS ) | 
|---|
 | 1251 |     { | 
|---|
 | 1252 |         _printf("\n[GIET_ERROR] in _sys_nic_move() : illegal NIC channel index\n"); | 
|---|
 | 1253 |         return -1; | 
|---|
 | 1254 |     } | 
|---|
 | 1255 |  | 
|---|
 | 1256 |     // get kernel chbuf virtual address | 
|---|
| [614] | 1257 |     ker_chbuf_t* ker_chbuf; | 
|---|
 | 1258 |     if ( is_rx )  ker_chbuf = &_nic_ker_rx_chbuf[channel]; | 
|---|
 | 1259 |     else          ker_chbuf = &_nic_ker_tx_chbuf[channel]; | 
|---|
| [494] | 1260 |  | 
|---|
 | 1261 |     // get xmax / ymax parameters | 
|---|
| [614] | 1262 |     unsigned int xmax = ker_chbuf->xmax; | 
|---|
 | 1263 |     unsigned int ymax = ker_chbuf->ymax; | 
|---|
| [494] | 1264 |  | 
|---|
| [478] | 1265 |     // get cluster coordinates for the processor running the calling task | 
|---|
 | 1266 |     unsigned int  procid = _get_procid(); | 
|---|
 | 1267 |     unsigned int  cx     = procid >> (Y_WIDTH + P_WIDTH); | 
|---|
 | 1268 |     unsigned int  cy     = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1); | 
|---|
 | 1269 |      | 
|---|
| [494] | 1270 |     // check processor coordinates / (xmax,ymax) | 
|---|
 | 1271 |     if ( cx >= xmax ) | 
|---|
 | 1272 |     { | 
|---|
 | 1273 |         _printf("\n[GIET_ERROR] in _sys_nic_move() : processor X coordinate = %d" | 
|---|
 | 1274 |                 " / xmax = %d\n", cx , xmax ); | 
|---|
 | 1275 |         return -1; | 
|---|
 | 1276 |     } | 
|---|
 | 1277 |     if ( cy >= ymax ) | 
|---|
 | 1278 |     { | 
|---|
 | 1279 |         _printf("\n[GIET_ERROR] in _sys_nic_move() : processor Y coordinate = %d" | 
|---|
 | 1280 |                 " / ymax = %d\n", cy , ymax ); | 
|---|
 | 1281 |         return -1; | 
|---|
 | 1282 |     } | 
|---|
 | 1283 |      | 
|---|
| [614] | 1284 |     unsigned long long usr_buf_paddr;       // user buffer physical address  | 
|---|
 | 1285 |     unsigned long long ker_buf_paddr;       // kernel buffer physical address | 
|---|
 | 1286 |     unsigned long long ker_sts_paddr;       // kernel buffer status physical address | 
|---|
 | 1287 |     unsigned long long ker_buf_desc;        // kernel buffer descriptor | 
|---|
 | 1288 |     unsigned int       ker_sts;             // kernel buffer status (full or empty) | 
|---|
 | 1289 |     unsigned int       index;               // kernel buffer index in chbuf | 
|---|
 | 1290 |     unsigned int       flags;               // for _v2P_translate | 
|---|
| [459] | 1291 |  | 
|---|
 | 1292 |     // Compute user buffer physical address and check access rights | 
|---|
| [614] | 1293 |     usr_buf_paddr = _v2p_translate( (unsigned int)buffer , &flags ); | 
|---|
| [478] | 1294 |  | 
|---|
| [440] | 1295 |     if ( (flags & PTE_U) == 0 ) | 
|---|
 | 1296 |     { | 
|---|
| [614] | 1297 |         _printf("\n[GIET ERROR] in _sys_nic_tx_move() : illegal user buffer address\n"); | 
|---|
| [440] | 1298 |         return -1; | 
|---|
 | 1299 |     } | 
|---|
 | 1300 |  | 
|---|
| [459] | 1301 | #if GIET_DEBUG_NIC | 
|---|
| [478] | 1302 | _printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_move() get user buffer : paddr = %l\n", | 
|---|
| [614] | 1303 |         thread, usr_buf_paddr ); | 
|---|
| [459] | 1304 | #endif | 
|---|
| [440] | 1305 |  | 
|---|
| [614] | 1306 |     // compute buffer index, buffer descriptor paddr and buffer status paddr | 
|---|
 | 1307 |     index = (ymax * cx) + cy; | 
|---|
 | 1308 |     ker_buf_desc = ker_chbuf->buf_desc[index]; | 
|---|
 | 1309 |     ker_sts_paddr = ((ker_buf_desc & 0xFFF0000000000000ULL) >> 20) + | 
|---|
 | 1310 |                     ((ker_buf_desc & 0x3FFFFFFULL) << 6); | 
|---|
| [459] | 1311 |  | 
|---|
| [614] | 1312 | #if GIET_DEBUG_NIC | 
|---|
 | 1313 | _printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_move() read ker_buf_desc %d at cycle %d\n" | 
|---|
 | 1314 |         "  kernel buffer descriptor = %l\n", | 
|---|
 | 1315 |         thread, index, _get_proctime(), ker_buf_desc ); | 
|---|
 | 1316 | #endif | 
|---|
 | 1317 |  | 
|---|
| [494] | 1318 |     // poll local kernel container status until success | 
|---|
| [478] | 1319 |     while ( 1 ) | 
|---|
| [449] | 1320 |     { | 
|---|
| [478] | 1321 |         // inval buffer descriptor in L2 before read in L2 | 
|---|
| [614] | 1322 |         _mmc_inval( ker_sts_paddr, 4 ); | 
|---|
 | 1323 |         ker_sts = _physical_read( ker_sts_paddr ); | 
|---|
| [459] | 1324 |  | 
|---|
 | 1325 | #if GIET_DEBUG_NIC | 
|---|
| [614] | 1326 | _printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_move() read ker_buf_sts %d at cycle %d\n" | 
|---|
 | 1327 |         "  paddr = %l / kernel buffer status = %x\n", | 
|---|
 | 1328 |         thread, index, _get_proctime(), ker_sts_paddr, ker_sts ); | 
|---|
| [459] | 1329 | #endif | 
|---|
 | 1330 |  | 
|---|
| [478] | 1331 |         // test buffer status and break if found | 
|---|
| [614] | 1332 |         if ( ( is_rx != 0 ) && ( ker_sts == 0x1 ) ) break; | 
|---|
 | 1333 |         if ( ( is_rx == 0 ) && ( ker_sts == 0 ) ) break; | 
|---|
| [449] | 1334 |     } | 
|---|
| [459] | 1335 |  | 
|---|
 | 1336 |     // compute kernel buffer physical address | 
|---|
| [614] | 1337 |     ker_buf_paddr = (ker_buf_desc & 0xFFFFFFFFFC000000ULL) >> 20; | 
|---|
| [449] | 1338 |      | 
|---|
| [494] | 1339 |     // move one container | 
|---|
 | 1340 |     if ( is_rx )              // RX transfer | 
|---|
| [459] | 1341 |     { | 
|---|
 | 1342 |         // inval kernel buffer in L2 before read in L2 | 
|---|
| [614] | 1343 |         _mmc_inval( ker_buf_paddr, NIC_CONTAINER_SIZE ); | 
|---|
| [449] | 1344 |  | 
|---|
| [459] | 1345 |         // transfer data from kernel buffer to user buffer | 
|---|
| [614] | 1346 |         _physical_memcpy( usr_buf_paddr,  | 
|---|
 | 1347 |                           ker_buf_paddr,  | 
|---|
| [478] | 1348 |                           NIC_CONTAINER_SIZE ); | 
|---|
 | 1349 | #if GIET_DEBUG_NIC | 
|---|
| [547] | 1350 | _printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_move() transfer kernel buffer %l\n" | 
|---|
 | 1351 |         " to user buffer %l at cycle %d\n", | 
|---|
| [614] | 1352 |         thread , ker_buf_paddr , usr_buf_paddr , _get_proctime() ); | 
|---|
| [478] | 1353 | #endif | 
|---|
| [449] | 1354 |  | 
|---|
| [459] | 1355 |     } | 
|---|
| [494] | 1356 |     else                      // TX transfer | 
|---|
| [459] | 1357 |     { | 
|---|
 | 1358 |         // transfer data from user buffer to kernel buffer | 
|---|
| [614] | 1359 |         _physical_memcpy( ker_buf_paddr,  | 
|---|
 | 1360 |                           usr_buf_paddr,  | 
|---|
| [478] | 1361 |                           NIC_CONTAINER_SIZE ); | 
|---|
| [449] | 1362 |  | 
|---|
| [459] | 1363 |         // sync kernel buffer in L2 after write in L2 | 
|---|
| [614] | 1364 |         _mmc_sync( ker_buf_paddr, NIC_CONTAINER_SIZE ); | 
|---|
| [478] | 1365 |  | 
|---|
 | 1366 | #if GIET_DEBUG_NIC | 
|---|
 | 1367 | _printf("\n[GIET DEBUG NIC] Task %d in _sys_nic_move() transfer " | 
|---|
 | 1368 |         "user buffer %l to kernel buffer %l at cycle %d\n", | 
|---|
| [614] | 1369 |         thread , usr_buf_paddr , ker_buf_paddr , _get_proctime() ); | 
|---|
| [478] | 1370 | #endif | 
|---|
 | 1371 |  | 
|---|
| [459] | 1372 |     } | 
|---|
 | 1373 |  | 
|---|
| [478] | 1374 |     // update kernel chbuf status  | 
|---|
| [614] | 1375 |     if ( is_rx ) _physical_write ( ker_sts_paddr, 0 ); | 
|---|
 | 1376 |     else         _physical_write ( ker_sts_paddr, 0x1 ); | 
|---|
| [459] | 1377 |  | 
|---|
 | 1378 |     // sync kernel chbuf in L2 after write in L2 | 
|---|
| [614] | 1379 |     _mmc_sync( ker_sts_paddr, 4 ); | 
|---|
| [459] | 1380 |  | 
|---|
 | 1381 | #if GIET_DEBUG_NIC | 
|---|
| [478] | 1382 | _printf("\n[GIET DEBUG NIC] Task %d get buffer %d  and exit _sys_nic_move() at cycle %d\n", | 
|---|
 | 1383 |         thread , index , _get_proctime() ); | 
|---|
| [459] | 1384 | #endif | 
|---|
 | 1385 |  | 
|---|
| [440] | 1386 |     return 0; | 
|---|
| [449] | 1387 | } // end _sys_nic_move() | 
|---|
| [440] | 1388 |  | 
|---|
| [494] | 1389 |  | 
|---|
| [449] | 1390 | //////////////////////////////////////// | 
|---|
| [489] | 1391 | int _sys_nic_stop( unsigned int is_rx, | 
|---|
 | 1392 |                    unsigned int channel ) | 
|---|
| [440] | 1393 | { | 
|---|
| [449] | 1394 |     unsigned int nic_channel; | 
|---|
 | 1395 |     unsigned int cma_channel; | 
|---|
| [440] | 1396 |  | 
|---|
| [449] | 1397 |     // get NIC channel index and CMA channel index | 
|---|
 | 1398 |     if ( is_rx ) | 
|---|
| [440] | 1399 |     { | 
|---|
| [449] | 1400 |         nic_channel = _get_context_slot( CTX_NIC_RX_ID ); | 
|---|
 | 1401 |         cma_channel = _get_context_slot( CTX_CMA_RX_ID ); | 
|---|
| [440] | 1402 |     } | 
|---|
| [449] | 1403 |     else | 
|---|
 | 1404 |     { | 
|---|
 | 1405 |         nic_channel = _get_context_slot( CTX_NIC_TX_ID ); | 
|---|
 | 1406 |         cma_channel = _get_context_slot( CTX_CMA_TX_ID ); | 
|---|
 | 1407 |     } | 
|---|
| [440] | 1408 |  | 
|---|
| [494] | 1409 |     // check NIC and CMA channels index | 
|---|
| [489] | 1410 |     if ( nic_channel != channel ) | 
|---|
| [440] | 1411 |     { | 
|---|
| [494] | 1412 |         _printf("\n[GIET_ERROR] in _sys_nic_stop(): illegal NIC channel\n"); | 
|---|
| [440] | 1413 |         return -1; | 
|---|
 | 1414 |     } | 
|---|
| [449] | 1415 |     if ( cma_channel >= NB_CMA_CHANNELS ) | 
|---|
| [440] | 1416 |     { | 
|---|
| [489] | 1417 |         _printf("\n[GIET_ERROR] in _sys_nic_stop(): illegal CMA channel\n"); | 
|---|
| [440] | 1418 |         return -1; | 
|---|
 | 1419 |     } | 
|---|
 | 1420 |  | 
|---|
| [449] | 1421 |     // desactivates the NIC channel | 
|---|
 | 1422 |     _nic_channel_stop( nic_channel, is_rx ); | 
|---|
| [440] | 1423 |  | 
|---|
| [449] | 1424 |     // desactivates the CMA channel | 
|---|
| [505] | 1425 |     _cma_set_register( cma_channel, CHBUF_RUN , 0 ); | 
|---|
| [449] | 1426 |  | 
|---|
| [440] | 1427 |     return 0; | 
|---|
| [494] | 1428 | }  // end _sys_nic_stop() | 
|---|
| [440] | 1429 |  | 
|---|
| [459] | 1430 | //////////////////////////////////////// | 
|---|
| [489] | 1431 | int _sys_nic_clear( unsigned int is_rx, | 
|---|
 | 1432 |                     unsigned int channel ) | 
|---|
| [459] | 1433 | { | 
|---|
 | 1434 |     unsigned int nic_channel; | 
|---|
 | 1435 |  | 
|---|
 | 1436 |     // get NIC channel  | 
|---|
 | 1437 |     if ( is_rx )  nic_channel = _get_context_slot( CTX_NIC_RX_ID ); | 
|---|
 | 1438 |     else          nic_channel = _get_context_slot( CTX_NIC_TX_ID ); | 
|---|
 | 1439 |  | 
|---|
| [489] | 1440 |     if ( nic_channel != channel ) | 
|---|
| [459] | 1441 |     { | 
|---|
| [489] | 1442 |         _printf("\n[GIET_ERROR] in _sys_nic_clear(): illegal NIC channel\n"); | 
|---|
| [459] | 1443 |         return -1; | 
|---|
 | 1444 |     } | 
|---|
 | 1445 |  | 
|---|
 | 1446 |     if ( is_rx ) | 
|---|
 | 1447 |     { | 
|---|
 | 1448 |         _nic_set_global_register( NIC_G_NPKT_RX_G2S_RECEIVED       , 0 ); | 
|---|
 | 1449 |         _nic_set_global_register( NIC_G_NPKT_RX_DES_TOO_SMALL      , 0 ); | 
|---|
 | 1450 |         _nic_set_global_register( NIC_G_NPKT_RX_DES_TOO_BIG        , 0 ); | 
|---|
 | 1451 |         _nic_set_global_register( NIC_G_NPKT_RX_DES_MFIFO_FULL     , 0 ); | 
|---|
 | 1452 |         _nic_set_global_register( NIC_G_NPKT_RX_DES_CRC_FAIL       , 0 ); | 
|---|
 | 1453 |         _nic_set_global_register( NIC_G_NPKT_RX_DISPATCH_RECEIVED  , 0 ); | 
|---|
 | 1454 |         _nic_set_global_register( NIC_G_NPKT_RX_DISPATCH_BROADCAST , 0 ); | 
|---|
 | 1455 |         _nic_set_global_register( NIC_G_NPKT_RX_DISPATCH_DST_FAIL  , 0 ); | 
|---|
 | 1456 |         _nic_set_global_register( NIC_G_NPKT_RX_DISPATCH_CH_FULL   , 0 ); | 
|---|
 | 1457 |     }  | 
|---|
 | 1458 |     else | 
|---|
 | 1459 |     { | 
|---|
 | 1460 |         _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_RECEIVED  , 0 ); | 
|---|
 | 1461 |         _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_TRANSMIT  , 0 ); | 
|---|
 | 1462 |         _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_TOO_BIG   , 0 ); | 
|---|
 | 1463 |         _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_TOO_SMALL , 0 ); | 
|---|
 | 1464 |         _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_SRC_FAIL  , 0 ); | 
|---|
 | 1465 |         _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_BYPASS    , 0 ); | 
|---|
 | 1466 |         _nic_set_global_register( NIC_G_NPKT_TX_DISPATCH_BROADCAST , 0 ); | 
|---|
 | 1467 |     } | 
|---|
 | 1468 |     return 0; | 
|---|
| [494] | 1469 | }  // en _sys_nic_clear() | 
|---|
| [459] | 1470 |  | 
|---|
 | 1471 | //////////////////////////////////////// | 
|---|
| [489] | 1472 | int _sys_nic_stats( unsigned int is_rx, | 
|---|
 | 1473 |                     unsigned int channel ) | 
|---|
| [459] | 1474 | { | 
|---|
 | 1475 |     unsigned int nic_channel; | 
|---|
 | 1476 |  | 
|---|
 | 1477 |     // get NIC channel  | 
|---|
 | 1478 |     if ( is_rx )  nic_channel = _get_context_slot( CTX_NIC_RX_ID ); | 
|---|
 | 1479 |     else          nic_channel = _get_context_slot( CTX_NIC_TX_ID ); | 
|---|
 | 1480 |  | 
|---|
| [489] | 1481 |     if ( nic_channel != channel ) | 
|---|
| [459] | 1482 |     { | 
|---|
| [489] | 1483 |         _printf("\n[GIET_ERROR] in _sys_nic_stats(): illegal NIC channel\n"); | 
|---|
| [459] | 1484 |         return -1; | 
|---|
 | 1485 |     } | 
|---|
 | 1486 |  | 
|---|
 | 1487 |     if ( is_rx ) | 
|---|
 | 1488 |     { | 
|---|
 | 1489 |         unsigned int received   = _nic_get_global_register( NIC_G_NPKT_RX_G2S_RECEIVED       ); | 
|---|
 | 1490 |         unsigned int too_small  = _nic_get_global_register( NIC_G_NPKT_RX_DES_TOO_SMALL      ); | 
|---|
 | 1491 |         unsigned int too_big    = _nic_get_global_register( NIC_G_NPKT_RX_DES_TOO_BIG        ); | 
|---|
 | 1492 |         unsigned int fifo_full  = _nic_get_global_register( NIC_G_NPKT_RX_DES_MFIFO_FULL     ); | 
|---|
 | 1493 |         unsigned int crc_fail   = _nic_get_global_register( NIC_G_NPKT_RX_DES_CRC_FAIL       ); | 
|---|
 | 1494 |         unsigned int broadcast  = _nic_get_global_register( NIC_G_NPKT_RX_DISPATCH_BROADCAST ); | 
|---|
 | 1495 |         unsigned int dst_fail   = _nic_get_global_register( NIC_G_NPKT_RX_DISPATCH_DST_FAIL  ); | 
|---|
 | 1496 |         unsigned int ch_full    = _nic_get_global_register( NIC_G_NPKT_RX_DISPATCH_CH_FULL   ); | 
|---|
 | 1497 |  | 
|---|
 | 1498 |         _printf("\n### Network Controller RX Statistics ###\n" | 
|---|
 | 1499 |                 "- packets received : %d\n" | 
|---|
 | 1500 |                 "- too small        : %d\n" | 
|---|
 | 1501 |                 "- too big          : %d\n" | 
|---|
 | 1502 |                 "- fifo full        : %d\n"  | 
|---|
 | 1503 |                 "- crc fail         : %d\n"  | 
|---|
 | 1504 |                 "- dst mac fail     : %d\n"  | 
|---|
 | 1505 |                 "- channel full     : %d\n"  | 
|---|
 | 1506 |                 "- broadcast        : %d\n", | 
|---|
 | 1507 |                 received, | 
|---|
 | 1508 |                 too_small, | 
|---|
 | 1509 |                 too_big, | 
|---|
 | 1510 |                 fifo_full, | 
|---|
 | 1511 |                 crc_fail, | 
|---|
 | 1512 |                 dst_fail, | 
|---|
 | 1513 |                 ch_full, | 
|---|
 | 1514 |                 broadcast ); | 
|---|
 | 1515 |     }  | 
|---|
 | 1516 |     else | 
|---|
 | 1517 |     { | 
|---|
 | 1518 |         unsigned int received   = _nic_get_global_register( NIC_G_NPKT_TX_DISPATCH_RECEIVED  ); | 
|---|
 | 1519 |         unsigned int too_big    = _nic_get_global_register( NIC_G_NPKT_TX_DISPATCH_TOO_BIG   ); | 
|---|
 | 1520 |         unsigned int too_small  = _nic_get_global_register( NIC_G_NPKT_TX_DISPATCH_TOO_SMALL ); | 
|---|
 | 1521 |         unsigned int src_fail   = _nic_get_global_register( NIC_G_NPKT_TX_DISPATCH_SRC_FAIL  ); | 
|---|
 | 1522 |         unsigned int bypass     = _nic_get_global_register( NIC_G_NPKT_TX_DISPATCH_BYPASS    ); | 
|---|
 | 1523 |         unsigned int broadcast  = _nic_get_global_register( NIC_G_NPKT_TX_DISPATCH_BROADCAST ); | 
|---|
 | 1524 |  | 
|---|
 | 1525 |         _printf("\n### Network Controller TX Statistics ###\n" | 
|---|
 | 1526 |                 "- packets received : %d\n" | 
|---|
 | 1527 |                 "- too small        : %d\n" | 
|---|
 | 1528 |                 "- too big          : %d\n" | 
|---|
 | 1529 |                 "- src mac fail     : %d\n"  | 
|---|
 | 1530 |                 "- bypass           : %d\n"  | 
|---|
 | 1531 |                 "- broadcast        : %d\n", | 
|---|
 | 1532 |                 received, | 
|---|
 | 1533 |                 too_big, | 
|---|
 | 1534 |                 too_small, | 
|---|
 | 1535 |                 src_fail, | 
|---|
 | 1536 |                 bypass, | 
|---|
 | 1537 |                 broadcast ); | 
|---|
 | 1538 |     } | 
|---|
 | 1539 |     return 0; | 
|---|
| [494] | 1540 | }  // end _sys_nic_stats() | 
|---|
| [459] | 1541 |  | 
|---|
| [440] | 1542 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 1543 | //    FBF related syscall handlers | 
|---|
 | 1544 | ///////////////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 1545 |  | 
|---|
 | 1546 | ///////////////////////////////////////////// | 
|---|
 | 1547 | int _sys_fbf_sync_write( unsigned int offset, | 
|---|
 | 1548 |                          void*        buffer, | 
|---|
 | 1549 |                          unsigned int length ) | 
|---|
 | 1550 | { | 
|---|
 | 1551 |     char* fbf_address = (char *)SEG_FBF_BASE + offset; | 
|---|
 | 1552 |     memcpy( fbf_address, buffer, length); | 
|---|
 | 1553 |  | 
|---|
 | 1554 |     return 0; | 
|---|
 | 1555 | } | 
|---|
 | 1556 |  | 
|---|
 | 1557 | ///////////////////////////////////////////// | 
|---|
 | 1558 | int _sys_fbf_sync_read(  unsigned int offset, | 
|---|
 | 1559 |                          void*        buffer, | 
|---|
 | 1560 |                          unsigned int length ) | 
|---|
 | 1561 | { | 
|---|
 | 1562 |     char* fbf_address = (char *)SEG_FBF_BASE + offset; | 
|---|
 | 1563 |     memcpy( buffer, fbf_address, length); | 
|---|
 | 1564 |  | 
|---|
 | 1565 |     return 0; | 
|---|
 | 1566 | } | 
|---|
 | 1567 |  | 
|---|
 | 1568 | //////////////////////// | 
|---|
 | 1569 | int _sys_fbf_cma_alloc() | 
|---|
 | 1570 | { | 
|---|
 | 1571 |    // get a new CMA channel index  | 
|---|
| [459] | 1572 |     unsigned int channel = _atomic_increment( &_cma_channel_allocator, 1 ); | 
|---|
| [440] | 1573 |  | 
|---|
 | 1574 |     if ( channel >= NB_CMA_CHANNELS ) | 
|---|
 | 1575 |     { | 
|---|
 | 1576 |         _printf("\n[GIET ERROR] in _sys_fbf_cma_alloc() : not enough CMA channels\n"); | 
|---|
 | 1577 |         return -1; | 
|---|
 | 1578 |     } | 
|---|
 | 1579 |     else | 
|---|
 | 1580 |     { | 
|---|
| [449] | 1581 |         _set_context_slot( CTX_CMA_FB_ID, channel ); | 
|---|
 | 1582 |         return 0; | 
|---|
| [440] | 1583 |     } | 
|---|
 | 1584 | } // end sys_fbf_cma_alloc() | 
|---|
 | 1585 |  | 
|---|
| [614] | 1586 |  | 
|---|
| [648] | 1587 | /////////////////////////////////////////////////// | 
|---|
 | 1588 | int _sys_fbf_cma_init_buf( void*        buf0_vbase,  | 
|---|
 | 1589 |                            void*        buf1_vbase,  | 
|---|
 | 1590 |                            void*        sts0_vaddr, | 
|---|
 | 1591 |                            void*        sts1_vaddr ) | 
|---|
| [440] | 1592 | { | 
|---|
 | 1593 | #if NB_CMA_CHANNELS > 0 | 
|---|
 | 1594 |  | 
|---|
 | 1595 |     unsigned int       vaddr;           // virtual address | 
|---|
| [528] | 1596 |     unsigned int       flags;           // for _v2p_translate() | 
|---|
| [614] | 1597 |     unsigned long long fbf_paddr;       // fbf physical address | 
|---|
 | 1598 |     unsigned long long fbf_sts_paddr;   // fbf status physical address | 
|---|
 | 1599 |     unsigned long long buf0_pbase;      // buffer 0 base physical address | 
|---|
 | 1600 |     unsigned long long sts0_paddr;      // buffer 0 status physical address | 
|---|
 | 1601 |     unsigned long long buf1_pbase;      // buffer 1 base physical address | 
|---|
 | 1602 |     unsigned long long sts1_paddr;      // buffer 1 status physical address | 
|---|
| [440] | 1603 |  | 
|---|
 | 1604 |     // get channel index | 
|---|
| [449] | 1605 |     unsigned int channel = _get_context_slot( CTX_CMA_FB_ID ); | 
|---|
| [440] | 1606 |  | 
|---|
 | 1607 |     if ( channel >= NB_CMA_CHANNELS ) | 
|---|
 | 1608 |     { | 
|---|
| [648] | 1609 |         _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : CMA channel index too large\n"); | 
|---|
| [440] | 1610 |         return -1; | 
|---|
 | 1611 |     } | 
|---|
 | 1612 |  | 
|---|
 | 1613 | #if GIET_DEBUG_FBF_CMA | 
|---|
| [614] | 1614 | _printf("\n[FBF_CMA DEBUG] enters _sys_fbf_cma_init_buf()\n" | 
|---|
 | 1615 |         " - channel           = %d\n" | 
|---|
 | 1616 |         " - buf0        vbase = %x\n" | 
|---|
 | 1617 |         " - buf1        vbase = %x\n" | 
|---|
 | 1618 |         " - sts0        vaddr = %x\n" | 
|---|
 | 1619 |         " - sts1        vaddr = %x\n", | 
|---|
| [440] | 1620 |         channel, | 
|---|
| [614] | 1621 |         (unsigned int)buf0_vbase, | 
|---|
 | 1622 |         (unsigned int)buf1_vbase, | 
|---|
 | 1623 |         (unsigned int)sts0_vaddr, | 
|---|
 | 1624 |         (unsigned int)sts1_vaddr ); | 
|---|
| [440] | 1625 | #endif | 
|---|
 | 1626 |  | 
|---|
| [614] | 1627 |     // checking user buffers virtual addresses alignment | 
|---|
 | 1628 |     if ( ((unsigned int)buf0_vbase & 0x3F) ||  | 
|---|
 | 1629 |          ((unsigned int)buf1_vbase & 0x3F) )  | 
|---|
| [440] | 1630 |     { | 
|---|
| [648] | 1631 |         _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : user buffer not aligned\n"); | 
|---|
| [440] | 1632 |         return -1; | 
|---|
 | 1633 |     } | 
|---|
 | 1634 |  | 
|---|
| [614] | 1635 |     // checking user buffers status virtual addresses alignment | 
|---|
 | 1636 |     if ( ((unsigned int)sts0_vaddr & 0x3F) || | 
|---|
 | 1637 |          ((unsigned int)sts1_vaddr & 0x3F) ) | 
|---|
 | 1638 |     { | 
|---|
| [648] | 1639 |         _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : user status not aligned\n"); | 
|---|
| [614] | 1640 |         return -1; | 
|---|
 | 1641 |     } | 
|---|
 | 1642 |  | 
|---|
| [440] | 1643 |     // compute frame buffer physical address and initialize _fbf_chbuf[channel] | 
|---|
| [528] | 1644 |     vaddr = (unsigned int)SEG_FBF_BASE; | 
|---|
| [614] | 1645 |     fbf_paddr = _v2p_translate( vaddr , &flags ); | 
|---|
 | 1646 |     vaddr = (unsigned int)&_fbf_status[channel]; | 
|---|
 | 1647 |     fbf_sts_paddr = _v2p_translate( vaddr , &flags ); | 
|---|
| [440] | 1648 |  | 
|---|
| [614] | 1649 |     _fbf_chbuf[channel].fbf_desc = | 
|---|
 | 1650 |         (unsigned long long) ((fbf_sts_paddr & 0xFFFFFFFFULL) >> 6) + | 
|---|
 | 1651 |         (((fbf_paddr & 0xFFFFFFFFULL) >> 6 ) << 26); | 
|---|
 | 1652 |  | 
|---|
| [528] | 1653 |     // Compute user buffer 0 physical addresses and intialize _fbf_chbuf[channel] | 
|---|
| [614] | 1654 |     vaddr = (unsigned int)buf0_vbase; | 
|---|
 | 1655 |     buf0_pbase = _v2p_translate( vaddr , &flags ); | 
|---|
| [440] | 1656 |     if ((flags & PTE_U) == 0)  | 
|---|
 | 1657 |     { | 
|---|
| [648] | 1658 |         _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : buf0 not in user space\n"); | 
|---|
| [440] | 1659 |         return -1; | 
|---|
 | 1660 |     } | 
|---|
 | 1661 |  | 
|---|
| [614] | 1662 |     vaddr = (unsigned int)sts0_vaddr; | 
|---|
 | 1663 |     sts0_paddr = _v2p_translate( vaddr , &flags ); | 
|---|
 | 1664 |     if ((flags & PTE_U) == 0)  | 
|---|
 | 1665 |     { | 
|---|
| [648] | 1666 |         _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : sts0 not in user space\n"); | 
|---|
| [614] | 1667 |         return -1; | 
|---|
 | 1668 |     } | 
|---|
 | 1669 |  | 
|---|
 | 1670 |     _fbf_chbuf[channel].buf0_desc =  | 
|---|
 | 1671 |         (unsigned long long) ((sts0_paddr & 0xFFFFFFFFULL) >> 6) + | 
|---|
 | 1672 |         (((buf0_pbase & 0xFFFFFFFFULL) >> 6 ) << 26); | 
|---|
 | 1673 |  | 
|---|
| [528] | 1674 |     // Compute user buffer 1 physical addresses and intialize _fbf_chbuf[channel] | 
|---|
| [614] | 1675 |     vaddr = (unsigned int)buf1_vbase; | 
|---|
 | 1676 |     buf1_pbase = _v2p_translate( vaddr , &flags ); | 
|---|
| [440] | 1677 |     if ((flags & PTE_U) == 0)  | 
|---|
 | 1678 |     { | 
|---|
| [648] | 1679 |         _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : buf1 not in user space\n"); | 
|---|
| [440] | 1680 |         return -1; | 
|---|
 | 1681 |     } | 
|---|
 | 1682 |  | 
|---|
| [614] | 1683 |     vaddr = (unsigned int)sts1_vaddr; | 
|---|
 | 1684 |     sts1_paddr = _v2p_translate( vaddr , &flags ); | 
|---|
 | 1685 |     if ((flags & PTE_U) == 0)  | 
|---|
 | 1686 |     { | 
|---|
| [648] | 1687 |         _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : sts1 not in user space\n"); | 
|---|
| [614] | 1688 |         return -1; | 
|---|
 | 1689 |     } | 
|---|
| [440] | 1690 |  | 
|---|
| [614] | 1691 |     _fbf_chbuf[channel].buf1_desc =  | 
|---|
 | 1692 |         (unsigned long long) ((sts1_paddr & 0xFFFFFFFFULL) >> 6) + | 
|---|
 | 1693 |         (((buf1_pbase & 0xFFFFFFFFULL) >> 6 ) << 26); | 
|---|
 | 1694 |  | 
|---|
| [505] | 1695 |     // Compute and register physical adress of the fbf_chbuf descriptor | 
|---|
| [528] | 1696 |     vaddr = (unsigned int)&_fbf_chbuf[channel]; | 
|---|
 | 1697 |     _fbf_chbuf_paddr[channel] = _v2p_translate( vaddr , &flags ); | 
|---|
| [440] | 1698 |   | 
|---|
| [614] | 1699 | #if GIET_DEBUG_FBF_CMA | 
|---|
 | 1700 | _printf(" - fbf         pbase = %l\n" | 
|---|
 | 1701 |         " - fbf status  paddr = %l\n" | 
|---|
 | 1702 |         " - buf0        pbase = %l\n" | 
|---|
 | 1703 |         " - buf0 status paddr = %l\n"  | 
|---|
 | 1704 |         " - buf1        pbase = %l\n" | 
|---|
 | 1705 |         " - buf0 status paddr = %l\n"  | 
|---|
 | 1706 |         " - chbuf       pbase = %l\n", | 
|---|
 | 1707 |         fbf_paddr, | 
|---|
 | 1708 |         fbf_sts_paddr, | 
|---|
 | 1709 |         buf0_pbase, | 
|---|
 | 1710 |         sts0_paddr, | 
|---|
 | 1711 |         buf1_pbase, | 
|---|
 | 1712 |         sts1_paddr, | 
|---|
 | 1713 |         _fbf_chbuf_paddr[channel] ); | 
|---|
 | 1714 | #endif | 
|---|
 | 1715 |  | 
|---|
 | 1716 |     return 0; | 
|---|
 | 1717 |  | 
|---|
 | 1718 | #else | 
|---|
 | 1719 |  | 
|---|
 | 1720 |     _printf("\n[GIET ERROR] in _sys_fbf_cma_init_buf() : NB_CMA_CHANNELS = 0\n"); | 
|---|
 | 1721 |     return -1; | 
|---|
 | 1722 |  | 
|---|
 | 1723 | #endif   | 
|---|
 | 1724 | } // end sys_fbf_cma_init_buf() | 
|---|
 | 1725 |  | 
|---|
 | 1726 | //////////////////////////////////////////// | 
|---|
 | 1727 | int _sys_fbf_cma_start( unsigned int length )  | 
|---|
 | 1728 | { | 
|---|
 | 1729 | #if NB_CMA_CHANNELS > 0 | 
|---|
 | 1730 |  | 
|---|
 | 1731 |     // get channel index | 
|---|
 | 1732 |     unsigned int channel = _get_context_slot( CTX_CMA_FB_ID ); | 
|---|
 | 1733 |  | 
|---|
 | 1734 |     if ( channel >= NB_CMA_CHANNELS ) | 
|---|
 | 1735 |     { | 
|---|
 | 1736 |         _printf("\n[GIET ERROR] in _fbf_cma_start() : CMA channel index too large\n"); | 
|---|
 | 1737 |         return -1; | 
|---|
 | 1738 |     } | 
|---|
 | 1739 |  | 
|---|
 | 1740 |     // check buffers initialization | 
|---|
 | 1741 |     if ( ( _fbf_chbuf[channel].buf0_desc == 0x0ULL ) && | 
|---|
 | 1742 |          ( _fbf_chbuf[channel].buf1_desc == 0x0ULL) && | 
|---|
 | 1743 |          ( _fbf_chbuf[channel].fbf_desc == 0x0ULL) ) | 
|---|
 | 1744 |     { | 
|---|
 | 1745 |         _printf("\n[GIET ERROR] in _sys_fbf_cma_start() :\n" | 
|---|
 | 1746 |                 "Buffer initialization has not been done\n"); | 
|---|
 | 1747 |         return -1; | 
|---|
 | 1748 |     } | 
|---|
 | 1749 |  | 
|---|
 | 1750 |     // initializes buffer length | 
|---|
 | 1751 |     _fbf_chbuf[channel].length = length; | 
|---|
 | 1752 |  | 
|---|
| [440] | 1753 |     if ( USE_IOB ) | 
|---|
 | 1754 |     { | 
|---|
| [505] | 1755 |         // SYNC request for fbf_chbuf descriptor | 
|---|
 | 1756 |         _mmc_sync( _fbf_chbuf_paddr[channel] , sizeof( fbf_chbuf_t ) ); | 
|---|
| [440] | 1757 |     } | 
|---|
 | 1758 |  | 
|---|
| [505] | 1759 |     // start CMA transfer | 
|---|
 | 1760 |     unsigned long long paddr = _fbf_chbuf_paddr[channel]; | 
|---|
 | 1761 |     unsigned int src_chbuf_paddr_lsb = (unsigned int)(paddr & 0xFFFFFFFF); | 
|---|
 | 1762 |     unsigned int src_chbuf_paddr_ext = (unsigned int)(paddr >> 32); | 
|---|
| [614] | 1763 |     unsigned int dst_chbuf_paddr_lsb = src_chbuf_paddr_lsb + 16; | 
|---|
| [505] | 1764 |     unsigned int dst_chbuf_paddr_ext = src_chbuf_paddr_ext; | 
|---|
 | 1765 |  | 
|---|
 | 1766 |     _cma_set_register( channel, CHBUF_SRC_DESC , src_chbuf_paddr_lsb ); | 
|---|
 | 1767 |     _cma_set_register( channel, CHBUF_SRC_EXT  , src_chbuf_paddr_ext ); | 
|---|
 | 1768 |     _cma_set_register( channel, CHBUF_SRC_NBUFS, 2 ); | 
|---|
 | 1769 |     _cma_set_register( channel, CHBUF_DST_DESC , dst_chbuf_paddr_lsb ); | 
|---|
 | 1770 |     _cma_set_register( channel, CHBUF_DST_EXT  , dst_chbuf_paddr_ext ); | 
|---|
 | 1771 |     _cma_set_register( channel, CHBUF_DST_NBUFS, 1 ); | 
|---|
 | 1772 |     _cma_set_register( channel, CHBUF_BUF_SIZE , length ); | 
|---|
 | 1773 |     _cma_set_register( channel, CHBUF_PERIOD   , 300 ); | 
|---|
 | 1774 |     _cma_set_register( channel, CHBUF_RUN      , 1 ); | 
|---|
 | 1775 |  | 
|---|
| [440] | 1776 |     return 0; | 
|---|
 | 1777 |  | 
|---|
 | 1778 | #else | 
|---|
 | 1779 |  | 
|---|
 | 1780 |     _printf("\n[GIET ERROR] in _sys_fbf_cma_start() : NB_CMA_CHANNELS = 0\n"); | 
|---|
 | 1781 |     return -1; | 
|---|
 | 1782 |  | 
|---|
 | 1783 | #endif | 
|---|
 | 1784 | } // end _sys_fbf_cma_start() | 
|---|
 | 1785 |  | 
|---|
 | 1786 | ///////////////////////////////////////////////////// | 
|---|
 | 1787 | int _sys_fbf_cma_display( unsigned int buffer_index ) | 
|---|
 | 1788 | { | 
|---|
 | 1789 | #if NB_CMA_CHANNELS > 0 | 
|---|
 | 1790 |  | 
|---|
| [505] | 1791 |     volatile unsigned int full = 1; | 
|---|
| [440] | 1792 |  | 
|---|
 | 1793 |     // get channel index | 
|---|
| [449] | 1794 |     unsigned int channel = _get_context_slot( CTX_CMA_FB_ID ); | 
|---|
| [440] | 1795 |  | 
|---|
 | 1796 |     if ( channel >= NB_CMA_CHANNELS ) | 
|---|
 | 1797 |     { | 
|---|
| [505] | 1798 |         _printf("\n[GIET ERROR] in _sys_fbf_cma_display() : " | 
|---|
 | 1799 |                 "CMA channel index too large\n"); | 
|---|
| [440] | 1800 |         return -1; | 
|---|
 | 1801 |     } | 
|---|
 | 1802 |  | 
|---|
| [505] | 1803 |     // get fbf_chbuf descriptor pointer | 
|---|
 | 1804 |     fbf_chbuf_t* pdesc = &_fbf_chbuf[channel];      | 
|---|
 | 1805 |  | 
|---|
| [440] | 1806 | #if GIET_DEBUG_FBF_CMA | 
|---|
 | 1807 | _printf("\n[FBF_CMA DEBUG] enters _sys_fb_cma_display()\n" | 
|---|
| [614] | 1808 |         " - cma channel      = %d\n" | 
|---|
 | 1809 |         " - buffer index     = %d\n" | 
|---|
 | 1810 |         " - buf0_desc value  = %l\n" | 
|---|
 | 1811 |         " - buf1_desc value  = %l\n" | 
|---|
 | 1812 |         " - fbf_desc  value  = %l\n", | 
|---|
| [505] | 1813 |         channel , buffer_index, | 
|---|
| [614] | 1814 |         _fbf_chbuf[channel].buf0_desc, | 
|---|
 | 1815 |         _fbf_chbuf[channel].buf1_desc, | 
|---|
 | 1816 |         _fbf_chbuf[channel].fbf_desc ); | 
|---|
| [440] | 1817 | #endif | 
|---|
 | 1818 |  | 
|---|
| [614] | 1819 |     unsigned long long buf_sts_paddr; | 
|---|
 | 1820 |     unsigned long long buf_paddr; | 
|---|
 | 1821 |     unsigned long long fbf_sts_paddr; | 
|---|
 | 1822 |  | 
|---|
| [478] | 1823 |     if ( buffer_index == 0 )    // user buffer 0 | 
|---|
 | 1824 |     { | 
|---|
| [614] | 1825 |         buf_sts_paddr = | 
|---|
 | 1826 |             ((pdesc->buf0_desc & 0xFFF0000000000000ULL) >> 20) + // compute address extension | 
|---|
 | 1827 |             ((pdesc->buf0_desc & 0x3FFFFFFULL) << 6);            // compute 32 LSB of the address | 
|---|
| [505] | 1828 |  | 
|---|
| [614] | 1829 |         buf_paddr = | 
|---|
 | 1830 |             (pdesc->buf0_desc & 0xFFFFFFFFFC000000ULL) >> 20;  // compute the entire address | 
|---|
| [440] | 1831 |     } | 
|---|
| [478] | 1832 |     else                        // user buffer 1 | 
|---|
 | 1833 |     { | 
|---|
| [614] | 1834 |         buf_sts_paddr = | 
|---|
 | 1835 |             ((pdesc->buf1_desc & 0xFFF0000000000000ULL) >> 20) + | 
|---|
 | 1836 |             ((pdesc->buf1_desc & 0x3FFFFFFULL) << 6); | 
|---|
| [505] | 1837 |  | 
|---|
| [614] | 1838 |         buf_paddr = | 
|---|
 | 1839 |             (pdesc->buf1_desc & 0xFFFFFFFFFC000000ULL) >> 20; | 
|---|
 | 1840 |     } | 
|---|
| [478] | 1841 |  | 
|---|
| [614] | 1842 |     fbf_sts_paddr = | 
|---|
 | 1843 |         ((pdesc->fbf_desc & 0xFFF0000000000000ULL) >> 20) + | 
|---|
 | 1844 |         ((pdesc->fbf_desc & 0x3FFFFFFULL) << 6); | 
|---|
| [440] | 1845 |  | 
|---|
| [614] | 1846 | #if GIET_DEBUG_FBF_CMA | 
|---|
 | 1847 | _printf(" - fbf status paddr = %l\n" | 
|---|
 | 1848 |         " - buf        pbase = %l\n" | 
|---|
 | 1849 |         " - buf status paddr = %l\n", | 
|---|
 | 1850 |         fbf_sts_paddr, | 
|---|
 | 1851 |         buf_paddr, | 
|---|
 | 1852 |         buf_sts_paddr ); | 
|---|
 | 1853 | #endif | 
|---|
 | 1854 |          | 
|---|
 | 1855 |     // waiting user buffer released by the CMA component) | 
|---|
 | 1856 |     while ( full ) | 
|---|
 | 1857 |     {   | 
|---|
| [648] | 1858 |         // INVAL L2 cache copy of user buffer status      | 
|---|
| [614] | 1859 |         // because it has been modified in RAM by the CMA component  | 
|---|
 | 1860 |         _mmc_inval( buf_sts_paddr , 4 );         | 
|---|
| [440] | 1861 |  | 
|---|
| [614] | 1862 |         full = _physical_read( buf_sts_paddr ); | 
|---|
| [440] | 1863 |     } | 
|---|
 | 1864 |  | 
|---|
| [614] | 1865 |     // SYNC request for the user buffer, because  | 
|---|
 | 1866 |     // it will be read from XRAM by the CMA component | 
|---|
 | 1867 |     _mmc_sync( buf_paddr , pdesc->length ); | 
|---|
| [440] | 1868 |  | 
|---|
| [614] | 1869 |     // set user buffer status | 
|---|
 | 1870 |     _physical_write( buf_sts_paddr, 0x1 ); | 
|---|
 | 1871 |  | 
|---|
 | 1872 |     // reset fbf buffer status | 
|---|
 | 1873 |     _physical_write( fbf_sts_paddr, 0x0 ); | 
|---|
 | 1874 |      | 
|---|
 | 1875 |     // SYNC request, because these buffer descriptors | 
|---|
 | 1876 |     // will be read from XRAM by the CMA component | 
|---|
 | 1877 |     _mmc_sync( buf_sts_paddr, 4 ); | 
|---|
 | 1878 |     _mmc_sync( fbf_sts_paddr, 4 ); | 
|---|
 | 1879 |  | 
|---|
| [440] | 1880 |     return 0; | 
|---|
 | 1881 |  | 
|---|
 | 1882 | #else | 
|---|
 | 1883 |  | 
|---|
 | 1884 |     _printf("\n[GIET ERROR] in _sys_fbf_cma_display() : no CMA channel allocated\n"); | 
|---|
 | 1885 |     return -1; | 
|---|
 | 1886 |  | 
|---|
 | 1887 | #endif | 
|---|
 | 1888 | } // end _sys_fbf_cma_display() | 
|---|
 | 1889 |  | 
|---|
 | 1890 | /////////////////////// | 
|---|
 | 1891 | int _sys_fbf_cma_stop() | 
|---|
 | 1892 | { | 
|---|
 | 1893 | #if NB_CMA_CHANNELS > 0 | 
|---|
 | 1894 |  | 
|---|
 | 1895 |     // get channel index | 
|---|
| [449] | 1896 |     unsigned int channel = _get_context_slot( CTX_CMA_FB_ID ); | 
|---|
| [440] | 1897 |  | 
|---|
 | 1898 |     if ( channel >= NB_CMA_CHANNELS ) | 
|---|
 | 1899 |     { | 
|---|
 | 1900 |         _printf("\n[GIET ERROR] in _sys_fbf_cma_stop() : CMA channel index too large\n"); | 
|---|
 | 1901 |         return -1; | 
|---|
 | 1902 |     } | 
|---|
 | 1903 |  | 
|---|
 | 1904 |     // Desactivate CMA channel | 
|---|
| [505] | 1905 |     _cma_set_register( channel, CHBUF_RUN, 0 ); | 
|---|
| [440] | 1906 |  | 
|---|
 | 1907 |     return 0; | 
|---|
 | 1908 |  | 
|---|
 | 1909 | #else | 
|---|
 | 1910 |  | 
|---|
 | 1911 |     _printf("\n[GIET ERROR] in _sys_fbf_cma_stop() : no CMA channel allocated\n"); | 
|---|
 | 1912 |     return -1; | 
|---|
 | 1913 |  | 
|---|
 | 1914 | #endif | 
|---|
 | 1915 | } // end _sys_fbf_cma_stop() | 
|---|
 | 1916 |  | 
|---|
 | 1917 |  | 
|---|
 | 1918 | ////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 1919 | //           Miscelaneous syscall handlers  | 
|---|
 | 1920 | ////////////////////////////////////////////////////////////////////////////// | 
|---|
 | 1921 |  | 
|---|
 | 1922 | /////////////// | 
|---|
 | 1923 | int _sys_ukn()  | 
|---|
 | 1924 | { | 
|---|
 | 1925 |     _printf("\n[GIET ERROR] Undefined System Call / EPC = %x\n", _get_epc() ); | 
|---|
 | 1926 |     return -1; | 
|---|
 | 1927 | } | 
|---|
 | 1928 |  | 
|---|
 | 1929 | //////////////////////////////////// | 
|---|
 | 1930 | int _sys_proc_xyp( unsigned int* x, | 
|---|
 | 1931 |                    unsigned int* y, | 
|---|
 | 1932 |                    unsigned int* p ) | 
|---|
 | 1933 | { | 
|---|
| [428] | 1934 |     unsigned int gpid = _get_procid();  // global processor index from CPO register | 
|---|
 | 1935 |  | 
|---|
 | 1936 |     *x = (gpid >> (Y_WIDTH + P_WIDTH)) & ((1<<X_WIDTH)-1); | 
|---|
 | 1937 |     *y = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1); | 
|---|
 | 1938 |     *p = gpid & ((1<<P_WIDTH)-1); | 
|---|
| [440] | 1939 |  | 
|---|
 | 1940 |     return 0; | 
|---|
| [428] | 1941 | } | 
|---|
| [440] | 1942 |  | 
|---|
 | 1943 | ////////////////////////////////// | 
|---|
 | 1944 | int _sys_task_exit( char* string )  | 
|---|
| [258] | 1945 | { | 
|---|
| [294] | 1946 |     unsigned int date       = _get_proctime(); | 
|---|
| [428] | 1947 |  | 
|---|
 | 1948 |     unsigned int gpid       = _get_procid(); | 
|---|
 | 1949 |     unsigned int cluster_xy = gpid >> P_WIDTH; | 
|---|
| [294] | 1950 |     unsigned int y          = cluster_xy & ((1<<Y_WIDTH)-1); | 
|---|
 | 1951 |     unsigned int x          = cluster_xy >> Y_WIDTH; | 
|---|
| [629] | 1952 |     unsigned int p          = gpid & ((1<<P_WIDTH)-1); | 
|---|
| [428] | 1953 |  | 
|---|
| [629] | 1954 |     unsigned int ltid       = _get_context_slot(CTX_LTID_ID); | 
|---|
| [258] | 1955 |  | 
|---|
| [440] | 1956 |     // print exit message | 
|---|
| [294] | 1957 |     _printf("\n[GIET] Exit task %d on processor[%d,%d,%d] at cycle %d" | 
|---|
 | 1958 |             "\n       Cause : %s\n\n", | 
|---|
| [629] | 1959 |             ltid, x, y, p, date, string ); | 
|---|
| [258] | 1960 |  | 
|---|
| [629] | 1961 |     // set NORUN_MASK_TASK bit (non runnable state) | 
|---|
 | 1962 |     static_scheduler_t*  psched  = (static_scheduler_t*)_schedulers[x][y][p]; | 
|---|
 | 1963 |     unsigned int*        ptr     = &psched->context[ltid][CTX_NORUN_ID]; | 
|---|
 | 1964 |     _atomic_or( ptr , NORUN_MASK_TASK ); | 
|---|
| [258] | 1965 |  | 
|---|
 | 1966 |     // deschedule | 
|---|
| [528] | 1967 |     _sys_context_switch(); | 
|---|
| [440] | 1968 |  | 
|---|
 | 1969 |     return 0; | 
|---|
| [258] | 1970 | }  | 
|---|
 | 1971 |  | 
|---|
| [528] | 1972 | ///////////////////////// | 
|---|
 | 1973 | int _sys_context_switch()  | 
|---|
| [258] | 1974 | { | 
|---|
| [440] | 1975 |     unsigned int save_sr; | 
|---|
| [258] | 1976 |  | 
|---|
| [440] | 1977 |     _it_disable( &save_sr ); | 
|---|
 | 1978 |     _ctx_switch(); | 
|---|
 | 1979 |     _it_restore( &save_sr ); | 
|---|
 | 1980 |  | 
|---|
 | 1981 |     return 0; | 
|---|
| [258] | 1982 | } | 
|---|
 | 1983 |  | 
|---|
| [440] | 1984 | //////////////////////// | 
|---|
 | 1985 | int _sys_local_task_id() | 
|---|
| [258] | 1986 | { | 
|---|
 | 1987 |     return _get_context_slot(CTX_LTID_ID); | 
|---|
 | 1988 | } | 
|---|
 | 1989 |  | 
|---|
| [440] | 1990 | ///////////////////////// | 
|---|
 | 1991 | int _sys_global_task_id() | 
|---|
| [258] | 1992 | { | 
|---|
 | 1993 |     return _get_context_slot(CTX_GTID_ID); | 
|---|
 | 1994 | } | 
|---|
 | 1995 |  | 
|---|
| [440] | 1996 | //////////////////// | 
|---|
 | 1997 | int _sys_thread_id() | 
|---|
| [267] | 1998 | { | 
|---|
 | 1999 |     return _get_context_slot(CTX_TRDID_ID); | 
|---|
 | 2000 | } | 
|---|
 | 2001 |  | 
|---|
| [494] | 2002 | //////////////////////////////////////////// | 
|---|
 | 2003 | int _sys_procs_number( unsigned int* x_size, | 
|---|
 | 2004 |                        unsigned int* y_size, | 
|---|
 | 2005 |                        unsigned int* nprocs ) | 
|---|
| [258] | 2006 | { | 
|---|
| [494] | 2007 |     mapping_header_t * header   = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; | 
|---|
| [440] | 2008 |     mapping_cluster_t * cluster = _get_cluster_base(header); | 
|---|
 | 2009 |  | 
|---|
| [494] | 2010 |     unsigned int x; | 
|---|
 | 2011 |     unsigned int y; | 
|---|
 | 2012 |     unsigned int okmin = 1; | 
|---|
 | 2013 |     unsigned int okmax = 1; | 
|---|
 | 2014 |  | 
|---|
 | 2015 |     // compute max values | 
|---|
 | 2016 |     unsigned int xmax  = header->x_size; | 
|---|
 | 2017 |     unsigned int ymax  = header->y_size; | 
|---|
 | 2018 |     unsigned int procs = cluster[0].procs; | 
|---|
 | 2019 |  | 
|---|
 | 2020 |     // check the (ymax-1) lower rows | 
|---|
 | 2021 |     for ( y = 0 ; y < ymax-1 ; y++ ) | 
|---|
| [440] | 2022 |     { | 
|---|
| [494] | 2023 |         for ( x = 0 ; x < xmax ; x++ ) | 
|---|
 | 2024 |         { | 
|---|
 | 2025 |             if (cluster[x*ymax+y].procs != procs ) okmin = 0; | 
|---|
 | 2026 |         } | 
|---|
| [440] | 2027 |     } | 
|---|
| [494] | 2028 |  | 
|---|
 | 2029 |     // check the upper row | 
|---|
 | 2030 |     for ( x = 0 ; x < xmax ; x++ ) | 
|---|
| [440] | 2031 |     { | 
|---|
| [494] | 2032 |         if (cluster[x*ymax+ymax-1].procs != procs ) okmax = 0; | 
|---|
| [440] | 2033 |     } | 
|---|
| [494] | 2034 |  | 
|---|
 | 2035 |     // return values | 
|---|
 | 2036 |     if ( okmin && okmax ) | 
|---|
 | 2037 |     { | 
|---|
 | 2038 |         *x_size = xmax; | 
|---|
 | 2039 |         *y_size = ymax; | 
|---|
 | 2040 |         *nprocs = procs; | 
|---|
 | 2041 |     } | 
|---|
 | 2042 |     else if ( okmin ) | 
|---|
 | 2043 |     { | 
|---|
 | 2044 |         *x_size = xmax; | 
|---|
 | 2045 |         *y_size = ymax-1; | 
|---|
 | 2046 |         *nprocs = procs; | 
|---|
 | 2047 |     } | 
|---|
 | 2048 |     else | 
|---|
 | 2049 |     { | 
|---|
 | 2050 |         *x_size = 0; | 
|---|
 | 2051 |         *y_size = 0; | 
|---|
 | 2052 |         *nprocs = 0; | 
|---|
 | 2053 |     } | 
|---|
 | 2054 |     return 0; | 
|---|
| [440] | 2055 | } | 
|---|
 | 2056 |  | 
|---|
 | 2057 | /////////////////////////////////////////////////////// | 
|---|
| [516] | 2058 | int _sys_vseg_get_vbase( char*             vspace_name,  | 
|---|
 | 2059 |                          char*             vseg_name,  | 
|---|
| [440] | 2060 |                          unsigned int*     vbase )  | 
|---|
 | 2061 | { | 
|---|
| [322] | 2062 |     mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; | 
|---|
| [258] | 2063 |     mapping_vspace_t * vspace = _get_vspace_base(header); | 
|---|
| [516] | 2064 |     mapping_vseg_t * vseg     = _get_vseg_base(header); | 
|---|
| [258] | 2065 |  | 
|---|
 | 2066 |     unsigned int vspace_id; | 
|---|
| [516] | 2067 |     unsigned int vseg_id; | 
|---|
| [258] | 2068 |  | 
|---|
 | 2069 |     // scan vspaces  | 
|---|
 | 2070 |     for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++)  | 
|---|
 | 2071 |     { | 
|---|
 | 2072 |         if (_strncmp( vspace[vspace_id].name, vspace_name, 31) == 0)  | 
|---|
 | 2073 |         { | 
|---|
| [516] | 2074 |             // scan vsegs | 
|---|
 | 2075 |             for (vseg_id = vspace[vspace_id].vseg_offset;  | 
|---|
 | 2076 |                  vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs);  | 
|---|
 | 2077 |                  vseg_id++)  | 
|---|
| [258] | 2078 |             { | 
|---|
| [516] | 2079 |                 if (_strncmp(vseg[vseg_id].name, vseg_name, 31) == 0)  | 
|---|
| [258] | 2080 |                 { | 
|---|
| [516] | 2081 |                     *vbase = vseg[vseg_id].vbase; | 
|---|
| [258] | 2082 |                     return 0; | 
|---|
 | 2083 |                 } | 
|---|
 | 2084 |             }  | 
|---|
 | 2085 |         } | 
|---|
 | 2086 |     }  | 
|---|
| [440] | 2087 |     return -1;    // not found  | 
|---|
| [258] | 2088 | } | 
|---|
 | 2089 |  | 
|---|
| [440] | 2090 | ///////////////////////////////////////////////////////// | 
|---|
| [516] | 2091 | int _sys_vseg_get_length( char*         vspace_name,  | 
|---|
 | 2092 |                           char*         vseg_name, | 
|---|
| [440] | 2093 |                           unsigned int* length )  | 
|---|
| [258] | 2094 | { | 
|---|
| [440] | 2095 |     mapping_header_t * header = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; | 
|---|
 | 2096 |     mapping_vspace_t * vspace = _get_vspace_base(header); | 
|---|
| [516] | 2097 |     mapping_vseg_t * vseg     = _get_vseg_base(header); | 
|---|
| [258] | 2098 |  | 
|---|
| [440] | 2099 |     unsigned int vspace_id; | 
|---|
| [516] | 2100 |     unsigned int vseg_id; | 
|---|
| [440] | 2101 |  | 
|---|
 | 2102 |     // scan vspaces  | 
|---|
 | 2103 |     for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++)  | 
|---|
| [258] | 2104 |     { | 
|---|
| [440] | 2105 |         if (_strncmp( vspace[vspace_id].name, vspace_name, 31) == 0)  | 
|---|
 | 2106 |         { | 
|---|
| [516] | 2107 |             // scan vsegs | 
|---|
 | 2108 |             for (vseg_id = vspace[vspace_id].vseg_offset;  | 
|---|
 | 2109 |                  vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs);  | 
|---|
 | 2110 |                  vseg_id++)  | 
|---|
| [440] | 2111 |             { | 
|---|
| [516] | 2112 |                 if (_strncmp(vseg[vseg_id].name, vseg_name, 31) == 0)  | 
|---|
| [440] | 2113 |                 { | 
|---|
| [516] | 2114 |                     *length = vseg[vseg_id].length; | 
|---|
| [440] | 2115 |                     return 0; | 
|---|
 | 2116 |                 } | 
|---|
 | 2117 |             }  | 
|---|
 | 2118 |         } | 
|---|
 | 2119 |     }  | 
|---|
 | 2120 |     return -1;    // not found  | 
|---|
| [258] | 2121 | } | 
|---|
 | 2122 |  | 
|---|
| [440] | 2123 | //////////////////////////////////////// | 
|---|
 | 2124 | int _sys_xy_from_ptr( void*         ptr, | 
|---|
 | 2125 |                       unsigned int* x, | 
|---|
 | 2126 |                       unsigned int* y ) | 
|---|
| [396] | 2127 | { | 
|---|
 | 2128 |     unsigned int flags; | 
|---|
| [528] | 2129 |     unsigned long long paddr = _v2p_translate( (unsigned int)ptr , &flags ); | 
|---|
| [396] | 2130 |      | 
|---|
| [528] | 2131 |     *x = (paddr>>36) & 0xF; | 
|---|
 | 2132 |     *y = (paddr>>32) & 0xF; | 
|---|
| [396] | 2133 |  | 
|---|
 | 2134 |     return 0; | 
|---|
 | 2135 | } | 
|---|
 | 2136 |  | 
|---|
| [440] | 2137 | ///////////////////////////////////////// | 
|---|
 | 2138 | int _sys_heap_info( unsigned int* vaddr,  | 
|---|
 | 2139 |                     unsigned int* length, | 
|---|
 | 2140 |                     unsigned int  x, | 
|---|
 | 2141 |                     unsigned int  y )  | 
|---|
| [258] | 2142 | { | 
|---|
| [440] | 2143 |     mapping_header_t * header  = (mapping_header_t *)SEG_BOOT_MAPPING_BASE; | 
|---|
| [516] | 2144 |     mapping_task_t *   task    = _get_task_base(header); | 
|---|
 | 2145 |     mapping_vseg_t *   vseg    = _get_vseg_base(header); | 
|---|
 | 2146 |     mapping_vspace_t * vspace  = _get_vspace_base(header); | 
|---|
| [294] | 2147 |  | 
|---|
| [440] | 2148 |     unsigned int task_id; | 
|---|
 | 2149 |     unsigned int vspace_id; | 
|---|
| [516] | 2150 |     unsigned int vseg_id = 0xFFFFFFFF; | 
|---|
| [258] | 2151 |  | 
|---|
| [516] | 2152 |     // searching the heap vseg | 
|---|
| [440] | 2153 |     if ( (x < X_SIZE) && (y < Y_SIZE) )  // searching a task in cluster(x,y) | 
|---|
 | 2154 |     { | 
|---|
 | 2155 |         // get vspace global index | 
|---|
 | 2156 |         vspace_id = _get_context_slot(CTX_VSID_ID); | 
|---|
 | 2157 |  | 
|---|
 | 2158 |         // scan all tasks in vspace | 
|---|
| [516] | 2159 |         unsigned int min = vspace[vspace_id].task_offset ; | 
|---|
 | 2160 |         unsigned int max = min + vspace[vspace_id].tasks ; | 
|---|
| [440] | 2161 |         for ( task_id = min ; task_id < max ; task_id++ ) | 
|---|
 | 2162 |         { | 
|---|
| [516] | 2163 |             if ( task[task_id].clusterid == (x * Y_SIZE + y) ) | 
|---|
| [440] | 2164 |             { | 
|---|
| [516] | 2165 |                 vseg_id = task[task_id].heap_vseg_id; | 
|---|
 | 2166 |                 if ( vseg_id != 0xFFFFFFFF ) break; | 
|---|
| [440] | 2167 |             } | 
|---|
 | 2168 |         } | 
|---|
 | 2169 |     } | 
|---|
 | 2170 |     else                                // searching in the calling task  | 
|---|
 | 2171 |     { | 
|---|
 | 2172 |         task_id = _get_context_slot(CTX_GTID_ID); | 
|---|
| [516] | 2173 |         vseg_id = task[task_id].heap_vseg_id; | 
|---|
| [440] | 2174 |     } | 
|---|
 | 2175 |  | 
|---|
| [516] | 2176 |     // analysing the vseg_id | 
|---|
 | 2177 |     if ( vseg_id != 0xFFFFFFFF )  | 
|---|
| [440] | 2178 |     { | 
|---|
| [516] | 2179 |         *vaddr  = vseg[vseg_id].vbase; | 
|---|
 | 2180 |         *length = vseg[vseg_id].length; | 
|---|
| [440] | 2181 |         return 0; | 
|---|
 | 2182 |     } | 
|---|
 | 2183 |     else  | 
|---|
 | 2184 |     { | 
|---|
 | 2185 |         *vaddr  = 0; | 
|---|
 | 2186 |         *length = 0; | 
|---|
 | 2187 |         return -1; | 
|---|
 | 2188 |     } | 
|---|
 | 2189 | }  // end _sys_heap_info() | 
|---|
 | 2190 |  | 
|---|
 | 2191 |  | 
|---|
| [258] | 2192 | // Local Variables: | 
|---|
 | 2193 | // tab-width: 4 | 
|---|
 | 2194 | // c-basic-offset: 4 | 
|---|
 | 2195 | // c-file-offsets:((innamespace . 0)(inline-open . 0)) | 
|---|
 | 2196 | // indent-tabs-mode: nil | 
|---|
 | 2197 | // End: | 
|---|
 | 2198 | // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 | 
|---|
 | 2199 |  | 
|---|