Changeset 254 for soft/giet_vm/sys
- Timestamp:
- Aug 27, 2013, 5:41:51 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/sys/drivers.c
r253 r254 715 715 _ioc_iommu_npages = (user_vpn_max - user_vpn_min) + 1; 716 716 717 // invalidate local datacache in case of memory write718 if ( to_mem) _dcache_buf_invalidate((void *) user_vaddr, length);717 // If no IOB, invalidate L1 cache in case of memory write 718 if ( to_mem && (USE_IOB == 0) ) _dcache_buf_invalidate((void *) user_vaddr, length); 719 719 720 720 #if GIET_DEBUG_IOC_DRIVER … … 742 742 #endif 743 743 744 // I nvalidate L2 cache if IO Bridge is used744 // If IOB, invalidate L2 cache in case of memory write 745 745 if ( to_mem && USE_IOB ) _memc_inval( buf_paddr, length ); 746 746 … … 1267 1267 // the VciChbufDma component (non replicated) to transfer a flow of images from 1268 1268 // an user space chained buffer (two buffers) to the frame buffer. 1269 // A CMA channel isallocated to the task requesting it in the mapping_info,1269 // A CMA channel must be allocated to the task requesting it in the mapping_info, 1270 1270 // and stored in the task context. 1271 1271 ////////////////////////////////////////////////////////////////////////////////// … … 1358 1358 // - The SRC chbuf descriptor contain two slots (two user buffers) 1359 1359 // - The DST chbuf descriptor contains only one slot (frame buffer) 1360 1360 1361 typedef struct fb_cma_channel_s 1361 1362 { 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 1363 paddr_t buf0; // physical address + status for user buffer 0 1364 paddr_t buf1; // physical address + status for user buffer 1 1365 paddr_t fbf; // physical address + status for frame buffer 1366 unsigned int length; // buffer length (number of bytes) 1367 unsigned int padding; // unused (just to hahe channel size = 32 bytes) 1365 1368 } fb_cma_channel_t; 1366 1369 1367 in_unckdata volatile fb_cma_channel_t _fb_cma_channel[NB_CMA_CHANNELS]; 1370 in_unckdata volatile fb_cma_channel_t _fb_cma_channel[NB_CMA_CHANNELS] __attribute__((aligned(64))); 1371 in_unckdata volatile paddr_t _fb_cma_desc_paddr[NB_CMA_CHANNELS]; 1368 1372 1369 1373 ////////////////////////////////////////////////////////////////////////////////// 1370 1374 // _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. 1375 // This function uses the _fb_cma_channel[] and _fb_cma_desc_paddr[] arrays, 1376 // that are both indexed by the channel index. 1377 // where each entry contains one fb_cma_channel structure (defining two 1378 // SRC and DST chbuf descriptors), and does four things: 1379 // 1380 // 1) computes the physical addresses for the two source user buffers, for 1381 // the destination frame buffer. It initialises the channel descriptor 1382 // _fb_cma_channel[i], containing the SRC chbuf descriptor (two buffers), 1383 // the DST chbuf descriptor (one single frame buffer), and the buffer length. 1384 // 1385 // 2) computes the physical address for the channel descriptor and register it 1386 // in the _fb_cma_desc_paddr[i]. 1387 // 1388 // 3) makes a SYNC request to L2 cache for channel descriptor, because the 1389 // channel descriptor is directly accessed in XRAM by the CMA component. 1390 // 1391 // 4) Starts the CMA hardware channel, that will poll the channel descriptor 1392 // to fransfer an user buffer to the frame buffer as soon as the source 1393 // user buffer is marked valid. 1394 // 1377 1395 // Arguments are: 1378 1396 // - vbase0 : virtual base address of the first user buffer. … … 1387 1405 #if NB_CMA_CHANNELS > 0 1388 1406 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 1407 unsigned int channel_id; // CMA channel index 1408 unsigned int user_ptab; // page table virtual address 1409 unsigned int ko; // unsuccessfull V2P translation 1410 unsigned int vaddr; // virtual address 1411 unsigned int flags; // protection flags 1412 unsigned int ppn; // physical page number 1413 paddr_t channel_pbase; // physical address of channel descriptor 1397 1414 1398 1415 // get CMA channel index … … 1406 1423 } 1407 1424 1408 // check user buffer virtual addresses and length alignment 1425 // checking size for channel descriptor 1426 if ( sizeof(fb_cma_channel_t) != 32 ) 1427 { 1428 _get_lock(&_tty_put_lock); 1429 _puts("\n[GIET ERROR] in _fb_cma_init() : bad fb_cma_channel size\n"); 1430 _release_lock(&_tty_put_lock); 1431 return 1; 1432 } 1433 1434 // checking channel descriptor alignment (32 bytes) 1435 if ( (unsigned int)(&_fb_cma_channel[channel_id]) & 0x1F ) 1436 { 1437 _get_lock(&_tty_put_lock); 1438 _puts("\n[GIET ERROR] in _fb_cma_init() : bad fb_cma_channel alignment\n"); 1439 _release_lock(&_tty_put_lock); 1440 return 1; 1441 } 1442 1443 // checking user buffer virtual addresses and length alignment 1409 1444 if ( ((unsigned int)vbase0 & 0x3) || ((unsigned int)vbase1 & 0x3) || (length & 0x3) ) 1410 1445 { … … 1418 1453 user_ptab = _get_context_slot(CTX_PTAB_ID); 1419 1454 1420 // get frame buffer virtual address1421 1422 1455 // compute and register frame buffer physical address 1423 v pn = ((unsigned int)&seg_fbf_base) >> 12;1424 ko = _v2p_translate( (page_table_t*) user_ptab,1425 vpn,1456 vaddr = ((unsigned int)&seg_fbf_base); 1457 ko = _v2p_translate( (page_table_t*) user_ptab, 1458 (vaddr >> 12), 1426 1459 &ppn, 1427 1460 &flags ); … … 1433 1466 return 1; 1434 1467 } 1435 _fb_cma_channel[channel_id].fbf = ((paddr_t)ppn << 12) | (v pn& 0x00000FFF);1468 _fb_cma_channel[channel_id].fbf = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF); 1436 1469 1437 1470 // Compute and register first user buffer physical address 1438 v pn = (unsigned int)vbase0 >> 12;1471 vaddr = (unsigned int)vbase0; 1439 1472 ko = _v2p_translate( (page_table_t*) user_ptab, 1440 vpn,1473 (vaddr >> 12), 1441 1474 &ppn, 1442 1475 &flags ); … … 1455 1488 return 1; 1456 1489 } 1457 _fb_cma_channel[channel_id].buf0 = ((paddr_t)ppn << 12) | (v pn& 0x00000FFF);1490 _fb_cma_channel[channel_id].buf0 = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF); 1458 1491 1459 1492 // Compute and register second user buffer physical address 1460 v pn = (unsigned int)vbase1 >> 12;1493 vaddr = (unsigned int)vbase1; 1461 1494 ko = _v2p_translate( (page_table_t*) user_ptab, 1462 vpn,1495 (vaddr >> 12), 1463 1496 &ppn, 1464 1497 &flags ); … … 1477 1510 return 1; 1478 1511 } 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; 1512 _fb_cma_channel[channel_id].buf1 = ((paddr_t)ppn << 12) | (vaddr & 0x00000FFF); 1513 1514 // register buffer length in channel descriptor 1515 _fb_cma_channel[channel_id].length = length; 1516 1517 // Compute and register physical adress of the channel descriptor 1518 vaddr = (unsigned int)(&_fb_cma_channel[channel_id]); 1483 1519 ko = _v2p_translate( (page_table_t*) user_ptab, 1484 vpn,1520 (vaddr >> 12), 1485 1521 &ppn, 1486 1522 &flags ); … … 1488 1524 { 1489 1525 _get_lock(&_tty_put_lock); 1490 _puts("\n[GIET ERROR] in _fb_cma_init() : SRC chbufdescriptor unmapped\n");1526 _puts("\n[GIET ERROR] in _fb_cma_init() : channel descriptor unmapped\n"); 1491 1527 _release_lock(&_tty_put_lock); 1492 1528 return 1; 1493 1529 } 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); 1530 channel_pbase = (((paddr_t)ppn) << 12) | (vaddr & 0x00000FFF); 1531 _fb_cma_desc_paddr[channel_id] = channel_pbase; 1532 1533 #if GIET_DEBUG_CMA_DRIVER 1534 _puts("\n"); 1535 _puts("- fbf pbase = "); 1536 _putl( _fb_cma_channel[channel_id].fbf ); 1537 _puts("\n"); 1538 _puts("- buf0 pbase = "); 1539 _putl( _fb_cma_channel[channel_id].buf0 ); 1540 _puts("\n"); 1541 _puts("- buf1 pbase = "); 1542 _putl( _fb_cma_channel[channel_id].buf1 ); 1543 _puts("\n"); 1544 _puts("- channel pbase = "); 1545 _putl( channel_pbase ); 1546 _puts("\n"); 1547 #endif 1548 1549 // SYNC request for channel descriptor 1550 _memc_sync( channel_pbase, 32 ); 1510 1551 1511 1552 // CMA channel activation … … 1513 1554 unsigned int offset = channel_id * CHBUF_CHANNEL_SPAN; 1514 1555 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);1556 cma_vbase[offset + CHBUF_SRC_DESC] = (unsigned int)(channel_pbase & 0xFFFFFFFF); 1557 cma_vbase[offset + CHBUF_SRC_EXT] = (unsigned int)(channel_pbase >> 32); 1517 1558 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);1559 cma_vbase[offset + CHBUF_DST_DESC] = (unsigned int)(channel_pbase & 0xFFFFFFFF) + 16; 1560 cma_vbase[offset + CHBUF_DST_EXT] = (unsigned int)(channel_pbase >> 32); 1520 1561 cma_vbase[offset + CHBUF_DST_NBUFS] = 1; 1521 1562 cma_vbase[offset + CHBUF_BUF_SIZE] = length; … … 1536 1577 ////////////////////////////////////////////////////////////////////////////////// 1537 1578 // _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. 1579 // This function makes a SYNC request for the source user buffer. 1580 // Then it updates the status of the SRC and DST chbuf descriptors, to allow 1581 // the CMA component to transfer the source user buffer buffer to the destination 1582 // frame buffer, and makes a SYNC request for the channel descriptor. 1583 // 1540 1584 // - buffer_id : user buffer index (0 => buf0 / not 0 => buf1) 1541 1585 // Returns 0 if success, > 0 if error … … 1545 1589 #if NB_CMA_CHANNELS > 0 1546 1590 1591 paddr_t buf_paddr; 1592 unsigned int buf_length; 1593 1547 1594 // get CMA channel index 1548 1595 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 } 1596 1597 // SYNC request for the source user buffer 1598 if ( buffer_id == 0 ) buf_paddr = _fb_cma_channel[channel_id].buf0; 1599 else buf_paddr = _fb_cma_channel[channel_id].buf1; 1600 buf_length = _fb_cma_channel[channel_id].length; 1601 _memc_sync( buf_paddr, buf_length ); 1602 1556 1603 // set SRC full 1557 1604 if ( buffer_id == 0 ) 1558 _fb_cma_channel[channel_id].buf0 = _fb_cma_channel[channel_id].buf0 1559 | 0x8000000000000000ULL; 1605 _fb_cma_channel[channel_id].buf0 = buf_paddr | 0x8000000000000000ULL; 1560 1606 else 1561 _fb_cma_channel[channel_id].buf1 = _fb_cma_channel[channel_id].buf11562 | 0x8000000000000000ULL; 1607 _fb_cma_channel[channel_id].buf1 = buf_paddr | 0x8000000000000000ULL; 1608 1563 1609 // set DST empty 1564 1610 _fb_cma_channel[channel_id].fbf = _fb_cma_channel[channel_id].fbf 1565 1611 & 0x7FFFFFFFFFFFFFFFULL; 1612 1613 // SYNC request for the channel descriptor 1614 buf_paddr = _fb_cma_desc_paddr[channel_id]; 1615 buf_length = 32; 1616 _memc_sync( buf_paddr, buf_length ); 1617 1566 1618 return 0; 1567 1619 … … 1586 1638 // get CMA channel allocated 1587 1639 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 } 1640 1595 1641 // CMA channel desactivation 1596 1642 unsigned int* cma_vbase = (unsigned int *)&seg_cma_base; … … 1704 1750 /////////////////////////////////////////////////////////////////////////////////// 1705 1751 // _memc_inval() 1706 // This function invalidate all cache lines covering a memory buffer defined1752 // This function invalidates all cache lines covering a memory buffer defined 1707 1753 // by the physical base address, and the length. 1708 1754 // The buffer address MSB are used to compute the cluster index. … … 1724 1770 mmc_address[MEMC_BUF_LENGTH] = buf_length; 1725 1771 mmc_address[MEMC_CMD_TYPE] = MEMC_CMD_INVAL; 1772 1773 // release the lock protecting MEMC 1774 mmc_address[MEMC_LOCK] = 0; 1775 } 1776 /////////////////////////////////////////////////////////////////////////////////// 1777 // _memc_sync() 1778 // This function copies to external RAM all cache lines covering a memory buffer 1779 // defined by the physical base address, and the length, if they are dirty. 1780 // The buffer address MSB are used to compute the cluster index. 1781 /////////////////////////////////////////////////////////////////////////////////// 1782 void _memc_sync( paddr_t buf_paddr, 1783 unsigned int buf_length ) 1784 { 1785 unsigned int cluster_id = (unsigned int)((buf_paddr>>32)/(256/NB_CLUSTERS)); 1786 1787 unsigned int * mmc_address = (unsigned int *) ((unsigned int)&seg_mmc_base + 1788 (cluster_id * (unsigned int)&vseg_cluster_increment)); 1789 1790 // get the lock protecting exclusive access to MEMC 1791 while ( mmc_address[MEMC_LOCK] ) { asm volatile("nop"); } 1792 1793 // write inval arguments 1794 mmc_address[MEMC_ADDR_LO] = (unsigned int)buf_paddr; 1795 mmc_address[MEMC_ADDR_HI] = (unsigned int)(buf_paddr>>32); 1796 mmc_address[MEMC_BUF_LENGTH] = buf_length; 1797 mmc_address[MEMC_CMD_TYPE] = MEMC_CMD_SYNC; 1726 1798 1727 1799 // release the lock protecting MEMC
Note: See TracChangeset
for help on using the changeset viewer.