Changeset 169 for soft/giet_vm/sys/drivers.c
- Timestamp:
- Jul 17, 2012, 2:39:10 PM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/sys/drivers.c
r167 r169 85 85 #define in_unckdata __attribute__((section (".unckdata"))) 86 86 87 in_unckdata volatile unsigned int _dma_status[NB_DMAS]; 88 in_unckdata volatile unsigned char _dma_busy[NB_DMAS] = { [0 ... NB_DMAS-1] = 0 }; 89 87 // IOC variables 90 88 in_unckdata volatile unsigned char _ioc_status = 0; 91 89 in_unckdata volatile unsigned char _ioc_done = 0; 92 90 in_unckdata unsigned int _ioc_lock = 0; 93 91 in_unckdata unsigned int _ioc_iommu_ix1 = 0; 94 in_unckdata unsigned int _ioc_iommu_npages = 0; 95 92 in_unckdata unsigned int _ioc_iommu_npages; 93 94 // DMA variables 95 in_unckdata volatile unsigned int _dma_status[NB_DMAS]; 96 in_unckdata volatile unsigned char _dma_busy[NB_DMAS] = { [0 ... NB_DMAS-1] = 0 }; 97 in_unckdata volatile unsigned char _dma_iommu_ix1 = 1; 98 in_unckdata volatile unsigned char _dma_iommu_npages[NB_DMAS]; 99 100 // TTY variables 96 101 in_unckdata volatile unsigned char _tty_get_buf[NB_TTYS]; 97 102 in_unckdata volatile unsigned char _tty_get_full[NB_TTYS] = { [0 ... NB_TTYS-1] = 0 }; 98 in_unckdata unsigned int _tty_put_lock ;103 in_unckdata unsigned int _tty_put_lock = 0; 99 104 100 105 ////////////////////////////////////////////////////////////////////////////// … … 610 615 611 616 // clear IOMMU TLB 612 iob_address[IOB_INVAL_PTE] = (_ioc_iommu_ix1 << 21) | (ix2 ) << 12;617 iob_address[IOB_INVAL_PTE] = (_ioc_iommu_ix1 << 21) | (ix2 << 12); 613 618 } 614 619 } … … 668 673 // implement the transfer between a data buffer (user space) and the frame 669 674 // buffer (kernel space). They are blocking until completion of the transfer. 675 // 670 676 // The '_fb_write()', '_fb_read()' and '_fb_completed()' functions use the DMA 671 677 // coprocessor to transfer data between the user buffer and the frame buffer. 672 678 // These functions use a polling policy to test the global variables _dma_busy[i] 673 679 // and detect the transfer completion. 674 // There is NB_PROCS DMA channels, that are indexed by the proc_id. 680 // There is NB_DMA channels, that are indexed by the dma_id stored in the 681 // task context. 675 682 // The _dma_busy[i] synchronisation variables (one per channel) are set by the OS, 676 // and reset by the ISR.683 // and reset by the DMA ISR. 677 684 ////////////////////////////////////////////////////////////////////////////////// 678 685 … … 692 699 volatile unsigned char *fb_address; 693 700 694 /* buffer must be in user space */ 695 if (((unsigned int)buffer >= 0x80000000) 696 || (((unsigned int)buffer + length ) >= 0x80000000 )) 701 // buffer must be mapped in user space 702 if ( ((unsigned int)buffer + length ) >= 0x80000000 ) 697 703 return 1; 698 704 699 705 fb_address = (unsigned char*)&seg_fb_base + offset; 700 706 701 / * buffer copy */707 // buffer copy 702 708 memcpy((void*)fb_address, (void*)buffer, length); 703 709 … … 720 726 volatile unsigned char *fb_address; 721 727 722 /* parameters checking */ 723 /* buffer must be in user space */ 724 if (((unsigned int)buffer >= 0x80000000) 725 || (((unsigned int)buffer + length ) >= 0x80000000 )) 728 // buffer must be mapped in user space 729 if ( ((unsigned int)buffer + length ) >= 0x80000000 ) 726 730 return 1; 727 731 728 732 fb_address = (unsigned char*)&seg_fb_base + offset; 729 733 730 / * buffer copy */734 // buffer copy 731 735 memcpy((void*)buffer, (void*)fb_address, length); 732 736 … … 735 739 736 740 ////////////////////////////////////////////////////////////////////////////////// 741 // _fb_access() 742 // Transfer data between a memory buffer and the frame_buffer device using DMA. 743 // - to_mem : from frame buffer to memory when true. 744 // - offset : offset (in bytes) in the frame buffer. 745 // - user_vaddr : virtual base address of the memory buffer. 746 // - length : number of bytes to be transfered. 747 // The memory buffer must be mapped in user address space and word-aligned. 748 // The user buffer length must be multiple of 4 bytes. 749 // Returns 0 if success, > 0 if error. 750 ////////////////////////////////////////////////////////////////////////////////// 751 unsigned int _fb_access( unsigned int to_mem, 752 unsigned int offset, 753 unsigned int user_vaddr, 754 unsigned int length ) 755 { 756 static_scheduler_t* psched; // pointer on the current task scheduler 757 unsigned char* fb_base; // frame buffer base address 758 unsigned int* dma_base; // dma component base address 759 unsigned int task_id; // task local index (for scheduler) 760 unsigned int dma_id; // DMA channel index 761 unsigned int vpn; // current virtual page number 762 unsigned int flags; // protection flags 763 unsigned int ppn; // current physical page number 764 unsigned int buf_base; // buffer base address for DMA access 765 unsigned int ppn_first; // first physical page index for user buffer 766 767 fb_base = (unsigned char*)&seg_fb_base + offset; 768 769 psched = &_scheduler[_procid()]; 770 task_id = psched->current; 771 dma_id = psched->context[task_id][CTX_FBDMA_ID]; 772 dma_base = (unsigned int*)&seg_dma_base + (dma_id * DMA_SPAN); 773 774 // check buffer address and ength alignment 775 if ( user_vaddr & 0x3 ) return 1; 776 if ( length & 0x3 ) return 1; 777 778 // get user space page table virtual address 779 unsigned int user_ptp = psched->context[task_id][CTX_PTAB_ID]; 780 781 unsigned int user_vpn_min = user_vaddr >> 12; 782 unsigned int user_vpn_max = (user_vaddr + length - 1) >> 12; 783 unsigned int ix2 = 0; 784 unsigned int ix1 = _dma_iommu_ix1 + dma_id; 785 unsigned int ko; 786 unsigned int i; 787 788 // loop on all virtual pages covering the user buffer 789 for ( vpn = user_vpn_min ; vpn <= user_vpn_max ; vpn++ ) 790 { 791 // get ppn and flags for each vpn 792 ko = _v2p_translate( (page_table_t*)user_ptp, 793 vpn, 794 &ppn, 795 &flags ); 796 797 // check access rights 798 if ( ko ) return 2; // unmapped 799 if ( (flags & PTE_U) == 0 ) return 3; // not in user space 800 if ( ( (flags & PTE_W) == 0 ) && to_mem ) return 4; // not writable 801 802 // save first ppn value 803 if ( ix2 == 0 ) ppn_first = ppn; 804 805 if ( GIET_IOMMU_ACTIVE ) // the user buffer must be remapped in the I/0 space 806 { 807 // check buffer length < 2 Mbytes 808 if ( ix2 > 511 ) return 2; 809 810 // map the physical page in IOMMU page table 811 _iommu_add_pte2( ix1, // PT1 index 812 ix2, // PT2 index 813 ppn, // physical page number 814 flags ); // protection flags 815 } 816 else // no IOMMU : check that physical pages are contiguous 817 { 818 if ( (ppn - ppn_first) != ix2 ) return 5; // split physical buffer 819 } 820 821 // increment page index 822 ix2++; 823 } // end for vpn 824 825 // register the number of pages to be unmapped 826 _dma_iommu_npages[dma_id] = (user_vpn_max - user_vpn_min) + 1; 827 828 // invalidate data cache in case of memory write 829 if ( to_mem ) _dcache_buf_invalidate( (void*)user_vaddr, length ); 830 831 // compute buffer base address for DMA depending on IOMMU activation 832 if ( GIET_IOMMU_ACTIVE ) buf_base = ( ix1 ) << 21 | (user_vaddr & 0xFFF); 833 else buf_base = (ppn_first << 12) | (user_vaddr & 0xFFF); 834 835 836 // waiting until DMA device is available 837 while (_dma_busy[dma_id] != 0) 838 { 839 // busy wait with a pseudo random delay between bus access 840 unsigned int delay = (_proctime() & 0xF) << 4; 841 for (i = 0; i < delay; i++) 842 asm volatile("nop"); 843 } 844 845 _dma_busy[dma_id] = 1; 846 847 // DMA configuration 848 dma_base[DMA_IRQ_DISABLE] = 0; 849 if ( to_mem ) 850 { 851 dma_base[DMA_SRC] = (unsigned int)fb_base; 852 dma_base[DMA_DST] = (unsigned int)buf_base; 853 } 854 else 855 { 856 dma_base[DMA_SRC] = (unsigned int)buf_base; 857 dma_base[DMA_DST] = (unsigned int)fb_base; 858 } 859 dma_base[DMA_LEN] = (unsigned int)length; 860 861 return 0; 862 } 863 ////////////////////////////////////////////////////////////////////////////////// 737 864 // _fb_write() 738 // Transfer data from an memory buffer to the frame_buffer device using a DMA. 739 // The source memory buffer must be in user address space. 865 // Transfer data from a memory buffer to the frame_buffer device using DMA. 740 866 // - offset : offset (in bytes) in the frame buffer. 741 867 // - buffer : base address of the memory buffer. … … 744 870 ////////////////////////////////////////////////////////////////////////////////// 745 871 unsigned int _fb_write( unsigned int offset, 746 const void* buffer,872 const void* buffer, 747 873 unsigned int length ) 748 874 { 749 volatile unsigned char *fb_address; 750 volatile unsigned int *dma; 751 752 unsigned int proc_id; 753 unsigned int delay; 754 unsigned int i; 755 756 /* buffer must be in user space */ 757 if (((unsigned int)buffer >= 0x80000000) 758 || (((unsigned int)buffer + length ) >= 0x80000000 )) 759 return 1; 760 761 proc_id = _procid(); 762 fb_address = (unsigned char*)&seg_fb_base + offset; 763 dma = (unsigned int*)&seg_dma_base + (proc_id * DMA_SPAN); 764 765 /* waiting until DMA device is available */ 766 while (_dma_busy[proc_id] != 0) 767 { 768 /* if the lock failed, busy wait with a pseudo random delay between bus 769 * accesses */ 770 delay = (_proctime() & 0xF) << 4; 875 return _fb_access( 0, // write to frame buffer 876 offset, 877 (unsigned int)buffer, 878 length ); 879 } 880 881 ////////////////////////////////////////////////////////////////////////////////// 882 // _fb_read() 883 // Transfer data from the frame_buffer device to a memory buffer using DMA. 884 // - offset : offset (in bytes) in the frame buffer. 885 // - buffer : base address of the memory buffer. 886 // - length : number of bytes to be transfered. 887 // Returns 0 if success, > 0 if error. 888 ////////////////////////////////////////////////////////////////////////////////// 889 unsigned int _fb_read( unsigned int offset, 890 const void* buffer, 891 unsigned int length ) 892 { 893 return _fb_access( 1, // read from frame buffer 894 offset, 895 (unsigned int)buffer, 896 length ); 897 } 898 899 ////////////////////////////////////////////////////////////////////////////////// 900 // _fb_completed() 901 // This function checks completion of a DMA transfer to or fom the frame buffer. 902 // As it is a blocking call, the processor is busy waiting. 903 // Returns 0 if success, > 0 if error 904 // (1 == read error / 2 == DMA idle error / 3 == write error) 905 ////////////////////////////////////////////////////////////////////////////////// 906 unsigned int _fb_completed() 907 { 908 static_scheduler_t* psched = &_scheduler[_procid()]; 909 unsigned int task_id = psched->current; 910 911 volatile unsigned int dma_id = psched->context[task_id][CTX_FBDMA_ID]; 912 913 // busy waiting with a pseudo random delay between bus access 914 while (_dma_busy[dma_id] != 0) 915 { 916 unsigned int i; 917 unsigned int delay = (_proctime() & 0xF) << 4; 771 918 for (i = 0; i < delay; i++) 772 919 asm volatile("nop"); 773 920 } 774 _dma_busy[proc_id] = 1; 775 776 /* DMA configuration for write transfer */ 777 dma[DMA_IRQ_DISABLE] = 0; 778 dma[DMA_SRC] = (unsigned int)buffer; 779 dma[DMA_DST] = (unsigned int)fb_address; 780 dma[DMA_LEN] = (unsigned int)length; 781 return 0; 782 } 783 784 ////////////////////////////////////////////////////////////////////////////////// 785 // _fb_read() 786 // Transfer data from the frame_buffer device to an memory buffer using a DMA. 787 // The destination memory buffer must be in user address space. 788 // - offset : offset (in bytes) in the frame buffer. 789 // - buffer : base address of the memory buffer. 790 // - length : number of bytes to be transfered. 791 // All cache lines corresponding to the the target buffer are invalidated 792 // for cache coherence. 793 // Returns 0 if success, > 0 if error. 794 ////////////////////////////////////////////////////////////////////////////////// 795 unsigned int _fb_read( unsigned int offset, 796 const void* buffer, 797 unsigned int length ) 798 { 799 volatile unsigned char *fb_address; 800 volatile unsigned int *dma; 801 802 unsigned int proc_id; 803 unsigned int delay; 804 unsigned int i; 805 806 /* buffer must be in user space */ 807 if (((unsigned int)buffer >= 0x80000000) 808 || (((unsigned int)buffer + length ) >= 0x80000000 )) 809 return 1; 810 811 proc_id = _procid(); 812 fb_address = (unsigned char*)&seg_fb_base + offset; 813 dma = (unsigned int*)&seg_dma_base + (proc_id * DMA_SPAN); 814 815 /* waiting until DMA device is available */ 816 while (_dma_busy[proc_id] != 0) 817 { 818 /* if the lock failed, busy wait with a pseudo random delay between bus 819 * accesses */ 820 delay = (_proctime() & 0xF) << 4; 821 for (i = 0; i < delay; i++) 822 asm volatile("nop"); 921 922 // unmap the buffer from IOMMU page table if IOMMU is activated 923 if ( GIET_IOMMU_ACTIVE ) 924 { 925 unsigned int* iob_address = (unsigned int*)&seg_iob_base; 926 unsigned int ix1 = _dma_iommu_ix1 + dma_id; 927 unsigned int ix2; 928 929 for ( ix2 = 0 ; ix2 < _dma_iommu_npages[dma_id] ; ix2++ ) 930 { 931 // unmap the page in IOMMU page table 932 _iommu_inval_pte2( ix1, // PT1 index 933 ix2 ); // PT2 index 934 935 // clear IOMMU TLB 936 iob_address[IOB_INVAL_PTE] = (ix1 << 21) | (ix2 << 12); 937 } 823 938 } 824 _dma_busy[proc_id] = 1; 825 826 /* DMA configuration for write transfer */ 827 dma[DMA_IRQ_DISABLE] = 0; 828 dma[DMA_SRC] = (unsigned int)fb_address; 829 dma[DMA_DST] = (unsigned int)buffer; 830 dma[DMA_LEN] = (unsigned int)length; 831 832 /* invalidation of data cache */ 833 _dcache_buf_invalidate(buffer, length); 834 835 return 0; 836 } 837 838 ////////////////////////////////////////////////////////////////////////////////// 839 // _fb_completed() 840 // This function checks completion of a DMA transfer to or fom the frame buffer. 841 // As it is a blocking call, the processor is stalled until the next interrupt. 842 // Returns 0 if success, > 0 if error. 843 ////////////////////////////////////////////////////////////////////////////////// 844 unsigned int _fb_completed() 845 { 846 unsigned int proc_id; 847 848 proc_id = _procid(); 849 850 while (_dma_busy[proc_id] != 0) 851 asm volatile("nop"); 852 853 if (_dma_status[proc_id] != 0) 854 return 1; 855 856 return 0; 857 } 858 939 940 return _dma_status[dma_id]; 941 } 942
Note: See TracChangeset
for help on using the changeset viewer.