Changeset 253 for soft/giet_vm/sys/drivers.c
- Timestamp:
- Aug 14, 2013, 11:19:29 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/sys/drivers.c
r249 r253 5 5 // Copyright (c) UPMC-LIP6 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 // The drivers.c and drivers.h files are part ot the GIET-VM nano kernel. 7 // The drivers.c and drivers.h files are part ot the GIET-VM kernel. 8 // 8 9 // They contains the drivers for the peripherals available in the SoCLib library: 9 10 // - vci_multi_tty … … 11 12 // - vci_multi_dma 12 13 // - vci_multi_icu 13 // - vci_xicu & vci_multi_icu14 // - vci_xicu 14 15 // - vci_gcd 15 16 // - vci_frame_buffer 16 17 // - vci_block_device 17 // 18 // For the peripherals replicated in each cluster (ICU, TIMER, DMA), 18 // - vci_multi_nic 19 // - vci_chbuf_dma 20 // 21 // For the peripherals replicated in each cluster (ICU, TIMER, XCU, DMA, MMC), 19 22 // the corresponding (virtual) base addresses must be completed by an offset 20 23 // depending on the cluster index. 21 //22 // The following global parameter must be defined in the giet_config.h file:23 // - GIET_CLUSTER_INCREMENT24 24 // 25 25 // The following global parameters must be defined in the hard_config.h file: … … 32 32 // The following virtual base addresses must be defined in the giet_vsegs.ld file: 33 33 // - seg_icu_base 34 // - seg_xcu_base 34 35 // - seg_tim_base 35 36 // - seg_dma_base … … 42 43 // - seg_iob_base 43 44 // - seg_mmc_base 44 // 45 // - vseg_cluster_increment 45 46 /////////////////////////////////////////////////////////////////////////////////// 46 47 … … 68 69 #if (NB_PROCS_MAX > 8) 69 70 # error: NB_PROCS_MAX cannot be larger than 8! 70 #endif71 72 #if !defined(GIET_CLUSTER_INCREMENT)73 # error: You must define GIET_CLUSTER_INCREMENT in the giet_config.h file74 71 #endif 75 72 … … 153 150 // The (virtual) base address of the associated segment is: 154 151 // 155 // timer_address = seg_icu_base + cluster_id * GIET_CLUSTER_INCREMENT 156 // 157 // - cluster id is an explicit argument of all access functions 158 // - seg_icu_base must be defined in the giet_vsegs.ld file 159 // - GIET_CLUSTER_INCREMENT must be defined in the giet_config.h file 152 // timer_address = seg_tim_base + cluster_id * vseg_cluster_increment 153 // or timer_address = seg_xcu_base + cluster_id * vseg_cluster_increment 154 // 160 155 //////////////////////////////////////////////////////////////////////////////// 161 156 … … 184 179 185 180 #if USE_XICU 186 unsigned int * timer_address = (unsigned int *) ((char *) &seg_icu_base +187 (cluster_id * GIET_CLUSTER_INCREMENT));181 unsigned int* timer_address = (unsigned int *) ((unsigned int)&seg_xcu_base + 182 (cluster_id * (unsigned int)&vseg_cluster_increment)); 188 183 189 184 timer_address[XICU_REG(XICU_PTI_PER, local_id)] = period; 190 185 #else 191 unsigned int* timer_address = (unsigned int *) (( char *)&seg_tim_base +192 (cluster_id * GIET_CLUSTER_INCREMENT));186 unsigned int* timer_address = (unsigned int *) ((unsigned int)&seg_tim_base + 187 (cluster_id * (unsigned int)&vseg_cluster_increment)); 193 188 194 189 timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period; … … 212 207 213 208 #if USE_XICU 214 unsigned int * timer_address = (unsigned int *) (( char *) &seg_icu_base +215 (cluster_id * GIET_CLUSTER_INCREMENT));209 unsigned int * timer_address = (unsigned int *) ((unsigned int)&seg_xcu_base + 210 (cluster_id * (unsigned int)&vseg_cluster_increment)); 216 211 217 212 timer_address[XICU_REG(XICU_PTI_PER, local_id)] = 0; 218 213 #else 219 unsigned int* timer_address = (unsigned int *) (( char *)&seg_tim_base +220 (cluster_id * GIET_CLUSTER_INCREMENT));214 unsigned int* timer_address = (unsigned int *) ((unsigned int)&seg_tim_base + 215 (cluster_id * (unsigned int)&vseg_cluster_increment)); 221 216 222 217 timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0; … … 224 219 return 0; 225 220 } 226 227 221 228 222 ////////////////////////////////////////////////////////////////////////////// … … 242 236 243 237 #if USE_XICU 244 unsigned int * timer_address = (unsigned int *) (( char *) &seg_icu_base +245 (cluster_id * GIET_CLUSTER_INCREMENT));238 unsigned int * timer_address = (unsigned int *) ((unsigned int)&seg_xcu_base + 239 (cluster_id * (unsigned int)&vseg_cluster_increment)); 246 240 247 241 unsigned int bloup = timer_address[XICU_REG(XICU_PTI_ACK, local_id)]; 248 242 bloup++; // to avoid a warning 249 243 #else 250 unsigned int * timer_address = (unsigned int *) (( char *)&seg_tim_base +251 (cluster_id * GIET_CLUSTER_INCREMENT));244 unsigned int * timer_address = (unsigned int *) ((unsigned int)&seg_tim_base + 245 (cluster_id * (unsigned int)&vseg_cluster_increment)); 252 246 253 247 timer_address[local_id * TIMER_SPAN + TIMER_RESETIRQ] = 0; … … 255 249 return 0; 256 250 } 257 258 259 251 260 252 /////////////////////////////////////////////////////////////////////// … … 263 255 // This function resets the period at the end of which 264 256 // an interrupt is sent. To do so, we re-write the period 265 // in ithe proper register, what causes the count to restart.257 // in the proper register, what causes the count to restart. 266 258 // The period value is read from the same (TIMER_PERIOD) register, 267 259 // this is why in appearance we do nothing useful (read a value … … 269 261 // This function is called during a context switch (user or preemptive) 270 262 /////////////////////////////////////////////////////////////////////// 271 unsigned int _timer_reset_irq_cpt(unsigned int cluster_id, unsigned int local_id) { 263 unsigned int _timer_reset_irq_cpt( unsigned int cluster_id, 264 unsigned int local_id) { 272 265 // parameters checking 273 266 if (cluster_id >= NB_CLUSTERS) { … … 279 272 280 273 #if USE_XICU 281 unsigned int * timer_address = (unsigned int *) ((char *) &seg_icu_base + (cluster_id * GIET_CLUSTER_INCREMENT)); 274 unsigned int * timer_address = (unsigned int *) ((unsigned int) &seg_xcu_base + 275 (cluster_id * (unsigned int)&vseg_cluster_increment)); 276 282 277 unsigned int timer_period = timer_address[XICU_REG(XICU_PTI_PER, local_id)]; 283 278 284 // we write 0 first because if the timer is currently running, the corresponding timer counter is not reset 279 // we write 0 first because if the timer is currently running, 280 //the corresponding timer counter is not reset 285 281 timer_address[XICU_REG(XICU_PTI_PER, local_id)] = 0; 286 282 timer_address[XICU_REG(XICU_PTI_PER, local_id)] = timer_period; 287 283 #else 288 284 // We suppose that the TIMER_MODE register value is 0x3 289 unsigned int * timer_address = (unsigned int *) ((char *) &seg_tim_base + (cluster_id * GIET_CLUSTER_INCREMENT)); 285 unsigned int * timer_address = (unsigned int *) ((unsigned int)&seg_tim_base + 286 (cluster_id * (unsigned int)&vseg_cluster_increment)); 287 290 288 unsigned int timer_period = timer_address[local_id * TIMER_SPAN + TIMER_PERIOD]; 291 289 … … 295 293 return 0; 296 294 } 297 298 295 299 296 ///////////////////////////////////////////////////////////////////////////////// … … 412 409 // This hardware component is replicated in all clusters. 413 410 // There is one vci_multi_icu (or vci_xicu) component per cluster, 414 // and the number of independant ICUs is equal to NB_PROCS_MAX,411 // and the number of ICU channels is equal to NB_PROCS_MAX, 415 412 // because there is one private interrupt controler per processor. 416 413 //////////////////////////////////////////////////////////////////////////////// 417 414 // The (virtual) base address of the associated segment is: 418 415 // 419 // icu_address = seg_icu_base + cluster_id * GIET_CLUSTER_INCREMENT 420 // 421 // - cluster id is an explicit argument of all access functions 422 // - seg_icu_base must be defined in the giet_vsegs.ld file 423 // - GIET_CLUSTER_INCREMENT must be defined in the giet_config.h file 416 // icu_address = seg_icu_base + cluster_id * vseg_cluster_increment 417 // or icu_address = seg_xcu_base + cluster_id * vseg_cluster_increment 418 // 424 419 //////////////////////////////////////////////////////////////////////////////// 425 420 … … 434 429 unsigned int proc_id, 435 430 unsigned int value, 436 unsigned int is_ timer)431 unsigned int is_PTI) 437 432 { 438 433 // parameters checking … … 440 435 if (proc_id >= NB_PROCS_MAX) return 1; 441 436 442 unsigned int * icu_address = (unsigned int *) ((char *) &seg_icu_base +443 (cluster_id * GIET_CLUSTER_INCREMENT));444 437 #if USE_XICU 445 if (is_timer) 438 unsigned int * icu_address = (unsigned int *) ((unsigned int)&seg_xcu_base + 439 (cluster_id * (unsigned int)&vseg_cluster_increment)); 440 if (is_PTI) 446 441 { 447 442 icu_address[XICU_REG(XICU_MSK_PTI_ENABLE, proc_id)] = value; … … 452 447 } 453 448 #else 449 unsigned int * icu_address = (unsigned int *) ((unsigned int)&seg_icu_base + 450 (cluster_id * (unsigned int)&vseg_cluster_increment)); 451 454 452 icu_address[proc_id * ICU_SPAN + ICU_MASK_SET] = value; 455 453 #endif 456 454 return 0; 457 455 } 458 459 456 460 457 //////////////////////////////////////////////////////////////////////////////// … … 473 470 if (proc_id >= NB_PROCS_MAX) return 1; 474 471 475 unsigned int * icu_address = (unsigned int *) ((char *) &seg_icu_base +476 (cluster_id * GIET_CLUSTER_INCREMENT));477 472 #if USE_XICU 473 unsigned int * icu_address = (unsigned int *) ((unsigned int)&seg_xcu_base + 474 (cluster_id * (unsigned int)&vseg_cluster_increment)); 475 478 476 unsigned int prio = icu_address[XICU_REG(XICU_PRIO, proc_id)]; 479 477 unsigned int pti_ok = (prio & 0x00000001); … … 488 486 else { *buffer = 32; } 489 487 #else 488 unsigned int * icu_address = (unsigned int *) ((unsigned int)&seg_icu_base + 489 (cluster_id * (unsigned int)&vseg_cluster_increment)); 490 490 491 *buffer = icu_address[proc_id * ICU_SPAN + ICU_IT_VECTOR]; 491 492 #endif 492 493 return 0; 493 494 } 494 495 495 496 496 //////////////////////////////////////////////////////////////////////////////// … … 912 912 // The (virtual) base address of the associated segment is: 913 913 // 914 // dma_address = seg_dma_base + cluster_id * GIET_CLUSTER_INCREMENT 915 // 916 // - seg_dma_base must be defined in the giet_vsegs.ld file 917 // - GIET_CLUSTER_INCREMENT must be defined in the giet_config.h file 914 // dma_address = seg_dma_base + cluster_id * vseg_cluster_increment 915 // 918 916 //////////////////////////////////////////////////////////////////////////////// 919 917 … … 942 940 943 941 // compute DMA base address 944 unsigned int * dma_address = (unsigned int *) (( char *)&seg_dma_base +945 (cluster_id * GIET_CLUSTER_INCREMENT));942 unsigned int * dma_address = (unsigned int *) ((unsigned int)&seg_dma_base + 943 (cluster_id * (unsigned int)&vseg_cluster_increment)); 946 944 947 945 dma_address[channel_id * DMA_SPAN + DMA_RESET] = 0; … … 951 949 #endif 952 950 } 953 954 951 955 952 ////////////////////////////////////////////////////////////////////////////////// … … 966 963 967 964 // compute DMA base address 968 unsigned int * dma_address = (unsigned int *) (( char *)&seg_dma_base +969 (cluster_id * GIET_CLUSTER_INCREMENT));965 unsigned int * dma_address = (unsigned int *) ((unsigned int)&seg_dma_base + 966 (cluster_id * (unsigned int)&vseg_cluster_increment)); 970 967 971 968 *status = dma_address[channel_id * DMA_SPAN + DMA_LEN]; … … 975 972 #endif 976 973 } 977 978 974 979 975 ////////////////////////////////////////////////////////////////////////////////// … … 1031 1027 unsigned int cluster_id = dma_id / NB_DMA_CHANNELS; 1032 1028 unsigned int channel_id = dma_id % NB_DMA_CHANNELS; 1033 unsigned int * dma_vbase = (unsigned int *) ((char *)&seg_dma_base +1034 (cluster_id * GIET_CLUSTER_INCREMENT));1029 unsigned int * dma_vbase = (unsigned int *) ((unsigned int)&seg_dma_base + 1030 (cluster_id * (unsigned int)&vseg_cluster_increment)); 1035 1031 // get page table address 1036 1032 unsigned int user_ptab = _get_context_slot(CTX_PTAB_ID); … … 1196 1192 } // end _dma_transfer() 1197 1193 1198 1199 1194 ////////////////////////////////////////////////////////////////////////////////// 1200 1195 // _dma_completed() … … 1257 1252 // VciFrameBuffer driver 1258 1253 ////////////////////////////////////////////////////////////////////////////////// 1259 // The vci_frame_buffer device can be accessed directly by software with memcpy(), 1260 // or it can be accessed through a multi-channels DMA component: 1254 // There three methods to access the VciFrameBuffer device: 1261 1255 // 1262 // The '_fb_sync_write' and '_fb_sync_read' functions use a memcpy strategy to1263 // implement the transfer between a data buffer (user space) and the frame1256 // 1) The _fb_sync_write() and _fb_sync_read() functions use a memcpy strategy 1257 // to implement the transfer between a data buffer (user space) and the frame 1264 1258 // buffer (kernel space). They are blocking until completion of the transfer. 1265 1259 // 1266 // The '_fb_write()', '_fb_read()' and '_fb_completed()' functions use the 1267 // VciMultiDma components (distributed in the clusters) to transfer data 1268 // between the user buffer and the frame buffer. A DMA channel is 1269 // allocated to each task requesting it in the mapping_info data structure. 1260 // 2) The _fb_dma_write(), _fb_dma_read() and _fb_mdma_completed() functions use 1261 // the VciMultiDma components (distributed in the clusters) to transfer data 1262 // between the user buffer and the frame buffer. 1263 // A DMA channel is allocated to the task requesting it in the mapping_info, 1264 // and stored in the task context. 1265 // 1266 // 3) The _fb_cma_init(), _fb_cma_write() and _fb_cma_stop() functions use 1267 // the VciChbufDma component (non replicated) to transfer a flow of images from 1268 // an user space chained buffer (two buffers) to the frame buffer. 1269 // A CMA channel is allocated to the task requesting it in the mapping_info, 1270 // and stored in the task context. 1270 1271 ////////////////////////////////////////////////////////////////////////////////// 1271 1272 … … 1306 1307 1307 1308 ////////////////////////////////////////////////////////////////////////////////// 1308 // _fb_ write()1309 // _fb_dma_write() 1309 1310 // Transfer data from a memory buffer to the frame_buffer device using DMA. 1310 1311 // - offset : offset (in bytes) in the frame buffer. … … 1313 1314 // Returns 0 if success, > 0 if error. 1314 1315 ////////////////////////////////////////////////////////////////////////////////// 1315 unsigned int _fb_ write( unsigned int offset,1316 const void* buffer,1317 unsigned int length)1316 unsigned int _fb_dma_write( unsigned int offset, 1317 const void* buffer, 1318 unsigned int length) 1318 1319 { 1319 1320 return _dma_transfer( 0, // frame buffer … … 1323 1324 length ); 1324 1325 } 1325 1326 1327 ////////////////////////////////////////////////////////////////////////////////// 1328 // _fb_read() 1326 ////////////////////////////////////////////////////////////////////////////////// 1327 // _fb_dma_read() 1329 1328 // Transfer data from the frame_buffer device to a memory buffer using DMA. 1330 1329 // - offset : offset (in bytes) in the frame buffer. 1331 // - buffer : base address of the memorybuffer.1332 // - length : number of bytes to be transfered.1330 // - buffer : virtual base address of the user buffer. 1331 // - length : buffer size (number of bytes) 1333 1332 // Returns 0 if success, > 0 if error. 1334 1333 ////////////////////////////////////////////////////////////////////////////////// 1335 unsigned int _fb_ read( unsigned int offset,1336 const void* buffer,1337 unsigned int length )1334 unsigned int _fb_dma_read( unsigned int offset, 1335 const void* buffer, 1336 unsigned int length ) 1338 1337 { 1339 1338 return _dma_transfer( 0, // frame buffer … … 1343 1342 length ); 1344 1343 } 1345 1346 1347 1344 ////////////////////////////////////////////////////////////////////////////////// 1348 1345 // _fb_completed() … … 1352 1349 // (1 == read error / 2 == DMA idle error / 3 == write error) 1353 1350 ////////////////////////////////////////////////////////////////////////////////// 1354 unsigned int _fb_ completed()1351 unsigned int _fb_dma_completed() 1355 1352 { 1356 1353 return _dma_completed(); 1357 1354 } 1358 1355 1356 // This structure contains two chbuf descriptors that can be used by 1357 // the VciChbufDma component to tranfer a flow of images: 1358 // - The SRC chbuf descriptor contain two slots (two user buffers) 1359 // - The DST chbuf descriptor contains only one slot (frame buffer) 1360 typedef struct fb_cma_channel_s 1361 { 1362 paddr_t buf0; // physical address + status for user buffer 0 1363 paddr_t buf1; // physical address + status for user buffer 1 1364 paddr_t fbf; // physical address + status for frame buffer 1365 } fb_cma_channel_t; 1366 1367 in_unckdata volatile fb_cma_channel_t _fb_cma_channel[NB_CMA_CHANNELS]; 1368 1369 ////////////////////////////////////////////////////////////////////////////////// 1370 // _fb_cma_init() 1371 // This function does two things: 1372 // 1) Initialises the SRC chbuf descriptor (two buffers), and the DST 1373 // chbuf descriptor (one single frame buffer), after translating 1374 // virtual addresses to physical addresses, and checking access rights. 1375 // 2) Starts the CMA hardware channel, that will permanently try to display 1376 // images as soon as the SRC buffers are filled. 1377 // Arguments are: 1378 // - vbase0 : virtual base address of the first user buffer. 1379 // - vbase1 : virtual base address of the second user buffer. 1380 // - length : user buffer size (number of bytes) 1381 // Returns 0 if success, > 0 if error 1382 ////////////////////////////////////////////////////////////////////////////////// 1383 unsigned int _fb_cma_init( const void* vbase0, 1384 const void* vbase1, 1385 unsigned int length ) 1386 { 1387 #if NB_CMA_CHANNELS > 0 1388 1389 unsigned int channel_id; // CMA channel index 1390 unsigned int user_ptab; // page table virtual address 1391 unsigned int ko; // unsuccessfull V2P translation 1392 unsigned int vpn; // virtual page number 1393 unsigned int flags; // protection flags 1394 unsigned int ppn; // physical page number 1395 paddr_t src_chbuf_pbase; // physical address for SRC chbuf descriptor 1396 paddr_t dst_chbuf_pbase; // physical address for SRC chbuf descriptor 1397 1398 // get CMA channel index 1399 channel_id = _get_context_slot(CTX_CMA_ID); 1400 if ( channel_id >= NB_CMA_CHANNELS ) 1401 { 1402 _get_lock(&_tty_put_lock); 1403 _puts("\n[GIET ERROR] in _fb_cma_init() : CMA channel index too large\n"); 1404 _release_lock(&_tty_put_lock); 1405 return 1; 1406 } 1407 1408 // check user buffer virtual addresses and length alignment 1409 if ( ((unsigned int)vbase0 & 0x3) || ((unsigned int)vbase1 & 0x3) || (length & 0x3) ) 1410 { 1411 _get_lock(&_tty_put_lock); 1412 _puts("\n[GIET ERROR] in _fb_cma_init() : user buffer not word aligned\n"); 1413 _release_lock(&_tty_put_lock); 1414 return 1; 1415 } 1416 1417 // get page table virtual address 1418 user_ptab = _get_context_slot(CTX_PTAB_ID); 1419 1420 // get frame buffer virtual address 1421 1422 // compute and register frame buffer physical address 1423 vpn = ((unsigned int)&seg_fbf_base) >> 12; 1424 ko = _v2p_translate( (page_table_t*) user_ptab, 1425 vpn, 1426 &ppn, 1427 &flags ); 1428 if (ko) 1429 { 1430 _get_lock(&_tty_put_lock); 1431 _puts("\n[GIET ERROR] in _fb_cma_init() : frame buffer unmapped\n"); 1432 _release_lock(&_tty_put_lock); 1433 return 1; 1434 } 1435 _fb_cma_channel[channel_id].fbf = ((paddr_t)ppn << 12) | (vpn & 0x00000FFF); 1436 1437 // Compute and register first user buffer physical address 1438 vpn = (unsigned int)vbase0 >> 12; 1439 ko = _v2p_translate( (page_table_t*) user_ptab, 1440 vpn, 1441 &ppn, 1442 &flags ); 1443 if (ko) 1444 { 1445 _get_lock(&_tty_put_lock); 1446 _puts("\n[GIET ERROR] in _fb_cma_init() : user buffer 0 unmapped\n"); 1447 _release_lock(&_tty_put_lock); 1448 return 1; 1449 } 1450 if ((flags & PTE_U) == 0) 1451 { 1452 _get_lock(&_tty_put_lock); 1453 _puts("[GIET ERROR] in _fb_cma_init() : user buffer 0 not in user space\n"); 1454 _release_lock(&_tty_put_lock); 1455 return 1; 1456 } 1457 _fb_cma_channel[channel_id].buf0 = ((paddr_t)ppn << 12) | (vpn & 0x00000FFF); 1458 1459 // Compute and register second user buffer physical address 1460 vpn = (unsigned int)vbase1 >> 12; 1461 ko = _v2p_translate( (page_table_t*) user_ptab, 1462 vpn, 1463 &ppn, 1464 &flags ); 1465 if (ko) 1466 { 1467 _get_lock(&_tty_put_lock); 1468 _puts("\n[GIET ERROR] in _fb_cma_init() : user buffer 1 unmapped\n"); 1469 _release_lock(&_tty_put_lock); 1470 return 1; 1471 } 1472 if ((flags & PTE_U) == 0) 1473 { 1474 _get_lock(&_tty_put_lock); 1475 _puts("[GIET ERROR] in _fb_cma_init() : user buffer 1 not in user space\n"); 1476 _release_lock(&_tty_put_lock); 1477 return 1; 1478 } 1479 _fb_cma_channel[channel_id].buf1 = ((paddr_t)ppn << 12) | (vpn & 0x00000FFF); 1480 1481 // Compute physical adress of the SRC chbuf descriptor 1482 vpn = ((unsigned int)(&_fb_cma_channel[channel_id].buf0)) >> 12; 1483 ko = _v2p_translate( (page_table_t*) user_ptab, 1484 vpn, 1485 &ppn, 1486 &flags ); 1487 if (ko) 1488 { 1489 _get_lock(&_tty_put_lock); 1490 _puts("\n[GIET ERROR] in _fb_cma_init() : SRC chbuf descriptor unmapped\n"); 1491 _release_lock(&_tty_put_lock); 1492 return 1; 1493 } 1494 src_chbuf_pbase = (((paddr_t)ppn) << 12) | (vpn & 0x00000FFF); 1495 1496 // Compute physical adress of the DST chbuf descriptor 1497 vpn = ((unsigned int)(&_fb_cma_channel[channel_id].fbf)) >> 12; 1498 ko = _v2p_translate( (page_table_t*) user_ptab, 1499 vpn, 1500 &ppn, 1501 &flags ); 1502 if (ko) 1503 { 1504 _get_lock(&_tty_put_lock); 1505 _puts("\n[GIET ERROR] in _fb_cma_init() : DST chbuf descriptor unmapped\n"); 1506 _release_lock(&_tty_put_lock); 1507 return 1; 1508 } 1509 dst_chbuf_pbase = (((paddr_t)ppn) << 12) | (vpn & 0x00000FFF); 1510 1511 // CMA channel activation 1512 unsigned int* cma_vbase = (unsigned int *)&seg_cma_base; 1513 unsigned int offset = channel_id * CHBUF_CHANNEL_SPAN; 1514 1515 cma_vbase[offset + CHBUF_SRC_DESC] = (unsigned int)(src_chbuf_pbase & 0xFFFFFFFF); 1516 cma_vbase[offset + CHBUF_SRC_EXT] = (unsigned int)(src_chbuf_pbase >> 32); 1517 cma_vbase[offset + CHBUF_SRC_NBUFS] = 2; 1518 cma_vbase[offset + CHBUF_DST_DESC] = (unsigned int)(dst_chbuf_pbase & 0xFFFFFFFF); 1519 cma_vbase[offset + CHBUF_DST_EXT] = (unsigned int)(dst_chbuf_pbase >> 32); 1520 cma_vbase[offset + CHBUF_DST_NBUFS] = 1; 1521 cma_vbase[offset + CHBUF_BUF_SIZE] = length; 1522 cma_vbase[offset + CHBUF_PERIOD] = 300; 1523 cma_vbase[offset + CHBUF_RUN] = 1; 1524 1525 return 0; 1526 1527 #else 1528 1529 _get_lock(&_tty_put_lock); 1530 _puts("\n[GIET ERROR] in _fb_cma_init() : no CMA channel allocated\n"); 1531 _release_lock(&_tty_put_lock); 1532 1533 return 1; 1534 #endif 1535 } 1536 ////////////////////////////////////////////////////////////////////////////////// 1537 // _fb_cma_write() 1538 // This function updates the status of the SRC and DST chbuf descriptors 1539 // to allows the CMA component to transfer another buffer. 1540 // - buffer_id : user buffer index (0 => buf0 / not 0 => buf1) 1541 // Returns 0 if success, > 0 if error 1542 ////////////////////////////////////////////////////////////////////////////////// 1543 unsigned int _fb_cma_write( unsigned int buffer_id ) 1544 { 1545 #if NB_CMA_CHANNELS > 0 1546 1547 // get CMA channel index 1548 unsigned int channel_id = _get_context_slot(CTX_CMA_ID); 1549 if ( channel_id >= NB_CMA_CHANNELS ) 1550 { 1551 _get_lock(&_tty_put_lock); 1552 _puts("\n[GIET ERROR] in _fb_cma_write() : CMA channel index too large\n"); 1553 _release_lock(&_tty_put_lock); 1554 return 1; 1555 } 1556 // set SRC full 1557 if ( buffer_id == 0 ) 1558 _fb_cma_channel[channel_id].buf0 = _fb_cma_channel[channel_id].buf0 1559 | 0x8000000000000000ULL; 1560 else 1561 _fb_cma_channel[channel_id].buf1 = _fb_cma_channel[channel_id].buf1 1562 | 0x8000000000000000ULL; 1563 // set DST empty 1564 _fb_cma_channel[channel_id].fbf = _fb_cma_channel[channel_id].fbf 1565 & 0x7FFFFFFFFFFFFFFFULL; 1566 return 0; 1567 1568 #else 1569 1570 _get_lock(&_tty_put_lock); 1571 _puts("\n[GIET ERROR] in _fb_cma_channel() : no CMA channel allocated\n"); 1572 _release_lock(&_tty_put_lock); 1573 return 1; 1574 1575 #endif 1576 } 1577 ////////////////////////////////////////////////////////////////////////////////// 1578 // _fb_cma_stop() 1579 // This function desactivates the CMA channel allocated to the calling task. 1580 // Returns 0 if success, > 0 if error 1581 ////////////////////////////////////////////////////////////////////////////////// 1582 unsigned int _fb_cma_stop( unsigned int buffer_id ) 1583 { 1584 #if NB_CMA_CHANNELS > 0 1585 1586 // get CMA channel allocated 1587 unsigned int channel_id = _get_context_slot(CTX_CMA_ID); 1588 if ( channel_id >= NB_CMA_CHANNELS ) 1589 { 1590 _get_lock(&_tty_put_lock); 1591 _puts("\n[GIET ERROR] in _fb_cma_stop() : CMA channel index too large\n"); 1592 _release_lock(&_tty_put_lock); 1593 return 1; 1594 } 1595 // CMA channel desactivation 1596 unsigned int* cma_vbase = (unsigned int *)&seg_cma_base; 1597 unsigned int offset = channel_id * CHBUF_CHANNEL_SPAN; 1598 cma_vbase[offset + CHBUF_RUN] = 0; 1599 return 0; 1600 1601 #else 1602 1603 _get_lock(&_tty_put_lock); 1604 _puts("\n[GIET ERROR] in _fb_cma_stop() : no CMA channel allocated\n"); 1605 _release_lock(&_tty_put_lock); 1606 return 1; 1607 1608 #endif 1609 } 1610 1359 1611 ////////////////////////////////////////////////////////////////////////////////// 1360 1612 // VciMultiNic driver 1361 1613 ////////////////////////////////////////////////////////////////////////////////// 1362 1614 // The VciMultiNic device can be accessed directly by software with memcpy(), 1363 // or it can be accessed through a multi-channels DMA component:1615 // or it can be accessed through a multi-channels CMA component: 1364 1616 // 1365 1617 // The '_nic_sync_write' and '_nic_sync_read' functions use a memcpy strategy to … … 1367 1619 // buffer (kernel space). They are blocking until completion of the transfer. 1368 1620 // 1369 // The '_nic_write()', '_nic_read()' and '_nic_completed()' functions use the 1370 // VciMultiDma components (distributed in the clusters) to transfer data 1371 // between the user buffer and the NIC. A NIDMA channel is allocated to each 1372 // task requesting it in the mapping_info data structure. 1621 // The _nic_cma_init() and _nic_cma_stop() functions use the VciChbufDma component 1622 // to transfer a flow of packets from the NIC RX hard chbuf (two containers) 1623 // to an user RX chbuf (two containers), and to transfer another flow of packets 1624 // from an user TX chbuf (two containers) to the NIC TX chbuf (two containers). 1625 // One NIC channel and two CMA channels must be allocated to the task 1626 // in the mapping_info data structure. 1373 1627 ////////////////////////////////////////////////////////////////////////////////// 1374 1628 … … 1376 1630 // _nic_sync_write() 1377 1631 // Transfer data from an memory buffer to the NIC device using a memcpy. 1378 // - offset : offset (in bytes) in the frame buffer.1379 1632 // - buffer : base address of the memory buffer. 1380 1633 // - length : number of bytes to be transfered. 1381 1634 ////////////////////////////////////////////////////////////////////////////////// 1382 unsigned int _nic_sync_write( unsigned int offset, 1383 const void* buffer, 1635 unsigned int _nic_sync_write( const void* buffer, 1384 1636 unsigned int length ) 1385 1637 { 1386 unsigned char* nic_address = (unsigned char *) &seg_nic_base + offset; 1387 memcpy((void *) nic_address, (void *) buffer, length); 1388 return 0; 1389 } 1390 1391 1638 // To be defined 1639 // unsigned char* nic_address = (unsigned char *) &seg_nic_base; 1640 // memcpy((void *) nic_address, (void *) buffer, length); 1641 return 0; 1642 } 1392 1643 ////////////////////////////////////////////////////////////////////////////////// 1393 1644 // _nic_sync_read() 1394 1645 // Transfer data from the NIC device to a memory buffer using a memcpy. 1395 // - offset : offset (in bytes) in the frame buffer.1396 1646 // - buffer : base address of the memory buffer. 1397 1647 // - length : number of bytes to be transfered. 1398 1648 ////////////////////////////////////////////////////////////////////////////////// 1399 unsigned int _nic_sync_read(unsigned int offset, const void * buffer, unsigned int length) { 1400 unsigned char *nic_address = (unsigned char *) &seg_nic_base + offset; 1401 memcpy((void *) buffer, (void *) nic_address, length); 1402 return 0; 1403 } 1404 1405 1406 ////////////////////////////////////////////////////////////////////////////////// 1407 // _nic_write() 1408 // Transfer data from a memory buffer to the NIC device using DMA. 1409 // - offset : offset (in bytes) in the frame buffer. 1410 // - buffer : base address of the memory buffer. 1411 // - length : number of bytes to be transfered. 1649 unsigned int _nic_sync_read( const void* buffer, 1650 unsigned int length ) 1651 { 1652 // To be defined 1653 // unsigned char* nic_address = (unsigned char *) &seg_nic_base; 1654 // memcpy((void *) buffer, (void *) nic_address, length); 1655 return 0; 1656 } 1657 ////////////////////////////////////////////////////////////////////////////////// 1658 // _nic_cma_rx_init() 1412 1659 // Returns 0 if success, > 0 if error. 1413 1660 ////////////////////////////////////////////////////////////////////////////////// 1414 unsigned int _nic_write(unsigned int offset, const void * buffer, unsigned int length) { 1415 return _dma_transfer( 1416 1, // NIC 1417 0, // write 1418 offset, 1419 (unsigned int) buffer, 1420 length ); 1421 } 1422 1423 1424 ////////////////////////////////////////////////////////////////////////////////// 1425 // _nic_read() 1426 // Transfer data from the NIC device to a memory buffer using DMA. 1427 // - offset : offset (in bytes) in the frame buffer. 1428 // - buffer : base address of the memory buffer. 1429 // - length : number of bytes to be transfered. 1661 unsigned int _nic_cma_rx_init( const void* buf0, 1662 const void* buf1, 1663 unsigned int length ) 1664 { 1665 // to be defined 1666 // unsigned char* nic_address = (unsigned char *) &seg_nic_base; 1667 return 0; 1668 } 1669 ////////////////////////////////////////////////////////////////////////////////// 1670 // _nic_cma_tx_init() 1430 1671 // Returns 0 if success, > 0 if error. 1431 1672 ////////////////////////////////////////////////////////////////////////////////// 1432 unsigned int _nic_read(unsigned int offset, const void * buffer, unsigned int length) { 1433 return _dma_transfer( 1434 1, // NIC 1435 1, // read 1436 offset, 1437 (unsigned int) buffer, 1438 length ); 1439 } 1440 1441 1442 ////////////////////////////////////////////////////////////////////////////////// 1443 // _nic_completed() 1444 // This function checks completion of a DMA transfer to or fom a NIC channel. 1445 // As it is a blocking call, the processor is busy waiting. 1446 // Returns 0 if success, > 0 if error 1447 // (1 == read error / 2 == DMA idle error / 3 == write error) 1448 ////////////////////////////////////////////////////////////////////////////////// 1449 unsigned int _nic_completed() 1450 { 1451 return _dma_completed(); 1452 } 1673 unsigned int _nic_cma_tx_init( const void* buf0, 1674 const void* buf1, 1675 unsigned int length ) 1676 { 1677 // to be defined 1678 // unsigned char* nic_address = (unsigned char *) &seg_nic_base; 1679 return 0; 1680 }////////////////////////////////////////////////////////////////////////////////// 1681 // _nic_cma_stop() 1682 // Returns 0 if success, > 0 if error. 1683 ////////////////////////////////////////////////////////////////////////////////// 1684 unsigned int _nic_cma_stop() 1685 { 1686 // to be defined 1687 // unsigned char* nic_address = (unsigned char *) &seg_nic_base; 1688 return 0; 1689 } 1690 1453 1691 1454 1692 ////////////////////////////////////////////////////////////////////////////////// … … 1458 1696 // as a set of uncached, memory mapped registers. 1459 1697 /////////////////////////////////////////////////////////////////////////////////// 1698 // The (virtual) base address of the associated segment is: 1699 // 1700 // mmc_address = seg_mmc_base + cluster_id * vseg_cluster_increment 1701 // 1702 //////////////////////////////////////////////////////////////////////////////// 1460 1703 1461 1704 /////////////////////////////////////////////////////////////////////////////////// … … 1470 1713 unsigned int cluster_id = (unsigned int)((buf_paddr>>32)/(256/NB_CLUSTERS)); 1471 1714 1472 unsigned int * mmc_address = (unsigned int *) (( char *)&seg_mmc_base +1473 (cluster_id * GIET_CLUSTER_INCREMENT));1715 unsigned int * mmc_address = (unsigned int *) ((unsigned int)&seg_mmc_base + 1716 (cluster_id * (unsigned int)&vseg_cluster_increment)); 1474 1717 1475 1718 // get the lock protecting exclusive access to MEMC … … 1485 1728 mmc_address[MEMC_LOCK] = 0; 1486 1729 } 1730 1487 1731 /////////////////////////////////////////////////////////////////////////////////// 1488 1732 // _heap_info()
Note: See TracChangeset
for help on using the changeset viewer.