Changeset 204 for soft/giet_vm/sys
- Timestamp:
- Aug 14, 2012, 8:14:55 PM (13 years ago)
- Location:
- soft/giet_vm/sys
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/sys/drivers.c
r203 r204 17 17 // 18 18 // The following global parameters must be defined in the giet_config.h file: 19 // - CLUSTER_IO_ID 20 // - CLUSTER_SIZE 19 21 // - NB_CLUSTERS 20 22 // - NB_PROCS_MAX … … 23 25 // - NB_TTYS 24 26 // 25 // The following virtual base addresses must be defined in the sys.ld file:27 // The following virtual base addresses must be defined in the giet.ld file: 26 28 // - seg_icu_base 27 29 // - seg_tim_base … … 31 33 // - seg_fbf_base 32 34 // - seg_ioc_base 35 // As some peripherals can be replicated in the clusters (ICU, TIMER, DMA) 36 // These addresses must be completed by an offset depending on the cluster index 37 // full_base_address = seg_***_base + cluster_id * CLUSTER_SIZE 33 38 /////////////////////////////////////////////////////////////////////////////////// 34 39 … … 54 59 #endif 55 60 56 #if !defined(CLUSTER_S PAN)57 # error: You must define CLUSTER_S PANin 'giet_config.h' file61 #if !defined(CLUSTER_SIZE) 62 # error: You must define CLUSTER_SIZE in 'giet_config.h' file 58 63 #endif 59 64 … … 132 137 133 138 #if GIET_USE_XICU 134 unsigned int* timer_address = (unsigned int*) &seg_icu_base +135 (cluster_id * CLUSTER_S PAN);139 unsigned int* timer_address = (unsigned int*)((char*)&seg_icu_base + 140 (cluster_id * CLUSTER_SIZE) ); 136 141 137 142 timer_address[XICU_REG(XICU_PTI_PER, local_id)] = period; 138 143 #else 139 unsigned int* timer_address = (unsigned int*) &seg_tim_base +140 (cluster_id * CLUSTER_S PAN);144 unsigned int* timer_address = (unsigned int*)((char*)&seg_tim_base + 145 (cluster_id * CLUSTER_SIZE) ); 141 146 142 147 timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period; … … 160 165 161 166 #if GIET_USE_XICU 162 unsigned int* timer_address = (unsigned int*) &seg_icu_base +163 (cluster_id * CLUSTER_S PAN);167 unsigned int* timer_address = (unsigned int*)((char*)&seg_icu_base + 168 (cluster_id * CLUSTER_SIZE) ); 164 169 165 170 timer_address[XICU_REG(XICU_PTI_PER, local_id)] = 0; 166 171 #else 167 unsigned int* timer_address = (unsigned int*) &seg_tim_base +168 (cluster_id * CLUSTER_S PAN);172 unsigned int* timer_address = (unsigned int*)((char*)&seg_tim_base + 173 (cluster_id * CLUSTER_SIZE) ); 169 174 170 175 timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0; … … 176 181 // _timer_reset_irq() 177 182 // This function acknowlegge a timer interrupt in the vci_timer (or vci_xicu) 178 // component by writing in the proper register the period value.183 // component by reading/writing in the proper register. 179 184 // It can be used by both the isr_switch() for a "system" timer, 180 185 // or by the _isr_timer() for an "user" timer. … … 189 194 190 195 #if GIET_USE_XICU 191 unsigned int* timer_address = (unsigned int*) &seg_icu_base +192 (cluster_id * CLUSTER_SPAN);196 unsigned int* timer_address = (unsigned int*)((char*)&seg_icu_base + 197 (cluster_id * (unsigned)CLUSTER_SIZE) ); 193 198 194 199 unsigned int bloup = timer_address[XICU_REG(XICU_PTI_ACK, local_id)]; 200 bloup++; // to avoid a warning 195 201 #else 196 unsigned int* timer_address = (unsigned int*) &seg_tim_base +197 (cluster_id * CLUSTER_S PAN);202 unsigned int* timer_address = (unsigned int*)((char*)&seg_tim_base + 203 (cluster_id * CLUSTER_SIZE) ); 198 204 199 205 timer_address[local_id * TIMER_SPAN + TIMER_RESETIRQ] = 0; … … 258 264 } 259 265 260 unsigned int* tty_address = (unsigned int*)&seg_tty_base + tty_id*TTY_SPAN; 266 unsigned int* tty_address = (unsigned int*)( (char*)&seg_tty_base + 267 (CLUSTER_IO_ID * (unsigned)CLUSTER_SIZE) ); 261 268 262 269 for (nwritten = 0; nwritten < length; nwritten++) 263 270 { 264 271 // check tty's status 265 if ((tty_address[ TTY_STATUS] & 0x2) == 0x2)272 if ((tty_address[tty_id*TTY_SPAN + TTY_STATUS] & 0x2) == 0x2) 266 273 break; 267 274 else 268 275 // write character 269 tty_address[ TTY_WRITE] = (unsigned int)buffer[nwritten];276 tty_address[tty_id*TTY_SPAN + TTY_WRITE] = (unsigned int)buffer[nwritten]; 270 277 } 271 278 return nwritten; 272 279 } 273 280 ////////////////////////////////////////////////////////////////////////////// 274 // _tty_read _irq()281 // _tty_read() 275 282 // This non-blocking function uses the TTY_GET_IRQ[tty_id] interrupt and 276 283 // the associated kernel buffer, that has been written by the ISR. 284 // It get the TTY terminal index from the context of the current task. 277 285 // It fetches one single character from the _tty_get_buf[tty_id] kernel 278 286 // buffer, writes this character to the user buffer, and resets the 279 287 // _tty_get_full[tty_id] buffer. 288 // The length argument is not used. 280 289 // Returns 0 if the kernel buffer is empty, 1 if the buffer is full. 281 290 ////////////////////////////////////////////////////////////////////////////// 282 unsigned int _tty_read _irq( char *buffer,283 291 unsigned int _tty_read( char *buffer, 292 unsigned int length) 284 293 { 285 294 unsigned int task_id = _get_current_task_id(); … … 304 313 } 305 314 //////////////////////////////////////////////////////////////////////////////// 306 // _tty_read() 307 // This non-blocking function fetches one character directly from the TTY_READ 308 // register of the TTY controler, and writes this character to the user buffer. 309 // It doesn't use the TTY_GET_IRQ interrupt and the associated kernel buffer. 310 // Returns 0 if the register is empty, 1 if the register is full. 311 //////////////////////////////////////////////////////////////////////////////// 312 unsigned int _tty_read( char *buffer, 313 unsigned int length) 314 { 315 unsigned int task_id = _get_current_task_id(); 316 unsigned int tty_id = _get_context_slot(task_id, CTX_TTY_ID); 317 318 if ( tty_id >= NB_TTYS ) 319 { 320 _tty_error( task_id ); 321 return 0; 322 } 323 324 unsigned int* tty_address = (unsigned int*)&seg_tty_base + tty_id*TTY_SPAN; 325 326 if ((tty_address[TTY_STATUS] & 0x1) != 0x1) 327 { 328 return 0; 329 } 330 else 331 { 332 *buffer = (char)tty_address[TTY_READ]; 333 return 1; 334 } 315 // _tty_get_char() 316 // This function is used by the _isr_tty to read a character in the TTY 317 // terminal defined by the tty_id argument. The character is stored 318 // in requested buffer, and the IRQ is acknowledged. 319 // Returns 0 if success, 1 if tty_id too large. 320 //////////////////////////////////////////////////////////////////////////////// 321 unsigned int _tty_get_char( unsigned int tty_id, 322 char* buffer ) 323 { 324 // checking argument 325 if ( tty_id >= NB_TTYS ) return 1; 326 327 // compute terminal base address 328 unsigned int *tty_address = (unsigned int*)( (char*)&seg_tty_base + 329 (CLUSTER_IO_ID * (unsigned)CLUSTER_SIZE) ); 330 331 *buffer = (unsigned char)tty_address[tty_id*TTY_SPAN + TTY_READ]; 332 return 0; 335 333 } 336 334 … … 359 357 if ( proc_id >= NB_PROCS_MAX ) return 1; 360 358 361 unsigned int* icu_address = (unsigned int*) &seg_icu_base +362 (cluster_id * CLUSTER_SPAN);359 unsigned int* icu_address = (unsigned int*)( (char*)&seg_icu_base + 360 (cluster_id * (unsigned)CLUSTER_SIZE) ); 363 361 #if GIET_USE_XICU 364 362 if ( is_timer ) icu_address[XICU_REG(XICU_MSK_PTI_ENABLE, proc_id)] = value; … … 385 383 if ( proc_id >= NB_PROCS_MAX ) return 1; 386 384 387 unsigned int* icu_address = (unsigned int*) &seg_icu_base +388 (cluster_id * CLUSTER_SPAN);385 unsigned int* icu_address = (unsigned int*)( (char*)&seg_icu_base + 386 (cluster_id * (unsigned)CLUSTER_SIZE) ); 389 387 #if GIET_USE_XICU 390 388 unsigned int prio = icu_address[XICU_REG(XICU_PRIO, proc_id)]; … … 422 420 unsigned int value) 423 421 { 424 volatile unsigned int *gcd_address;425 426 422 // parameters checking 427 423 if (register_index >= GCD_END) 428 424 return 1; 429 425 430 gcd_address = (unsigned int*)&seg_gcd_base; 426 unsigned int* gcd_address = (unsigned int*)( (char*)&seg_gcd_base + 427 (CLUSTER_IO_ID * (unsigned)CLUSTER_SIZE) ); 431 428 432 429 gcd_address[register_index] = value; // write word … … 441 438 unsigned int *buffer) 442 439 { 443 volatile unsigned int *gcd_address;444 445 440 // parameters checking 446 441 if (register_index >= GCD_END) 447 442 return 1; 448 443 449 gcd_address = (unsigned int*)&seg_gcd_base; 444 unsigned int* gcd_address = (unsigned int*)( (char*)&seg_gcd_base + 445 (CLUSTER_IO_ID * (unsigned)CLUSTER_SIZE) ); 450 446 451 447 *buffer = gcd_address[register_index]; // read word … … 538 534 if ( (unsigned int)user_vaddr & 0x3 ) return 1; 539 535 540 unsigned int* ioc_address = (unsigned int*)&seg_ioc_base; 536 unsigned int* ioc_address = (unsigned int*)( (char*)&seg_ioc_base + 537 (CLUSTER_IO_ID * (unsigned)CLUSTER_SIZE) ); 538 541 539 unsigned int block_size = ioc_address[BLOCK_DEVICE_BLOCK_SIZE]; 542 540 unsigned int length = count*block_size; … … 630 628 if ( GIET_IOMMU_ACTIVE ) 631 629 { 632 unsigned int* iob_address = (unsigned int*)&seg_iob_base; 630 unsigned int* iob_address = (unsigned int*)( (char*)&seg_iob_base + 631 (CLUSTER_IO_ID * (unsigned)CLUSTER_SIZE) ); 633 632 634 633 for ( ix2 = 0 ; ix2 < _ioc_iommu_npages ; ix2++ ) … … 687 686 (unsigned int)buffer, 688 687 count ); 688 } 689 /////////////////////////////////////////////////////////////////////////////// 690 // _ioc_get_status() 691 // This function returns the transfert status, and acknowledge the IRQ. 692 // Returns 0 if success, > 0 if error. 693 /////////////////////////////////////////////////////////////////////////////// 694 unsigned int _ioc_get_status(unsigned int* status) 695 { 696 // get IOC base address 697 unsigned int* ioc_address = (unsigned int*)( (char*)&seg_ioc_base + 698 (CLUSTER_IO_ID * (unsigned)CLUSTER_SIZE) ); 699 700 *status = ioc_address[BLOCK_DEVICE_STATUS]; // read status & reset IRQ 701 return 0; 689 702 } 690 703 … … 718 731 in_unckdata unsigned int _dma_iommu_npages[NB_DMAS_MAX * NB_CLUSTERS]; 719 732 #endif 733 734 ////////////////////////////////////////////////////////////////////////////////// 735 // _dma_reset_irq() 736 ////////////////////////////////////////////////////////////////////////////////// 737 unsigned int _dma_reset_irq( unsigned int cluster_id, 738 unsigned int local_id ) 739 { 740 // parameters checking 741 if ( cluster_id >= NB_CLUSTERS ) return 1; 742 if ( local_id >= NB_DMAS_MAX ) return 1; 743 744 // compute DMA base address 745 unsigned int* dma_address = (unsigned int*)( (char*)&seg_dma_base + 746 (cluster_id * (unsigned)CLUSTER_SIZE) ); 747 748 dma_address[local_id*DMA_SPAN + DMA_RESET] = 0; 749 return 0; 750 } 751 ////////////////////////////////////////////////////////////////////////////////// 752 // _dma_get_status() 753 ////////////////////////////////////////////////////////////////////////////////// 754 unsigned int _dma_get_status( unsigned int cluster_id, 755 unsigned int local_id, 756 unsigned int* status ) 757 { 758 // parameters checking 759 if ( cluster_id >= NB_CLUSTERS ) return 1; 760 if ( local_id >= NB_DMAS_MAX ) return 1; 761 762 // compute DMA base address 763 unsigned int* dma_address = (unsigned int*)( (char*)&seg_dma_base + 764 (cluster_id * (unsigned)CLUSTER_SIZE) ); 765 766 *status = dma_address[local_id*DMA_SPAN + DMA_LEN]; 767 return 0; 768 } 720 769 721 770 ////////////////////////////////////////////////////////////////////////////////// … … 819 868 unsigned int cluster_id = dma_id / NB_DMAS_MAX; 820 869 unsigned int loc_id = dma_id % NB_DMAS_MAX; 821 unsigned int* dma_base = (unsigned int*)&seg_dma_base + 822 (cluster_id * CLUSTER_SPAN) +823 ( loc_id * DMA_SPAN);824 870 871 unsigned int* dma_base = (unsigned int*)( (char*)&seg_dma_base + 872 (cluster_id * (unsigned)CLUSTER_SIZE) ); 873 825 874 // check user buffer address and length alignment 826 875 if ( (user_vaddr & 0x3) || (length & 0x3) ) … … 930 979 931 980 */ 981 932 982 // invalidate data cache in case of memory write 933 983 if ( to_user ) _dcache_buf_invalidate( (void*)user_vaddr, length ); … … 939 989 if ( to_user ) 940 990 { 941 dma_base[ DMA_SRC] = (unsigned int)fb_pbase;942 dma_base[ DMA_DST] = (unsigned int)user_pbase;991 dma_base[loc_id*DMA_SPAN + DMA_SRC] = (unsigned int)fb_pbase; 992 dma_base[loc_id*DMA_SPAN + DMA_DST] = (unsigned int)user_pbase; 943 993 } 944 994 else 945 995 { 946 dma_base[ DMA_SRC] = (unsigned int)user_pbase;947 dma_base[ DMA_DST] = (unsigned int)fb_pbase;948 } 949 dma_base[ DMA_LEN] = (unsigned int)length;996 dma_base[loc_id*DMA_SPAN + DMA_SRC] = (unsigned int)user_pbase; 997 dma_base[loc_id*DMA_SPAN + DMA_DST] = (unsigned int)fb_pbase; 998 } 999 dma_base[loc_id*DMA_SPAN + DMA_LEN] = (unsigned int)length; 950 1000 951 1001 return 0; … … 1011 1061 if ( GIET_IOMMU_ACTIVE ) 1012 1062 { 1013 unsigned int* iob_address = (unsigned int*)&seg_iob_base; 1063 unsigned int* iob_address = (unsigned int*)( (char*)&seg_iob_base + 1064 (CLUSTER_IO_ID * (unsigned)CLUSTER_SIZE) ); 1065 1014 1066 unsigned int ix1 = _dma_iommu_ix1 + dma_id; 1015 1067 unsigned int ix2; -
soft/giet_vm/sys/drivers.h
r203 r204 40 40 unsigned int length); 41 41 42 unsigned int _tty_ read_irq( char* buffer,43 unsigned int length);42 unsigned int _tty_get_char( unsigned int tty_id, 43 char* buffer); 44 44 45 45 /////////////////////////////////////////////////////////////////////////////////// … … 77 77 unsigned int _ioc_completed(); 78 78 79 unsigned int _ioc_get_status( unsigned int* status); 80 79 81 /////////////////////////////////////////////////////////////////////////////////// 80 82 // Multi DMA variables (vci_multi_dma) … … 86 88 extern unsigned int _dma_iommu_ix1; 87 89 extern unsigned int _dma_iommu_npages[]; 90 91 unsigned int _dma_reset_irq( unsigned int cluster_id, 92 unsigned int local_id ); 93 94 unsigned int _dma_get_status( unsigned int cluster_id, 95 unsigned int local_id, 96 unsigned int* status ); 88 97 89 98 /////////////////////////////////////////////////////////////////////////////////// -
soft/giet_vm/sys/irq_handler.c
r203 r204 92 92 // compute cluster_id and loc_id 93 93 unsigned int cluster_id = channel_id / NB_DMAS_MAX; 94 unsigned int loc_id = channel_id % NB_DMAS_MAX; 95 96 // compute DMA channel address 97 unsigned int* dma_address = (unsigned int*)&seg_dma_base + 98 (loc_id * DMA_SPAN) + 99 (cluster_id * CLUSTER_SPAN); 94 unsigned int local_id = channel_id % NB_DMAS_MAX; 100 95 101 96 // save DMA channel status 102 _dma_status[channel_id] = dma_address[DMA_LEN]; 103 104 // reset DMA channel 105 dma_address[DMA_RESET] = 0; 97 if ( _dma_get_status(cluster_id, local_id, &_dma_status[channel_id]) ) 98 { 99 _get_lock(&_tty_put_lock); 100 _puts("[GIET ERROR] illegal DMA channel detected by _isr_dma\n"); 101 _release_lock(&_tty_put_lock); 102 return; 103 } 104 105 // reset DMA channel irq 106 if ( _dma_reset_irq(cluster_id, local_id) ) 107 { 108 _get_lock(&_tty_put_lock); 109 _puts("[GIET ERROR] illegal DMA channel detected by _isr_dma\n"); 110 _release_lock(&_tty_put_lock); 111 return; 112 } 106 113 107 114 // release DMA channel … … 117 124 void _isr_ioc() 118 125 { 119 unsigned int* ioc_address = (unsigned int*)&seg_ioc_base; 120 121 _ioc_status = ioc_address[BLOCK_DEVICE_STATUS]; // save status & reset IRQ 122 _ioc_done = 1; // signals completion 126 // save status & reset IRQ 127 if ( _ioc_get_status( &_ioc_status ) ) 128 { 129 _get_lock(&_tty_put_lock); 130 _puts("[GIET ERROR] bad access to IOC status detected by _isr_ioc\n"); 131 _release_lock(&_tty_put_lock); 132 return; 133 } 134 135 // signals completion 136 _ioc_done = 1; 123 137 } 124 138 … … 148 162 _puts("[GIET ERROR] Strange... User timer ISR for a system timer\n"); 149 163 _release_lock(&_tty_put_lock); 164 return; 150 165 } 151 166 152 167 // aknowledge IRQ 153 _timer_reset_irq( cluster_id, local_id ); 168 if ( _timer_reset_irq( cluster_id, local_id ) ) 169 { 170 _get_lock(&_tty_put_lock); 171 _puts("[GIET ERROR] illegal timer index detected by _isr_timer\n"); 172 _release_lock(&_tty_put_lock); 173 return; 174 } 154 175 155 176 #if NB_TIMERS_MAX … … 172 193 // This ISR handles the IRQs generated by the multi_tty controler, 173 194 // signaling that a character is available. 174 // There is one single multi_tty component controling all TTYs, and the tty_id175 // a rgument is the global TTY index.195 // There is one single multi_tty component controling all TTYs, 196 // and the tty_id // argument is the global TTY index. 176 197 // There is one communication buffer _tty_buf[tty_id] per terminal. 177 198 // The sychronisation variable _tty_full[tty_id], is set by the ISR, … … 181 202 void _isr_tty(unsigned int tty_id) 182 203 { 183 // compute terminal base address184 unsigned int *tty_address = (unsigned int*)&seg_tty_base + (tty_id * TTY_SPAN);185 186 204 // save character and reset IRQ 187 _tty_get_buf[tty_id] = (unsigned char)tty_address[TTY_READ]; 205 if ( _tty_get_char( tty_id, &_tty_get_buf[tty_id] ) ) 206 { 207 _get_lock(&_tty_put_lock); 208 _puts("[GIET ERROR] illegal tty index detected by _isr_tty\n"); 209 _release_lock(&_tty_put_lock); 210 return; 211 } 188 212 189 213 // signals character available … … 207 231 208 232 // acknowledge IRQ 209 _timer_reset_irq( cluster_id, local_id ); 233 if ( _timer_reset_irq( cluster_id, local_id ) ) 234 { 235 _get_lock(&_tty_put_lock); 236 _puts("[GIET ERROR] illegal proc index detected by _isr_switch\n"); 237 _release_lock(&_tty_put_lock); 238 return; 239 } 210 240 211 241 // performs the context switch -
soft/giet_vm/sys/sys_handler.c
r203 r204 32 32 &_sys_ukn, /* 0x08 */ 33 33 &_sys_ukn, /* 0x09 */ 34 &_ tty_read_irq,/* 0x0A */34 &_sys_ukn, /* 0x0A */ 35 35 &_sys_ukn, /* 0x0B */ 36 36 &_sys_ukn, /* 0x0C */
Note: See TracChangeset
for help on using the changeset viewer.