Changeset 238 for soft/giet_vm/sys/drivers.c
- Timestamp:
- May 29, 2013, 1:24:09 AM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/sys/drivers.c
r237 r238 1 1 /////////////////////////////////////////////////////////////////////////////////// 2 2 // File : drivers.c 3 // Date : 01/04/20123 // Date : 23/05/2013 4 4 // Author : alain greiner 5 5 // Copyright (c) UPMC-LIP6 … … 16 16 // - vci_block_device 17 17 // 18 // The following global parameters must be defined in the giet_config.h file: 19 // - CLUSTER_SIZE 18 // For the peripherals replicated in each cluster (ICU, TIMER, DMA), 19 // the corresponding (virtual) base addresses must be completed by an offset 20 // depending on the cluster index. 21 // 22 // The following global parameter must be defined in the giet_config.h file: 23 // - GIET_CLUSTER_INCREMENT 24 // 25 // The following global parameters must be defined in the hard_config.h file: 20 26 // - NB_CLUSTERS 21 27 // - NB_PROCS_MAX 22 // - NB_TIM ERS_MAX23 // - NB_DMA S_MAX24 // - NB_TTY S28 // - NB_TIM_CHANNELS 29 // - NB_DMA_CHANNELS 30 // - NB_TTY_CHANNELS_MAX 25 31 // 26 32 // The following virtual base addresses must be defined in the giet_vsegs.ld file: 27 33 // - seg_icu_base 28 34 // - seg_tim_base 35 // - seg_dma_base 29 36 // - seg_tty_base 30 37 // - seg_gcd_base 31 // - seg_dma_base32 38 // - seg_fbf_base 33 39 // - seg_ioc_base 34 40 // - seg_nic_base 35 // As some peripherals can be replicated in the clusters (ICU, TIMER, DMA)36 // These addresses must be completed by an offset depending on the cluster index37 // full_base_address = seg_***_base + cluster_id * CLUSTER_SIZE41 // - seg_cma_base 42 // - seg_iob_base 43 // 38 44 /////////////////////////////////////////////////////////////////////////////////// 39 45 … … 48 54 49 55 #if !defined(NB_CLUSTERS) 50 # error: You must define NB_CLUSTERS in the configsfile56 # error: You must define NB_CLUSTERS in the hard_config.h file 51 57 #endif 52 58 53 59 #if !defined(NB_PROCS_MAX) 54 # error: You must define NB_PROCS_MAX in the configsfile60 # error: You must define NB_PROCS_MAX in the hard_config.h file 55 61 #endif 56 62 … … 59 65 #endif 60 66 61 #if !defined(CLUSTER_SIZE) 62 # error: You must define CLUSTER_SIZE in the configs file 63 #endif 64 65 #if !defined(NB_TTYS) 66 # error: You must define NB_TTYS in the configs file 67 #endif 68 69 #if (NB_TTYS < 1) 70 # error: NB_TTYS cannot be smaller than 1! 71 #endif 72 73 #if !defined(NB_DMAS_MAX) 74 #define NB_DMAS_MAX 0 75 #endif 76 77 #if !defined(NB_TIMERS_MAX) 78 #define NB_TIMERS_MAX 0 79 #endif 80 81 #if ( (NB_TIMERS_MAX) > 32 ) 82 # error: NB_TIMERS_MAX + NB_PROCS_MAX cannot be larger than 32 83 #endif 84 85 #if !defined(NB_IOCS) 86 # error: You must define NB_IOCS in the configs file 87 #endif 88 89 #if ( NB_IOCS > 1 ) 90 # error: NB_IOCS cannot be larger than 1 67 #if !defined(GIET_CLUSTER_INCREMENT) 68 # error: You must define GIET_CLUSTER_INCREMENT in the giet_config.h file 69 #endif 70 71 #if !defined(NB_TTY_CHANNELS) 72 # error: You must define NB_TTY_CHANNELS in the hard_config.h file 73 #endif 74 75 #if (NB_TTY_CHANNELS < 1) 76 # error: NB_TTY_CHANNELS cannot be smaller than 1! 77 #endif 78 79 #if !defined(NB_DMA_CHANNELS) 80 # error: You must define NB_DMA_CHANNELS in the hard_config.h file 81 #endif 82 83 #if (NB_DMA_CHANNELS > 8) 84 # error: NB_DMA_CHANNELS cannot be smaller than 8! 85 #endif 86 87 #if !defined(NB_TIM_CHANNELS) 88 #define NB_TIM_CHANNELS 0 89 #endif 90 91 #if ( (NB_TIM_CHANNELS + NB_PROC_MAX) > 32 ) 92 # error: NB_TIM_CHANNELS + NB_PROCS_MAX cannot be larger than 32 93 #endif 94 95 #if !defined(NB_IOC_CHANNELS) 96 # error: You must define NB_IOC_CHANNELS in the hard_config.h file 97 #endif 98 99 #if ( NB_IOC_CHANNELS > 8 ) 100 # error: NB_IOC_CHANNELS cannot be larger than 8 101 #endif 102 103 #if !defined(NB_NIC_CHANNELS) 104 # error: You must define NB_NIC_CHANNELS in the hard_config.h file 105 #endif 106 107 #if ( NB_NIC_CHANNELS > 8 ) 108 # error: NB_NIC_CHANNELS cannot be larger than 8 109 #endif 110 111 #if !defined(NB_CMA_CHANNELS) 112 # error: You must define NB_CMA_CHANNELS in the hard_config.h file 113 #endif 114 115 #if ( NB_CMA_CHANNELS > 8 ) 116 # error: NB_CMA_CHANNELS cannot be larger than 8 91 117 #endif 92 118 93 119 #if !defined( USE_XICU ) 94 # error: You must define USE_XICU in the configsfile120 # error: You must define USE_XICU in the hard_config.h file 95 121 #endif 96 122 97 123 #if !defined( IOMMU_ACTIVE ) 98 # error: You must define IOMMU_ACTIVE in the configsfile124 # error: You must define IOMMU_ACTIVE in the hard_config.h file 99 125 #endif 100 126 … … 105 131 // Timers driver 106 132 ////////////////////////////////////////////////////////////////////////////// 133 // This peripheral is replicated in all clusters. 107 134 // The timers can be implemented in a vci_timer component or in a vci_xicu 108 135 // component (depending on the USE_XICU parameter). … … 113 140 // - "user" timers : requested by the task in the mapping_info data structure. 114 141 // For each user timer, the timer_id is stored in the context of the task. 115 // The global index is cluster_id * (NB_PROCS_MAX+NB_TIM ERS_MAX) + local_id142 // The global index is cluster_id * (NB_PROCS_MAX+NB_TIM_CHANNELS) + local_id 116 143 ////////////////////////////////////////////////////////////////////////////// 144 // The (virtual) base address of the associated segment is: 145 // 146 // timer_address = seg_icu_base + cluster_id * GIET_CLUSTER_INCREMENT 147 // 148 // - cluster id is an explicit argument of all access functions 149 // - seg_icu_base must be defined in the giet_vsegs.ld file 150 // - GIET_CLUSTER_INCREMENT must be defined in the giet_config.h file 151 //////////////////////////////////////////////////////////////////////////////// 117 152 118 153 // User Timer signaling variables 119 154 120 #if (NB_TIM ERS_MAX> 0)121 in_unckdata volatile unsigned char _user_timer_event[NB_CLUSTERS * NB_TIM ERS_MAX]122 = { [0 ... ((NB_CLUSTERS * NB_TIM ERS_MAX) - 1)] = 0 };155 #if (NB_TIM_CHANNELS > 0) 156 in_unckdata volatile unsigned char _user_timer_event[NB_CLUSTERS * NB_TIM_CHANNELS] 157 = { [0 ... ((NB_CLUSTERS * NB_TIM_CHANNELS) - 1)] = 0 }; 123 158 #endif 124 159 … … 131 166 // Returns 0 if success, > 0 if error. 132 167 ////////////////////////////////////////////////////////////////////////////// 133 unsigned int _timer_start(unsigned int cluster_id, unsigned int local_id, unsigned int period) { 168 unsigned int _timer_start( unsigned int cluster_id, 169 unsigned int local_id, 170 unsigned int period) 171 { 134 172 // parameters checking 135 if (cluster_id >= NB_CLUSTERS) { 136 return 1; 137 } 138 if (local_id >= NB_TIMERS_MAX) { 139 return 2; 140 } 173 if (cluster_id >= NB_CLUSTERS) return 1; 174 if (local_id >= NB_TIM_CHANNELS) return 2; 141 175 142 176 #if USE_XICU 143 unsigned int * timer_address = (unsigned int *) ((char *) &seg_icu_base + (cluster_id * CLUSTER_SIZE)); 177 unsigned int * timer_address = (unsigned int *) ((char *) &seg_icu_base + 178 (cluster_id * GIET_CLUSTER_INCREMENT)); 144 179 145 180 timer_address[XICU_REG(XICU_PTI_PER, local_id)] = period; 146 181 #else 147 unsigned int* timer_address = (unsigned int *) ((char *) &seg_tim_base + (cluster_id * CLUSTER_SIZE)); 182 unsigned int* timer_address = (unsigned int *) ((char *) &seg_tim_base + 183 (cluster_id * GIET_CLUSTER_INCREMENT)); 148 184 149 185 timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period; … … 152 188 return 0; 153 189 } 154 155 190 156 191 ////////////////////////////////////////////////////////////////////////////// … … 160 195 // Returns 0 if success, > 0 if error. 161 196 ////////////////////////////////////////////////////////////////////////////// 162 unsigned int _timer_stop(unsigned int cluster_id, unsigned int local_id) { 197 unsigned int _timer_stop( unsigned int cluster_id, 198 unsigned int local_id) 199 { 163 200 // parameters checking 164 if (cluster_id >= NB_CLUSTERS) { 165 return 1; 166 } 167 if (local_id >= NB_TIMERS_MAX) { 168 return 2; 169 } 201 if (cluster_id >= NB_CLUSTERS) return 1; 202 if (local_id >= NB_TIM_CHANNELS) return 2; 170 203 171 204 #if USE_XICU 172 unsigned int * timer_address = (unsigned int *) ((char *) &seg_icu_base + (cluster_id * CLUSTER_SIZE)); 205 unsigned int * timer_address = (unsigned int *) ((char *) &seg_icu_base + 206 (cluster_id * GIET_CLUSTER_INCREMENT)); 173 207 174 208 timer_address[XICU_REG(XICU_PTI_PER, local_id)] = 0; 175 209 #else 176 unsigned int* timer_address = (unsigned int *) ((char *) &seg_tim_base + (cluster_id * CLUSTER_SIZE)); 210 unsigned int* timer_address = (unsigned int *) ((char *) &seg_tim_base + 211 (cluster_id * GIET_CLUSTER_INCREMENT)); 212 177 213 timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0; 178 214 #endif … … 189 225 // Returns 0 if success, > 0 if error. 190 226 ////////////////////////////////////////////////////////////////////////////// 191 unsigned int _timer_reset_irq(unsigned int cluster_id, unsigned int local_id) { 227 unsigned int _timer_reset_irq( unsigned int cluster_id, 228 unsigned int local_id ) 229 { 192 230 // parameters checking 193 if (cluster_id >= NB_CLUSTERS) { 194 return 1; 195 } 196 if (local_id >= NB_TIMERS_MAX) { 197 return 2; 198 } 231 if (cluster_id >= NB_CLUSTERS) return 1; 232 if (local_id >= NB_TIM_CHANNELS) return 2; 199 233 200 234 #if USE_XICU 201 235 unsigned int * timer_address = (unsigned int *) ((char *) &seg_icu_base + 202 (cluster_id * (unsigned) CLUSTER_SIZE));236 (cluster_id * GIET_CLUSTER_INCREMENT)); 203 237 204 238 unsigned int bloup = timer_address[XICU_REG(XICU_PTI_ACK, local_id)]; … … 206 240 #else 207 241 unsigned int * timer_address = (unsigned int *) ((char *) &seg_tim_base + 208 (cluster_id * CLUSTER_SIZE));242 (cluster_id * GIET_CLUSTER_INCREMENT)); 209 243 210 244 timer_address[local_id * TIMER_SPAN + TIMER_RESETIRQ] = 0; 211 245 #endif 212 213 246 return 0; 214 247 } … … 223 256 // return 1; 224 257 // } 225 // if (local_id >= NB_TIM ERS_MAX) {258 // if (local_id >= NB_TIM_CHANNELS) { 226 259 // return 2; 227 260 // } … … 230 263 //#error // not implemented 231 264 //#else 232 // unsigned int * timer_address = (unsigned int *) ((char *) &seg_tim_base + (cluster_id * CLUSTER_SIZE));265 // unsigned int * timer_address = (unsigned int *) ((char *) &seg_tim_base + (cluster_id * GIET_CLUSTER_INCREMENT)); 233 266 // unsigned int timer_period = timer_address[local_id * TIMER_SPAN + TIMER_PERIOD]; 234 267 // … … 244 277 ///////////////////////////////////////////////////////////////////////////////// 245 278 // There is only one multi_tty controler in the architecture. 246 // The total number of TTYs is defined by the configuration parameter NB_TTY S.279 // The total number of TTYs is defined by the configuration parameter NB_TTY_CHANNELS. 247 280 // The "system" terminal is TTY[0]. 248 281 // The "user" TTYs are allocated to applications by the GIET in the boot phase, … … 253 286 254 287 // TTY variables 255 in_unckdata volatile unsigned char _tty_get_buf[NB_TTYS]; 256 in_unckdata volatile unsigned char _tty_get_full[NB_TTYS] = { [0 ... NB_TTYS - 1] = 0 }; 288 in_unckdata volatile unsigned char _tty_get_buf[NB_TTY_CHANNELS]; 289 in_unckdata volatile unsigned char _tty_get_full[NB_TTY_CHANNELS] 290 = { [0 ... NB_TTY_CHANNELS - 1] = 0 }; 257 291 in_unckdata unsigned int _tty_put_lock = 0; // protect kernel TTY[0] 258 292 … … 260 294 // _tty_error() 261 295 //////////////////////////////////////////////////////////////////////////////// 262 void _tty_error(unsigned int tty_id, unsigned int task_id) { 296 void _tty_error(unsigned int tty_id, unsigned int task_id) 297 { 263 298 unsigned int proc_id = _procid(); 264 299 … … 287 322 // The function returns the number of characters that have been written. 288 323 ///////////////////////////////////////////////////////////////////////////////// 289 unsigned int _tty_write(const char * buffer, unsigned int length) { 324 unsigned int _tty_write(const char * buffer, 325 unsigned int length) 326 { 290 327 unsigned int nwritten; 291 unsigned int task_id = _get_proc_task_id(); 292 unsigned int tty_id = _get_context_slot(task_id, CTX_TTY_ID); 293 294 if (tty_id >= NB_TTYS) { 295 _tty_error(tty_id , task_id); 296 return 0; 297 } 298 299 unsigned int * tty_address = (unsigned int *) &seg_tty_base; 300 301 for (nwritten = 0; nwritten < length; nwritten++) { 328 unsigned int tty_id = _get_context_slot(CTX_TTY_ID); 329 unsigned int* tty_address = (unsigned int *) &seg_tty_base; 330 331 for (nwritten = 0; nwritten < length; nwritten++) 332 { 302 333 // check tty's status 303 if ((tty_address[tty_id * TTY_SPAN + TTY_STATUS] & 0x2) == 0x2) { 304 break; 305 } 306 else { 307 // write character 308 tty_address[tty_id * TTY_SPAN + TTY_WRITE] = (unsigned int) buffer[nwritten]; 309 } 334 if ((tty_address[tty_id * TTY_SPAN + TTY_STATUS] & 0x2) == 0x2) break; 335 tty_address[tty_id * TTY_SPAN + TTY_WRITE] = (unsigned int) buffer[nwritten]; 310 336 } 311 337 return nwritten; 312 338 } 313 314 339 315 340 ////////////////////////////////////////////////////////////////////////////// … … 324 349 // Returns 0 if the kernel buffer is empty, 1 if the buffer is full. 325 350 ////////////////////////////////////////////////////////////////////////////// 326 unsigned int _tty_read(char * buffer, unsigned int length) { 327 unsigned int task_id = _get_proc_task_id(); 328 unsigned int tty_id = _get_context_slot(task_id, CTX_TTY_ID); 329 330 if (tty_id >= NB_TTYS) { 331 _tty_error(tty_id, task_id); 351 unsigned int _tty_read(char * buffer, 352 unsigned int length) 353 { 354 unsigned int tty_id = _get_context_slot(CTX_TTY_ID); 355 356 if (_tty_get_full[tty_id] == 0) 357 { 332 358 return 0; 333 359 } 334 335 if (_tty_get_full[tty_id] == 0) { 336 return 0; 337 } 338 else { 360 else 361 { 339 362 *buffer = _tty_get_buf[tty_id]; 340 363 _tty_get_full[tty_id] = 0; … … 342 365 } 343 366 } 344 345 367 346 368 //////////////////////////////////////////////////////////////////////////////// … … 351 373 // Returns 0 if success, 1 if tty_id too large. 352 374 //////////////////////////////////////////////////////////////////////////////// 353 unsigned int _tty_get_char(unsigned int tty_id, unsigned char * buffer) { 375 unsigned int _tty_get_char(unsigned int tty_id, 376 unsigned char * buffer) 377 { 354 378 // checking argument 355 if (tty_id >= NB_TTYS) { 356 return 1; 357 } 379 if (tty_id >= NB_TTY_CHANNELS) { return 1; } 358 380 359 381 // compute terminal base address … … 366 388 367 389 //////////////////////////////////////////////////////////////////////////////// 368 // VciMultiIcu and VciXicu drivers 369 //////////////////////////////////////////////////////////////////////////////// 390 // VciMultiIcu or VciXicu driver 391 //////////////////////////////////////////////////////////////////////////////// 392 // This hardware component is replicated in all clusters. 370 393 // There is one vci_multi_icu (or vci_xicu) component per cluster, 371 394 // and the number of independant ICUs is equal to NB_PROCS_MAX, 372 // because there is one private interrupr controler per processor. 395 // because there is one private interrupt controler per processor. 396 //////////////////////////////////////////////////////////////////////////////// 397 // The (virtual) base address of the associated segment is: 398 // 399 // icu_address = seg_icu_base + cluster_id * GIET_CLUSTER_INCREMENT 400 // 401 // - cluster id is an explicit argument of all access functions 402 // - seg_icu_base must be defined in the giet_vsegs.ld file 403 // - GIET_CLUSTER_INCREMENT must be defined in the giet_config.h file 373 404 //////////////////////////////////////////////////////////////////////////////// 374 405 … … 380 411 // Returns 0 if success, > 0 if error. 381 412 //////////////////////////////////////////////////////////////////////////////// 382 unsigned int _icu_set_mask( 383 unsigned int cluster_id,384 unsigned int proc_id,385 unsigned int value,386 unsigned int is_timer){413 unsigned int _icu_set_mask( unsigned int cluster_id, 414 unsigned int proc_id, 415 unsigned int value, 416 unsigned int is_timer) 417 { 387 418 // parameters checking 388 if (cluster_id >= NB_CLUSTERS) { 389 return 1; 390 } 391 if (proc_id >= NB_PROCS_MAX) { 392 return 1; 393 } 419 if (cluster_id >= NB_CLUSTERS) return 1; 420 if (proc_id >= NB_PROCS_MAX) return 1; 394 421 395 422 unsigned int * icu_address = (unsigned int *) ((char *) &seg_icu_base + 396 (cluster_id * (unsigned) CLUSTER_SIZE));423 (cluster_id * GIET_CLUSTER_INCREMENT)); 397 424 #if USE_XICU 398 if (is_timer) { 425 if (is_timer) 426 { 399 427 icu_address[XICU_REG(XICU_MSK_PTI_ENABLE, proc_id)] = value; 400 428 } 401 else { 429 else 430 { 402 431 icu_address[XICU_REG(XICU_MSK_HWI_ENABLE, proc_id)] = value; 403 432 } … … 405 434 icu_address[proc_id * ICU_SPAN + ICU_MASK_SET] = value; 406 435 #endif 407 408 436 return 0; 409 437 } … … 417 445 // Returns 0 if success, > 0 if error. 418 446 //////////////////////////////////////////////////////////////////////////////// 419 unsigned int _icu_get_index(unsigned int cluster_id, unsigned int proc_id, unsigned int * buffer) { 447 unsigned int _icu_get_index( unsigned int cluster_id, 448 unsigned int proc_id, 449 unsigned int * buffer) 450 { 420 451 // parameters checking 421 if (cluster_id >= NB_CLUSTERS) { 422 return 1; 423 } 424 if (proc_id >= NB_PROCS_MAX) { 425 return 1; 426 } 452 if (cluster_id >= NB_CLUSTERS) return 1; 453 if (proc_id >= NB_PROCS_MAX) return 1; 427 454 428 455 unsigned int * icu_address = (unsigned int *) ((char *) &seg_icu_base + 429 (cluster_id * (unsigned) CLUSTER_SIZE));456 (cluster_id * GIET_CLUSTER_INCREMENT)); 430 457 #if USE_XICU 431 458 unsigned int prio = icu_address[XICU_REG(XICU_PRIO, proc_id)]; … … 436 463 unsigned int hwi_id = (prio & 0x001F0000) >> 16; 437 464 unsigned int swi_id = (prio & 0x1F000000) >> 24; 438 if (pti_ok) { 439 *buffer = pti_id; 440 } 441 else if (hwi_ok) { 442 *buffer = hwi_id; 443 } 444 else if (swi_ok) { 445 *buffer = swi_id; 446 } 447 else { 448 *buffer = 32; 449 } 465 if (pti_ok) { *buffer = pti_id; } 466 else if (hwi_ok) { *buffer = hwi_id; } 467 else if (swi_ok) { *buffer = swi_id; } 468 else { *buffer = 32; } 450 469 #else 451 470 *buffer = icu_address[proc_id * ICU_SPAN + ICU_IT_VECTOR]; 452 471 #endif 453 454 472 return 0; 455 473 } … … 469 487 // Returns 0 if success, > 0 if error. 470 488 //////////////////////////////////////////////////////////////////////////////// 471 unsigned int _gcd_write(unsigned int register_index, unsigned int value) { 489 unsigned int _gcd_write( unsigned int register_index, 490 unsigned int value) 491 { 472 492 // parameters checking 473 if (register_index >= GCD_END) { 474 return 1; 475 } 493 if (register_index >= GCD_END) return 1; 476 494 477 495 unsigned int * gcd_address = (unsigned int *) &seg_gcd_base; … … 487 505 // Returns 0 if success, > 0 if error. 488 506 //////////////////////////////////////////////////////////////////////////////// 489 unsigned int _gcd_read(unsigned int register_index, unsigned int * buffer) { 507 unsigned int _gcd_read( unsigned int register_index, 508 unsigned int * buffer ) 509 { 490 510 // parameters checking 491 if (register_index >= GCD_END) { 492 return 1; 493 } 511 if (register_index >= GCD_END) return 1; 494 512 495 513 unsigned int * gcd_address = (unsigned int *) &seg_gcd_base; … … 567 585 // Returns 0 if success, > 0 if error. 568 586 /////////////////////////////////////////////////////////////////////////////// 569 unsigned int _ioc_access( 570 unsigned int to_mem, 571 unsigned int lba, 572 unsigned int user_vaddr, 573 unsigned int count) { 574 unsigned int user_vpn_min; // first virtuel page index in user space 575 unsigned int user_vpn_max; // last virtual page index in user space 576 unsigned int vpn; // current virtual page index in user space 577 unsigned int ppn; // physical page number 578 unsigned int flags; // page protection flags 579 unsigned int ix2; // page index in IOMMU PT1 page table 580 unsigned int addr; // buffer address for IOC peripheral 581 unsigned int ppn_first; // first physical page number for user buffer 582 587 unsigned int _ioc_access( unsigned int to_mem, 588 unsigned int lba, 589 unsigned int user_vaddr, 590 unsigned int count) 591 { 592 unsigned int user_vpn_min; // first virtuel page index in user space 593 unsigned int user_vpn_max; // last virtual page index in user space 594 unsigned int vpn; // current virtual page index in user space 595 unsigned int ppn; // physical page number 596 unsigned int flags; // page protection flags 597 unsigned int ix2; // page index in IOMMU PT1 page table 598 unsigned int ppn_first; // first physical page number for user buffer 599 unsigned int buf_xaddr = 0; // user buffer virtual address in IO space (if IOMMU) 600 paddr_t buf_paddr = 0; // user buffer physical address (if no IOMMU), 601 583 602 // check buffer alignment 584 if ((unsigned int) user_vaddr & 0x3) { 585 return 1; 603 if ((unsigned int) user_vaddr & 0x3) 604 { 605 _get_lock(&_tty_put_lock); 606 _puts("[GIET ERROR] in _ioc_access() : user buffer not word aligned\n"); 607 _release_lock(&_tty_put_lock); 608 return 1; 586 609 } 587 610 … … 592 615 593 616 // get user space page table virtual address 594 unsigned int task_id = _get_proc_task_id(); 595 unsigned int user_pt_vbase = _get_context_slot(task_id, CTX_PTAB_ID); 617 unsigned int user_pt_vbase = _get_context_slot(CTX_PTAB_ID); 596 618 597 619 user_vpn_min = user_vaddr >> 12; 598 620 user_vpn_max = (user_vaddr + length - 1) >> 12; 599 ix2 = 0;600 621 601 622 // loop on all virtual pages covering the user buffer 602 for (vpn = user_vpn_min; vpn <= user_vpn_max; vpn++) { 623 for (vpn = user_vpn_min, ix2 = 0 ; 624 vpn <= user_vpn_max ; 625 vpn++, ix2++ ) 626 { 603 627 // get ppn and flags for each vpn 604 unsigned int ko = _v2p_translate((page_table_t *) user_pt_vbase, vpn, &ppn, &flags); 605 628 unsigned int ko = _v2p_translate( (page_table_t*)user_pt_vbase, 629 vpn, 630 &ppn, 631 &flags); 606 632 // check access rights 607 if (ko) { 608 return 2; // unmapped 633 if (ko) 634 { 635 _get_lock(&_tty_put_lock); 636 _puts("[GIET ERROR] in _ioc_access() : user buffer unmapped\n"); 637 _release_lock(&_tty_put_lock); 638 return 1; 609 639 } 610 if ((flags & PTE_U) == 0) { 611 return 3; // not in user space 640 if ((flags & PTE_U) == 0) 641 { 642 _get_lock(&_tty_put_lock); 643 _puts("[GIET ERROR] in _ioc_access() : user buffer not in user space\n"); 644 _release_lock(&_tty_put_lock); 645 return 1; 612 646 } 613 if (((flags & PTE_W) == 0 ) && to_mem) { 614 return 4; // not writable 647 if (((flags & PTE_W) == 0 ) && to_mem) 648 { 649 _get_lock(&_tty_put_lock); 650 _puts("[GIET ERROR] in _ioc_access() : user buffer not writable\n"); 651 _release_lock(&_tty_put_lock); 652 return 1; 615 653 } 616 654 617 655 // save first ppn value 618 if (ix2 == 0) { 619 ppn_first = ppn; 656 if (ix2 == 0) ppn_first = ppn; 657 658 if (IOMMU_ACTIVE) // the user buffer must be remapped in the I/0 space 659 { 660 // check buffer length < 2 Mbytes 661 if (ix2 > 511) 662 { 663 _get_lock(&_tty_put_lock); 664 _puts("[GIET ERROR] in _ioc_access() : user buffer > 2 Mbytes\n"); 665 _release_lock(&_tty_put_lock); 666 return 1; 667 } 668 669 // map the physical page in IOMMU page table 670 _iommu_add_pte2( _ioc_iommu_ix1, // PT1 index 671 ix2, // PT2 index 672 ppn, // Physical page number 673 flags); // Protection flags 674 675 // compute user buffer virtual adress in IO space 676 buf_xaddr = (_ioc_iommu_ix1) << 21 | (user_vaddr & 0xFFF); 620 677 } 621 622 if (IOMMU_ACTIVE) { 623 // the user buffer must be remapped in the I/0 space 624 // check buffer length < 2 Mbytes 625 if (ix2 > 511) { 626 return 2; 678 else // No IOMMU 679 { 680 // check that physical pages are contiguous 681 if ((ppn - ppn_first) != ix2) 682 { 683 _get_lock(&_tty_put_lock); 684 _puts("[GIET ERROR] in _ioc_access() : split physical user buffer\n"); 685 _release_lock(&_tty_put_lock); 686 return 1; 627 687 } 628 688 629 // map the physical page in IOMMU page table 630 _iommu_add_pte2( 631 _ioc_iommu_ix1, // PT1 index 632 ix2, // PT2 index 633 ppn, // Physical page number 634 flags); // Protection flags 689 // compute user buffer physical adress 690 buf_paddr = (((paddr_t)ppn_first) << 12) | (user_vaddr & 0xFFF); 635 691 } 636 else {637 // no IOMMU : check that physical pages are contiguous638 if ((ppn - ppn_first) != ix2) {639 return 5; // split physical buffer640 }641 }642 643 // increment page index644 ix2++;645 692 } // end for vpn 646 693 … … 649 696 650 697 // invalidate data cache in case of memory write 651 if (to_mem) { 652 _dcache_buf_invalidate((void *) user_vaddr, length); 653 } 654 655 // compute buffer base address for IOC depending on IOMMU activation 656 if (IOMMU_ACTIVE) { 657 addr = (_ioc_iommu_ix1) << 21 | (user_vaddr & 0xFFF); 658 } 659 else { 660 addr = (ppn_first << 12) | (user_vaddr & 0xFFF); 661 } 698 if (to_mem) _dcache_buf_invalidate((void *) user_vaddr, length); 699 700 #if GIET_DEBUG_IOC_DRIVER 701 _get_lock(&_tty_put_lock); 702 _puts("\n[GIET DEBUG] IOC_ACCESS at cycle "); 703 _putd( _proctime() ); 704 _puts("\n - proc_id = "); 705 _putd( _procid() ); 706 _puts("\n - ioc_vbase = "); 707 _putx( (unsigned int)ioc_address ); 708 _puts("\n - psched_vbase = "); 709 _putx( (unsigned int)_get_sched() ); 710 _puts("\n - pt_vbase = "); 711 _putx( user_pt_vbase ); 712 _puts("\n - user_buf_vbase = "); 713 _putx( user_vaddr ); 714 _puts("\n - user_buf_length = "); 715 _putx( length ); 716 _puts("\n - user_buf_paddr = "); 717 _putl( buf_paddr ); 718 _puts("\n - user_buf_xaddr = "); 719 _putx( buf_xaddr ); 720 _puts("\n"); 721 _release_lock(&_tty_put_lock); 722 #endif 662 723 663 724 // get the lock on ioc device … … 665 726 666 727 // peripheral configuration 667 ioc_address[BLOCK_DEVICE_BUFFER] = addr; 728 if ( IOMMU_ACTIVE ) 729 { 730 ioc_address[BLOCK_DEVICE_BUFFER] = buf_xaddr; 731 } 732 else 733 { 734 ioc_address[BLOCK_DEVICE_BUFFER] = (unsigned int)buf_paddr; 735 ioc_address[BLOCK_DEVICE_BUFFER_EXT] = (unsigned int)(buf_paddr>>32); 736 } 668 737 ioc_address[BLOCK_DEVICE_COUNT] = count; 669 738 ioc_address[BLOCK_DEVICE_LBA] = lba; 670 if (to_mem == 0) { 739 if (to_mem == 0) 740 { 671 741 ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_WRITE; 672 742 } 673 else { 743 else 744 { 674 745 ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_READ; 675 746 } 676 677 return 0; 678 } 679 747 return 0; 748 } 680 749 681 750 ///////////////////////////////////////////////////////////////////////////////// … … 688 757 // Returns 0 if success, > 0 if error. 689 758 ///////////////////////////////////////////////////////////////////////////////// 690 unsigned int _ioc_completed() { 759 unsigned int _ioc_completed() 760 { 691 761 unsigned int ret; 692 762 unsigned int ix2; 693 763 694 764 // busy waiting 695 while (_ioc_done == 0) { 696 asm volatile("nop"); 697 } 765 while (_ioc_done == 0) { asm volatile("nop"); } 766 767 #if GIET_DEBUG_IOC_DRIVER 768 _get_lock(&_tty_put_lock); 769 _puts("\n[GIET DEBUG] IOC_COMPLETED at cycle "); 770 _putd( _proctime() ); 771 _puts("\n - proc_id = "); 772 _putd( _procid() ); 773 _puts("\n"); 774 _release_lock(&_tty_put_lock); 775 #endif 698 776 699 777 // unmap the buffer from IOMMU page table if IOMMU is activated 700 if (IOMMU_ACTIVE) { 778 if (IOMMU_ACTIVE) 779 { 701 780 unsigned int * iob_address = (unsigned int *) &seg_iob_base; 702 781 703 for (ix2 = 0; ix2 < _ioc_iommu_npages; ix2++) { 782 for (ix2 = 0; ix2 < _ioc_iommu_npages; ix2++) 783 { 704 784 // unmap the page in IOMMU page table 705 785 _iommu_inval_pte2( … … 714 794 // test IOC status 715 795 if ((_ioc_status != BLOCK_DEVICE_READ_SUCCESS) 716 && (_ioc_status != BLOCK_DEVICE_WRITE_SUCCESS)) { 717 ret = 1; // error 718 } 719 else { 720 ret = 0; // success 721 } 796 && (_ioc_status != BLOCK_DEVICE_WRITE_SUCCESS)) ret = 1; // error 797 else ret = 0; // success 722 798 723 799 // reset synchronization variables … … 738 814 // Returns 0 if success, > 0 if error. 739 815 /////////////////////////////////////////////////////////////////////////////// 740 unsigned int _ioc_read(unsigned int lba, void * buffer, unsigned int count) { 816 unsigned int _ioc_read( unsigned int lba, 817 void * buffer, 818 unsigned int count) 819 { 741 820 return _ioc_access( 742 821 1, // read access … … 755 834 // Returns 0 if success, > 0 if error. 756 835 /////////////////////////////////////////////////////////////////////////////// 757 unsigned int _ioc_write(unsigned int lba, const void * buffer, unsigned int count) { 836 unsigned int _ioc_write( unsigned int lba, 837 const void * buffer, 838 unsigned int count) 839 { 758 840 return _ioc_access( 759 841 0, // write access … … 769 851 // Returns 0 if success, > 0 if error. 770 852 /////////////////////////////////////////////////////////////////////////////// 771 unsigned int _ioc_get_status(unsigned int * status) { 853 unsigned int _ioc_get_status(unsigned int * status) 854 { 772 855 // get IOC base address 773 856 unsigned int * ioc_address = (unsigned int *) &seg_ioc_base; … … 782 865 // This function returns the block_size with which the IOC has been configured. 783 866 /////////////////////////////////////////////////////////////////////////////// 784 unsigned int _ioc_get_block_size() { 867 unsigned int _ioc_get_block_size() 868 { 785 869 // get IOC base address 786 870 unsigned int * ioc_address = (unsigned int *) &seg_ioc_base; … … 794 878 ////////////////////////////////////////////////////////////////////////////////// 795 879 // The DMA controllers are physically distributed in the clusters. 796 // There is (NB_CLUSTERS * NB_DMA S_MAX) channels, indexed by a global index:797 // dma_id = cluster_id * NB_DMA_ MAX+ loc_id798 // 799 // As a DMA channel can be used by several tasks, each DMA channel is protected800 // by a specific lock: _dma_lock[dma_id]880 // There is (NB_CLUSTERS * NB_DMA_CHANNELS) channels, indexed by a global index: 881 // dma_id = cluster_id * NB_DMA_CHANNELS + loc_id 882 // 883 // As a DMA channel is a private ressource allocated to a task, 884 // there is no lock protecting exclusive access to the channel. 801 885 // The signalisation between the OS and the DMA uses the _dma_done[dma_id] 802 886 // synchronisation variables (set by the ISR, and reset by the OS). 803 887 // The transfer status is copied by the ISR in the _dma_status[dma_id] variables. 804 // 805 // These DMA channels can be used by the FB driver, or by the NIC driver. 806 ////////////////////////////////////////////////////////////////////////////////// 807 808 #if NB_DMAS_MAX > 0 809 in_unckdata unsigned int _dma_lock[NB_DMAS_MAX * NB_CLUSTERS] = { 810 [0 ... (NB_DMAS_MAX * NB_CLUSTERS) - 1] = 0 811 }; 812 813 in_unckdata volatile unsigned int _dma_done[NB_DMAS_MAX * NB_CLUSTERS] = { 814 [0 ... (NB_DMAS_MAX * NB_CLUSTERS) - 1] = 0 815 }; 816 817 in_unckdata volatile unsigned int _dma_status[NB_DMAS_MAX * NB_CLUSTERS]; 888 ////////////////////////////////////////////////////////////////////////////////// 889 // The (virtual) base address of the associated segment is: 890 // 891 // dma_address = seg_dma_base + cluster_id * GIET_CLUSTER_INCREMENT 892 // 893 // - seg_dma_base must be defined in the giet_vsegs.ld file 894 // - GIET_CLUSTER_INCREMENT must be defined in the giet_config.h file 895 //////////////////////////////////////////////////////////////////////////////// 896 897 #if NB_DMA_CHANNELS > 0 898 899 // in_unckdata unsigned int _dma_lock[NB_DMA_CHANNELS * NB_CLUSTERS] 900 // = { [0 ... (NB_DMA_CHANNELS * NB_CLUSTERS) - 1] = 0 }; 901 902 in_unckdata volatile unsigned int _dma_done[NB_DMA_CHANNELS * NB_CLUSTERS] 903 = { [0 ... (NB_DMA_CHANNELS * NB_CLUSTERS) - 1] = 0 }; 904 in_unckdata volatile unsigned int _dma_status[NB_DMA_CHANNELS * NB_CLUSTERS]; 818 905 in_unckdata unsigned int _dma_iommu_ix1 = 1; 819 in_unckdata unsigned int _dma_iommu_npages[NB_DMA S_MAX* NB_CLUSTERS];906 in_unckdata unsigned int _dma_iommu_npages[NB_DMA_CHANNELS * NB_CLUSTERS]; 820 907 #endif 821 908 … … 823 910 // _dma_reset_irq() 824 911 ////////////////////////////////////////////////////////////////////////////////// 825 unsigned int _dma_reset_irq(unsigned int cluster_id, unsigned int channel_id) { 826 #if NB_DMAS_MAX > 0 912 unsigned int _dma_reset_irq( unsigned int cluster_id, 913 unsigned int channel_id) 914 { 915 #if NB_DMA_CHANNELS > 0 827 916 // parameters checking 828 if (cluster_id >= NB_CLUSTERS) { 829 return 1; 830 } 831 if (channel_id >= NB_DMAS_MAX) { 832 return 1; 833 } 917 if (cluster_id >= NB_CLUSTERS) return 1; 918 if (channel_id >= NB_DMA_CHANNELS) return 1; 834 919 835 920 // compute DMA base address 836 921 unsigned int * dma_address = (unsigned int *) ((char *) &seg_dma_base + 837 (cluster_id * (unsigned) CLUSTER_SIZE));922 (cluster_id * GIET_CLUSTER_INCREMENT)); 838 923 839 924 dma_address[channel_id * DMA_SPAN + DMA_RESET] = 0; … … 848 933 // _dma_get_status() 849 934 ////////////////////////////////////////////////////////////////////////////////// 850 unsigned int _dma_get_status(unsigned int cluster_id, unsigned int channel_id, unsigned int * status) { 851 #if NB_DMAS_MAX > 0 935 unsigned int _dma_get_status( unsigned int cluster_id, 936 unsigned int channel_id, 937 unsigned int * status) 938 { 939 #if NB_DMA_CHANNELS > 0 852 940 // parameters checking 853 if (cluster_id >= NB_CLUSTERS) { 854 return 1; 855 } 856 if (channel_id >= NB_DMAS_MAX) { 857 return 1; 858 } 941 if (cluster_id >= NB_CLUSTERS) return 1; 942 if (channel_id >= NB_DMA_CHANNELS) return 1; 859 943 860 944 // compute DMA base address 861 945 unsigned int * dma_address = (unsigned int *) ((char *) &seg_dma_base + 862 (cluster_id * (unsigned) CLUSTER_SIZE));946 (cluster_id * GIET_CLUSTER_INCREMENT)); 863 947 864 948 *status = dma_address[channel_id * DMA_SPAN + DMA_LEN]; … … 873 957 // _dma_transfer() 874 958 // Transfer data between a user buffer and a device buffer using DMA. 875 // Two devices types are supported: Frame Buffer if dev_type == 0 876 // Multi-Nic if dev_type != 0 959 // Only one device type is supported: Frame Buffer (dev_type == 0) 877 960 // Arguments are: 878 961 // - dev_type : device type. … … 882 965 // - length : number of bytes to be transfered. 883 966 // 884 // The DMA channel is obtained from task context (CTX_FBDMA_ID / CTX_NIDMA_ID.967 // The cluster_id and channel_id are obtained from task context (CTX_DMA_ID). 885 968 // The user buffer must be mapped in user address space and word-aligned. 886 969 // The user buffer length must be multiple of 4 bytes. 887 // Me mustcompute the physical base addresses for both the device buffer970 // We compute the physical base addresses for both the device buffer 888 971 // and the user buffer before programming the DMA transfer. 889 972 // The GIET being fully static, we don't need to split the transfer in 4 Kbytes … … 891 974 // Returns 0 if success, > 0 if error. 892 975 ////////////////////////////////////////////////////////////////////////////////// 893 unsigned int _dma_transfer( 894 unsigned int dev_type,895 unsigned int to_user,896 unsigned int offset,897 unsigned int user_vaddr,898 unsigned int length){899 #if NB_DMA S_MAX> 0976 unsigned int _dma_transfer( unsigned int dev_type, 977 unsigned int to_user, 978 unsigned int offset, 979 unsigned int user_vaddr, 980 unsigned int length ) 981 { 982 #if NB_DMA_CHANNELS > 0 900 983 unsigned int ko; // unsuccessfull V2P translation 984 unsigned int device_vbase; // device buffer vbase address 901 985 unsigned int flags; // protection flags 902 986 unsigned int ppn; // physical page number 903 unsigned int user_pbase; // user buffer pbase address 904 unsigned int device_pbase; // frame buffer pbase address 905 unsigned int device_vaddr; // device buffer vbase address 987 paddr_t user_pbase; // user buffer pbase address 988 paddr_t device_pbase; // frame buffer pbase address 906 989 907 990 // check user buffer address and length alignment 908 if ((user_vaddr & 0x3) || (length & 0x3)) { 991 if ((user_vaddr & 0x3) || (length & 0x3)) 992 { 909 993 _get_lock(&_tty_put_lock); 910 994 _puts("\n[GIET ERROR] in _dma_transfer : user buffer not word aligned\n"); … … 914 998 915 999 // get DMA channel and compute DMA vbase address 916 unsigned int task_id = _get_proc_task_id(); 917 unsigned int dma_id = _get_context_slot(task_id, CTX_DMA_ID); 918 unsigned int cluster_id = dma_id / NB_DMAS_MAX; 919 unsigned int loc_id = dma_id % NB_DMAS_MAX; 920 unsigned int * dma_base = (unsigned int *) ((char *) &seg_dma_base + 921 (cluster_id * (unsigned) CLUSTER_SIZE)); 922 1000 unsigned int dma_id = _get_context_slot(CTX_DMA_ID); 1001 if ( dma_id == 0xFFFFFFFF ) 1002 { 1003 _get_lock(&_tty_put_lock); 1004 _puts("\n[GIET ERROR] in _dma_transfer : no DMA channel allocated\n"); 1005 _release_lock(&_tty_put_lock); 1006 return 1; 1007 } 1008 unsigned int cluster_id = dma_id / NB_DMA_CHANNELS; 1009 unsigned int channel_id = dma_id % NB_DMA_CHANNELS; 1010 unsigned int * dma_vbase = (unsigned int *) ((char *) &seg_dma_base + 1011 (cluster_id * GIET_CLUSTER_INCREMENT)); 923 1012 // get page table address 924 unsigned int user_ptab = _get_context_slot(task_id, CTX_PTAB_ID); 925 926 // get peripheral buffer virtual address 927 if (dev_type) { 928 device_vaddr = (unsigned int) &seg_nic_base + offset; 929 } 930 else { 931 device_vaddr = (unsigned int) &seg_fbf_base + offset; 1013 unsigned int user_ptab = _get_context_slot(CTX_PTAB_ID); 1014 1015 // get devic buffer virtual address, depending on peripheral type 1016 if (dev_type == 0) 1017 { 1018 device_vbase = (unsigned int) &seg_fbf_base + offset; 1019 } 1020 else 1021 { 1022 _get_lock(&_tty_put_lock); 1023 _puts("\n[GIET ERROR] in _dma_transfer : device type not supported\n"); 1024 _release_lock(&_tty_put_lock); 1025 return 1; 932 1026 } 933 1027 934 1028 // get device buffer physical address 935 ko = _v2p_translate((page_table_t *) user_ptab, (device_vaddr >> 12), &ppn, &flags); 936 if (ko) { 1029 ko = _v2p_translate( (page_table_t*) user_ptab, 1030 (device_vbase >> 12), 1031 &ppn, 1032 &flags ); 1033 if (ko) 1034 { 937 1035 _get_lock(&_tty_put_lock); 938 1036 _puts("\n[GIET ERROR] in _dma_transfer : device buffer unmapped\n"); 939 1037 _release_lock(&_tty_put_lock); 940 return 2;941 } 942 device_pbase = ( ppn << 12) | (device_vaddr& 0x00000FFF);1038 return 1; 1039 } 1040 device_pbase = ((paddr_t)ppn << 12) | (device_vbase & 0x00000FFF); 943 1041 944 1042 // Compute user buffer physical address 945 ko = _v2p_translate((page_table_t*) user_ptab, (user_vaddr >> 12), &ppn, &flags); 946 if (ko) { 1043 ko = _v2p_translate( (page_table_t*) user_ptab, 1044 (user_vaddr >> 12), 1045 &ppn, 1046 &flags ); 1047 if (ko) 1048 { 947 1049 _get_lock(&_tty_put_lock); 948 1050 _puts("\n[GIET ERROR] in _dma_transfer() : user buffer unmapped\n"); 949 1051 _release_lock(&_tty_put_lock); 950 return 3;1052 return 1; 951 1053 } 952 if ((flags & PTE_U) == 0) { 1054 if ((flags & PTE_U) == 0) 1055 { 953 1056 _get_lock(&_tty_put_lock); 954 1057 _puts("[GIET ERROR] in _dma_transfer() : user buffer not in user space\n"); 955 1058 _release_lock(&_tty_put_lock); 956 return 4; 957 } 958 if (((flags & PTE_W) == 0 ) && to_user) { 1059 return 1; 1060 } 1061 if (((flags & PTE_W) == 0 ) && to_user) 1062 { 959 1063 _get_lock(&_tty_put_lock); 960 1064 _puts("\n[GIET ERROR] in _dma_transfer() : user buffer not writable\n"); 961 1065 _release_lock(&_tty_put_lock); 962 return 5;963 } 964 user_pbase = ( ppn<< 12) | (user_vaddr & 0x00000FFF);965 966 1066 return 1; 1067 } 1068 user_pbase = (((paddr_t)ppn) << 12) | (user_vaddr & 0x00000FFF); 1069 1070 /* This is a draft for IOMMU support 967 1071 968 1072 // loop on all virtual pages covering the user buffer … … 1014 1118 1015 1119 // invalidate data cache in case of memory write 1016 if (to_user) { 1017 _dcache_buf_invalidate((void *) user_vaddr, length); 1018 } 1019 1020 // get the lock 1021 _get_lock(&_dma_lock[dma_id]); 1120 if (to_user) _dcache_buf_invalidate((void *) user_vaddr, length); 1121 1122 // get the lock 1123 // _get_lock(&_dma_lock[dma_id]); 1124 1125 #if GIET_DEBUG_DMA_DRIVER 1126 _get_lock(&_tty_put_lock); 1127 _puts("\n[GIET DEBUG] DMA TRANSFER at cycle "); 1128 _putd( _proctime() ); 1129 _puts("\n - cluster_id = "); 1130 _putx( cluster_id ); 1131 _puts("\n - channel_id = "); 1132 _putx( channel_id ); 1133 _puts("\n - dma_vbase = "); 1134 _putx( (unsigned int)dma_vbase ); 1135 _puts("\n - device_buf_vbase = "); 1136 _putx( device_vbase ); 1137 _puts("\n - device_buf_pbase = "); 1138 _putl( device_pbase ); 1139 _puts("\n - user_buf_vbase = "); 1140 _putx( user_vaddr ); 1141 _puts("\n - user_buf_pbase = "); 1142 _putl( user_pbase ); 1143 _puts("\n"); 1144 _release_lock(&_tty_put_lock); 1145 #endif 1022 1146 1023 1147 // DMA configuration 1024 if (to_user) { 1025 dma_base[loc_id * DMA_SPAN + DMA_SRC] = (unsigned int) device_pbase; 1026 dma_base[loc_id * DMA_SPAN + DMA_DST] = (unsigned int) user_pbase; 1027 } 1028 else { 1029 dma_base[loc_id * DMA_SPAN + DMA_SRC] = (unsigned int) user_pbase; 1030 dma_base[loc_id * DMA_SPAN + DMA_DST] = (unsigned int) device_pbase; 1031 } 1032 dma_base[loc_id * DMA_SPAN + DMA_LEN] = (unsigned int) length; 1033 1034 return 0; 1035 #else //NB_DMAS_MAX == 0 1036 return -1; 1037 #endif 1148 if (to_user) 1149 { 1150 dma_vbase[channel_id * DMA_SPAN + DMA_SRC] = (unsigned int)(device_pbase); 1151 dma_vbase[channel_id * DMA_SPAN + DMA_SRC_EXT] = (unsigned int)(device_pbase>>32); 1152 dma_vbase[channel_id * DMA_SPAN + DMA_DST] = (unsigned int)(user_pbase); 1153 dma_vbase[channel_id * DMA_SPAN + DMA_DST_EXT] = (unsigned int)(user_pbase>>32); 1154 } 1155 else 1156 { 1157 dma_vbase[channel_id * DMA_SPAN + DMA_SRC] = (unsigned int)(user_pbase); 1158 dma_vbase[channel_id * DMA_SPAN + DMA_SRC_EXT] = (unsigned int)(user_pbase>>32); 1159 dma_vbase[channel_id * DMA_SPAN + DMA_DST] = (unsigned int)(device_pbase); 1160 dma_vbase[channel_id * DMA_SPAN + DMA_DST_EXT] = (unsigned int)(device_pbase>>32); 1161 } 1162 dma_vbase[channel_id * DMA_SPAN + DMA_LEN] = (unsigned int) length; 1163 1164 return 0; 1165 1166 #else // NB_DMA_CHANNELS == 0 1167 _get_lock(&_tty_put_lock); 1168 _puts("\n[GIET ERROR] in _dma_transfer() : NB_DMA_CHANNELS == 0"); 1169 _release_lock(&_tty_put_lock); 1170 return 1; 1171 #endif 1172 1038 1173 } // end _dma_transfer() 1039 1174 … … 1047 1182 // (1 == read error / 2 == DMA idle error / 3 == write error) 1048 1183 ////////////////////////////////////////////////////////////////////////////////// 1049 unsigned int _dma_completed() {1050 #if NB_DMAS_MAX > 0 1051 unsigned int task_id = _get_proc_task_id(); 1052 unsigned int dma_id = _get_context_slot( task_id,CTX_DMA_ID);1184 unsigned int _dma_completed() 1185 { 1186 #if NB_DMA_CHANNELS > 0 1187 unsigned int dma_id = _get_context_slot(CTX_DMA_ID); 1053 1188 unsigned int dma_ret; 1054 1189 1055 1190 // busy waiting with a pseudo random delay between bus access 1056 while (_dma_done[dma_id] == 0) { 1191 while (_dma_done[dma_id] == 0) 1192 { 1057 1193 unsigned int delay = (( _proctime() ^ _procid() << 4) & 0x3F) + 1; 1058 1194 asm volatile( … … 1067 1203 } 1068 1204 1069 /* draft support for IOMMU 1070 // unmap the buffer from IOMMU page table if IOMMU is activated 1071 if ( GIET_IOMMU_ACTIVE ) 1072 { 1073 unsigned int* iob_address = (unsigned int*)&seg_iob_base; 1074 1075 unsigned int ix1 = _dma_iommu_ix1 + dma_id; 1076 unsigned int ix2; 1077 1078 for ( ix2 = 0 ; ix2 < _dma_iommu_npages[dma_id] ; ix2++ ) 1079 { 1080 // unmap the page in IOMMU page table 1081 _iommu_inval_pte2( ix1, // PT1 index 1082 ix2 ); // PT2 index 1083 1084 // clear IOMMU TLB 1085 iob_address[IOB_INVAL_PTE] = (ix1 << 21) | (ix2 << 12); 1086 } 1087 } 1088 */ 1205 #if GIET_DEBUG_DMA_DRIVER 1206 _get_lock(&_tty_put_lock); 1207 _puts("\n[GIET DEBUG] DMA COMPLETED at cycle "); 1208 _putd( _proctime() ); 1209 _puts("\n - cluster_id = "); 1210 _putx( dma_id/NB_DMA_CHANNELS ); 1211 _puts("\n - channel_id = "); 1212 _putx( dma_id%NB_DMA_CHANNELS ); 1213 _puts("\n"); 1214 _release_lock(&_tty_put_lock); 1215 #endif 1089 1216 1090 1217 // reset synchronization variables … … 1092 1219 dma_ret = _dma_status[dma_id]; 1093 1220 asm volatile("sync\n"); 1094 _dma_lock[dma_id] = 0; 1221 1222 // _dma_lock[dma_id] = 0; 1095 1223 1096 1224 return dma_ret; 1097 1225 1098 #else // NB_DMAS_MAX== 01226 #else // NB_DMA_CHANNELS == 0 1099 1227 return -1; 1100 1228 #endif 1229 1101 1230 } // end _dma_completed 1231 1102 1232 1103 1233 ////////////////////////////////////////////////////////////////////////////////// … … 1113 1243 // The '_fb_write()', '_fb_read()' and '_fb_completed()' functions use the 1114 1244 // VciMultiDma components (distributed in the clusters) to transfer data 1115 // between the user buffer and the frame buffer. A FBDMA channel is1245 // between the user buffer and the frame buffer. A DMA channel is 1116 1246 // allocated to each task requesting it in the mapping_info data structure. 1117 1247 ////////////////////////////////////////////////////////////////////////////////// … … 1124 1254 // - length : number of bytes to be transfered. 1125 1255 ////////////////////////////////////////////////////////////////////////////////// 1126 unsigned int _fb_sync_write(unsigned int offset, const void * buffer, unsigned int length) { 1127 unsigned char * fb_address = (unsigned char *) &seg_fbf_base + offset; 1256 unsigned int _fb_sync_write( unsigned int offset, 1257 const void* buffer, 1258 unsigned int length) 1259 { 1260 unsigned char* fb_address = (unsigned char *) &seg_fbf_base + offset; 1128 1261 memcpy((void *) fb_address, (void *) buffer, length); 1129 1262 return 0; … … 1138 1271 // - length : number of bytes to be transfered. 1139 1272 ////////////////////////////////////////////////////////////////////////////////// 1140 unsigned int _fb_sync_read(unsigned int offset, const void * buffer, unsigned int length) { 1141 unsigned char * fb_address = (unsigned char *) &seg_fbf_base + offset; 1273 unsigned int _fb_sync_read( unsigned int offset, 1274 const void* buffer, 1275 unsigned int length) 1276 { 1277 unsigned char* fb_address = (unsigned char *) &seg_fbf_base + offset; 1142 1278 memcpy((void *) buffer, (void *) fb_address, length); 1143 1279 return 0; … … 1153 1289 // Returns 0 if success, > 0 if error. 1154 1290 ////////////////////////////////////////////////////////////////////////////////// 1155 unsigned int _fb_write(unsigned int offset, const void * buffer, unsigned int length) { 1156 return _dma_transfer( 1157 0, // frame buffer 1158 0, // write 1159 offset, 1160 (unsigned int) buffer, 1161 length); 1291 unsigned int _fb_write( unsigned int offset, 1292 const void* buffer, 1293 unsigned int length) 1294 { 1295 return _dma_transfer( 0, // frame buffer 1296 0, // write 1297 offset, 1298 (unsigned int) buffer, 1299 length ); 1162 1300 } 1163 1301 … … 1171 1309 // Returns 0 if success, > 0 if error. 1172 1310 ////////////////////////////////////////////////////////////////////////////////// 1173 unsigned int _fb_read(unsigned int offset, const void * buffer, unsigned int length) { 1174 return _dma_transfer( 1175 0, // frame buffer 1176 1, // read 1177 offset, 1178 (unsigned int) buffer, 1179 length); 1311 unsigned int _fb_read( unsigned int offset, 1312 const void* buffer, 1313 unsigned int length ) 1314 { 1315 return _dma_transfer( 0, // frame buffer 1316 1, // read 1317 offset, 1318 (unsigned int) buffer, 1319 length ); 1180 1320 } 1181 1321 … … 1188 1328 // (1 == read error / 2 == DMA idle error / 3 == write error) 1189 1329 ////////////////////////////////////////////////////////////////////////////////// 1190 unsigned int _fb_completed() { 1330 unsigned int _fb_completed() 1331 { 1191 1332 return _dma_completed(); 1192 1333 } … … 1215 1356 // - length : number of bytes to be transfered. 1216 1357 ////////////////////////////////////////////////////////////////////////////////// 1217 unsigned int _nic_sync_write(unsigned int offset, const void * buffer, unsigned int length) { 1218 unsigned char * nic_address = (unsigned char *) &seg_nic_base + offset; 1358 unsigned int _nic_sync_write( unsigned int offset, 1359 const void* buffer, 1360 unsigned int length ) 1361 { 1362 unsigned char* nic_address = (unsigned char *) &seg_nic_base + offset; 1219 1363 memcpy((void *) nic_address, (void *) buffer, length); 1220 1364 return 0; … … 1279 1423 // (1 == read error / 2 == DMA idle error / 3 == write error) 1280 1424 ////////////////////////////////////////////////////////////////////////////////// 1281 unsigned int _nic_completed() { 1425 unsigned int _nic_completed() 1426 { 1282 1427 return _dma_completed(); 1283 1428 } … … 1286 1431 // _heap_info() 1287 1432 // This function returns the information associated to a heap (size and vaddr) 1288 // It uses the global task i d(CTX_GTID_ID, unique for each giet task) and the1289 // vspace i d (CTX_VSID_ID) defined in the context1433 // It uses the global task index (CTX_GTID_ID, unique for each giet task) and the 1434 // vspace index (CTX_VSID_ID) defined in the task context. 1290 1435 /////////////////////////////////////////////////////////////////////////////////// 1291 unsigned int _heap_info(unsigned int * vaddr, unsigned int * size) { 1436 unsigned int _heap_info( unsigned int* vaddr, 1437 unsigned int* size ) 1438 { 1292 1439 mapping_header_t * header = (mapping_header_t *) (&seg_mapping_base); 1293 1440 mapping_task_t * tasks = _get_task_base(header); 1294 1441 mapping_vobj_t * vobjs = _get_vobj_base(header); 1295 1442 mapping_vspace_t * vspaces = _get_vspace_base(header); 1296 unsigned int taskid = _get_context_slot(_get_proc_task_id(), CTX_GTID_ID); 1297 unsigned int vspaceid = _get_context_slot(_get_proc_task_id(), CTX_VSID_ID); 1443 1444 unsigned int taskid = _get_context_slot(CTX_GTID_ID); 1445 unsigned int vspaceid = _get_context_slot(CTX_VSID_ID); 1446 1298 1447 int heap_local_vobjid = tasks[taskid].heap_vobjid; 1299 if (heap_local_vobjid != -1) { 1448 if (heap_local_vobjid != -1) 1449 { 1300 1450 unsigned int vobjheapid = heap_local_vobjid + vspaces[vspaceid].vobj_offset; 1301 1451 *vaddr = vobjs[vobjheapid].vaddr; … … 1303 1453 return 0; 1304 1454 } 1305 else { 1455 else 1456 { 1306 1457 *vaddr = 0; 1307 1458 *size = 0;
Note: See TracChangeset
for help on using the changeset viewer.