Changeset 169
- Timestamp:
- Jul 17, 2012, 2:39:10 PM (12 years ago)
- Location:
- soft/giet_vm
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/apps/display/main.c
r168 r169 9 9 unsigned char buf_out[128*128]; 10 10 unsigned int i; 11 unsigned int x; 11 12 unsigned int base = 0; 12 13 … … 18 19 19 20 /* Phase 1 : lecture image sur le disque et transfert vers buf_in */ 20 if (giet_ioc_read(base, buf_in, NBLOCS)) 21 x = giet_ioc_read(base, buf_in, NBLOCS); 22 if ( x ) 21 23 { 22 giet_tty_printf("echec giet_ioc_read \n");24 giet_tty_printf("echec giet_ioc_read : %d\n", x); 23 25 giet_exit(); 24 26 } 25 else 27 x = giet_ioc_completed(); 28 if ( x ) 26 29 { 27 giet_ ioc_completed();28 giet_ tty_printf("io_read completed at date = %d \n", giet_proctime());30 giet_tty_printf("echec giet_ioc_completed : %d\n", x); 31 giet_exit(); 29 32 } 33 giet_tty_printf("io_read completed at date = %d \n", giet_proctime()); 30 34 31 35 /* Phase 2 : transfert de buf_in vers buf_out avec seuillage */ … … 40 44 41 45 /* Phase 3 : transfert de buf_out vers le frame buffer par dma */ 42 if (giet_fb_sync_write(0, buf_out, 128 * 128)) 46 x = giet_fb_write(0, buf_out, 128 * 128); 47 if ( x ) 43 48 { 44 giet_tty_printf("echec giet_fb_write \n");49 giet_tty_printf("echec giet_fb_write : %d\n", x); 45 50 giet_exit(); 46 51 } 47 else 52 x = giet_fb_completed(); 53 if ( x ) 48 54 { 49 giet_tty_printf("transfer completed at date = %d \n", giet_proctime()); 55 giet_tty_printf("echec giet_fb_completed : %d\n", x); 56 giet_exit(); 50 57 } 58 giet_tty_printf("transfer completed at date = %d \n", giet_proctime()); 51 59 52 60 base = base + NBLOCS; -
soft/giet_vm/boot/boot_handler.c
r167 r169 51 51 #include "../sys/mips32_registers.h" 52 52 #include <boot_handler.h> 53 #include <giet_config.h> 53 54 #include <mapping_info.h> 54 55 #include <mwmr_channel.h> … … 612 613 unsigned int vspace_id ) 613 614 { 614 unsigned int pages;615 615 unsigned int vobj_id; 616 616 unsigned int cur_vaddr; -
soft/giet_vm/boot/boot_handler.h
r167 r169 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 7 8 #include <giet_config.h> 9 #include <mapping_info.h> 10 8 11 #ifndef _BOOT_HANDLER_H_ 9 12 #define _BOOT_HANDLER_H_ 10 11 #include <giet_config.h>12 #include <mapping_info.h>13 13 14 14 ///////////////////////////////////////////////////////////////////////////////////// -
soft/giet_vm/giet_config.h
r167 r169 27 27 #define NB_TIMERS 4 /* number of timers per cluster */ 28 28 #define NB_DMAS 1 /* total number of DMA channels */ 29 #define NB_TTYS 8 /* total number of TTY terminals */ 29 #define NB_TTYS 2 /* total number of TTY terminals */ 30 #define NB_IOC 1 /* total number of IOC channels */ 30 31 31 32 /* software parameters */ -
soft/giet_vm/map.xml
r167 r169 5 5 clusters = "1" 6 6 psegs = "9" 7 ttys = " 8"8 fbs = " 0"9 vspaces = " 4"7 ttys = "2" 8 fbs = "1" 9 vspaces = "1" 10 10 globals = "13" > 11 11 12 12 <clusterset> 13 13 <cluster index = "0" 14 procs = " 4" />14 procs = "2" /> 15 15 </clusterset> 16 16 … … 139 139 <vobj name = "tty" 140 140 type = "PERI" 141 length = "0x0000 1000" />141 length = "0x00000100" /> 142 142 </vseg> 143 143 … … 149 149 <vobj name = "timer" 150 150 type = "PERI" 151 length = "0x0000 1000" />151 length = "0x00000080" /> 152 152 </vseg> 153 153 … … 169 169 <vobj name = "dma" 170 170 type = "PERI" 171 length = "0x0000 1000" />171 length = "0x00000100" /> 172 172 </vseg> 173 173 … … 194 194 195 195 <vspaceset> 196 <vspace name = " router"197 startname = "seg_data_ router" >198 199 <vseg name = "seg_data_ router"196 <vspace name = "display" 197 startname = "seg_data_display" > 198 199 <vseg name = "seg_data_display" 200 200 vbase = "0x00800000" 201 mode = "__WU" 202 psegname = "PSEG_RAU" > 203 <vobj name = "seg_data_router" 204 type = "ELF" 205 length = "0x00010000" 206 binpath = "build/router.elf" /> 207 </vseg> 208 209 <vseg name = "seg_code_router" 210 vbase = "0x00400000" 211 mode = "CX_U" 212 psegname = "PSEG_RAU" > 213 <vobj name = "seg_code_router" 201 mode = "C_WU" 202 psegname = "PSEG_RAU" > 203 <vobj name = "seg_data_display" 214 204 type = "ELF" 215 205 length = "0x00010000" 216 binpath = "build/router.elf" /> 217 </vseg> 218 219 <vseg name = "seg_ptab" 220 vbase = "0x00300000" 221 mode = "C___" 222 psegname = "PSEG_RAU" > 223 <vobj name = "ptab_router" 224 type = "PTAB" 225 length = "0x00012000" 226 align = "13" /> 227 </vseg> 228 229 <vseg name = "seg_stack_producer" 230 vbase = "0x00010000" 231 mode = "C_WU" 232 psegname = "PSEG_RAU" > 233 <vobj name = "stack_producer" 234 type = "BUFFER" 235 length = "0x00010000" /> 236 </vseg> 237 238 <vseg name = "seg_stack_consumer" 239 vbase = "0x00020000" 240 mode = "C_WU" 241 psegname = "PSEG_RAU" > 242 <vobj name = "stack_consumer" 243 type = "BUFFER" 244 length = "0x00010000" /> 245 </vseg> 246 247 <vseg name = "seg_stack_router_A" 248 vbase = "0x00030000" 249 mode = "C_WU" 250 psegname = "PSEG_RAU" > 251 <vobj name = "stack_router_A" 252 type = "BUFFER" 253 length = "0x00010000" /> 254 </vseg> 255 256 <vseg name = "seg_stack_router_B" 257 vbase = "0x00040000" 258 mode = "C_WU" 259 psegname = "PSEG_RAU" > 260 <vobj name = "stack_router_B" 261 type = "BUFFER" 262 length = "0x00010000" /> 263 </vseg> 264 265 <vseg name = "seg_mwmr_channels" 266 vbase = "0x00050000" 267 mode = "__WU" 268 psegname = "PSEG_RAU" > 269 <vobj name = "mwmr_in" 270 type = "MWMR" 271 length = "0x00000020" /> 272 <vobj name = "mwmr_out" 273 type = "MWMR" 274 length = "0x00000020" /> 275 </vseg> 276 277 <task name = "producer" 278 clusterid = "0" 279 proclocid = "0" 280 stackname = "stack_producer" 281 startid = "0" 282 usetty = "1" /> 283 284 <task name = "consumer" 285 clusterid = "0" 286 proclocid = "1" 287 stackname = "stack_consumer" 288 startid = "1" 289 usetty = "1" /> 290 291 <task name = "router_A" 292 clusterid = "0" 293 proclocid = "2" 294 stackname = "stack_router_A" 295 startid = "2" 296 usetty = "1" /> 297 298 <task name = "router_B" 299 clusterid = "0" 300 proclocid = "3" 301 stackname = "stack_router_B" 302 startid = "2" 303 usetty = "1" /> 304 </vspace> 305 306 <vspace name = "hello" 307 startname = "seg_data_hello" > 308 309 <vseg name = "seg_data_hello" 310 vbase = "0x00800000" 311 mode = "C_WU" 312 psegname = "PSEG_RAU" > 313 <vobj name = "seg_data_hello" 314 type = "ELF" 315 length = "0x00010000" 316 binpath = "build/hello.elf" /> 317 </vseg> 318 319 <vseg name = "seg_code_hello" 320 vbase = "0x00400000" 321 mode = "CX_U" 322 psegname = "PSEG_RAU" > 323 <vobj name = "seg_code_hello" 324 type = "ELF" 325 length = "0x00010000" 326 binpath = "build/hello.elf" /> 206 binpath = "build/display.elf" /> 327 207 </vseg> 328 208 … … 337 217 </vseg> 338 218 339 <vseg name = "seg_stack"340 vbase = "0x00000000"341 mode = "C_WU"342 psegname = "PSEG_RAU" >343 <vobj name = "stack"344 type = "BUFFER"345 length = "0x00010000" />346 </vseg>347 348 349 <task name = "main_hello"350 clusterid = "0"351 proclocid = "2"352 stackname = "stack"353 startid = "0"354 usetty = "1" />355 </vspace>356 357 <vspace name = "pgcd"358 startname = "seg_data_pgcd" >359 360 <vseg name = "seg_data_pgcd"361 vbase = "0x00800000"362 mode = "C_WU"363 psegname = "PSEG_RAU" >364 <vobj name = "seg_data_pgcd"365 type = "ELF"366 length = "0x00010000"367 binpath = "build/pgcd.elf" />368 </vseg>369 370 <vseg name = "seg_ptab"371 vbase = "0x00300000"372 mode = "C___"373 psegname = "PSEG_RAU" >374 <vobj name = "ptab"375 type = "PTAB"376 length = "0x00012000"377 align = "13" />378 </vseg>379 380 <vseg name = "seg_code_pgcd"381 vbase = "0x00400000"382 mode = "CX_U"383 psegname = "PSEG_RAU" >384 <vobj name = "seg_code_pgcd"385 type = "ELF"386 length = "0x00010000"387 binpath = "build/pgcd.elf" />388 </vseg>389 390 <vseg name = "seg_stack"391 vbase = "0x00000000"392 mode = "C_WU"393 psegname = "PSEG_RAU" >394 <vobj name = "stack"395 type = "BUFFER"396 length = "0x00010000" />397 </vseg>398 399 <task name = "main_pgcd"400 clusterid = "0"401 proclocid = "3"402 stackname = "stack"403 startid = "0"404 usetty = "1" />405 </vspace>406 407 <vspace name = "display"408 startname = "seg_data_display" >409 410 <vseg name = "seg_data_display"411 vbase = "0x00800000"412 mode = "C_WU"413 psegname = "PSEG_RAU" >414 <vobj name = "seg_data_display"415 type = "ELF"416 length = "0x00010000"417 binpath = "build/display.elf" />418 </vseg>419 420 <vseg name = "seg_ptab_display"421 vbase = "0x00300000"422 mode = "C___"423 psegname = "PSEG_RAU" >424 <vobj name = "ptab"425 type = "PTAB"426 length = "0x00012000"427 align = "13" />428 </vseg>429 430 219 <vseg name = "seg_code_display" 431 220 vbase = "0x00400000" … … 449 238 <task name = "main_display" 450 239 clusterid = "0" 451 proclocid = " 3"240 proclocid = "1" 452 241 stackname = "stack_display" 453 242 startid = "0" 454 usetty = "1" /> 243 usetty = "1" 244 usefb = "1" /> 455 245 </vspace> 456 246 -
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 -
soft/giet_vm/sys/irq_handler.c
r167 r169 86 86 volatile unsigned int* dma_address; 87 87 88 // compute DMA channel address 88 89 dma_address = (unsigned int*)&seg_dma_base + (dma_id * DMA_SPAN); 89 90 91 // save DMA channel status 92 _dma_status[dma_id] = dma_address[DMA_LEN]; /* save status */ 93 94 // reset DMA channel 90 95 dma_address[DMA_RESET] = 0; /* reset IRQ */ 91 96 92 _dma_status[dma_id] = dma_address[DMA_LEN]; /* save status */97 // release DMA channel 93 98 _dma_busy[dma_id] = 0; /* release DMA */ 94 99 } -
soft/giet_vm/sys/kernel_init.c
r167 r169 542 542 in_kinit void _kernel_peripherals_init() 543 543 { 544 // IOC peripheral initialisation 544 ///////////////////// 545 // IOC peripheral 545 546 // we simply activate the IOC interrupts... 546 unsigned int* ioc_address = (unsigned int*)&seg_ioc_base; 547 548 ioc_address[BLOCK_DEVICE_IRQ_ENABLE] = 1; 547 if ( NB_IOC ) 548 { 549 unsigned int* ioc_address = (unsigned int*)&seg_ioc_base; 550 ioc_address[BLOCK_DEVICE_IRQ_ENABLE] = 1; 551 } 549 552 553 ///////////////////// 554 // FBDMA peripheral 555 // we simply activate the DMA interrupts... 556 if ( NB_DMAS ) 557 { 558 unsigned int* dma_address = (unsigned int*)&seg_dma_base; 559 dma_address[DMA_IRQ_DISABLE] = 0; 560 } 561 562 ///////////////////// 550 563 // IOB peripheral 564 // must be initialised in case of IOMMU 551 565 if ( GIET_IOMMU_ACTIVE ) 552 566 { … … 560 574 // activate IOMMU 561 575 iob_address[IOB_IOMMU_ACTIVE] = 1; 562 } 576 } 563 577 564 578 _puts("\n[INIT] Peripherals initialisation completed at cycle ");
Note: See TracChangeset
for help on using the changeset viewer.