Changeset 218 for soft/giet_vm/sys/drivers.c
- Timestamp:
- Sep 19, 2012, 10:52:43 AM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/sys/drivers.c
r216 r218 24 24 // - NB_TTYS 25 25 // 26 // The following virtual base addresses must be defined in the giet .ld file:26 // The following virtual base addresses must be defined in the giet_vsegs.ld file: 27 27 // - seg_icu_base 28 28 // - seg_tim_base … … 32 32 // - seg_fbf_base 33 33 // - seg_ioc_base 34 // - seg_nic_base 34 35 // As some peripherals can be replicated in the clusters (ICU, TIMER, DMA) 35 36 // These addresses must be completed by an offset depending on the cluster index … … 713 714 ////////////////////////////////////////////////////////////////////////////////// 714 715 715 //+1: for the case where the NB_DMAS_MAX == 0716 716 #if NB_DMAS_MAX > 0 717 717 in_unckdata unsigned int _dma_lock[NB_DMAS_MAX * NB_CLUSTERS] 718 = { [0 ... ( (NB_DMAS_MAX)* NB_CLUSTERS)-1] = 0 };718 = { [0 ... (NB_DMAS_MAX * NB_CLUSTERS)-1] = 0 }; 719 719 720 720 in_unckdata volatile unsigned int _dma_done[NB_DMAS_MAX * NB_CLUSTERS] … … 749 749 #endif 750 750 } 751 751 752 ////////////////////////////////////////////////////////////////////////////////// 752 753 // _dma_get_status() … … 773 774 774 775 ////////////////////////////////////////////////////////////////////////////////// 775 // VciFrameBuffer driver 776 ////////////////////////////////////////////////////////////////////////////////// 777 // The vci_frame_buffer device can be accessed directly by software with memcpy(), 778 // or it can be accessed through a multi-channels DMA component: 779 // 780 // The '_fb_sync_write' and '_fb_sync_read' functions use a memcpy strategy to 781 // implement the transfer between a data buffer (user space) and the frame 782 // buffer (kernel space). They are blocking until completion of the transfer. 783 // 784 // The '_fb_write()', '_fb_read()' and '_fb_completed()' functions use the DMA 785 // controlers (distributed in the clusters) to transfer data 786 // between the user buffer and the frame buffer. A DMA channel is 787 // allocated to each task requesting it in the mapping_info data structure. 788 ////////////////////////////////////////////////////////////////////////////////// 789 790 ////////////////////////////////////////////////////////////////////////////////// 791 // _fb_sync_write() 792 // Transfer data from an memory buffer to the frame_buffer device using 793 // a memcpy. The source memory buffer must be in user address space. 794 // - offset : offset (in bytes) in the frame buffer. 795 // - buffer : base address of the memory buffer. 796 // - length : number of bytes to be transfered. 797 // Returns 0 if success, > 0 if error. 798 ////////////////////////////////////////////////////////////////////////////////// 799 unsigned int _fb_sync_write( unsigned int offset, 800 const void* buffer, 801 unsigned int length ) 802 { 803 804 // buffer must be mapped in user space 805 if ( ((unsigned int)buffer + length ) >= 0x80000000 ) 806 { 807 return 1; 808 } 809 else 810 { 811 unsigned char *fb_address = (unsigned char*)&seg_fbf_base + offset; 812 memcpy((void*)fb_address, (void*)buffer, length); 813 return 0; 814 } 815 } 816 817 ////////////////////////////////////////////////////////////////////////////////// 818 // _fb_sync_read() 819 // Transfer data from the frame_buffer device to a memory buffer using 820 // a memcpy. The destination memory buffer must be in user address space. 821 // - offset : offset (in bytes) in the frame buffer. 822 // - buffer : base address of the memory buffer. 823 // - length : number of bytes to be transfered. 824 // Returns 0 if success, > 0 if error. 825 ////////////////////////////////////////////////////////////////////////////////// 826 unsigned int _fb_sync_read( unsigned int offset, 827 const void* buffer, 828 unsigned int length ) 829 { 830 // buffer must be mapped in user space 831 if ( ((unsigned int)buffer + length ) >= 0x80000000 ) 832 { 833 return 1; 834 } 835 else 836 { 837 unsigned char *fb_address = (unsigned char*)&seg_fbf_base + offset; 838 memcpy((void*)buffer, (void*)fb_address, length); 839 return 0; 840 } 841 } 842 843 ////////////////////////////////////////////////////////////////////////////////// 844 // _fb_dma_access() 845 // Transfer data between a user buffer and the frame_buffer using DMA. 846 // - to_user : from frame buffer to user buffer when true. 847 // - offset : offset (in bytes) in the frame buffer. 848 // - user_vaddr : virtual base address of the memory buffer. 849 // - length : number of bytes to be transfered. 776 // _dma_transfer() 777 // Transfer data between a user buffer and a device buffer using DMA. 778 // Two devices types are supported: Frame Buffer if dev_type == 0 779 // Multi-Nic if dev_type != 0 780 // Arguments are: 781 // - dev_type : device type. 782 // - to_user : from device buffer to user buffer when true. 783 // - offset : offset (in bytes) in the device buffer. 784 // - user_vaddr : virtual base address of the user buffer. 785 // - length : number of bytes to be transfered. 786 // 787 // The DMA channel is obtained from task context (CTX_FBDMA_ID / CTX_NIDMA_ID. 850 788 // The user buffer must be mapped in user address space and word-aligned. 851 789 // The user buffer length must be multiple of 4 bytes. 852 // Me must compute the physical base addresses for both the frame buffer790 // Me must compute the physical base addresses for both the device buffer 853 791 // and the user buffer before programming the DMA transfer. 854 792 // The GIET being fully static, we don't need to split the transfer in 4 Kbytes … … 856 794 // Returns 0 if success, > 0 if error. 857 795 ////////////////////////////////////////////////////////////////////////////////// 858 unsigned int _fb_dma_access( unsigned int to_user, 796 unsigned int _dma_transfer( unsigned int dev_type, 797 unsigned int to_user, 859 798 unsigned int offset, 860 799 unsigned int user_vaddr, … … 862 801 { 863 802 #if NB_DMAS_MAX > 0 864 unsigned int ko; // unsuccessfull V2P translation 865 unsigned int flags; // protection flags 866 unsigned int ppn; // physical page number 867 unsigned int user_pbase; // user buffer pbase address 868 unsigned int fb_pbase; // frame buffer pbase address 803 unsigned int ko; // unsuccessfull V2P translation 804 unsigned int flags; // protection flags 805 unsigned int ppn; // physical page number 806 unsigned int user_pbase; // user buffer pbase address 807 unsigned int device_pbase; // frame buffer pbase address 808 unsigned int device_vaddr; // device buffer vbase address 809 810 // check user buffer address and length alignment 811 if ( (user_vaddr & 0x3) || (length & 0x3) ) 812 { 813 _get_lock(&_tty_put_lock); 814 _puts("\n[GIET ERROR] in _dma_transfer : user buffer not word aligned\n"); 815 _release_lock(&_tty_put_lock); 816 return 1; 817 } 869 818 870 819 // get DMA channel and compute DMA vbase address 871 820 unsigned int task_id = _get_current_task_id(); 872 unsigned int dma_id = _get_context_slot( task_id, CTX_FBDMA_ID );821 unsigned int dma_id = _get_context_slot( task_id, CTX_DMA_ID ); 873 822 unsigned int cluster_id = dma_id / NB_DMAS_MAX; 874 823 unsigned int loc_id = dma_id % NB_DMAS_MAX; 875 876 unsigned int* dma_base = (unsigned int*)( (char*)&seg_dma_base + 877 (cluster_id * (unsigned)CLUSTER_SIZE) ); 878 879 // check user buffer address and length alignment 880 if ( (user_vaddr & 0x3) || (length & 0x3) ) 881 { 882 _get_lock(&_tty_put_lock); 883 _puts("\n[GIET ERROR] in _fbdma_access() : user buffer not word aligned\n"); 884 _release_lock(&_tty_put_lock); 885 return 1; 886 } 887 888 // get user space page table virtual address 824 unsigned int* dma_base = (unsigned int*)( (char*)&seg_dma_base + 825 (cluster_id * (unsigned)CLUSTER_SIZE) ); 826 827 // get page table address 889 828 unsigned int user_ptab = _get_context_slot( task_id, CTX_PTAB_ID ); 890 829 891 // compute frame buffer pbase address 892 unsigned int fb_vaddr = (unsigned int)&seg_fbf_base + offset; 893 830 // get peripheral buffer virtual address 831 if ( dev_type) device_vaddr = (unsigned int)&seg_nic_base + offset; 832 else device_vaddr = (unsigned int)&seg_fbf_base + offset; 833 834 // get device buffer physical address 894 835 ko = _v2p_translate( (page_table_t*)user_ptab, 895 ( fb_vaddr >> 12),836 (device_vaddr >> 12), 896 837 &ppn, 897 838 &flags ); 898 fb_pbase = (ppn << 12) | (fb_vaddr & 0x00000FFF);899 900 839 if ( ko ) 901 840 { 902 841 _get_lock(&_tty_put_lock); 903 _puts("\n[GIET ERROR] in _ fbdma_access() : frame buffer unmapped\n");842 _puts("\n[GIET ERROR] in _dma_transfer : device buffer unmapped\n"); 904 843 _release_lock(&_tty_put_lock); 905 844 return 2; 906 845 } 907 908 // Compute user buffer pbase address 846 device_pbase = (ppn << 12) | (device_vaddr & 0x00000FFF); 847 848 // Compute user buffer physical address 909 849 ko = _v2p_translate( (page_table_t*)user_ptab, 910 850 (user_vaddr >> 12), 911 851 &ppn, 912 852 &flags ); 913 user_pbase = (ppn << 12) | (user_vaddr & 0x00000FFF);914 915 853 if ( ko ) 916 854 { 917 855 _get_lock(&_tty_put_lock); 918 _puts("\n[GIET ERROR] in _ fbdma_access() : user buffer unmapped\n");856 _puts("\n[GIET ERROR] in _dma_transfer() : user buffer unmapped\n"); 919 857 _release_lock(&_tty_put_lock); 920 858 return 3; … … 923 861 { 924 862 _get_lock(&_tty_put_lock); 925 _puts("[GIET ERROR] in _ fbdma_access() : user buffer not in user space\n");863 _puts("[GIET ERROR] in _dma_transfer() : user buffer not in user space\n"); 926 864 _release_lock(&_tty_put_lock); 927 865 return 4; … … 930 868 { 931 869 _get_lock(&_tty_put_lock); 932 _puts("\n[GIET ERROR] in _ fbdma_access() : user buffer not writable\n");870 _puts("\n[GIET ERROR] in _dma_transfer() : user buffer not writable\n"); 933 871 _release_lock(&_tty_put_lock); 934 872 return 5; 935 873 } 936 937 938 939 /* 874 user_pbase = (ppn << 12) | (user_vaddr & 0x00000FFF); 875 876 /* This is a draft for IOMMU support 877 940 878 // loop on all virtual pages covering the user buffer 941 879 unsigned int user_vpn_min = user_vaddr >> 12; … … 987 925 // invalidate data cache in case of memory write 988 926 if ( to_user ) _dcache_buf_invalidate( (void*)user_vaddr, length ); 989 927 990 928 // get the lock 991 929 _get_lock( &_dma_lock[dma_id] ); … … 994 932 if ( to_user ) 995 933 { 996 dma_base[loc_id*DMA_SPAN + DMA_SRC] = (unsigned int) fb_pbase;934 dma_base[loc_id*DMA_SPAN + DMA_SRC] = (unsigned int)device_pbase; 997 935 dma_base[loc_id*DMA_SPAN + DMA_DST] = (unsigned int)user_pbase; 998 936 } … … 1000 938 { 1001 939 dma_base[loc_id*DMA_SPAN + DMA_SRC] = (unsigned int)user_pbase; 1002 dma_base[loc_id*DMA_SPAN + DMA_DST] = (unsigned int) fb_pbase;940 dma_base[loc_id*DMA_SPAN + DMA_DST] = (unsigned int)device_pbase; 1003 941 } 1004 942 dma_base[loc_id*DMA_SPAN + DMA_LEN] = (unsigned int)length; … … 1007 945 1008 946 #else //NB_DMAS_MAX == 0 947 1009 948 return -1; 1010 #endif 1011 } 949 950 #endif 951 } // end _dma_transfer() 952 953 ////////////////////////////////////////////////////////////////////////////////// 954 // _dma_completed() 955 // This function checks completion of a DMA transfer to or from a peripheral 956 // device (Frame Buffer or Multi-Nic). 957 // As it is a blocking call, the processor is busy waiting. 958 // Returns 0 if success, > 0 if error 959 // (1 == read error / 2 == DMA idle error / 3 == write error) 960 ////////////////////////////////////////////////////////////////////////////////// 961 unsigned int _dma_completed() 962 { 963 #if NB_DMAS_MAX > 0 964 unsigned int task_id = _get_current_task_id(); 965 unsigned int dma_id = _get_context_slot( task_id, CTX_DMA_ID ); 966 967 // busy waiting with a pseudo random delay between bus access 968 while (_dma_done[dma_id] == 0) 969 { 970 unsigned int delay = (( _proctime() ^ _procid()<<4 ) & 0x3F) + 1; 971 asm volatile("move $3, %0 \n" 972 "loop_nic_completed: \n" 973 "addi $3, $3, -1 \n" 974 "bnez $3, loop_nic_completed \n" 975 "nop \n" 976 : 977 : "r"(delay) 978 : "$3" ); 979 } 980 981 /* draft support for IOMMU 982 // unmap the buffer from IOMMU page table if IOMMU is activated 983 if ( GIET_IOMMU_ACTIVE ) 984 { 985 unsigned int* iob_address = (unsigned int*)&seg_iob_base; 986 987 unsigned int ix1 = _dma_iommu_ix1 + dma_id; 988 unsigned int ix2; 989 990 for ( ix2 = 0 ; ix2 < _dma_iommu_npages[dma_id] ; ix2++ ) 991 { 992 // unmap the page in IOMMU page table 993 _iommu_inval_pte2( ix1, // PT1 index 994 ix2 ); // PT2 index 995 996 // clear IOMMU TLB 997 iob_address[IOB_INVAL_PTE] = (ix1 << 21) | (ix2 << 12); 998 } 999 } 1000 */ 1001 1002 // reset synchronization variables 1003 _dma_lock[dma_id] = 0; 1004 _dma_done[dma_id] = 0; 1005 1006 return _dma_status[dma_id]; 1007 1008 #else //NB_DMAS_MAX == 0 1009 return -1; 1010 #endif 1011 } // end _dma_completed 1012 1013 ////////////////////////////////////////////////////////////////////////////////// 1014 // VciFrameBuffer driver 1015 ////////////////////////////////////////////////////////////////////////////////// 1016 // The vci_frame_buffer device can be accessed directly by software with memcpy(), 1017 // or it can be accessed through a multi-channels DMA component: 1018 // 1019 // The '_fb_sync_write' and '_fb_sync_read' functions use a memcpy strategy to 1020 // implement the transfer between a data buffer (user space) and the frame 1021 // buffer (kernel space). They are blocking until completion of the transfer. 1022 // 1023 // The '_fb_write()', '_fb_read()' and '_fb_completed()' functions use the 1024 // VciMultiDma components (distributed in the clusters) to transfer data 1025 // between the user buffer and the frame buffer. A FBDMA channel is 1026 // allocated to each task requesting it in the mapping_info data structure. 1027 ////////////////////////////////////////////////////////////////////////////////// 1028 1029 ////////////////////////////////////////////////////////////////////////////////// 1030 // _fb_sync_write() 1031 // Transfer data from an memory buffer to the frame_buffer device using a memcpy. 1032 // - offset : offset (in bytes) in the frame buffer. 1033 // - buffer : base address of the memory buffer. 1034 // - length : number of bytes to be transfered. 1035 ////////////////////////////////////////////////////////////////////////////////// 1036 unsigned int _fb_sync_write( unsigned int offset, 1037 const void* buffer, 1038 unsigned int length ) 1039 { 1040 unsigned char *fb_address = (unsigned char*)&seg_fbf_base + offset; 1041 memcpy((void*)fb_address, (void*)buffer, length); 1042 return 0; 1043 } 1044 1045 ////////////////////////////////////////////////////////////////////////////////// 1046 // _fb_sync_read() 1047 // Transfer data from the frame_buffer device to a memory buffer using a memcpy. 1048 // - offset : offset (in bytes) in the frame buffer. 1049 // - buffer : base address of the memory buffer. 1050 // - length : number of bytes to be transfered. 1051 ////////////////////////////////////////////////////////////////////////////////// 1052 unsigned int _fb_sync_read( unsigned int offset, 1053 const void* buffer, 1054 unsigned int length ) 1055 { 1056 unsigned char *fb_address = (unsigned char*)&seg_fbf_base + offset; 1057 memcpy((void*)buffer, (void*)fb_address, length); 1058 return 0; 1059 } 1060 1012 1061 ////////////////////////////////////////////////////////////////////////////////// 1013 1062 // _fb_write() … … 1019 1068 ////////////////////////////////////////////////////////////////////////////////// 1020 1069 unsigned int _fb_write( unsigned int offset, 1021 const void*buffer,1070 const void* buffer, 1022 1071 unsigned int length ) 1023 1072 { 1024 return _fb_dma_access( 0, // write to frame buffer 1025 offset, 1026 (unsigned int)buffer, 1027 length ); 1073 return _dma_transfer( 0, // frame buffer 1074 0, // write 1075 offset, 1076 (unsigned int)buffer, 1077 length ); 1028 1078 } 1029 1079 … … 1040 1090 unsigned int length ) 1041 1091 { 1042 return _fb_dma_access( 1, // read from frame buffer 1043 offset, 1044 (unsigned int)buffer, 1045 length ); 1092 return _dma_transfer( 0, // frame buffer 1093 1, // read 1094 offset, 1095 (unsigned int)buffer, 1096 length ); 1046 1097 } 1047 1098 … … 1055 1106 unsigned int _fb_completed() 1056 1107 { 1057 #if NB_DMAS_MAX > 0 1058 unsigned int task_id = _get_current_task_id(); 1059 unsigned int dma_id = _get_context_slot( task_id, CTX_FBDMA_ID ); 1060 1061 // busy waiting with a pseudo random delay between bus access 1062 while (_dma_done[dma_id] == 0) 1063 { 1064 unsigned int i; 1065 unsigned int delay = ( _proctime() ^ _procid()<<4 ) & 0xFF; 1066 for (i = 0; i < delay; i++) 1067 asm volatile("nop"); 1068 } 1069 1070 // unmap the buffer from IOMMU page table if IOMMU is activated 1071 if ( 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 1089 // reset synchronization variables 1090 _dma_lock[dma_id] = 0; 1091 _dma_done[dma_id] = 0; 1092 1093 return _dma_status[dma_id]; 1094 1095 #else //NB_DMAS_MAX == 0 1096 1097 return -1; 1098 1099 #endif 1100 } 1101 1108 return _dma_completed(); 1109 } 1110 1111 ////////////////////////////////////////////////////////////////////////////////// 1112 // VciMultiNic driver 1113 ////////////////////////////////////////////////////////////////////////////////// 1114 // The VciMultiNic device can be accessed directly by software with memcpy(), 1115 // or it can be accessed through a multi-channels DMA component: 1116 // 1117 // The '_nic_sync_write' and '_nic_sync_read' functions use a memcpy strategy to 1118 // implement the transfer between a data buffer (user space) and the NIC 1119 // buffer (kernel space). They are blocking until completion of the transfer. 1120 // 1121 // The '_nic_write()', '_nic_read()' and '_nic_completed()' functions use the 1122 // VciMultiDma components (distributed in the clusters) to transfer data 1123 // between the user buffer and the NIC. A NIDMA channel is allocated to each 1124 // task requesting it in the mapping_info data structure. 1125 ////////////////////////////////////////////////////////////////////////////////// 1126 1127 ////////////////////////////////////////////////////////////////////////////////// 1128 // _nic_sync_write() 1129 // Transfer data from an memory buffer to the NIC device using a memcpy. 1130 // - offset : offset (in bytes) in the frame buffer. 1131 // - buffer : base address of the memory buffer. 1132 // - length : number of bytes to be transfered. 1133 ////////////////////////////////////////////////////////////////////////////////// 1134 unsigned int _nic_sync_write( unsigned int offset, 1135 const void* buffer, 1136 unsigned int length ) 1137 { 1138 unsigned char *nic_address = (unsigned char*)&seg_nic_base + offset; 1139 memcpy((void*)nic_address, (void*)buffer, length); 1140 return 0; 1141 } 1142 1143 ////////////////////////////////////////////////////////////////////////////////// 1144 // _nic_sync_read() 1145 // Transfer data from the NIC device to a memory buffer using a memcpy. 1146 // - offset : offset (in bytes) in the frame buffer. 1147 // - buffer : base address of the memory buffer. 1148 // - length : number of bytes to be transfered. 1149 ////////////////////////////////////////////////////////////////////////////////// 1150 unsigned int _nic_sync_read( unsigned int offset, 1151 const void* buffer, 1152 unsigned int length ) 1153 { 1154 unsigned char *nic_address = (unsigned char*)&seg_nic_base + offset; 1155 memcpy((void*)buffer, (void*)nic_address, length); 1156 return 0; 1157 } 1158 1159 ////////////////////////////////////////////////////////////////////////////////// 1160 // _nic_write() 1161 // Transfer data from a memory buffer to the NIC device using DMA. 1162 // - offset : offset (in bytes) in the frame buffer. 1163 // - buffer : base address of the memory buffer. 1164 // - length : number of bytes to be transfered. 1165 // Returns 0 if success, > 0 if error. 1166 ////////////////////////////////////////////////////////////////////////////////// 1167 unsigned int _nic_write( unsigned int offset, 1168 const void* buffer, 1169 unsigned int length ) 1170 { 1171 return _dma_transfer( 1, // NIC 1172 0, // write 1173 offset, 1174 (unsigned int)buffer, 1175 length ); 1176 } 1177 1178 ////////////////////////////////////////////////////////////////////////////////// 1179 // _nic_read() 1180 // Transfer data from the NIC device to a memory buffer using DMA. 1181 // - offset : offset (in bytes) in the frame buffer. 1182 // - buffer : base address of the memory buffer. 1183 // - length : number of bytes to be transfered. 1184 // Returns 0 if success, > 0 if error. 1185 ////////////////////////////////////////////////////////////////////////////////// 1186 unsigned int _nic_read( unsigned int offset, 1187 const void* buffer, 1188 unsigned int length ) 1189 { 1190 return _dma_transfer( 1, // NIC 1191 1, // read 1192 offset, 1193 (unsigned int)buffer, 1194 length ); 1195 } 1196 1197 ////////////////////////////////////////////////////////////////////////////////// 1198 // _nic_completed() 1199 // This function checks completion of a DMA transfer to or fom a NIC channel. 1200 // As it is a blocking call, the processor is busy waiting. 1201 // Returns 0 if success, > 0 if error 1202 // (1 == read error / 2 == DMA idle error / 3 == write error) 1203 ////////////////////////////////////////////////////////////////////////////////// 1204 unsigned int _nic_completed() 1205 { 1206 return _dma_completed(); 1207 } 1208
Note: See TracChangeset
for help on using the changeset viewer.