Changeset 228 for soft/giet_vm/sys
- Timestamp:
- Feb 12, 2013, 6:33:31 PM (12 years ago)
- Location:
- soft/giet_vm/sys
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/sys/common.c
r221 r228 17 17 18 18 /////////////////////////////////////////////////////////////////////////////////// 19 // 19 // Global variables 20 20 /////////////////////////////////////////////////////////////////////////////////// 21 21 … … 23 23 24 24 // SR save (used by _it_mask() / it_restore() 25 unsigned int 26 27 /////////////////////////////////////////////////////////////////////////////////// 28 // 25 unsigned int _status_register_save; 26 27 /////////////////////////////////////////////////////////////////////////////////// 28 // _get_sched() 29 29 // Access CP0 and returns scheduler physical address. 30 30 /////////////////////////////////////////////////////////////////////////////////// 31 inline unsigned int _get_sched() 32 { 33 unsigned int ret; 34 asm volatile ( "mfc0 %0, $22" 35 : "=r"(ret) ); 36 return ret; 37 } 38 /////////////////////////////////////////////////////////////////////////////////// 39 // _get_ptpr() 31 inline unsigned int _get_sched() { 32 unsigned int ret; 33 asm volatile( 34 "mfc0 %0, $22" 35 : "=r"(ret)); 36 return ret; 37 } 38 39 40 /////////////////////////////////////////////////////////////////////////////////// 41 // _get_ptpr() 40 42 // Access CP2 and returns PTPR register. 41 43 /////////////////////////////////////////////////////////////////////////////////// 42 inline unsigned int _get_ptpr() 43 { 44 unsigned int ret; 45 asm volatile ( "mfc2 %0, $0" 46 : "=r"(ret) ); 47 return ret; 48 } 49 /////////////////////////////////////////////////////////////////////////////////// 50 // _get_epc() 44 inline unsigned int _get_ptpr() { 45 unsigned int ret; 46 asm volatile( 47 "mfc2 %0, $0" 48 : "=r"(ret)); 49 return ret; 50 } 51 52 53 /////////////////////////////////////////////////////////////////////////////////// 54 // _get_epc() 51 55 // Access CP0 and returns EPC register. 52 56 /////////////////////////////////////////////////////////////////////////////////// 53 inline unsigned int _get_epc() 54 { 55 unsigned int ret; 56 asm volatile ( "mfc0 %0, $14" 57 : "=r"(ret) ); 58 return ret; 59 } 60 /////////////////////////////////////////////////////////////////////////////////// 61 // _get_bar() 57 inline unsigned int _get_epc() { 58 unsigned int ret; 59 asm volatile("mfc0 %0, $14" 60 : "=r"(ret)); 61 return ret; 62 } 63 64 65 /////////////////////////////////////////////////////////////////////////////////// 66 // _get_bar() 62 67 // Access CP0 and returns BAR register. 63 68 /////////////////////////////////////////////////////////////////////////////////// 64 inline unsigned int _get_bvar() 65 { 66 unsigned int ret; 67 asm volatile ( "mfc0 %0, $8" 68 : "=r"(ret) ); 69 return ret; 70 } 71 /////////////////////////////////////////////////////////////////////////////////// 72 // _get_cr() 69 inline unsigned int _get_bvar() { 70 unsigned int ret; 71 asm volatile( 72 "mfc0 %0, $8" 73 : "=r"(ret)); 74 return ret; 75 } 76 77 78 /////////////////////////////////////////////////////////////////////////////////// 79 // _get_cr() 73 80 // Access CP0 and returns CR register. 74 81 /////////////////////////////////////////////////////////////////////////////////// 75 inline unsigned int _get_cause() 76 { 77 unsigned int ret; 78 asm volatile ( "mfc0 %0, $13" 79 : "=r"(ret) ); 80 return ret; 81 } 82 /////////////////////////////////////////////////////////////////////////////////// 83 // _get_sr() 82 inline unsigned int _get_cause() { 83 unsigned int ret; 84 asm volatile("mfc0 %0, $13" 85 : "=r"(ret)); 86 return ret; 87 } 88 89 90 /////////////////////////////////////////////////////////////////////////////////// 91 // _get_sr() 84 92 // Access CP0 and returns SR register. 85 93 /////////////////////////////////////////////////////////////////////////////////// 86 inline unsigned int _get_sr() 87 { 88 unsigned int ret; 89 asm volatile ( "mfc0 %0, $12" 90 : "=r"(ret) ); 91 return ret; 92 } 94 inline unsigned int _get_sr() { 95 unsigned int ret; 96 asm volatile( 97 "mfc0 %0, $12" 98 : "=r"(ret)); 99 return ret; 100 } 101 93 102 /////////////////////////////////////////////////////////////////////////////////// 94 103 // _it_mask() 95 104 // Access CP0 and mask IRQs 96 105 /////////////////////////////////////////////////////////////////////////////////// 97 inline void _it_mask() 98 { 99 unsigned int sr_value; 100 asm volatile( "li $3, 0xFFFFFFFE \n" 101 "mfc0 %0, $12 \n" 102 "and $3, $3, %0 \n" 103 "mtc0 $3, $12 \n" 104 : "=r"(sr_value) : : "$3" ); 106 inline void _it_mask() { 107 unsigned int sr_value; 108 asm volatile( 109 "li $3, 0xFFFFFFFE \n" 110 "mfc0 %0, $12 \n" 111 "and $3, $3, %0 \n" 112 "mtc0 $3, $12 \n" 113 : "=r"(sr_value) 114 : 115 : "$3"); 105 116 _status_register_save = sr_value; 106 117 } 107 /////////////////////////////////////////////////////////////////////////////////// 108 // _it_enable() 118 119 120 /////////////////////////////////////////////////////////////////////////////////// 121 // _it_restore() 109 122 // Access CP0 and enable IRQs 110 123 /////////////////////////////////////////////////////////////////////////////////// 111 inline void _it_restore() 112 { 113 unsigned int sr_value = _status_register_save; 114 asm volatile( "mtc0 %0, $12 \n" 115 : : "r"(sr_value) ); 116 } 124 inline void _it_restore() { 125 unsigned int sr_value = _status_register_save; 126 asm volatile( 127 "mtc0 %0, $12 \n" 128 : 129 : "r"(sr_value)); 130 } 131 132 117 133 //////////////////////////////////////////////////////////////////////////// 118 134 // _get_lock() … … 121 137 // (delay average value = 100 cycles) 122 138 //////////////////////////////////////////////////////////////////////////// 123 inline void _get_lock( unsigned int* plock ) 124 { 125 register unsigned int delay = ( _proctime() ^ _procid()<<4 ) & 0xFF; 139 inline void _get_lock(unsigned int * plock) { 140 register unsigned int delay = ( _proctime() ^ _procid() << 4) & 0xFF; 126 141 127 142 asm volatile ( … … 144 159 } 145 160 161 146 162 //////////////////////////////////////////////////////////////////////////// 147 163 // _release_lock() 148 164 //////////////////////////////////////////////////////////////////////////// 149 inline void _release_lock( unsigned int* plock ) 150 { 165 inline void _release_lock(unsigned int * plock) { 151 166 asm volatile ( 152 "sync\n" /* necessary because of the consistency model in tsar */153 );167 "sync\n" /* necessary because of the consistency model in tsar */ 168 ); 154 169 *plock = 0; 155 170 } 171 156 172 157 173 //////////////////////////////////////////////////////////////////////////// … … 159 175 // display a string on TTY0 / used for system code debug and log 160 176 //////////////////////////////////////////////////////////////////////////// 161 void _puts(char* buffer) 162 { 163 unsigned int* tty_address = (unsigned int*) &seg_tty_base; 177 void _puts(char * buffer) { 178 unsigned int * tty_address = (unsigned int *) &seg_tty_base; 164 179 unsigned int n; 165 180 166 for ( n=0; n<100; n++) 167 { 168 if (buffer[n] == 0) break; 169 tty_address[TTY_WRITE] = (unsigned int)buffer[n]; 181 for (n = 0; n < 100; n++) { 182 if (buffer[n] == 0) { 183 break; 184 } 185 tty_address[TTY_WRITE] = (unsigned int) buffer[n]; 170 186 } 171 187 } 188 189 172 190 //////////////////////////////////////////////////////////////////////////// 173 191 // _putx() 174 192 // display an int (hexa) on TTY0 / used for system code debug and log 175 193 //////////////////////////////////////////////////////////////////////////// 176 void _putx(unsigned int val) 177 { 178 static const char HexaTab[] = "0123456789ABCDEF"; 179 char buf[11]; 180 unsigned int c; 181 182 buf[0] = '0'; 183 buf[1] = 'x'; 194 void _putx(unsigned int val) { 195 static const char HexaTab[] = "0123456789ABCDEF"; 196 char buf[11]; 197 unsigned int c; 198 199 buf[0] = '0'; 200 buf[1] = 'x'; 184 201 buf[10] = 0; 185 202 186 for ( c = 0 ; c < 8 ; c++ ) 187 { 188 buf[9-c] = HexaTab[val&0xF]; 203 for (c = 0; c < 8; c++) { 204 buf[9 - c] = HexaTab[val & 0xF]; 189 205 val = val >> 4; 190 206 } 191 207 _puts(buf); 192 208 } 209 210 193 211 //////////////////////////////////////////////////////////////////////////// 194 212 // _putd() 195 213 // display an int (decimal) on TTY0 / used for system code debug and log 196 214 //////////////////////////////////////////////////////////////////////////// 197 void _putd(unsigned int val) 198 { 199 static const char DecTab[] = "0123456789"; 200 char buf[11]; 201 unsigned int i; 202 unsigned int first; 215 void _putd(unsigned int val) { 216 static const char DecTab[] = "0123456789"; 217 char buf[11]; 218 unsigned int i; 219 unsigned int first; 203 220 204 221 buf[10] = 0; 205 222 206 for (i = 0; i < 10; i++) 207 { 208 if ((val != 0) || (i == 0)) 209 { 210 buf[9-i] = DecTab[val % 10]; 211 first = 9-i; 223 for (i = 0; i < 10; i++) { 224 if ((val != 0) || (i == 0)) { 225 buf[9 - i] = DecTab[val % 10]; 226 first = 9 - i; 212 227 } 213 else 214 { 228 else { 215 229 break; 216 230 } 217 231 val /= 10; 218 232 } 219 _puts( &buf[first] ); 220 } 233 _puts(&buf[first]); 234 } 235 236 221 237 //////////////////////////////////////////////////////////////////////////// 222 238 // _strncmp() 223 239 // compare two strings s1 & s2 (no more than n characters) 224 240 //////////////////////////////////////////////////////////////////////////// 225 unsigned int _strncmp(const char* s1, 226 const char* s2, 227 unsigned int n) 228 { 241 unsigned int _strncmp(const char * s1, const char * s2, unsigned int n) { 229 242 unsigned int i; 230 for ( i=0 ; i<n ; i++) 231 { 232 if ( s1[i] != s2[i] ) return 1; 233 if ( s1[i] == 0 ) break; 243 for (i = 0; i < n; i++) { 244 if (s1[i] != s2[i]) { 245 return 1; 246 } 247 if (s1[i] == 0) { 248 break; 249 } 234 250 } 235 251 return 0; 236 252 } 237 //////////////////////////////////////////////////////////////////////////// 238 // _dcache_buf_invalidate() 253 254 255 //////////////////////////////////////////////////////////////////////////// 256 // _dcache_buf_invalidate() 239 257 // Invalidate all data cache lines corresponding to a memory 240 258 // buffer (identified by an address and a size). 241 259 //////////////////////////////////////////////////////////////////////////// 242 void _dcache_buf_invalidate(const void *buffer, 243 unsigned int size) 244 { 260 void _dcache_buf_invalidate(const void * buffer, unsigned int size) { 245 261 unsigned int i; 246 262 unsigned int tmp; … … 248 264 249 265 // compute data cache line size based on config register (bits 12:10) 250 asm volatile("mfc0 %0, $16, 1" : "=r" (tmp));251 tmp = ((tmp >>10) & 0x7);266 asm volatile("mfc0 %0, $16, 1" : "=r" (tmp)); 267 tmp = ((tmp >> 10) & 0x7); 252 268 line_size = 2 << tmp; 253 269 254 270 // iterate on cache lines 255 for (i = 0; i < size; i += line_size) 256 { 271 for (i = 0; i < size; i += line_size) { 257 272 asm volatile( 258 273 " cache %0, %1" 259 ::"i" (0x11), "R" (*((unsigned char*)buffer+i)) 274 : 275 :"i" (0x11), "R" (*((unsigned char *) buffer + i)) 260 276 ); 261 277 } 262 278 } 279 280 263 281 //////////////////////////////////////////////////////////////////////////// 264 282 // _physical_read_access() … … 266 284 // after a temporary DTLB desactivation. 267 285 //////////////////////////////////////////////////////////////////////////// 268 unsigned int _physical_read_access(unsigned int* paddr) 269 { 286 unsigned int _physical_read_access(unsigned int * paddr) { 270 287 unsigned int value; 271 288 272 asm volatile( "li $3, 0xFFFFFFFE \n" 273 "mfc0 $2, $12 \n" /* $2 <= SR */ 274 "and $3, $3, $2 \n" 275 "mtc0 $3, $12 \n" /* interrupt masked */ 276 "li $3, 0xB \n" 277 "mtc2 $3, $1 \n" /* DTLB off */ 278 279 "lw %0, 0(%1) \n" /* entry <= *pslot */ 280 281 "li $3, 0xF \n" 282 "mtc2 $3, $1 \n" /* DTLB on */ 283 "mtc0 $2, $12 \n" /* restore SR */ 284 : "=r"(value) 285 : "r"(paddr) 286 : "$2", "$3" ); 289 asm volatile( 290 "li $3, 0xFFFFFFFE \n" 291 "mfc0 $2, $12 \n" /* $2 <= SR */ 292 "and $3, $3, $2 \n" 293 "mtc0 $3, $12 \n" /* interrupt masked */ 294 "li $3, 0xB \n" 295 "mtc2 $3, $1 \n" /* DTLB off */ 296 297 "lw %0, 0(%1) \n" /* entry <= *pslot */ 298 299 "li $3, 0xF \n" 300 "mtc2 $3, $1 \n" /* DTLB on */ 301 "mtc0 $2, $12 \n" /* restore SR */ 302 : "=r" (value) 303 : "r" (paddr) 304 : "$2", "$3"); 287 305 return value; 288 306 } 307 308 289 309 //////////////////////////////////////////////////////////////////////////// 290 310 // _physical_write_access() … … 292 312 // after a temporary DTLB desactivation. 293 313 //////////////////////////////////////////////////////////////////////////// 294 void _physical_write_access(unsigned int* paddr, unsigned int value) 295 { 296 asm volatile( "li $3, 0xFFFFFFFE \n" 297 "mfc0 $2, $12 \n" /* $26 <= SR */ 298 "and $3, $3, $2 \n" 299 "mtc0 $3, $12 \n" /* interrupt masked */ 300 "li $3, 0xB \n" 301 "mtc2 $3, $1 \n" /* DTLB off */ 302 303 "sw %0, 0(%1) \n" /* entry <= *pslot */ 304 305 "li $3, 0xF \n" 306 "mtc2 $3, $1 \n" /* DTLB on */ 307 "mtc0 $2, $12 \n" /* restore SR */ 308 : 309 : "r"(value), "r"(paddr) 310 : "$2", "$3" ); 311 } 314 void _physical_write_access(unsigned int * paddr, unsigned int value) { 315 asm volatile( 316 "li $3, 0xFFFFFFFE \n" 317 "mfc0 $2, $12 \n" /* $26 <= SR */ 318 "and $3, $3, $2 \n" 319 "mtc0 $3, $12 \n" /* interrupt masked */ 320 "li $3, 0xB \n" 321 "mtc2 $3, $1 \n" /* DTLB off */ 322 323 "sw %0, 0(%1) \n" /* entry <= *pslot */ 324 325 "li $3, 0xF \n" 326 "mtc2 $3, $1 \n" /* DTLB on */ 327 "mtc0 $2, $12 \n" /* restore SR */ 328 : 329 : "r" (value), "r" (paddr) 330 : "$2", "$3"); 331 } 332 333 312 334 //////////////////////////////////////////////////////////////////////////// 313 335 // _get_tasks_number() 314 336 // This function returns the number of tasks allocated to processor. 315 337 //////////////////////////////////////////////////////////////////////////// 316 unsigned int _get_tasks_number() 317 { 318 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 319 return _physical_read_access( &(psched->tasks) ); 320 } 338 unsigned int _get_tasks_number() { 339 static_scheduler_t * psched = (static_scheduler_t *) _get_sched(); 340 return _physical_read_access(&(psched->tasks)); 341 } 342 343 321 344 //////////////////////////////////////////////////////////////////////////// 322 345 // _get_current_task_id() 323 346 // This function returns the index of the currently running task. 324 347 //////////////////////////////////////////////////////////////////////////// 325 unsigned int _get_current_task_id() 326 { 327 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 328 return _physical_read_access( &(psched->current) ); 329 } 348 unsigned int _get_current_task_id() { 349 static_scheduler_t * psched = (static_scheduler_t *) _get_sched(); 350 return _physical_read_access(&(psched->current)); 351 } 352 353 330 354 //////////////////////////////////////////////////////////////////////////// 331 355 // _set_current_task_id() 332 356 // This function returns the index of the currently running task. 333 357 //////////////////////////////////////////////////////////////////////////// 334 void _set_current_task_id( unsigned int value ) 335 { 336 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 337 _physical_write_access( &(psched->current), value ); 338 } 358 void _set_current_task_id(unsigned int value) { 359 static_scheduler_t * psched = (static_scheduler_t *) _get_sched(); 360 _physical_write_access(&(psched->current), value); 361 } 362 363 339 364 /////////////////////////////////////////////////////////////////////////////// 340 365 // _get_context_slot() 341 366 // This function returns a slot content for the task defined by task_id. 342 367 /////////////////////////////////////////////////////////////////////////////// 343 unsigned int _get_context_slot( unsigned int task_id,344 unsigned int slot_id )345 { 346 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 347 return _physical_read_access( &(psched->context[task_id][slot_id]) ); 348 } 368 unsigned int _get_context_slot(unsigned int task_id, unsigned int slot_id) { 369 static_scheduler_t * psched = (static_scheduler_t *) _get_sched(); 370 return _physical_read_access(&(psched->context[task_id][slot_id])); 371 } 372 373 349 374 /////////////////////////////////////////////////////////////////////////////// 350 375 // _set_context_slot() … … 352 377 /////////////////////////////////////////////////////////////////////////////// 353 378 void _set_context_slot( unsigned int task_id, 354 unsigned int slot_id, 355 unsigned int value ) 356 { 357 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 358 _physical_write_access( &(psched->context[task_id][slot_id]), value ); 359 } 379 unsigned int slot_id, 380 unsigned int value) { 381 static_scheduler_t * psched = (static_scheduler_t *) _get_sched(); 382 _physical_write_access(&(psched->context[task_id][slot_id]), value); 383 } 384 385 360 386 //////////////////////////////////////////////////////////////////////////////// 361 387 // _get_interrupt_vector_entry() 362 388 // This function returns the interrupt_vector entry defined by argument index. 363 389 //////////////////////////////////////////////////////////////////////////////// 364 unsigned int _get_interrupt_vector_entry( unsigned int index ) 390 unsigned int _get_interrupt_vector_entry(unsigned int index) { 391 static_scheduler_t * psched = (static_scheduler_t *) _get_sched(); 392 return _physical_read_access( &(psched->interrupt_vector[index])); 393 } 394 395 396 ///////////////////////////////////////////////////////////////////////////// 397 // access functions to mapping_info data structure 398 ///////////////////////////////////////////////////////////////////////////// 399 mapping_cluster_t * _get_cluster_base(mapping_header_t * header) { 400 return (mapping_cluster_t *) ((char *) header + 401 MAPPING_HEADER_SIZE); 402 } 403 404 405 ///////////////////////////////////////////////////////////////////////////// 406 mapping_pseg_t * _get_pseg_base(mapping_header_t * header) { 407 return (mapping_pseg_t *) ((char *) header + 408 MAPPING_HEADER_SIZE + 409 MAPPING_CLUSTER_SIZE * header->clusters); 410 } 411 ///////////////////////////////////////////////////////////////////////////// 412 mapping_vspace_t * _get_vspace_base(mapping_header_t * header) { 413 return (mapping_vspace_t *) ((char *) header + 414 MAPPING_HEADER_SIZE + 415 MAPPING_CLUSTER_SIZE * header->clusters + 416 MAPPING_PSEG_SIZE * header->psegs); 417 } 418 419 420 ///////////////////////////////////////////////////////////////////////////// 421 mapping_vseg_t * _get_vseg_base(mapping_header_t * header) 365 422 { 366 static_scheduler_t* psched = (static_scheduler_t*)_get_sched(); 367 return _physical_read_access( &(psched->interrupt_vector[index]) ); 368 } 369 370 ///////////////////////////////////////////////////////////////////////////// 371 // access functions to mapping_info data structure 372 ///////////////////////////////////////////////////////////////////////////// 373 mapping_cluster_t* _get_cluster_base( mapping_header_t* header ) 374 { 375 return (mapping_cluster_t*) ((char*)header + 376 MAPPING_HEADER_SIZE); 377 } 378 ///////////////////////////////////////////////////////////////////////////// 379 mapping_pseg_t* _get_pseg_base( mapping_header_t* header ) 380 { 381 return (mapping_pseg_t*) ((char*)header + 382 MAPPING_HEADER_SIZE + 383 MAPPING_CLUSTER_SIZE*header->clusters); 384 } 385 ///////////////////////////////////////////////////////////////////////////// 386 mapping_vspace_t* _get_vspace_base( mapping_header_t* header ) 387 { 388 return (mapping_vspace_t*) ((char*)header + 389 MAPPING_HEADER_SIZE + 390 MAPPING_CLUSTER_SIZE*header->clusters + 391 MAPPING_PSEG_SIZE*header->psegs); 392 } 393 ///////////////////////////////////////////////////////////////////////////// 394 mapping_vseg_t* _get_vseg_base( mapping_header_t* header ) 395 { 396 return (mapping_vseg_t*) ((char*)header + 397 MAPPING_HEADER_SIZE + 398 MAPPING_CLUSTER_SIZE*header->clusters + 399 MAPPING_PSEG_SIZE*header->psegs + 400 MAPPING_VSPACE_SIZE*header->vspaces); 401 } 402 ///////////////////////////////////////////////////////////////////////////// 403 mapping_vobj_t* _get_vobj_base( mapping_header_t* header ) 404 { 405 return (mapping_vobj_t*) ((char*)header + 406 MAPPING_HEADER_SIZE + 407 MAPPING_CLUSTER_SIZE*header->clusters + 408 MAPPING_PSEG_SIZE*header->psegs + 409 MAPPING_VSPACE_SIZE*header->vspaces + 410 MAPPING_VSEG_SIZE*header->vsegs ); 411 } 412 ///////////////////////////////////////////////////////////////////////////// 413 mapping_task_t* _get_task_base( mapping_header_t* header ) 414 { 415 return (mapping_task_t*) ((char*)header + 416 MAPPING_HEADER_SIZE + 417 MAPPING_CLUSTER_SIZE*header->clusters + 418 MAPPING_PSEG_SIZE*header->psegs + 419 MAPPING_VSPACE_SIZE*header->vspaces + 420 MAPPING_VOBJ_SIZE*header->vobjs + 421 MAPPING_VSEG_SIZE*header->vsegs); 422 } 423 423 return (mapping_vseg_t *) ((char *) header + 424 MAPPING_HEADER_SIZE + 425 MAPPING_CLUSTER_SIZE * header->clusters + 426 MAPPING_PSEG_SIZE * header->psegs + 427 MAPPING_VSPACE_SIZE * header->vspaces); 428 } 429 430 431 ///////////////////////////////////////////////////////////////////////////// 432 mapping_vobj_t * _get_vobj_base(mapping_header_t * header) { 433 return (mapping_vobj_t *) ((char *) header + 434 MAPPING_HEADER_SIZE + 435 MAPPING_CLUSTER_SIZE * header->clusters + 436 MAPPING_PSEG_SIZE * header->psegs + 437 MAPPING_VSPACE_SIZE * header->vspaces + 438 MAPPING_VSEG_SIZE * header->vsegs ); 439 } 440 441 442 ///////////////////////////////////////////////////////////////////////////// 443 mapping_task_t * _get_task_base(mapping_header_t * header) { 444 return (mapping_task_t *) ((char *) header + 445 MAPPING_HEADER_SIZE + 446 MAPPING_CLUSTER_SIZE * header->clusters + 447 MAPPING_PSEG_SIZE * header->psegs + 448 MAPPING_VSPACE_SIZE * header->vspaces + 449 MAPPING_VOBJ_SIZE * header->vobjs + 450 MAPPING_VSEG_SIZE * header->vsegs); 451 } 452 453 454 // Local Variables: 455 // tab-width: 4 456 // c-basic-offset: 4 457 // c-file-offsets:((innamespace . 0)(inline-open . 0)) 458 // indent-tabs-mode: nil 459 // End: 460 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 461 -
soft/giet_vm/sys/common.h
r218 r228 30 30 31 31 /////////////////////////////////////////////////////////////////////////////////// 32 // 32 // Prototypes of common functions 33 33 /////////////////////////////////////////////////////////////////////////////////// 34 34 35 void 36 void 37 void 35 void _puts(char *string); 36 void _putx(unsigned int val); 37 void _putd(unsigned int val); 38 38 39 unsigned int _strncmp( const char* s1, 40 const char* s2, 41 unsigned int n ); 39 unsigned int _strncmp(const char * s1, const char * s2, unsigned int n); 40 void _dcache_buf_invalidate(const void * buffer, unsigned int size); 42 41 43 void _dcache_buf_invalidate( const void *buffer,44 unsigned int size);42 void _dtlb_off(void); 43 void _dtlb_on(void); 45 44 46 void _dtlb_off(void);47 void _dtlb_on(void);45 void _it_mask(void); 46 void _it_restore(void); 48 47 49 void _it_mask(void); 50 void _it_enable(void); 48 unsigned int _get_epc(void); 49 unsigned int _get_ptpr(void); 50 unsigned int _get_bvar(void); 51 unsigned int _get_cr(void); 52 unsigned int _get_sched(void); 51 53 52 unsigned int _get_epc(void); 53 unsigned int _get_ptpr(void); 54 unsigned int _get_bvar(void); 55 unsigned int _get_cr(void); 56 unsigned int _get_sched(void); 54 unsigned int _get_context_slot(unsigned int task_id, unsigned int slot_id); 55 void _set_context_slot(unsigned int task_id, unsigned int slot_id, unsigned int value); 57 56 58 unsigned int _get_context_slot( unsigned int task_id, 59 unsigned int slot_id ); 57 unsigned int _get_interrupt_vector_entry(unsigned int index); 60 58 61 void _set_context_slot( unsigned int task_id, 62 unsigned int slot_id, 63 unsigned int value ); 59 unsigned int _get_current_task_id(void); 60 void _set_current_task_id(unsigned int value); 64 61 65 unsigned int _get_interrupt_vector_entry(unsigned int index);62 unsigned int _get_tasks_number(void); 66 63 67 unsigned int _get_current_task_id( void);68 void _set_current_task_id( unsigned int value);64 void _get_lock(unsigned int * lock); 65 void _release_lock(unsigned int * lock); 69 66 70 unsigned int _get_tasks_number(void); 71 72 73 void _get_lock(unsigned int* lock); 74 void _release_lock(unsigned int* lock); 75 76 mapping_cluster_t* _get_cluster_base( mapping_header_t* header ); 77 mapping_pseg_t* _get_pseg_base( mapping_header_t* header ); 78 mapping_vspace_t* _get_vspace_base( mapping_header_t* header ); 79 mapping_vseg_t* _get_vseg_base( mapping_header_t* header ); 80 mapping_vobj_t* _get_vobj_base( mapping_header_t* header ); 81 mapping_task_t* _get_task_base( mapping_header_t* header ); 67 mapping_cluster_t * _get_cluster_base(mapping_header_t* header); 68 mapping_pseg_t * _get_pseg_base(mapping_header_t* header); 69 mapping_vspace_t * _get_vspace_base(mapping_header_t* header); 70 mapping_vseg_t * _get_vseg_base(mapping_header_t* header); 71 mapping_vobj_t * _get_vobj_base(mapping_header_t* header); 72 mapping_task_t * _get_task_base(mapping_header_t* header); 82 73 83 74 … … 89 80 // Code taken from MutekH. 90 81 /////////////////////////////////////////////////////////////////////////////////// 91 static inline void *memcpy(void *_dst, const void *_src, unsigned int size) 92 { 93 unsigned int *dst = _dst; 94 const unsigned int *src = _src; 82 static inline void * memcpy(void * _dst, const void * _src, unsigned int size) { 83 unsigned int * dst = _dst; 84 const unsigned int * src = _src; 95 85 96 86 /* if source and destination buffer are word-aligned, 97 87 * then copy word-by-word */ 98 if (!((unsigned int) dst & 3) && !((unsigned int)src & 3))88 if (!((unsigned int) dst & 3) && !((unsigned int) src & 3)) { 99 89 while (size > 3) { 100 90 *dst++ = *src++; 101 91 size -= 4; 102 92 } 93 } 103 94 104 unsigned char * cdst = (unsigned char*)dst;105 unsigned char * csrc = (unsigned char*)src;95 unsigned char * cdst = (unsigned char *) dst; 96 unsigned char * csrc = (unsigned char *) src; 106 97 107 98 /* byte-by-byte copy */ … … 113 104 114 105 #endif 106 107 // Local Variables: 108 // tab-width: 4 109 // c-basic-offset: 4 110 // c-file-offsets:((innamespace . 0)(inline-open . 0)) 111 // indent-tabs-mode: nil 112 // End: 113 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 114 -
soft/giet_vm/sys/ctx_handler.c
r218 r228 30 30 // - CP2 registers : PTPR 31 31 // It contains some general informations associated to the task: 32 // - TTY 33 // - FBDMA 34 // - NIC 32 // - TTY : terminal global index 33 // - FBDMA : DMA channel global index 34 // - NIC : NIC channel global index 35 35 // - TIMER : Timer global index 36 36 // - PTAB : page table virtual base address 37 // - LTID 37 // - LTID : Task local index (in scheduler) 38 38 // - VSID : Virtual space index 39 // - RUN 39 // - RUN : Task state (0 => sleeping / 1 => runable ) 40 40 // 41 41 // ctx[0]<- ***|ctx[8] <- $8 |ctx[16]<- $16|ctx[24]<- $24|ctx[32]<- EPC |ctx[40]<- TTY … … 49 49 ////////////////////////////////////////////////////////////////////////////////////////// 50 50 51 extern void _task_switch(unsigned int *, unsigned int*);51 extern void _task_switch(unsigned int *, unsigned int *); 52 52 53 53 ///////////////////////////////////////////////////////////////////////////////// 54 // 54 // _ctx_switch() 55 55 // This function performs a context switch between the running task 56 56 // and another task, using a round-robin sheduling policy between all … … 68 68 // contained in the ctx[31] slot of the next task context. 69 69 ///////////////////////////////////////////////////////////////////////////////// 70 void _ctx_switch() 71 { 70 void _ctx_switch() { 72 71 // get scheduler physical address 73 static_scheduler_t * psched = (static_scheduler_t*)_get_sched();72 static_scheduler_t * psched = (static_scheduler_t *) _get_sched(); 74 73 75 74 // get number of tasks allocated to scheduler 76 unsigned int 75 unsigned int tasks = _get_tasks_number(); 77 76 78 77 // get current task index 79 unsigned int 78 unsigned int curr_task_id = _get_current_task_id(); 80 79 81 80 // select the next task using a round-robin policy 82 unsigned int 83 unsigned int 84 unsigned int 81 unsigned int next_task_id; 82 unsigned int tid; 83 unsigned int found = 0; 85 84 86 for ( tid = curr_task_id + 1 ; 87 tid < curr_task_id + 1 + tasks ; 88 tid++ ) 89 { 85 for (tid = curr_task_id + 1; tid < curr_task_id + 1 + tasks; tid++) { 90 86 next_task_id = tid % tasks; 91 87 92 88 // test if the task is runable 93 if ( _get_context_slot( next_task_id, CTX_RUN_ID ) ) 94 { 89 if (_get_context_slot(next_task_id, CTX_RUN_ID)) { 95 90 found = 1; 96 91 break; 97 92 } 98 93 } 99 94 100 95 // launch "idle" task if no runable task 101 if ( found == 0 ) 102 { 96 if (found == 0) { 103 97 next_task_id = IDLE_TASK_INDEX; 104 98 } 105 99 106 100 // no switch if no change 107 if ( curr_task_id != next_task_id ) 108 { 109 unsigned int* curr_ctx_paddr = &(psched->context[curr_task_id][0]); 110 unsigned int* next_ctx_paddr = &(psched->context[next_task_id][0]); 101 if (curr_task_id != next_task_id) { 102 unsigned int * curr_ctx_paddr = &(psched->context[curr_task_id][0]); 103 unsigned int * next_ctx_paddr = &(psched->context[next_task_id][0]); 111 104 112 _set_current_task_id( next_task_id ); 113 _task_switch( curr_ctx_paddr, next_ctx_paddr ); 105 _set_current_task_id(next_task_id); 106 //_timer_reset_irq_cpt(cluster_id, local_id); // commented until not properly supported in soclib 107 // (the function is not yet present in drivers.c) 108 _task_switch(curr_ctx_paddr, next_ctx_paddr); 114 109 115 110 #if GIET_DEBUG_SWITCH 116 _get_lock( &_tty_put_lock);117 _puts("\n[GIET DEBUG] Context switch for processor ");118 _putd( _procid());119 _puts(" at cycle ");120 _putd( _proctime());121 _puts("\n");122 _puts(" - tasks = ");123 _putd( tasks);124 _puts("\n");125 _puts(" - curr_task_id = ");126 _putd( curr_task_id );127 _puts("\n");128 _puts(" - next_task_id = ");129 _putd( next_task_id);130 _puts("\n");131 _release_lock( &_tty_put_lock);111 _get_lock(&_tty_put_lock); 112 _puts("\n[GIET DEBUG] Context switch for processor "); 113 _putd(_procid()); 114 _puts(" at cycle "); 115 _putd(_proctime()); 116 _puts("\n"); 117 _puts(" - tasks = "); 118 _putd(tasks); 119 _puts("\n"); 120 _puts(" - curr_task_id = "); 121 _putd( curr_task_id ); 122 _puts("\n"); 123 _puts(" - next_task_id = "); 124 _putd(next_task_id); 125 _puts("\n"); 126 _release_lock( &_tty_put_lock); 132 127 #endif 133 128 … … 138 133 // This function is executed as the"idle" task when no other task can be executed 139 134 ///////////////////////////////////////////////////////////////////////////////////// 140 void _ctx_idle() 141 { 135 void _ctx_idle() { 142 136 unsigned int delay = 1000000; 143 137 144 while (1)145 {146 asm volatile("move $3, %0\n"147 "loop:\n"148 "addi $3, $3, -1\n"149 "bnez $3, loop\n"150 "nop\n"151 152 153 138 while (1) { 139 asm volatile( 140 "move $3, %0 \n" 141 "loop: \n" 142 "addi $3, $3, -1 \n" 143 "bnez $3, loop \n" 144 "nop \n" 145 : 146 : "r"(delay) 147 : "$3" ); 154 148 155 _get_lock( &_tty_put_lock);156 _puts( 157 _putd( _procid());158 _puts( 159 _putd( _proctime());149 _get_lock(&_tty_put_lock); 150 _puts("\n[GIET WARNING] Processor "); 151 _putd(_procid()); 152 _puts(" still idle at cycle "); 153 _putd(_proctime()); 160 154 _puts("\n"); 161 _release_lock( &_tty_put_lock);162 155 _release_lock(&_tty_put_lock); 156 163 157 } 164 158 } // end ctx_idle() 159 165 160 166 161 ///////////////////////////////////////////////////////////////////////////////// … … 168 163 // in the "idle" task context. 169 164 ///////////////////////////////////////////////////////////////////////////////// 170 void _ctx_eret() 171 { 165 void _ctx_eret() { 172 166 asm volatile("eret"); 173 167 } 174 168 175 169 170 // Local Variables: 171 // tab-width: 4 172 // c-basic-offset: 4 173 // c-file-offsets:((innamespace . 0)(inline-open . 0)) 174 // indent-tabs-mode: nil 175 // End: 176 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 177 -
soft/giet_vm/sys/drivers.c
r226 r228 103 103 104 104 ////////////////////////////////////////////////////////////////////////////// 105 // 105 // Timers driver 106 106 ////////////////////////////////////////////////////////////////////////////// 107 107 // The timers can be implemented in a vci_timer component or in a vci_xicu … … 119 119 120 120 #if (NB_TIMERS_MAX > 0) 121 in_unckdata volatile unsigned char _user_timer_event[NB_CLUSTERS *NB_TIMERS_MAX]122 = { [0 ... ((NB_CLUSTERS*NB_TIMERS_MAX)-1)] = 0 };121 in_unckdata volatile unsigned char _user_timer_event[NB_CLUSTERS * NB_TIMERS_MAX] 122 = { [0 ... ((NB_CLUSTERS * NB_TIMERS_MAX) - 1)] = 0 }; 123 123 #endif 124 124 … … 131 131 // Returns 0 if success, > 0 if error. 132 132 ////////////////////////////////////////////////////////////////////////////// 133 unsigned int _timer_start( unsigned int cluster_id, 134 unsigned int local_id, 135 unsigned int period ) 136 { 133 unsigned int _timer_start(unsigned int cluster_id, unsigned int local_id, unsigned int period) { 137 134 // parameters checking 138 if ( cluster_id >= NB_CLUSTERS) return 1; 139 if ( local_id >= NB_TIMERS_MAX) return 2; 135 if (cluster_id >= NB_CLUSTERS) { 136 return 1; 137 } 138 if (local_id >= NB_TIMERS_MAX) { 139 return 2; 140 } 140 141 141 142 #if USE_XICU 142 unsigned int* timer_address = (unsigned int*)((char*)&seg_icu_base + 143 (cluster_id * CLUSTER_SIZE) ); 143 unsigned int * timer_address = (unsigned int *) ((char *) &seg_icu_base + (cluster_id * CLUSTER_SIZE)); 144 144 145 145 timer_address[XICU_REG(XICU_PTI_PER, local_id)] = period; 146 146 #else 147 unsigned int* timer_address = (unsigned int*)((char*)&seg_tim_base + 148 (cluster_id * CLUSTER_SIZE) ); 147 unsigned int* timer_address = (unsigned int *) ((char *) &seg_tim_base + (cluster_id * CLUSTER_SIZE)); 149 148 150 149 timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period; 151 timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0x3; 152 #endif 153 154 return 0; 155 } 150 timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0x3; 151 #endif 152 return 0; 153 } 154 155 156 156 ////////////////////////////////////////////////////////////////////////////// 157 157 // _timer_stop() … … 160 160 // Returns 0 if success, > 0 if error. 161 161 ////////////////////////////////////////////////////////////////////////////// 162 unsigned int _timer_stop( unsigned int cluster_id, 163 unsigned int local_id ) 164 { 162 unsigned int _timer_stop(unsigned int cluster_id, unsigned int local_id) { 165 163 // parameters checking 166 if ( cluster_id >= NB_CLUSTERS) return 1; 167 if ( local_id >= NB_TIMERS_MAX ) return 2; 164 if (cluster_id >= NB_CLUSTERS) { 165 return 1; 166 } 167 if (local_id >= NB_TIMERS_MAX) { 168 return 2; 169 } 168 170 169 171 #if USE_XICU 170 unsigned int* timer_address = (unsigned int*)((char*)&seg_icu_base + 171 (cluster_id * CLUSTER_SIZE) ); 172 unsigned int * timer_address = (unsigned int *) ((char *) &seg_icu_base + (cluster_id * CLUSTER_SIZE)); 172 173 173 174 timer_address[XICU_REG(XICU_PTI_PER, local_id)] = 0; 174 175 #else 175 unsigned int* timer_address = (unsigned int*)((char*)&seg_tim_base + 176 (cluster_id * CLUSTER_SIZE) ); 177 176 unsigned int* timer_address = (unsigned int *) ((char *) &seg_tim_base + (cluster_id * CLUSTER_SIZE)); 178 177 timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0; 179 178 #endif 180 181 return 0; 182 } 179 return 0; 180 } 181 182 183 183 ////////////////////////////////////////////////////////////////////////////// 184 184 // _timer_reset_irq() … … 189 189 // Returns 0 if success, > 0 if error. 190 190 ////////////////////////////////////////////////////////////////////////////// 191 unsigned int _timer_reset_irq( unsigned int cluster_id, 192 unsigned int local_id ) 193 { 191 unsigned int _timer_reset_irq(unsigned int cluster_id, unsigned int local_id) { 194 192 // parameters checking 195 if ( cluster_id >= NB_CLUSTERS) return 1; 196 if ( local_id >= NB_TIMERS_MAX ) return 2; 193 if (cluster_id >= NB_CLUSTERS) { 194 return 1; 195 } 196 if (local_id >= NB_TIMERS_MAX) { 197 return 2; 198 } 197 199 198 200 #if USE_XICU 199 unsigned int * timer_address = (unsigned int*)((char*)&seg_icu_base +200 (cluster_id * (unsigned)CLUSTER_SIZE));201 unsigned int * timer_address = (unsigned int *) ((char *) &seg_icu_base + 202 (cluster_id * (unsigned) CLUSTER_SIZE)); 201 203 202 204 unsigned int bloup = timer_address[XICU_REG(XICU_PTI_ACK, local_id)]; 203 bloup++; 205 bloup++; // to avoid a warning 204 206 #else 205 unsigned int * timer_address = (unsigned int*)((char*)&seg_tim_base +206 (cluster_id * CLUSTER_SIZE));207 unsigned int * timer_address = (unsigned int *)((char *) &seg_tim_base + 208 (cluster_id * CLUSTER_SIZE)); 207 209 208 210 timer_address[local_id * TIMER_SPAN + TIMER_RESETIRQ] = 0; … … 212 214 } 213 215 216 214 217 ///////////////////////////////////////////////////////////////////////////////// 215 // 218 // VciMultiTty driver 216 219 ///////////////////////////////////////////////////////////////////////////////// 217 220 // There is only one multi_tty controler in the architecture. … … 226 229 // TTY variables 227 230 in_unckdata volatile unsigned char _tty_get_buf[NB_TTYS]; 228 in_unckdata volatile unsigned char _tty_get_full[NB_TTYS] = { [0 ... NB_TTYS -1] = 0 };229 in_unckdata unsigned int 231 in_unckdata volatile unsigned char _tty_get_full[NB_TTYS] = { [0 ... NB_TTYS - 1] = 0 }; 232 in_unckdata unsigned int _tty_put_lock = 0; // protect kernel TTY[0] 230 233 231 234 //////////////////////////////////////////////////////////////////////////////// 232 235 // _tty_error() 233 236 //////////////////////////////////////////////////////////////////////////////// 234 void _tty_error( unsigned int tty_id, unsigned int task_id ) 235 { 237 void _tty_error(unsigned int tty_id, unsigned int task_id) { 236 238 unsigned int proc_id = _procid(); 237 239 238 240 _get_lock(&_tty_put_lock); 239 if ( tty_id == 0xFFFFFFFF )241 if (tty_id == 0xFFFFFFFF) { 240 242 _puts("\n[GIET ERROR] no TTY assigned to the task "); 241 else 243 } 244 else { 242 245 _puts("\n[GIET ERROR] TTY index too large for task "); 243 _putd( task_id ); 246 } 247 _putd(task_id); 244 248 _puts(" on processor "); 245 _putd( proc_id);249 _putd(proc_id); 246 250 _puts("\n"); 247 251 _release_lock(&_tty_put_lock); 248 252 } 253 254 249 255 ///////////////////////////////////////////////////////////////////////////////// 250 256 // _tty_write() … … 256 262 // The function returns the number of characters that have been written. 257 263 ///////////////////////////////////////////////////////////////////////////////// 258 unsigned int _tty_write( const char *buffer, 259 unsigned int length) 260 { 261 unsigned int nwritten; 262 263 unsigned int task_id = _get_current_task_id(); 264 unsigned int tty_id = _get_context_slot(task_id, CTX_TTY_ID); 265 266 if ( tty_id >= NB_TTYS ) 267 { 268 _tty_error( tty_id , task_id ); 264 unsigned int _tty_write(const char * buffer, unsigned int length) { 265 unsigned int nwritten; 266 unsigned int task_id = _get_current_task_id(); 267 unsigned int tty_id = _get_context_slot(task_id, CTX_TTY_ID); 268 269 if (tty_id >= NB_TTYS) { 270 _tty_error(tty_id , task_id); 269 271 return 0; 270 272 } 271 273 272 unsigned int* tty_address = (unsigned int*) &seg_tty_base; 273 274 for (nwritten = 0; nwritten < length; nwritten++) 275 { 274 unsigned int * tty_address = (unsigned int *) &seg_tty_base; 275 276 for (nwritten = 0; nwritten < length; nwritten++) { 276 277 // check tty's status 277 if ((tty_address[tty_id *TTY_SPAN + TTY_STATUS] & 0x2) == 0x2)278 if ((tty_address[tty_id * TTY_SPAN + TTY_STATUS] & 0x2) == 0x2) { 278 279 break; 279 else 280 } 281 else { 280 282 // write character 281 tty_address[tty_id*TTY_SPAN + TTY_WRITE] = (unsigned int)buffer[nwritten]; 283 tty_address[tty_id * TTY_SPAN + TTY_WRITE] = (unsigned int) buffer[nwritten]; 284 } 282 285 } 283 286 return nwritten; 284 287 } 288 289 285 290 ////////////////////////////////////////////////////////////////////////////// 286 291 // _tty_read() … … 294 299 // Returns 0 if the kernel buffer is empty, 1 if the buffer is full. 295 300 ////////////////////////////////////////////////////////////////////////////// 296 unsigned int _tty_read( char *buffer, 297 unsigned int length) 298 { 299 unsigned int task_id = _get_current_task_id(); 300 unsigned int tty_id = _get_context_slot(task_id, CTX_TTY_ID); 301 302 if ( tty_id >= NB_TTYS ) 303 { 304 _tty_error( tty_id, task_id ); 301 unsigned int _tty_read(char * buffer, unsigned int length) { 302 unsigned int task_id = _get_current_task_id(); 303 unsigned int tty_id = _get_context_slot(task_id, CTX_TTY_ID); 304 305 if (tty_id >= NB_TTYS) { 306 _tty_error(tty_id, task_id); 305 307 return 0; 306 308 } 307 309 308 if (_tty_get_full[tty_id] == 0) 309 { 310 if (_tty_get_full[tty_id] == 0) { 310 311 return 0; 311 312 } 312 else 313 { 313 else { 314 314 *buffer = _tty_get_buf[tty_id]; 315 315 _tty_get_full[tty_id] = 0; 316 316 return 1; 317 317 } 318 } 318 } 319 320 319 321 //////////////////////////////////////////////////////////////////////////////// 320 322 // _tty_get_char() … … 324 326 // Returns 0 if success, 1 if tty_id too large. 325 327 //////////////////////////////////////////////////////////////////////////////// 326 unsigned int _tty_get_char( unsigned int tty_id, 327 unsigned char* buffer ) 328 { 328 unsigned int _tty_get_char(unsigned int tty_id, unsigned char * buffer) { 329 329 // checking argument 330 if ( tty_id >= NB_TTYS ) return 1; 330 if (tty_id >= NB_TTYS) { 331 return 1; 332 } 331 333 332 334 // compute terminal base address 333 unsigned int *tty_address = (unsigned int*) &seg_tty_base; 334 335 *buffer = (unsigned char)tty_address[tty_id*TTY_SPAN + TTY_READ]; 336 return 0; 337 } 338 339 //////////////////////////////////////////////////////////////////////////////// 340 // VciMultiIcu and VciXicu drivers 335 unsigned int * tty_address = (unsigned int *) &seg_tty_base; 336 337 *buffer = (unsigned char) tty_address[tty_id * TTY_SPAN + TTY_READ]; 338 return 0; 339 } 340 341 342 //////////////////////////////////////////////////////////////////////////////// 343 // VciMultiIcu and VciXicu drivers 341 344 //////////////////////////////////////////////////////////////////////////////// 342 345 // There is one vci_multi_icu (or vci_xicu) component per cluster, … … 352 355 // Returns 0 if success, > 0 if error. 353 356 //////////////////////////////////////////////////////////////////////////////// 354 unsigned int _icu_set_mask( unsigned int cluster_id,355 unsigned int proc_id,356 unsigned int value,357 unsigned int is_timer )358 {357 unsigned int _icu_set_mask( 358 unsigned int cluster_id, 359 unsigned int proc_id, 360 unsigned int value, 361 unsigned int is_timer) { 359 362 // parameters checking 360 if ( cluster_id >= NB_CLUSTERS) return 1; 361 if ( proc_id >= NB_PROCS_MAX ) return 1; 362 363 unsigned int* icu_address = (unsigned int*)( (char*)&seg_icu_base + 364 (cluster_id * (unsigned)CLUSTER_SIZE) ); 363 if (cluster_id >= NB_CLUSTERS) { 364 return 1; 365 } 366 if (proc_id >= NB_PROCS_MAX) { 367 return 1; 368 } 369 370 unsigned int * icu_address = (unsigned int *) ((char *) &seg_icu_base + 371 (cluster_id * (unsigned) CLUSTER_SIZE)); 365 372 #if USE_XICU 366 if ( is_timer ) icu_address[XICU_REG(XICU_MSK_PTI_ENABLE, proc_id)] = value; 367 else icu_address[XICU_REG(XICU_MSK_HWI_ENABLE, proc_id)] = value; 373 if (is_timer) { 374 icu_address[XICU_REG(XICU_MSK_PTI_ENABLE, proc_id)] = value; 375 } 376 else { 377 icu_address[XICU_REG(XICU_MSK_HWI_ENABLE, proc_id)] = value; 378 } 368 379 #else 369 380 icu_address[proc_id * ICU_SPAN + ICU_MASK_SET] = value; … … 372 383 return 0; 373 384 } 385 386 374 387 //////////////////////////////////////////////////////////////////////////////// 375 388 // _icu_get_index() … … 379 392 // Returns 0 if success, > 0 if error. 380 393 //////////////////////////////////////////////////////////////////////////////// 381 unsigned int _icu_get_index( unsigned int cluster_id, 382 unsigned int proc_id, 383 unsigned int* buffer ) 384 { 394 unsigned int _icu_get_index(unsigned int cluster_id, unsigned int proc_id, unsigned int * buffer) { 385 395 // parameters checking 386 if ( cluster_id >= NB_CLUSTERS) return 1; 387 if ( proc_id >= NB_PROCS_MAX ) return 1; 388 389 unsigned int* icu_address = (unsigned int*)( (char*)&seg_icu_base + 390 (cluster_id * (unsigned)CLUSTER_SIZE) ); 396 if (cluster_id >= NB_CLUSTERS) { 397 return 1; 398 } 399 if (proc_id >= NB_PROCS_MAX) { 400 return 1; 401 } 402 403 unsigned int * icu_address = (unsigned int *) ((char *) &seg_icu_base + 404 (cluster_id * (unsigned) CLUSTER_SIZE)); 391 405 #if USE_XICU 392 unsigned int prio 406 unsigned int prio = icu_address[XICU_REG(XICU_PRIO, proc_id)]; 393 407 unsigned int pti_ok = (prio & 0x00000001); 394 408 unsigned int hwi_ok = (prio & 0x00000002); … … 397 411 unsigned int hwi_id = (prio & 0x001F0000) >> 16; 398 412 unsigned int swi_id = (prio & 0x1F000000) >> 24; 399 if (pti_ok) *buffer = pti_id; 400 else if (hwi_ok) *buffer = hwi_id; 401 else if (swi_ok) *buffer = swi_id; 402 else *buffer = 32; 413 if (pti_ok) { 414 *buffer = pti_id; 415 } 416 else if (hwi_ok) { 417 *buffer = hwi_id; 418 } 419 else if (swi_ok) { 420 *buffer = swi_id; 421 } 422 else { 423 *buffer = 32; 424 } 403 425 #else 404 426 *buffer = icu_address[proc_id * ICU_SPAN + ICU_IT_VECTOR]; … … 408 430 } 409 431 410 //////////////////////////////////////////////////////////////////////////////// 411 // VciGcd driver 432 433 //////////////////////////////////////////////////////////////////////////////// 434 // VciGcd driver 412 435 //////////////////////////////////////////////////////////////////////////////// 413 436 // The Greater Dommon Divider is a -very- simple hardware coprocessor … … 421 444 // Returns 0 if success, > 0 if error. 422 445 //////////////////////////////////////////////////////////////////////////////// 423 unsigned int _gcd_write( unsigned int register_index, 424 unsigned int value) 425 { 446 unsigned int _gcd_write(unsigned int register_index, unsigned int value) { 426 447 // parameters checking 427 if (register_index >= GCD_END) 428 return 1; 429 430 unsigned int* gcd_address = (unsigned int*) &seg_gcd_base; 448 if (register_index >= GCD_END) { 449 return 1; 450 } 451 452 unsigned int * gcd_address = (unsigned int *) &seg_gcd_base; 431 453 432 454 gcd_address[register_index] = value; // write word 433 455 return 0; 434 456 } 457 458 435 459 //////////////////////////////////////////////////////////////////////////////// 436 460 // _gcd_read() … … 438 462 // Returns 0 if success, > 0 if error. 439 463 //////////////////////////////////////////////////////////////////////////////// 440 unsigned int _gcd_read( unsigned int register_index, 441 unsigned int *buffer) 442 { 464 unsigned int _gcd_read(unsigned int register_index, unsigned int * buffer) { 443 465 // parameters checking 444 if (register_index >= GCD_END) 445 return 1; 446 447 unsigned int* gcd_address = (unsigned int*) &seg_gcd_base; 466 if (register_index >= GCD_END) { 467 return 1; 468 } 469 470 unsigned int * gcd_address = (unsigned int *) &seg_gcd_base; 448 471 449 472 *buffer = gcd_address[register_index]; // read word … … 502 525 503 526 // IOC global variables 504 in_unckdata volatile unsigned int _ioc_status= 0;505 in_unckdata volatile unsigned int _ioc_done= 0;506 in_unckdata unsigned int _ioc_lock= 0;507 in_unckdata unsigned int _ioc_iommu_ix1= 0;508 in_unckdata unsigned int 527 in_unckdata volatile unsigned int _ioc_status= 0; 528 in_unckdata volatile unsigned int _ioc_done = 0; 529 in_unckdata unsigned int _ioc_lock = 0; 530 in_unckdata unsigned int _ioc_iommu_ix1 = 0; 531 in_unckdata unsigned int _ioc_iommu_npages; 509 532 510 533 /////////////////////////////////////////////////////////////////////////////// … … 519 542 // Returns 0 if success, > 0 if error. 520 543 /////////////////////////////////////////////////////////////////////////////// 521 unsigned int _ioc_access( unsigned int to_mem,522 unsigned int lba,523 unsigned int user_vaddr,524 unsigned int count )525 {526 unsigned int user_vpn_min;// first virtuel page index in user space527 unsigned int user_vpn_max;// last virtual page index in user space528 unsigned int vpn;// current virtual page index in user space529 unsigned int ppn;// physical page number530 unsigned int flags;// page protection flags531 unsigned int ix2;// page index in IOMMU PT1 page table532 unsigned int addr;// buffer address for IOC peripheral533 unsigned int ppn_first;// first physical page number for user buffer534 544 unsigned int _ioc_access( 545 unsigned int to_mem, 546 unsigned int lba, 547 unsigned int user_vaddr, 548 unsigned int count) { 549 unsigned int user_vpn_min; // first virtuel page index in user space 550 unsigned int user_vpn_max; // last virtual page index in user space 551 unsigned int vpn; // current virtual page index in user space 552 unsigned int ppn; // physical page number 553 unsigned int flags; // page protection flags 554 unsigned int ix2; // page index in IOMMU PT1 page table 555 unsigned int addr; // buffer address for IOC peripheral 556 unsigned int ppn_first; // first physical page number for user buffer 557 535 558 // check buffer alignment 536 if ( (unsigned int)user_vaddr & 0x3 ) return 1; 537 538 unsigned int* ioc_address = (unsigned int*) &seg_ioc_base ; 539 540 unsigned int block_size = ioc_address[BLOCK_DEVICE_BLOCK_SIZE]; 541 unsigned int length = count*block_size; 559 if ((unsigned int) user_vaddr & 0x3) { 560 return 1; 561 } 562 563 unsigned int * ioc_address = (unsigned int *) &seg_ioc_base ; 564 565 unsigned int block_size = ioc_address[BLOCK_DEVICE_BLOCK_SIZE]; 566 unsigned int length = count * block_size; 542 567 543 568 // get user space page table virtual address 544 unsigned int task_id 545 unsigned int user_pt_vbase = _get_context_slot( task_id, CTX_PTAB_ID);546 569 unsigned int task_id = _get_current_task_id(); 570 unsigned int user_pt_vbase = _get_context_slot(task_id, CTX_PTAB_ID); 571 547 572 user_vpn_min = user_vaddr >> 12; 548 573 user_vpn_max = (user_vaddr + length - 1) >> 12; 549 ix2 574 ix2 = 0; 550 575 551 576 // loop on all virtual pages covering the user buffer 552 for ( vpn = user_vpn_min ; vpn <= user_vpn_max ; vpn++ ) 553 { 577 for (vpn = user_vpn_min; vpn <= user_vpn_max; vpn++) { 554 578 // get ppn and flags for each vpn 555 unsigned int ko = _v2p_translate( (page_table_t*)user_pt_vbase, 556 vpn, 557 &ppn, 558 &flags ); 579 unsigned int ko = _v2p_translate((page_table_t *) user_pt_vbase, vpn, &ppn, &flags); 559 580 560 581 // check access rights 561 if ( ko ) return 2; // unmapped 562 if ( (flags & PTE_U) == 0 ) return 3; // not in user space 563 if ( ( (flags & PTE_W) == 0 ) && to_mem ) return 4; // not writable 582 if (ko) { 583 return 2; // unmapped 584 } 585 if ((flags & PTE_U) == 0) { 586 return 3; // not in user space 587 } 588 if (((flags & PTE_W) == 0 ) && to_mem) { 589 return 4; // not writable 590 } 564 591 565 592 // save first ppn value 566 if ( ix2 == 0 ) ppn_first = ppn; 567 568 if ( IOMMU_ACTIVE ) // the user buffer must be remapped in the I/0 space 569 { 593 if (ix2 == 0) { 594 ppn_first = ppn; 595 } 596 597 if (IOMMU_ACTIVE) { 598 // the user buffer must be remapped in the I/0 space 570 599 // check buffer length < 2 Mbytes 571 if ( ix2 > 511 ) return 2; 600 if (ix2 > 511) { 601 return 2; 602 } 572 603 573 604 // map the physical page in IOMMU page table 574 _iommu_add_pte2( _ioc_iommu_ix1, // PT1 index 575 ix2, // PT2 index 576 ppn, // Physical page number 577 flags ); // Protection flags 605 _iommu_add_pte2( 606 _ioc_iommu_ix1, // PT1 index 607 ix2, // PT2 index 608 ppn, // Physical page number 609 flags); // Protection flags 578 610 } 579 else // no IOMMU : check that physical pages are contiguous 580 { 581 if ( (ppn - ppn_first) != ix2 ) return 5; // split physical buffer 611 else { 612 // no IOMMU : check that physical pages are contiguous 613 if ((ppn - ppn_first) != ix2) { 614 return 5; // split physical buffer 615 } 582 616 } 583 617 584 618 // increment page index 585 619 ix2++; … … 590 624 591 625 // invalidate data cache in case of memory write 592 if ( to_mem ) _dcache_buf_invalidate( (void*)user_vaddr, length ); 626 if (to_mem) { 627 _dcache_buf_invalidate((void *) user_vaddr, length); 628 } 593 629 594 630 // compute buffer base address for IOC depending on IOMMU activation 595 if ( IOMMU_ACTIVE ) addr = (_ioc_iommu_ix1) << 21 | (user_vaddr & 0xFFF); 596 else addr = (ppn_first << 12) | (user_vaddr & 0xFFF); 631 if (IOMMU_ACTIVE) { 632 addr = (_ioc_iommu_ix1) << 21 | (user_vaddr & 0xFFF); 633 } 634 else { 635 addr = (ppn_first << 12) | (user_vaddr & 0xFFF); 636 } 597 637 598 638 // get the lock on ioc device 599 _get_lock( &_ioc_lock);639 _get_lock(&_ioc_lock); 600 640 601 641 // peripheral configuration 602 ioc_address[BLOCK_DEVICE_BUFFER] = addr; 603 ioc_address[BLOCK_DEVICE_COUNT] = count; 604 ioc_address[BLOCK_DEVICE_LBA] = lba; 605 if ( to_mem == 0 ) ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_WRITE; 606 else ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_READ; 607 608 return 0; 609 } 642 ioc_address[BLOCK_DEVICE_BUFFER] = addr; 643 ioc_address[BLOCK_DEVICE_COUNT] = count; 644 ioc_address[BLOCK_DEVICE_LBA] = lba; 645 if (to_mem == 0) { 646 ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_WRITE; 647 } 648 else { 649 ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_READ; 650 } 651 652 return 0; 653 } 654 655 610 656 ///////////////////////////////////////////////////////////////////////////////// 611 657 // _ioc_completed() … … 617 663 // Returns 0 if success, > 0 if error. 618 664 ///////////////////////////////////////////////////////////////////////////////// 619 unsigned int _ioc_completed() 620 { 621 unsigned int ret; 622 unsigned int ix2; 665 unsigned int _ioc_completed() { 666 unsigned int ret; 667 unsigned int ix2; 623 668 624 669 // busy waiting 625 while (_ioc_done == 0) 670 while (_ioc_done == 0) { 626 671 asm volatile("nop"); 672 } 627 673 628 674 // unmap the buffer from IOMMU page table if IOMMU is activated 629 if ( IOMMU_ACTIVE ) 630 { 631 unsigned int* iob_address = (unsigned int*) &seg_iob_base; 632 633 for ( ix2 = 0 ; ix2 < _ioc_iommu_npages ; ix2++ ) 634 { 675 if (IOMMU_ACTIVE) { 676 unsigned int * iob_address = (unsigned int *) &seg_iob_base; 677 678 for (ix2 = 0; ix2 < _ioc_iommu_npages; ix2++) { 635 679 // unmap the page in IOMMU page table 636 _iommu_inval_pte2( _ioc_iommu_ix1, // PT1 index 637 ix2 ); // PT2 index 680 _iommu_inval_pte2( 681 _ioc_iommu_ix1, // PT1 index 682 ix2 ); // PT2 index 638 683 639 684 // clear IOMMU TLB … … 644 689 // test IOC status 645 690 if ((_ioc_status != BLOCK_DEVICE_READ_SUCCESS) 646 && (_ioc_status != BLOCK_DEVICE_WRITE_SUCCESS)) ret = 1; // error 647 else ret = 0; // success 691 && (_ioc_status != BLOCK_DEVICE_WRITE_SUCCESS)) { 692 ret = 1; // error 693 } 694 else { 695 ret = 0; // success 696 } 648 697 649 698 // reset synchronization variables 650 699 _ioc_done = 0; 651 asm volatile 700 asm volatile("sync"); 652 701 _ioc_lock = 0; 653 702 654 703 return ret; 655 704 } 705 706 656 707 /////////////////////////////////////////////////////////////////////////////// 657 708 // _ioc_read() … … 662 713 // Returns 0 if success, > 0 if error. 663 714 /////////////////////////////////////////////////////////////////////////////// 664 unsigned int _ioc_read( unsigned int lba,665 void* buffer,666 unsigned int count )667 { 668 return _ioc_access( 1, // read access669 lba,670 (unsigned int)buffer, 671 count ); 672 } 715 unsigned int _ioc_read(unsigned int lba, void * buffer, unsigned int count) { 716 return _ioc_access( 717 1, // read access 718 lba, 719 (unsigned int) buffer, 720 count); 721 } 722 723 673 724 /////////////////////////////////////////////////////////////////////////////// 674 725 // _ioc_write() … … 679 730 // Returns 0 if success, > 0 if error. 680 731 /////////////////////////////////////////////////////////////////////////////// 681 unsigned int _ioc_write( unsigned int lba,682 const void* buffer,683 unsigned int count )684 { 685 return _ioc_access( 0, // write access686 lba,687 (unsigned int)buffer, 688 count ); 689 } 732 unsigned int _ioc_write(unsigned int lba, const void * buffer, unsigned int count) { 733 return _ioc_access( 734 0, // write access 735 lba, 736 (unsigned int) buffer, 737 count); 738 } 739 740 690 741 /////////////////////////////////////////////////////////////////////////////// 691 742 // _ioc_get_status() … … 693 744 // Returns 0 if success, > 0 if error. 694 745 /////////////////////////////////////////////////////////////////////////////// 695 unsigned int _ioc_get_status(unsigned int* status) 696 { 746 unsigned int _ioc_get_status(unsigned int * status) { 697 747 // get IOC base address 698 unsigned int * ioc_address = (unsigned int*) &seg_ioc_base;748 unsigned int * ioc_address = (unsigned int *) &seg_ioc_base; 699 749 700 750 *status = ioc_address[BLOCK_DEVICE_STATUS]; // read status & reset IRQ 701 751 return 0; 702 752 } 753 703 754 704 755 ////////////////////////////////////////////////////////////////////////////////// … … 719 770 720 771 #if NB_DMAS_MAX > 0 721 in_unckdata unsigned int _dma_lock[NB_DMAS_MAX * NB_CLUSTERS]722 = { [0 ... (NB_DMAS_MAX * NB_CLUSTERS)-1] = 0 };723 724 in_unckdata volatile unsigned int _dma_done[NB_DMAS_MAX * NB_CLUSTERS] 725 = { [0 ... (NB_DMAS_MAX * NB_CLUSTERS)-1] = 0 }; 726 727 in_unckdata volatile unsigned int _dma_status[NB_DMAS_MAX * NB_CLUSTERS];728 729 in_unckdata unsigned int _dma_iommu_ix1 = 1;730 731 in_unckdata unsigned int 772 in_unckdata unsigned int _dma_lock[NB_DMAS_MAX * NB_CLUSTERS] = { 773 [0 ... (NB_DMAS_MAX * NB_CLUSTERS) - 1] = 0 774 }; 775 776 in_unckdata volatile unsigned int _dma_done[NB_DMAS_MAX * NB_CLUSTERS] = { 777 [0 ... (NB_DMAS_MAX * NB_CLUSTERS) - 1] = 0 778 }; 779 780 in_unckdata volatile unsigned int _dma_status[NB_DMAS_MAX * NB_CLUSTERS]; 781 in_unckdata unsigned int _dma_iommu_ix1 = 1; 782 in_unckdata unsigned int _dma_iommu_npages[NB_DMAS_MAX * NB_CLUSTERS]; 732 783 #endif 733 784 … … 735 786 // _dma_reset_irq() 736 787 ////////////////////////////////////////////////////////////////////////////////// 737 unsigned int _dma_reset_irq( unsigned int cluster_id, 738 unsigned int channel_id ) 739 { 788 unsigned int _dma_reset_irq(unsigned int cluster_id, unsigned int channel_id) { 740 789 #if NB_DMAS_MAX > 0 741 790 // parameters checking 742 if ( cluster_id >= NB_CLUSTERS ) return 1; 743 if ( channel_id >= NB_DMAS_MAX ) return 1; 791 if (cluster_id >= NB_CLUSTERS) { 792 return 1; 793 } 794 if (channel_id >= NB_DMAS_MAX) { 795 return 1; 796 } 744 797 745 798 // compute DMA base address 746 unsigned int * dma_address = (unsigned int*)( (char*)&seg_dma_base +747 (cluster_id * (unsigned)CLUSTER_SIZE));748 749 dma_address[channel_id *DMA_SPAN + DMA_RESET] = 0;799 unsigned int * dma_address = (unsigned int *) ((char *) &seg_dma_base + 800 (cluster_id * (unsigned) CLUSTER_SIZE)); 801 802 dma_address[channel_id * DMA_SPAN + DMA_RESET] = 0; 750 803 return 0; 751 804 #else … … 754 807 } 755 808 809 756 810 ////////////////////////////////////////////////////////////////////////////////// 757 811 // _dma_get_status() 758 812 ////////////////////////////////////////////////////////////////////////////////// 759 unsigned int _dma_get_status( unsigned int cluster_id, 760 unsigned int channel_id, 761 unsigned int* status ) 762 { 813 unsigned int _dma_get_status(unsigned int cluster_id, unsigned int channel_id, unsigned int * status) { 763 814 #if NB_DMAS_MAX > 0 764 815 // parameters checking 765 if ( cluster_id >= NB_CLUSTERS ) return 1; 766 if ( channel_id >= NB_DMAS_MAX ) return 1; 816 if (cluster_id >= NB_CLUSTERS) { 817 return 1; 818 } 819 if (channel_id >= NB_DMAS_MAX) { 820 return 1; 821 } 767 822 768 823 // compute DMA base address 769 unsigned int * dma_address = (unsigned int*)( (char*)&seg_dma_base +770 (cluster_id * (unsigned)CLUSTER_SIZE));771 772 *status = dma_address[channel_id *DMA_SPAN + DMA_LEN];824 unsigned int * dma_address = (unsigned int *) ((char *) &seg_dma_base + 825 (cluster_id * (unsigned) CLUSTER_SIZE)); 826 827 *status = dma_address[channel_id * DMA_SPAN + DMA_LEN]; 773 828 return 0; 774 829 #else … … 776 831 #endif 777 832 } 833 778 834 779 835 ////////////////////////////////////////////////////////////////////////////////// … … 798 854 // Returns 0 if success, > 0 if error. 799 855 ////////////////////////////////////////////////////////////////////////////////// 800 unsigned int _dma_transfer( unsigned int dev_type,801 unsigned int to_user,802 unsigned int offset,803 unsigned int user_vaddr,804 unsigned int length )805 {856 unsigned int _dma_transfer( 857 unsigned int dev_type, 858 unsigned int to_user, 859 unsigned int offset, 860 unsigned int user_vaddr, 861 unsigned int length) { 806 862 #if NB_DMAS_MAX > 0 807 unsigned int ko;// unsuccessfull V2P translation808 unsigned int flags;// protection flags809 unsigned int ppn;// physical page number810 unsigned int user_pbase;// user buffer pbase address811 unsigned int device_pbase;// frame buffer pbase address812 unsigned int device_vaddr;// device buffer vbase address863 unsigned int ko; // unsuccessfull V2P translation 864 unsigned int flags; // protection flags 865 unsigned int ppn; // physical page number 866 unsigned int user_pbase; // user buffer pbase address 867 unsigned int device_pbase; // frame buffer pbase address 868 unsigned int device_vaddr; // device buffer vbase address 813 869 814 870 // check user buffer address and length alignment 815 if ( (user_vaddr & 0x3) || (length & 0x3) ) 816 { 871 if ((user_vaddr & 0x3) || (length & 0x3)) { 817 872 _get_lock(&_tty_put_lock); 818 873 _puts("\n[GIET ERROR] in _dma_transfer : user buffer not word aligned\n"); … … 822 877 823 878 // get DMA channel and compute DMA vbase address 824 unsigned int 825 unsigned int dma_id = _get_context_slot( task_id, CTX_DMA_ID);826 unsigned int 827 unsigned int 828 unsigned int * dma_base = (unsigned int*)( (char*)&seg_dma_base +829 (cluster_id * (unsigned)CLUSTER_SIZE));879 unsigned int task_id = _get_current_task_id(); 880 unsigned int dma_id = _get_context_slot(task_id, CTX_DMA_ID); 881 unsigned int cluster_id = dma_id / NB_DMAS_MAX; 882 unsigned int loc_id = dma_id % NB_DMAS_MAX; 883 unsigned int * dma_base = (unsigned int *) ((char *) &seg_dma_base + 884 (cluster_id * (unsigned) CLUSTER_SIZE)); 830 885 831 886 // get page table address 832 unsigned int user_ptab = _get_context_slot( task_id, CTX_PTAB_ID);887 unsigned int user_ptab = _get_context_slot( task_id, CTX_PTAB_ID); 833 888 834 889 // get peripheral buffer virtual address 835 if ( dev_type) device_vaddr = (unsigned int)&seg_nic_base + offset; 836 else device_vaddr = (unsigned int)&seg_fbf_base + offset; 890 if ( dev_type) { 891 device_vaddr = (unsigned int) &seg_nic_base + offset; 892 } 893 else { 894 device_vaddr = (unsigned int) &seg_fbf_base + offset; 895 } 837 896 838 897 // get device buffer physical address 839 ko = _v2p_translate( (page_table_t*)user_ptab, 840 (device_vaddr >> 12), 841 &ppn, 842 &flags ); 843 if ( ko ) 844 { 898 ko = _v2p_translate((page_table_t *) user_ptab, (device_vaddr >> 12), &ppn, &flags); 899 if (ko) { 845 900 _get_lock(&_tty_put_lock); 846 901 _puts("\n[GIET ERROR] in _dma_transfer : device buffer unmapped\n"); … … 851 906 852 907 // Compute user buffer physical address 853 ko = _v2p_translate( (page_table_t*)user_ptab, 854 (user_vaddr >> 12), 855 &ppn, 856 &flags ); 857 if ( ko ) 858 { 908 ko = _v2p_translate( (page_table_t*)user_ptab, (user_vaddr >> 12), &ppn, &flags); 909 if (ko) { 859 910 _get_lock(&_tty_put_lock); 860 911 _puts("\n[GIET ERROR] in _dma_transfer() : user buffer unmapped\n"); … … 862 913 return 3; 863 914 } 864 if ( (flags & PTE_U) == 0 ) 865 { 915 if ((flags & PTE_U) == 0) { 866 916 _get_lock(&_tty_put_lock); 867 917 _puts("[GIET ERROR] in _dma_transfer() : user buffer not in user space\n"); … … 869 919 return 4; 870 920 } 871 if ( ( (flags & PTE_W) == 0 ) && to_user ) 872 { 921 if (((flags & PTE_W) == 0 ) && to_user) { 873 922 _get_lock(&_tty_put_lock); 874 923 _puts("\n[GIET ERROR] in _dma_transfer() : user buffer not writable\n"); … … 878 927 user_pbase = (ppn << 12) | (user_vaddr & 0x00000FFF); 879 928 880 /* This is a draft for IOMMU support881 929 /* This is a draft for IOMMU support 930 882 931 // loop on all virtual pages covering the user buffer 883 932 unsigned int user_vpn_min = user_vaddr >> 12; … … 888 937 for ( vpn = user_vpn_min ; vpn <= user_vpn_max ; vpn++ ) 889 938 { 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 _iommu_add_pte2( ix1,// PT1 index911 ix2,// PT2 index912 ppn,// physical page number913 flags );// protection flags914 915 916 917 918 919 920 921 939 // get ppn and flags for each vpn 940 unsigned int ko = _v2p_translate( (page_table_t*)user_pt_vbase, 941 vpn, 942 &ppn, 943 &flags ); 944 945 // check access rights 946 if ( ko ) return 3; // unmapped 947 if ( (flags & PTE_U) == 0 ) return 4; // not in user space 948 if ( ( (flags & PTE_W) == 0 ) && to_user ) return 5; // not writable 949 950 // save first ppn value 951 if ( ix2 == 0 ) ppn_first = ppn; 952 953 if ( IOMMU_ACTIVE ) // the user buffer must be remapped in the I/0 space 954 { 955 // check buffer length < 2 Mbytes 956 if ( ix2 > 511 ) return 2; 957 958 // map the physical page in IOMMU page table 959 _iommu_add_pte2( ix1, // PT1 index 960 ix2, // PT2 index 961 ppn, // physical page number 962 flags ); // protection flags 963 } 964 else // no IOMMU : check that physical pages are contiguous 965 { 966 if ( (ppn - ppn_first) != ix2 ) return 6; // split physical buffer 967 } 968 969 // increment page index 970 ix2++; 922 971 } // end for vpn 923 972 … … 928 977 929 978 // invalidate data cache in case of memory write 930 if ( to_user ) _dcache_buf_invalidate( (void*)user_vaddr, length ); 931 979 if (to_user) { 980 _dcache_buf_invalidate((void *) user_vaddr, length); 981 } 982 932 983 // get the lock 933 _get_lock( &_dma_lock[dma_id]);984 _get_lock(&_dma_lock[dma_id]); 934 985 935 986 // DMA configuration 936 if ( to_user ) 937 { 938 dma_base[loc_id*DMA_SPAN + DMA_SRC] = (unsigned int)device_pbase; 939 dma_base[loc_id*DMA_SPAN + DMA_DST] = (unsigned int)user_pbase; 940 } 941 else 942 { 943 dma_base[loc_id*DMA_SPAN + DMA_SRC] = (unsigned int)user_pbase; 944 dma_base[loc_id*DMA_SPAN + DMA_DST] = (unsigned int)device_pbase; 945 } 946 dma_base[loc_id*DMA_SPAN + DMA_LEN] = (unsigned int)length; 947 948 return 0; 949 987 if (to_user) { 988 dma_base[loc_id * DMA_SPAN + DMA_SRC] = (unsigned int) device_pbase; 989 dma_base[loc_id * DMA_SPAN + DMA_DST] = (unsigned int) user_pbase; 990 } 991 else { 992 dma_base[loc_id * DMA_SPAN + DMA_SRC] = (unsigned int) user_pbase; 993 dma_base[loc_id * DMA_SPAN + DMA_DST] = (unsigned int) device_pbase; 994 } 995 dma_base[loc_id * DMA_SPAN + DMA_LEN] = (unsigned int) length; 996 997 return 0; 950 998 #else //NB_DMAS_MAX == 0 951 952 999 return -1; 953 954 1000 #endif 955 1001 } // end _dma_transfer() 1002 956 1003 957 1004 ////////////////////////////////////////////////////////////////////////////////// … … 963 1010 // (1 == read error / 2 == DMA idle error / 3 == write error) 964 1011 ////////////////////////////////////////////////////////////////////////////////// 965 unsigned int _dma_completed() 966 { 1012 unsigned int _dma_completed() { 967 1013 #if NB_DMAS_MAX > 0 968 unsigned int 969 unsigned int dma_id = _get_context_slot( task_id, CTX_DMA_ID);970 unsigned int 1014 unsigned int task_id = _get_current_task_id(); 1015 unsigned int dma_id = _get_context_slot(task_id, CTX_DMA_ID); 1016 unsigned int dma_ret; 971 1017 972 1018 // busy waiting with a pseudo random delay between bus access 973 while (_dma_done[dma_id] == 0) 974 {975 unsigned int delay = (( _proctime() ^ _procid()<<4 ) & 0x3F) + 1;976 asm volatile("move $3, %0\n"977 "loop_nic_completed:\n"978 "addi $3, $3, -1\n"979 "bnez $3, loop_nic_completed\n"980 "nop\n"981 982 : "r"(delay)983 : "$3");984 } 985 986 /* draft support for IOMMU1019 while (_dma_done[dma_id] == 0) { 1020 unsigned int delay = (( _proctime() ^ _procid() << 4) & 0x3F) + 1; 1021 asm volatile( 1022 "move $3, %0 \n" 1023 "loop_nic_completed: \n" 1024 "addi $3, $3, -1 \n" 1025 "bnez $3, loop_nic_completed \n" 1026 "nop \n" 1027 : 1028 : "r" (delay) 1029 : "$3"); 1030 } 1031 1032 /* draft support for IOMMU 987 1033 // unmap the buffer from IOMMU page table if IOMMU is activated 988 1034 if ( GIET_IOMMU_ACTIVE ) 989 1035 { 990 991 992 993 994 995 996 997 998 _iommu_inval_pte2( ix1,// PT1 index999 1000 1001 1002 1003 1004 } 1005 */1036 unsigned int* iob_address = (unsigned int*)&seg_iob_base; 1037 1038 unsigned int ix1 = _dma_iommu_ix1 + dma_id; 1039 unsigned int ix2; 1040 1041 for ( ix2 = 0 ; ix2 < _dma_iommu_npages[dma_id] ; ix2++ ) 1042 { 1043 // unmap the page in IOMMU page table 1044 _iommu_inval_pte2( ix1, // PT1 index 1045 ix2 ); // PT2 index 1046 1047 // clear IOMMU TLB 1048 iob_address[IOB_INVAL_PTE] = (ix1 << 21) | (ix2 << 12); 1049 } 1050 } 1051 */ 1006 1052 1007 1053 // reset synchronization variables … … 1019 1065 1020 1066 ////////////////////////////////////////////////////////////////////////////////// 1021 // 1067 // VciFrameBuffer driver 1022 1068 ////////////////////////////////////////////////////////////////////////////////// 1023 1069 // The vci_frame_buffer device can be accessed directly by software with memcpy(), … … 1041 1087 // - length : number of bytes to be transfered. 1042 1088 ////////////////////////////////////////////////////////////////////////////////// 1043 unsigned int _fb_sync_write( unsigned int offset, 1044 const void* buffer, 1045 unsigned int length ) 1046 { 1047 unsigned char *fb_address = (unsigned char*)&seg_fbf_base + offset; 1048 memcpy((void*)fb_address, (void*)buffer, length); 1049 return 0; 1050 } 1089 unsigned int _fb_sync_write(unsigned int offset, const void * buffer, unsigned int length) { 1090 unsigned char * fb_address = (unsigned char *) &seg_fbf_base + offset; 1091 memcpy((void *) fb_address, (void *) buffer, length); 1092 return 0; 1093 } 1094 1051 1095 1052 1096 ////////////////////////////////////////////////////////////////////////////////// … … 1057 1101 // - length : number of bytes to be transfered. 1058 1102 ////////////////////////////////////////////////////////////////////////////////// 1059 unsigned int _fb_sync_read( unsigned int offset, 1060 const void* buffer, 1061 unsigned int length ) 1062 { 1063 unsigned char *fb_address = (unsigned char*)&seg_fbf_base + offset; 1064 memcpy((void*)buffer, (void*)fb_address, length); 1065 return 0; 1066 } 1103 unsigned int _fb_sync_read(unsigned int offset, const void * buffer, unsigned int length) { 1104 unsigned char * fb_address = (unsigned char *) &seg_fbf_base + offset; 1105 memcpy((void *) buffer, (void *) fb_address, length); 1106 return 0; 1107 } 1108 1067 1109 1068 1110 ////////////////////////////////////////////////////////////////////////////////// … … 1074 1116 // Returns 0 if success, > 0 if error. 1075 1117 ////////////////////////////////////////////////////////////////////////////////// 1076 unsigned int _fb_write( unsigned int offset, 1077 const void* buffer, 1078 unsigned int length ) 1079 { 1080 return _dma_transfer( 0, // frame buffer 1081 0, // write 1082 offset, 1083 (unsigned int)buffer, 1084 length ); 1085 } 1118 unsigned int _fb_write(unsigned int offset, const void * buffer, unsigned int length) { 1119 return _dma_transfer( 1120 0, // frame buffer 1121 0, // write 1122 offset, 1123 (unsigned int) buffer, 1124 length); 1125 } 1126 1086 1127 1087 1128 ////////////////////////////////////////////////////////////////////////////////// … … 1093 1134 // Returns 0 if success, > 0 if error. 1094 1135 ////////////////////////////////////////////////////////////////////////////////// 1095 unsigned int _fb_read( unsigned int offset, 1096 const void* buffer, 1097 unsigned int length ) 1098 { 1099 return _dma_transfer( 0, // frame buffer 1100 1, // read 1101 offset, 1102 (unsigned int)buffer, 1103 length ); 1104 } 1136 unsigned int _fb_read(unsigned int offset, const void * buffer, unsigned int length) { 1137 return _dma_transfer( 1138 0, // frame buffer 1139 1, // read 1140 offset, 1141 (unsigned int) buffer, 1142 length); 1143 } 1144 1105 1145 1106 1146 ////////////////////////////////////////////////////////////////////////////////// … … 1111 1151 // (1 == read error / 2 == DMA idle error / 3 == write error) 1112 1152 ////////////////////////////////////////////////////////////////////////////////// 1113 unsigned int _fb_completed() 1114 { 1153 unsigned int _fb_completed() { 1115 1154 return _dma_completed(); 1116 1155 } 1117 1156 1118 1157 ////////////////////////////////////////////////////////////////////////////////// 1119 // 1158 // VciMultiNic driver 1120 1159 ////////////////////////////////////////////////////////////////////////////////// 1121 1160 // The VciMultiNic device can be accessed directly by software with memcpy(), … … 1139 1178 // - length : number of bytes to be transfered. 1140 1179 ////////////////////////////////////////////////////////////////////////////////// 1141 unsigned int _nic_sync_write( unsigned int offset, 1142 const void* buffer, 1143 unsigned int length ) 1144 { 1145 unsigned char *nic_address = (unsigned char*)&seg_nic_base + offset; 1146 memcpy((void*)nic_address, (void*)buffer, length); 1147 return 0; 1148 } 1180 unsigned int _nic_sync_write(unsigned int offset, const void * buffer, unsigned int length) { 1181 unsigned char * nic_address = (unsigned char *) &seg_nic_base + offset; 1182 memcpy((void *) nic_address, (void *) buffer, length); 1183 return 0; 1184 } 1185 1149 1186 1150 1187 ////////////////////////////////////////////////////////////////////////////////// … … 1155 1192 // - length : number of bytes to be transfered. 1156 1193 ////////////////////////////////////////////////////////////////////////////////// 1157 unsigned int _nic_sync_read( unsigned int offset, 1158 const void* buffer, 1159 unsigned int length ) 1160 { 1161 unsigned char *nic_address = (unsigned char*)&seg_nic_base + offset; 1162 memcpy((void*)buffer, (void*)nic_address, length); 1163 return 0; 1164 } 1194 unsigned int _nic_sync_read(unsigned int offset, const void * buffer, unsigned int length) { 1195 unsigned char *nic_address = (unsigned char *) &seg_nic_base + offset; 1196 memcpy((void *) buffer, (void *) nic_address, length); 1197 return 0; 1198 } 1199 1165 1200 1166 1201 ////////////////////////////////////////////////////////////////////////////////// … … 1172 1207 // Returns 0 if success, > 0 if error. 1173 1208 ////////////////////////////////////////////////////////////////////////////////// 1174 unsigned int _nic_write( unsigned int offset, 1175 const void* buffer, 1176 unsigned int length ) 1177 { 1178 return _dma_transfer( 1, // NIC 1179 0, // write 1180 offset, 1181 (unsigned int)buffer, 1182 length ); 1183 } 1209 unsigned int _nic_write(unsigned int offset, const void * buffer, unsigned int length) { 1210 return _dma_transfer( 1211 1, // NIC 1212 0, // write 1213 offset, 1214 (unsigned int) buffer, 1215 length ); 1216 } 1217 1184 1218 1185 1219 ////////////////////////////////////////////////////////////////////////////////// … … 1191 1225 // Returns 0 if success, > 0 if error. 1192 1226 ////////////////////////////////////////////////////////////////////////////////// 1193 unsigned int _nic_read( unsigned int offset, 1194 const void* buffer, 1195 unsigned int length ) 1196 { 1197 return _dma_transfer( 1, // NIC 1198 1, // read 1199 offset, 1200 (unsigned int)buffer, 1201 length ); 1202 } 1227 unsigned int _nic_read(unsigned int offset, const void * buffer, unsigned int length) { 1228 return _dma_transfer( 1229 1, // NIC 1230 1, // read 1231 offset, 1232 (unsigned int) buffer, 1233 length ); 1234 } 1235 1203 1236 1204 1237 ////////////////////////////////////////////////////////////////////////////////// … … 1209 1242 // (1 == read error / 2 == DMA idle error / 3 == write error) 1210 1243 ////////////////////////////////////////////////////////////////////////////////// 1211 unsigned int _nic_completed() 1212 { 1244 unsigned int _nic_completed() { 1213 1245 return _dma_completed(); 1214 1246 } 1215 1247 1248 // Local Variables: 1249 // tab-width: 4 1250 // c-basic-offset: 4 1251 // c-file-offsets:((innamespace . 0)(inline-open . 0)) 1252 // indent-tabs-mode: nil 1253 // End: 1254 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 1255 -
soft/giet_vm/sys/drivers.h
r218 r228 16 16 extern volatile unsigned char _timer_event[]; 17 17 18 unsigned int _timer_start( unsigned int cluster_id, 19 unsigned int local_id, 20 unsigned int period ); 18 unsigned int _timer_start(unsigned int cluster_id, unsigned int local_id, unsigned int period); 19 unsigned int _timer_stop(unsigned int cluster_id, unsigned int local_id); 20 unsigned int _timer_reset_irq(unsigned int cluster_id, unsigned int local_id); 21 unsigned int _timer_reset_irq_cpt(unsigned int cluster_id, unsigned int local_id); 21 22 22 unsigned int _timer_stop( unsigned int cluster_id,23 unsigned int local_id );24 25 26 unsigned int _timer_reset_irq( unsigned int cluster_id,27 unsigned int local_id );28 23 29 24 /////////////////////////////////////////////////////////////////////////////////// … … 33 28 extern volatile unsigned char _tty_get_buf[]; 34 29 extern volatile unsigned char _tty_get_full[]; 35 extern unsigned int 30 extern unsigned int _tty_put_lock; 36 31 37 unsigned int _tty_write( const char* buffer, 38 unsigned int length); 39 40 unsigned int _tty_read( char* buffer, 41 unsigned int length); 42 43 unsigned int _tty_get_char( unsigned int tty_id, 44 unsigned char* buffer); 32 unsigned int _tty_write(const char * buffer, unsigned int length); 33 unsigned int _tty_read(char * buffer, unsigned int length); 34 unsigned int _tty_get_char(unsigned int tty_id, unsigned char * buffer); 45 35 46 36 /////////////////////////////////////////////////////////////////////////////////// … … 48 38 /////////////////////////////////////////////////////////////////////////////////// 49 39 50 unsigned int _icu_get_index(unsigned int cluster_id, 51 unsigned int proc_id, 52 unsigned int* buffer ); 53 54 unsigned int _icu_set_mask( unsigned int cluster_id, 55 unsigned int proc_id, 56 unsigned int mask, 57 unsigned int is_timer ); 40 unsigned int _icu_get_index(unsigned int cluster_id, unsigned int proc_id, unsigned int * buffer); 41 unsigned int _icu_set_mask( 42 unsigned int cluster_id, 43 unsigned int proc_id, 44 unsigned int mask, 45 unsigned int is_timer); 58 46 59 47 /////////////////////////////////////////////////////////////////////////////////// … … 61 49 /////////////////////////////////////////////////////////////////////////////////// 62 50 63 extern volatile unsigned int 64 extern volatile unsigned int 65 extern unsigned int 66 extern unsigned int 67 extern unsigned int 51 extern volatile unsigned int _ioc_status; 52 extern volatile unsigned int _ioc_done; 53 extern unsigned int _ioc_lock; 54 extern unsigned int _ioc_iommu_ix1; 55 extern unsigned int _ioc_iommu_npages; 68 56 69 57 70 unsigned int _ioc_write( unsigned int lba, 71 const void* buffer, 72 unsigned int count); 73 74 unsigned int _ioc_read( unsigned int lba, 75 void* buffer, 76 unsigned int count); 77 58 unsigned int _ioc_write(unsigned int lba, const void * buffer, unsigned int count); 59 unsigned int _ioc_read(unsigned int lba, void * buffer, unsigned int count); 78 60 unsigned int _ioc_completed(); 79 80 unsigned int _ioc_get_status( unsigned int* status); 61 unsigned int _ioc_get_status(unsigned int * status); 81 62 82 63 /////////////////////////////////////////////////////////////////////////////////// 83 // Multi DMA variables 64 // Multi DMA variables (vci_multi_dma) 84 65 /////////////////////////////////////////////////////////////////////////////////// 85 86 extern volatile unsigned int _dma_status[];87 extern volatile unsigned int _dma_done[];88 extern unsigned int _dma_lock[];89 extern unsigned int _dma_iommu_ix1;90 extern unsigned int _dma_iommu_npages[];91 66 92 unsigned int _dma_reset_irq( unsigned int cluster_id, 93 unsigned int local_id ); 67 extern volatile unsigned int _dma_status[]; 68 extern volatile unsigned int _dma_done[]; 69 extern unsigned int _dma_lock[]; 70 extern unsigned int _dma_iommu_ix1; 71 extern unsigned int _dma_iommu_npages[]; 94 72 95 unsigned int _dma_get_status( unsigned int cluster_id, 96 unsigned int local_id, 97 unsigned int* status ); 73 unsigned int _dma_reset_irq(unsigned int cluster_id, unsigned int local_id); 74 unsigned int _dma_get_status(unsigned int cluster_id, unsigned int local_id, unsigned int * status); 98 75 99 unsigned int _dma_transfer( unsigned int dev_type, 100 unsigned int to_user, 101 unsigned int offset, 102 unsigned int user_vaddr, 103 unsigned int length ); 76 unsigned int _dma_transfer( 77 unsigned int dev_type, 78 unsigned int to_user, 79 unsigned int offset, 80 unsigned int user_vaddr, 81 unsigned int length); 104 82 105 83 unsigned int _dma_completed(); … … 108 86 // Frame Buffer access functions (vci_frame_buffer) 109 87 /////////////////////////////////////////////////////////////////////////////////// 110 111 unsigned int _fb_sync_write(unsigned int offset,112 const void* buffer,113 unsigned int length);114 88 115 unsigned int _fb_sync_read( unsigned int offset, 116 const void* buffer, 117 unsigned int length); 118 119 unsigned int _fb_write( unsigned int offset, 120 const void* buffer, 121 unsigned int length); 122 123 unsigned int _fb_read( unsigned int offset, 124 const void* buffer, 125 unsigned int length); 89 unsigned int _fb_sync_write(unsigned int offset, const void * buffer, unsigned int length); 90 unsigned int _fb_sync_read( unsigned int offset, const void * buffer, unsigned int length); 91 unsigned int _fb_write( unsigned int offset, const void * buffer, unsigned int length); 92 unsigned int _fb_read( unsigned int offset, const void * buffer, unsigned int length); 126 93 127 94 unsigned int _fb_completed(); … … 131 98 /////////////////////////////////////////////////////////////////////////////////// 132 99 133 unsigned int _nic_sync_write(unsigned int offset, 134 const void* buffer, 135 unsigned int length); 136 137 unsigned int _nic_sync_read( unsigned int offset, 138 const void* buffer, 139 unsigned int length); 140 141 142 unsigned int _nic_write( unsigned int offset, 143 const void* buffer, 144 unsigned int length); 145 146 unsigned int _nic_read( unsigned int offset, 147 const void* buffer, 148 unsigned int length); 100 unsigned int _nic_sync_write(unsigned int offset, const void * buffer, unsigned int length); 101 unsigned int _nic_sync_read( unsigned int offset, const void * buffer, unsigned int length); 102 unsigned int _nic_write( unsigned int offset, const void * buffer, unsigned int length); 103 unsigned int _nic_read( unsigned int offset, const void * buffer, unsigned int length); 149 104 150 105 unsigned int _nic_completed(); … … 154 109 /////////////////////////////////////////////////////////////////////////////////// 155 110 156 unsigned int _gcd_write( unsigned int register_index, 157 unsigned int value); 158 159 unsigned int _gcd_read( unsigned int register_index, 160 unsigned int* buffer); 111 unsigned int _gcd_write(unsigned int register_index, unsigned int value); 112 unsigned int _gcd_read( unsigned int register_index, unsigned int * buffer); 161 113 162 114 163 115 #endif 164 116 117 // Local Variables: 118 // tab-width: 4 119 // c-basic-offset: 4 120 // c-file-offsets:((innamespace . 0)(inline-open . 0)) 121 // indent-tabs-mode: nil 122 // End: 123 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 124 -
soft/giet_vm/sys/exc_handler.c
r218 r228 54 54 }; 55 55 56 static const char * exc_type[] = {56 static const char * exc_type[] = { 57 57 "strange unknown cause", 58 58 "illegal read address", … … 62 62 "breakpoint", 63 63 "reserved instruction", 64 "illegal coproc access" 64 "illegal coproc access", 65 65 "arithmetic overflow", 66 66 }; 67 67 68 static void _display_cause(unsigned int type) 69 {68 69 static void _display_cause(unsigned int type) { 70 70 _get_lock(&_tty_put_lock); 71 71 _puts("\n[GIET] Exception for task "); 72 _putd( _get_current_task_id());72 _putd(_get_current_task_id()); 73 73 _puts(" on processor "); 74 _putd( _procid());74 _putd(_procid()); 75 75 _puts(" at cycle "); 76 _putd( _proctime());76 _putd(_proctime()); 77 77 _puts("\n - type : "); 78 _puts( (char*)exc_type[type]);78 _puts((char *) exc_type[type]); 79 79 _puts("\n - EPC : "); 80 _putx( _get_epc());80 _putx(_get_epc()); 81 81 _puts("\n - BVAR : "); 82 _putx( _get_bvar());82 _putx(_get_bvar()); 83 83 _puts("\n"); 84 84 _puts("...Task desactivated\n"); … … 87 87 // goes to sleeping state 88 88 unsigned int task_id = _get_current_task_id(); 89 _set_context_slot( task_id, CTX_RUN_ID, 0 90 89 _set_context_slot( task_id, CTX_RUN_ID, 0); 90 91 91 // deschedule 92 92 _ctx_switch(); … … 103 103 static void _cause_ovf() { _display_cause(8); } 104 104 105 // Local Variables: 106 // tab-width: 4 107 // c-basic-offset: 4 108 // c-file-offsets:((innamespace . 0)(inline-open . 0)) 109 // indent-tabs-mode: nil 110 // End: 111 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 112 -
soft/giet_vm/sys/hwr_mapping.h
r209 r228 90 90 91 91 #define XICU_REG(func, index) (((func)<<5)|(index)) 92 92 93 93 /* TIMER */ 94 94 enum TIMER_registers { … … 113 113 /* IOB */ 114 114 enum IOB_registers { 115 IOB_IOMMU_PTPR = 0, 116 IOB_IOMMU_ACTIVE = 1, 117 IOB_IOMMU_BVAR = 2, 118 IOB_IOMMU_ETR = 3, 119 IOB_IOMMU_BAD_ID = 4, 120 IOB_INVAL_PTE = 5, 121 IOB_IT_ADDR_IOMMU_LO = 6, 122 IOB_IT_ADDR_IOMMU_HI = 7, 123 IOB_IT_ADDRESS_BEGIN = 8, 115 IOB_IOMMU_PTPR = 0, /* R/W : Page Table Pointer Register */ 116 IOB_IOMMU_ACTIVE = 1, /* R/W : IOMMU activated if not 0 */ 117 IOB_IOMMU_BVAR = 2, /* R : Bad Virtual Address (unmapped) */ 118 IOB_IOMMU_ETR = 3, /* R : Error Type */ 119 IOB_IOMMU_BAD_ID = 4, /* R : Faulty Peripheral Index */ 120 IOB_INVAL_PTE = 5, /* W : Invalidate a PTE (virtual address) */ 121 IOB_IT_ADDR_IOMMU_LO = 6, /* W/R : 32 LSB bits for IOMMU IT*/ 122 IOB_IT_ADDR_IOMMU_HI = 7, /* W/R : 32 MSB bits for IOMMU IT */ 123 IOB_IT_ADDRESS_BEGIN = 8, /* R/W : Peripheral IT address (2 32 bits registers) */ 124 124 }; 125 125 … … 145 145 #endif 146 146 147 // Local Variables: 148 // tab-width: 4 149 // c-basic-offset: 4 150 // c-file-offsets:((innamespace . 0)(inline-open . 0)) 151 // indent-tabs-mode: nil 152 // End: 153 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 154 -
soft/giet_vm/sys/irq_handler.c
r216 r228 20 20 21 21 #if NB_TIMERS_MAX 22 extern volatile unsigned char _user_timer_event[NB_CLUSTERS *NB_TIMERS_MAX] ;22 extern volatile unsigned char _user_timer_event[NB_CLUSTERS * NB_TIMERS_MAX] ; 23 23 #endif 24 24 25 25 /////////////////////////////////////////////////////////////////////////////////// 26 // 26 // _irq_demux() 27 27 // This function uses the ICU or XICU component (Interrupt Controler Unit) 28 28 // to get the interrupt vector entry. There is one ICU or XICU component per … … 40 40 // a global index : channel_id = cluster_id * NB_CHANNELS_MAX + loc_id 41 41 /////////////////////////////////////////////////////////////////////////////////// 42 void _irq_demux() 43 { 44 unsigned int pid = _procid(); 45 unsigned int irq_id; 42 void _irq_demux() { 43 unsigned int pid = _procid(); 44 unsigned int irq_id; 46 45 47 46 48 47 // get the highest priority active IRQ index 49 if ( _icu_get_index( pid / NB_PROCS_MAX, 50 pid % NB_PROCS_MAX, 51 &irq_id ) ) 52 { 48 if (_icu_get_index( pid / NB_PROCS_MAX, pid % NB_PROCS_MAX, &irq_id)) { 53 49 _get_lock(&_tty_put_lock); 54 50 _puts("\n[GIET ERROR] Strange... Wrong _icu_read in _irq_demux()\n"); … … 57 53 58 54 59 if ( irq_id < 32 ) // do nothing if no interrupt active 60 { 61 unsigned int entry = _get_interrupt_vector_entry(irq_id); 62 unsigned int isr_id = entry & 0x000000FF; 63 unsigned int channel_id = (entry>>16) & 0x0000FFFF; 64 if ( isr_id == ISR_SWITCH ) _isr_switch( channel_id ); 65 else if ( isr_id == ISR_IOC ) _isr_ioc(); 66 else if ( isr_id == ISR_DMA ) _isr_dma( channel_id ); 67 else if ( isr_id == ISR_TTY ) _isr_tty( channel_id ); 68 else if ( isr_id == ISR_TIMER ) _isr_timer( channel_id ); 69 else _isr_default(); 70 } 71 } 72 /////////////////////////////////////////////////////////////////////////////////// 73 // _isr_default() 55 if (irq_id < 32) { 56 // do nothing if no interrupt active 57 unsigned int entry = _get_interrupt_vector_entry(irq_id); 58 unsigned int isr_id = entry & 0x000000FF; 59 unsigned int channel_id = (entry >> 16) & 0x0000FFFF; 60 if ( isr_id == ISR_SWITCH) _isr_switch( channel_id); 61 else if ( isr_id == ISR_IOC ) _isr_ioc(); 62 else if ( isr_id == ISR_DMA ) _isr_dma(channel_id); 63 else if ( isr_id == ISR_TTY ) _isr_tty(channel_id); 64 else if ( isr_id == ISR_TIMER ) _isr_timer(channel_id); 65 else _isr_default(); 66 } 67 } 68 69 70 /////////////////////////////////////////////////////////////////////////////////// 71 // _isr_default() 74 72 // The default ISR is called when no specific ISR has been installed in the 75 73 // interrupt vector. It simply displays an error message on kernel TTY[0]. 76 74 /////////////////////////////////////////////////////////////////////////////////// 77 void _isr_default() 78 { 75 void _isr_default() { 79 76 _get_lock(&_tty_put_lock); 80 77 _puts("\n[GIET ERROR] Strange... Default ISR activated for processor "); … … 84 81 } 85 82 86 /////////////////////////////////////////////////////////////////////////////////// 87 // _isr_dma() 83 84 /////////////////////////////////////////////////////////////////////////////////// 85 // _isr_dma() 88 86 // This ISR handles all IRQs generated by the multi-channels DMA controlers. 89 87 // The multi_dma components can be distributed in the clusters. … … 94 92 // - it resets the synchronisation variable _dma_busy[dma_global_id]. 95 93 /////////////////////////////////////////////////////////////////////////////////// 96 void _isr_dma( unsigned int channel_id ) 97 { 94 void _isr_dma(unsigned int channel_id) { 98 95 #if NB_DMAS_MAX > 0 99 96 // compute cluster_id 100 unsigned int cluster_id = _procid() /NB_PROCS_MAX;97 unsigned int cluster_id = _procid() / NB_PROCS_MAX; 101 98 102 99 // compute dma_global_id 103 unsigned int dma_global_id = cluster_id *NB_DMAS_MAX + channel_id;100 unsigned int dma_global_id = cluster_id * NB_DMAS_MAX + channel_id; 104 101 105 102 // save DMA channel status 106 if ( _dma_get_status(cluster_id, 107 channel_id, 108 (unsigned int*)&_dma_status[dma_global_id] ) ) 109 { 103 if (_dma_get_status(cluster_id, channel_id, 104 (unsigned int *) &_dma_status[dma_global_id])) { 110 105 _get_lock(&_tty_put_lock); 111 106 _puts("[GIET ERROR] illegal DMA channel detected by _isr_dma\n"); … … 115 110 116 111 // reset DMA channel irq 117 if ( _dma_reset_irq( cluster_id, 118 channel_id) ) 119 { 112 if (_dma_reset_irq(cluster_id, channel_id)) { 120 113 _get_lock(&_tty_put_lock); 121 114 _puts("[GIET ERROR] illegal DMA channel detected by _isr_dma\n"); … … 133 126 134 127 /////////////////////////////////////////////////////////////////////////////////// 135 // 128 // _isr_ioc() 136 129 // There is only one IOC controler shared by all tasks. 137 130 // - The ISR save the status and acknowledge the IRQ. 138 131 // - It sets the _ioc_done variable to signal completion. 139 132 /////////////////////////////////////////////////////////////////////////////////// 140 void _isr_ioc() 141 { 142 // save status & reset IRQ 143 if ( _ioc_get_status( (unsigned int*)&_ioc_status ) ) 144 { 133 void _isr_ioc() { 134 // save status & reset IRQ 135 if (_ioc_get_status((unsigned int *) &_ioc_status )) { 145 136 _get_lock(&_tty_put_lock); 146 137 _puts("[GIET ERROR] bad access to IOC status detected by _isr_ioc\n"); … … 150 141 151 142 // signals completion 152 _ioc_done = 1; 153 } 154 155 /////////////////////////////////////////////////////////////////////////////////// 156 // _isr_timer() 143 _ioc_done = 1; 144 } 145 146 147 /////////////////////////////////////////////////////////////////////////////////// 148 // _isr_timer() 157 149 // This ISR handles the IRQs generated by the "user" timers (the IRQs generated 158 150 // by the "system" timers should be handled by the _isr_switch(). … … 164 156 // of the _timer_event[] array, and a log message is displayed on kernel terminal. 165 157 /////////////////////////////////////////////////////////////////////////////////// 166 void _isr_timer(unsigned int timer_id) 167 { 158 void _isr_timer(unsigned int timer_id) { 168 159 // compute cluster_id 169 unsigned int cluster_id = _procid() /NB_PROCS_MAX;160 unsigned int cluster_id = _procid() / NB_PROCS_MAX; 170 161 171 162 // aknowledge IRQ 172 if ( _timer_reset_irq( cluster_id, 173 timer_id ) ) 174 { 163 if (_timer_reset_irq( cluster_id, timer_id)) { 175 164 _get_lock(&_tty_put_lock); 176 165 _puts("[GIET ERROR] illegal timer index detected by _isr_timer\n"); … … 181 170 #if NB_TIMERS_MAX 182 171 // register the event 183 unsigned int timer_global_id = cluster_id *NB_TIMERS_MAX + timer_id;172 unsigned int timer_global_id = cluster_id * NB_TIMERS_MAX + timer_id; 184 173 _user_timer_event[timer_global_id] = 1; 185 174 #endif … … 188 177 _get_lock(&_tty_put_lock); 189 178 _puts("\n[GIET] User Timer IRQ at cycle "); 190 _putd( _proctime());179 _putd(_proctime()); 191 180 _puts("\n - cluster_id = "); 192 _putd( cluster_id);181 _putd(cluster_id); 193 182 _puts("\n - timer_id = "); 194 _putd( timer_id);183 _putd(timer_id); 195 184 _puts("\n"); 196 185 _release_lock(&_tty_put_lock); 197 186 } 187 198 188 199 189 /////////////////////////////////////////////////////////////////////////////////// … … 208 198 // A character is lost if the buffer is full when the ISR is executed. 209 199 /////////////////////////////////////////////////////////////////////////////////// 210 void _isr_tty(unsigned int tty_id) 211 { 200 void _isr_tty(unsigned int tty_id) { 212 201 // save character and reset IRQ 213 if ( _tty_get_char( tty_id, 214 (unsigned char*)&_tty_get_buf[tty_id] ) ) 215 { 202 if (_tty_get_char( tty_id, (unsigned char *) &_tty_get_buf[tty_id])) { 216 203 _get_lock(&_tty_put_lock); 217 204 _puts("[GIET ERROR] illegal tty index detected by _isr_tty\n"); … … 223 210 _tty_get_full[tty_id] = 1; 224 211 } 212 225 213 226 214 ///////////////////////////////////////////////////////////////////////////////////// … … 232 220 // The ISR acknowledges the IRQ and calls the _ctx_switch() function. 233 221 ///////////////////////////////////////////////////////////////////////////////////// 234 void _isr_switch( unsigned int timer_id) 235 { 222 void _isr_switch( unsigned int timer_id) { 236 223 // get cluster index and proc local index 237 224 unsigned int cluster_id = _procid() / NB_PROCS_MAX; 238 225 239 226 // acknowledge IRQ 240 if ( _timer_reset_irq( cluster_id, timer_id ) ) 241 { 227 if (_timer_reset_irq(cluster_id, timer_id)) { 242 228 _get_lock(&_tty_put_lock); 243 229 _puts("[GIET ERROR] illegal proc index detected by _isr_switch\n"); … … 250 236 } 251 237 238 239 // Local Variables: 240 // tab-width: 4 241 // c-basic-offset: 4 242 // c-file-offsets:((innamespace . 0)(inline-open . 0)) 243 // indent-tabs-mode: nil 244 // End: 245 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 246 -
soft/giet_vm/sys/irq_handler.h
r189 r228 21 21 void _isr_default(); 22 22 void _isr_ioc(); 23 void _isr_timer( unsigned int channel);24 void _isr_dma( unsigned int channel);25 void _isr_tty( unsigned int channel);23 void _isr_timer(unsigned int channel); 24 void _isr_dma(unsigned int channel); 25 void _isr_tty(unsigned int channel); 26 26 void _isr_switch(); 27 27 28 28 #endif 29 30 // Local Variables: 31 // tab-width: 4 32 // c-basic-offset: 4 33 // c-file-offsets:((innamespace . 0)(inline-open . 0)) 34 // indent-tabs-mode: nil 35 // End: 36 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 37 -
soft/giet_vm/sys/kernel_init.c
r220 r228 37 37 38 38 __attribute__((section (".kdata"))) 39 unsigned int 40 41 __attribute__((section (".kdata"))) 42 unsigned int 39 unsigned int _ptabs_paddr[GIET_NB_VSPACE_MAX]; 40 41 __attribute__((section (".kdata"))) 42 unsigned int _ptabs_vaddr[GIET_NB_VSPACE_MAX]; 43 43 44 44 /////////////////////////////////////////////////////////////////////////////////// … … 47 47 48 48 __attribute__((section (".kdata"))) 49 static_scheduler_t * _schedulers_paddr[NB_CLUSTERS*NB_PROCS_MAX];49 static_scheduler_t * _schedulers_paddr[NB_CLUSTERS * NB_PROCS_MAX]; 50 50 51 51 /////////////////////////////////////////////////////////////////////////////////// … … 54 54 55 55 __attribute__((section (".kdata"))) 56 unsigned int _idle_stack[NB_CLUSTERS*NB_PROCS_MAX*64]; 57 58 void _sys_exit() 59 { 60 while(1); 56 unsigned int _idle_stack[NB_CLUSTERS*NB_PROCS_MAX * 64]; 57 58 void _sys_exit() { 59 while (1); 61 60 } 61 62 62 63 63 ////////////////////////////////////////////////////////////////////////////////// 64 64 // This function is the entry point for the last step of the boot sequence. 65 65 ////////////////////////////////////////////////////////////////////////////////// 66 __attribute__((section (".kinit"))) void _kernel_init() 67 { 66 __attribute__((section (".kinit"))) void _kernel_init() { 68 67 // compute cluster and local processor index 69 unsigned int 70 unsigned int 71 unsigned int proc_id= global_pid % NB_PROCS_MAX;68 unsigned int global_pid = _procid(); 69 unsigned int cluster_id = global_pid / NB_PROCS_MAX; 70 unsigned int proc_id = global_pid % NB_PROCS_MAX; 72 71 73 72 // Step 0 : Compute number of tasks allocated to proc … … 76 75 77 76 #if GIET_DEBUG_INIT 78 _get_lock(&_tty_put_lock);79 _puts("\n[GIET DEBUG] step 0 for processor ");80 _putd( global_pid);81 _puts(" : tasks = ");82 _putd( tasks);83 _puts("\n");84 _release_lock(&_tty_put_lock);77 _get_lock(&_tty_put_lock); 78 _puts("\n[GIET DEBUG] step 0 for processor "); 79 _putd(global_pid); 80 _puts(" : tasks = "); 81 _putd(tasks); 82 _puts("\n"); 83 _release_lock(&_tty_put_lock); 85 84 #endif 86 85 … … 88 87 // get scheduler physical address (from CP0 register) 89 88 90 static_scheduler_t * psched = (static_scheduler_t*)_get_sched();91 _schedulers_paddr[global_pid] 92 93 #if GIET_DEBUG_INIT 94 _get_lock(&_tty_put_lock);95 _puts("\n[GIET DEBUG] step 1 for processor ");96 _putd( global_pid);97 _puts(" / scheduler pbase = ");98 _putx( (unsigned int)psched);99 _puts("\n");100 _release_lock(&_tty_put_lock);89 static_scheduler_t * psched = (static_scheduler_t *) _get_sched(); 90 _schedulers_paddr[global_pid] = psched; 91 92 #if GIET_DEBUG_INIT 93 _get_lock(&_tty_put_lock); 94 _puts("\n[GIET DEBUG] step 1 for processor "); 95 _putd(global_pid); 96 _puts(" / scheduler pbase = "); 97 _putx((unsigned int) psched); 98 _puts("\n"); 99 _release_lock(&_tty_put_lock); 101 100 #endif 102 101 … … 107 106 unsigned int ltid; 108 107 109 for ( ltid = 0 ; ltid < tasks ; ltid++ ) 110 { 111 unsigned int vspace_id = _get_context_slot( ltid , CTX_VSID_ID ); 112 unsigned int ptab_vaddr = _get_context_slot( ltid , CTX_PTAB_ID ); 113 unsigned int ptab_paddr = _get_context_slot( ltid , CTX_PTPR_ID ) << 13; 108 for (ltid = 0; ltid < tasks; ltid++) { 109 unsigned int vspace_id = _get_context_slot(ltid , CTX_VSID_ID); 110 unsigned int ptab_vaddr = _get_context_slot(ltid , CTX_PTAB_ID); 111 unsigned int ptab_paddr = _get_context_slot(ltid , CTX_PTPR_ID) << 13; 114 112 115 113 _ptabs_vaddr[vspace_id] = ptab_vaddr; … … 117 115 118 116 #if GIET_DEBUG_INIT 119 _get_lock(&_tty_put_lock);120 _puts("\n[GIET DEBUG] step 2 for processor ");121 _putd( global_pid);122 _puts(" / vspace ");123 _putd( vspace_id);124 _puts("\n- ptab vbase = ");125 _putx( ptab_vaddr);126 _puts("\n- ptab pbase = ");127 _putx( ptab_paddr);128 _puts("\n");129 _release_lock(&_tty_put_lock);130 #endif 131 132 } 133 117 _get_lock(&_tty_put_lock); 118 _puts("\n[GIET DEBUG] step 2 for processor "); 119 _putd(global_pid); 120 _puts(" / vspace "); 121 _putd(vspace_id); 122 _puts("\n- ptab vbase = "); 123 _putx(ptab_vaddr); 124 _puts("\n- ptab pbase = "); 125 _putx(ptab_paddr); 126 _puts("\n"); 127 _release_lock(&_tty_put_lock); 128 #endif 129 130 } 131 134 132 unsigned int isr_switch_channel = 0xFFFFFFFF; 135 133 … … 142 140 unsigned int pti_mask = 0; 143 141 144 for ( irq_id = 0 ; irq_id < 32 ; irq_id++ ) 145 { 146 unsigned int entry = _get_interrupt_vector_entry(irq_id); 147 unsigned int isr = entry & 0x000000FF; 148 149 if ( (isr == ISR_DMA) || (isr == ISR_IOC) || (isr == ISR_TTY) ) 150 { 151 hwi_mask = hwi_mask | 0x1<< irq_id; 152 } 153 else if ( (isr == ISR_SWITCH) ) 154 { 155 pti_mask = pti_mask | 0x1<< irq_id; 142 for (irq_id = 0; irq_id < 32; irq_id++) { 143 unsigned int entry = _get_interrupt_vector_entry(irq_id); 144 unsigned int isr = entry & 0x000000FF; 145 146 if ((isr == ISR_DMA) || (isr == ISR_IOC) || (isr == ISR_TTY)) { 147 hwi_mask = hwi_mask | 0x1 << irq_id; 148 } 149 else if ((isr == ISR_SWITCH)) { 150 pti_mask = pti_mask | 0x1 << irq_id; 156 151 isr_switch_channel = irq_id; 157 152 } 158 else if ( (isr == ISR_TIMER) ) 159 { 160 pti_mask = pti_mask | 0x1<< irq_id; 161 } 162 } 163 _icu_set_mask( cluster_id, proc_id, hwi_mask, 0 ); // set HWI_MASK 164 _icu_set_mask( cluster_id, proc_id, pti_mask, 1 ); // set PTI_MASK 165 166 #if GIET_DEBUG_INIT 167 _get_lock(&_tty_put_lock); 168 _puts("\n[GIET DEBUG] step 3 for processor "); 169 _putd( global_pid ); 170 _puts("\n - ICU HWI_MASK = "); 171 _putx( hwi_mask ); 172 _puts("\n - ICU PTI_MASK = "); 173 _putx( pti_mask ); 174 _puts("\n"); 175 _release_lock(&_tty_put_lock); 153 else if ((isr == ISR_TIMER)) { 154 pti_mask = pti_mask | 0x1 << irq_id; 155 } 156 } 157 _icu_set_mask(cluster_id, proc_id, hwi_mask, 0); // set HWI_MASK 158 _icu_set_mask(cluster_id, proc_id, pti_mask, 1); // set PTI_MASK 159 160 #if GIET_DEBUG_INIT 161 _get_lock(&_tty_put_lock); 162 _puts("\n[GIET DEBUG] step 3 for processor "); 163 _putd(global_pid); 164 _puts("\n - ICU HWI_MASK = "); 165 _putx(hwi_mask); 166 _puts("\n - ICU PTI_MASK = "); 167 _putx(pti_mask); 168 _puts("\n"); 169 _release_lock(&_tty_put_lock); 176 170 #endif 177 171 178 172 // step 4 : start TICK timer if more than one task 179 if ( tasks > 1 ) 180 { 181 if(isr_switch_channel == 0xFFFFFFFF) 182 { 173 if (tasks > 1) { 174 if (isr_switch_channel == 0xFFFFFFFF) { 183 175 _get_lock(&_tty_put_lock); 184 176 _puts("\n[GIET ERROR] ISR_SWITCH not found on proc "); 185 _putd( 177 _putd(proc_id); 186 178 _puts("\n"); 187 179 _release_lock(&_tty_put_lock); … … 189 181 } 190 182 191 if(_timer_start( cluster_id, isr_switch_channel, GIET_TICK_VALUE )) 192 { 183 if (_timer_start( cluster_id, isr_switch_channel, GIET_TICK_VALUE)) { 193 184 _get_lock(&_tty_put_lock); 194 185 _puts("\n[GIET ERROR] ISR_SWITCH init error for proc "); 195 _putd( 186 _putd(proc_id); 196 187 _puts("\n"); 197 188 _release_lock(&_tty_put_lock); 198 189 _sys_exit(); 199 190 } 200 201 #if GIET_DEBUG_INIT 202 _get_lock(&_tty_put_lock);203 _puts("\n[GIET DEBUG] Step 4 for processor ");204 _putd( global_pid);205 _puts(" / context switch activated\n");206 _release_lock(&_tty_put_lock);207 #endif 208 191 192 #if GIET_DEBUG_INIT 193 _get_lock(&_tty_put_lock); 194 _puts("\n[GIET DEBUG] Step 4 for processor "); 195 _putd(global_pid); 196 _puts(" / context switch activated\n"); 197 _release_lock(&_tty_put_lock); 198 #endif 199 209 200 } 210 201 … … 214 205 // it uses the page table of vspace[0] 215 206 // the stack size is 256 bytes 216 217 _set_context_slot( IDLE_TASK_INDEX, CTX_RUN_ID, 1);218 _set_context_slot( IDLE_TASK_INDEX, CTX_SR_ID, 0xFF03);219 _set_context_slot( IDLE_TASK_INDEX, CTX_SP_ID, (unsigned int)_idle_stack + ((global_pid+1)<<8));220 _set_context_slot( IDLE_TASK_INDEX, CTX_RA_ID, (unsigned int)&_ctx_eret);221 _set_context_slot( IDLE_TASK_INDEX, CTX_EPC_ID, (unsigned int)&_ctx_idle);222 _set_context_slot( IDLE_TASK_INDEX, CTX_LTID_ID, IDLE_TASK_INDEX 223 _set_context_slot( IDLE_TASK_INDEX, CTX_PTPR_ID, _ptabs_paddr[0] >> 13 224 225 #if GIET_DEBUG_INIT 226 _get_lock(&_tty_put_lock);227 _puts("\n[GIET DEBUG] Step 5 for processor ");228 _putd( global_pid);229 _puts(" / idle task context set\n");230 _release_lock(&_tty_put_lock);231 #endif 232 207 208 _set_context_slot( IDLE_TASK_INDEX, CTX_RUN_ID, 1); 209 _set_context_slot( IDLE_TASK_INDEX, CTX_SR_ID, 0xFF03); 210 _set_context_slot( IDLE_TASK_INDEX, CTX_SP_ID, (unsigned int) _idle_stack + ((global_pid + 1) << 8)); 211 _set_context_slot( IDLE_TASK_INDEX, CTX_RA_ID, (unsigned int) &_ctx_eret); 212 _set_context_slot( IDLE_TASK_INDEX, CTX_EPC_ID, (unsigned int) &_ctx_idle); 213 _set_context_slot( IDLE_TASK_INDEX, CTX_LTID_ID, IDLE_TASK_INDEX); 214 _set_context_slot( IDLE_TASK_INDEX, CTX_PTPR_ID, _ptabs_paddr[0] >> 13); 215 216 #if GIET_DEBUG_INIT 217 _get_lock(&_tty_put_lock); 218 _puts("\n[GIET DEBUG] Step 5 for processor "); 219 _putd(global_pid); 220 _puts(" / idle task context set\n"); 221 _release_lock(&_tty_put_lock); 222 #endif 223 233 224 // step 6 : each processor initialises SP, SR, PTPR, EPC, registers 234 225 // with the values corresponding to the first allocated task, … … 237 228 unsigned int task_id; 238 229 239 if ( tasks == 0 ) 240 { 230 if (tasks == 0) { 241 231 task_id = IDLE_TASK_INDEX; 242 232 243 _get_lock( &_tty_put_lock);233 _get_lock(&_tty_put_lock); 244 234 _puts("\n[GIET WARNING] No task allocated to processor "); 245 _putd( global_pid);235 _putd(global_pid); 246 236 _puts(" => idle\n"); 247 _release_lock ( &_tty_put_lock ); 248 } 249 else 250 { 251 task_id = 0; 252 } 253 254 unsigned int sp_value = _get_context_slot( task_id, CTX_SP_ID ); 255 unsigned int sr_value = _get_context_slot( task_id, CTX_SR_ID ); 256 unsigned int ptpr_value = _get_context_slot( task_id, CTX_PTPR_ID ); 257 unsigned int epc_value = _get_context_slot( task_id, CTX_EPC_ID ); 258 259 #if GIET_DEBUG_INIT 260 _get_lock(&_tty_put_lock); 261 _puts("\n[GIET DEBUG] step 6 for processor "); 262 _putd( global_pid ); 263 _puts(" / registers initialised \n"); 264 _puts("- sp = "); 265 _putx( sp_value ); 266 _puts("\n"); 267 _puts("- sr = "); 268 _putx( sr_value ); 269 _puts("\n"); 270 _puts("- ptpr = "); 271 _putx( ptpr_value<<13 ); 272 _puts("\n"); 273 _puts("- epc = "); 274 _putx( epc_value ); 275 _puts("\n"); 276 _release_lock(&_tty_put_lock); 237 _release_lock (&_tty_put_lock); 238 } 239 else { 240 task_id = 0; 241 } 242 243 unsigned int sp_value = _get_context_slot(task_id, CTX_SP_ID); 244 unsigned int sr_value = _get_context_slot(task_id, CTX_SR_ID); 245 unsigned int ptpr_value = _get_context_slot(task_id, CTX_PTPR_ID); 246 unsigned int epc_value = _get_context_slot(task_id, CTX_EPC_ID); 247 248 #if GIET_DEBUG_INIT 249 _get_lock(&_tty_put_lock); 250 _puts("\n[GIET DEBUG] step 6 for processor "); 251 _putd(global_pid); 252 _puts(" / registers initialised \n"); 253 _puts("- sp = "); 254 _putx(sp_value); 255 _puts("\n"); 256 _puts("- sr = "); 257 _putx(sr_value); 258 _puts("\n"); 259 _puts("- ptpr = "); 260 _putx(ptpr_value << 13); 261 _puts("\n"); 262 _puts("- epc = "); 263 _putx(epc_value); 264 _puts("\n"); 265 _release_lock(&_tty_put_lock); 277 266 #endif 278 267 279 268 // set registers and jump to user code 280 asm volatile ( "move $29, %0 \n" /* SP <= ctx[CTX_SP_ID] */ 281 "mtc0 %1, $12 \n" /* SR <= ctx[CTX_SR_ID] */ 282 "mtc2 %2, $0 \n" /* PTPR <= ctx[CTX_PTPR_ID] */ 283 "mtc0 %3, $14 \n" /* EPC <= ctx[CTX_EPC_ID] */ 284 "eret \n" /* jump to user code */ 285 "nop \n" 286 : 287 : "r"(sp_value), "r"(sr_value), "r"(ptpr_value), "r"(epc_value) ); 269 asm volatile ( 270 "move $29, %0 \n" /* SP <= ctx[CTX_SP_ID] */ 271 "mtc0 %1, $12 \n" /* SR <= ctx[CTX_SR_ID] */ 272 "mtc2 %2, $0 \n" /* PTPR <= ctx[CTX_PTPR_ID] */ 273 "mtc0 %3, $14 \n" /* EPC <= ctx[CTX_EPC_ID] */ 274 "eret \n" /* jump to user code */ 275 "nop \n" 276 : 277 : "r" (sp_value), "r" (sr_value), "r" (ptpr_value), "r" (epc_value)); 288 278 289 279 } // end _kernel_init() 280 281 // Local Variables: 282 // tab-width: 4 283 // c-basic-offset: 4 284 // c-file-offsets:((innamespace . 0)(inline-open . 0)) 285 // indent-tabs-mode: nil 286 // End: 287 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 288 -
soft/giet_vm/sys/mips32_registers.h
r199 r228 1 1 /********************************************************************************/ 2 /* File : mips32_registers.h*/3 /* Author : Alain Greiner*/4 /* Date : 26/03/2012*/2 /* File : mips32_registers.h */ 3 /* Author : Alain Greiner */ 4 /* Date : 26/03/2012 */ 5 5 /********************************************************************************/ 6 /* We define mnemonics for MIPS32 registers*/6 /* We define mnemonics for MIPS32 registers */ 7 7 /********************************************************************************/ 8 8 9 9 #ifndef _MIPS32_REGISTER_H 10 10 #define _MIPS32_REGISTER_H … … 12 12 /* processor registers */ 13 13 14 #define zero 15 #define at 16 #define v0 17 #define v1 18 #define a0 19 #define a1 20 #define a2 21 #define a3 22 #define t0 23 #define t1 24 #define t2 25 #define t3 26 #define t4 27 #define t5 28 #define t6 29 #define t7 30 #define s0 31 #define s1 32 #define s2 33 #define s3 34 #define s4 35 #define s5 36 #define s6 37 #define s7 38 #define t8 39 #define t9 40 #define k0 41 #define k1 42 #define gp 43 #define sp 44 #define fp 45 #define ra 14 #define zero $0 15 #define at $1 16 #define v0 $2 17 #define v1 $3 18 #define a0 $4 19 #define a1 $5 20 #define a2 $6 21 #define a3 $7 22 #define t0 $8 23 #define t1 $9 24 #define t2 $10 25 #define t3 $11 26 #define t4 $12 27 #define t5 $13 28 #define t6 $14 29 #define t7 $15 30 #define s0 $16 31 #define s1 $17 32 #define s2 $18 33 #define s3 $19 34 #define s4 $20 35 #define s5 $21 36 #define s6 $22 37 #define s7 $23 38 #define t8 $24 39 #define t9 $25 40 #define k0 $26 41 #define k1 $27 42 #define gp $28 43 #define sp $29 44 #define fp $30 45 #define ra $31 46 46 47 47 /* CP0 registers */ 48 48 49 #define CP0_BVAR 50 #define CP0_TIME 51 #define CP0_SR$1252 #define CP0_CR 53 #define CP0_EPC 54 #define CP0_PROCID 55 #define CP0_SCHED 49 #define CP0_BVAR $8 50 #define CP0_TIME $9 51 #define CP0_SR $12 52 #define CP0_CR $13 53 #define CP0_EPC $14 54 #define CP0_PROCID $15,1 55 #define CP0_SCHED $22 56 56 57 57 /* CP2 registers */ 58 58 59 #define CP2_PTPR 60 #define CP2_MODE 61 #define CP2_ICACHE_FLUSH 62 #define CP2_DCACHE_FLUSH 63 #define CP2_ITLB_INVAL 64 #define CP2_DTLB_INVAL 65 #define CP2_ICACHE_INVAL 66 #define CP2_DCACHE_INVAL 67 #define CP2_ICACHE_PREFETCH 68 #define CP2_DCACHE_PREFETCH 69 #define CP2_SYNC 70 #define CP2_IETR 71 #define CP2_DETR 72 #define CP2_IBVAR 73 #define CP2_DBVAR 74 #define CP2_PARAMS 75 #define CP2_RELEASE 76 #define CP2_DATA_LO $1777 #define CP2_DATA_HI $1878 #define CP2_ICACHE_INVAL_PA $1979 #define CP2_DCACHE_INVAL_PA 59 #define CP2_PTPR $0 60 #define CP2_MODE $1 61 #define CP2_ICACHE_FLUSH $2 62 #define CP2_DCACHE_FLUSH $3 63 #define CP2_ITLB_INVAL $4 64 #define CP2_DTLB_INVAL $5 65 #define CP2_ICACHE_INVAL $6 66 #define CP2_DCACHE_INVAL $7 67 #define CP2_ICACHE_PREFETCH $8 68 #define CP2_DCACHE_PREFETCH $9 69 #define CP2_SYNC $10 70 #define CP2_IETR $11 71 #define CP2_DETR $12 72 #define CP2_IBVAR $13 73 #define CP2_DBVAR $14 74 #define CP2_PARAMS $15 75 #define CP2_RELEASE $16 76 #define CP2_DATA_LO $17 77 #define CP2_DATA_HI $18 78 #define CP2_ICACHE_INVAL_PA $19 79 #define CP2_DCACHE_INVAL_PA $20 80 80 81 81 #endif 82 83 // Local Variables: 84 // tab-width: 4 85 // c-basic-offset: 4 86 // c-file-offsets:((innamespace . 0)(inline-open . 0)) 87 // indent-tabs-mode: nil 88 // End: 89 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 90 -
soft/giet_vm/sys/sys_handler.c
r218 r228 17 17 #include <giet_config.h> 18 18 #include <mapping_info.h> 19 20 //////////////////////////////////////////////////////////////////////////// 21 // Initialize the syscall vector with syscall handlers 22 //////////////////////////////////////////////////////////////////////////// 23 const void *_syscall_vector[32] = { 24 &_procid, /* 0x00 */ 25 &_proctime, /* 0x01 */ 26 &_tty_write, /* 0x02 */ 27 &_tty_read, /* 0x03 */ 28 &_timer_start, /* 0x04 */ 29 &_timer_stop, /* 0x05 */ 30 &_gcd_write, /* 0x06 */ 31 &_gcd_read, /* 0x07 */ 32 &_sys_ukn, /* 0x08 */ 33 &_sys_ukn, /* 0x09 */ 34 &_sys_ukn, /* 0x0A */ 35 &_sys_ukn, /* 0x0B */ 36 &_sys_ukn, /* 0x0C */ 37 &_ctx_switch, /* 0x0D */ 38 &_exit, /* 0x0E */ 39 &_procs_number, /* 0x0F */ 40 &_fb_sync_write, /* 0x10 */ 41 &_fb_sync_read, /* 0x11 */ 42 &_fb_write, /* 0x12 */ 43 &_fb_read, /* 0x13 */ 44 &_fb_completed, /* 0x14 */ 45 &_ioc_write, /* 0x15 */ 46 &_ioc_read, /* 0x16 */ 47 &_ioc_completed, /* 0x17 */ 48 &_sys_ukn, /* 0x18 */ 49 &_sys_ukn, /* 0x19 */ 50 &_vobj_get_vbase, /* 0x1A */ 51 &_nic_write, /* 0x1B */ 52 &_nic_read, /* 0x1C */ 53 &_nic_completed, /* 0x1D */ 54 &_sys_ukn, /* 0x1E */ 55 &_sys_ukn, /* 0x1F */ 19 #include <srl_memspace.h> 20 21 //////////////////////////////////////////////////////////////////////////// 22 // Initialize the syscall vector with syscall handlers 23 //////////////////////////////////////////////////////////////////////////// 24 const void * _syscall_vector[32] = { 25 &_procid, /* 0x00 */ 26 &_proctime, /* 0x01 */ 27 &_tty_write, /* 0x02 */ 28 &_tty_read, /* 0x03 */ 29 &_timer_start, /* 0x04 */ 30 &_timer_stop, /* 0x05 */ 31 &_gcd_write, /* 0x06 */ 32 &_gcd_read, /* 0x07 */ 33 &_sys_ukn, /* 0x08 */ 34 &_get_current_task_id, /* 0x09 */ 35 &_sys_ukn, /* 0x0A */ 36 &_sys_ukn, /* 0x0B */ 37 &_sys_ukn, /* 0x0C */ 38 &_context_switch, /* 0x0D */ 39 &_exit, /* 0x0E */ 40 &_procs_number, /* 0x0F */ 41 &_fb_sync_write, /* 0x10 */ 42 &_fb_sync_read, /* 0x11 */ 43 &_fb_write, /* 0x12 */ 44 &_fb_read, /* 0x13 */ 45 &_fb_completed, /* 0x14 */ 46 &_ioc_write, /* 0x15 */ 47 &_ioc_read, /* 0x16 */ 48 &_ioc_completed, /* 0x17 */ 49 &_sys_ukn, /* 0x18 */ 50 &_sys_ukn, /* 0x19 */ 51 &_vobj_get_vbase, /* 0x1A */ 52 &_nic_write, /* 0x1B */ 53 &_nic_read, /* 0x1C */ 54 &_nic_completed, /* 0x1D */ 55 &_sys_ukn, /* 0x1E */ 56 &_sys_ukn, /* 0x1F */ 56 57 }; 57 58 … … 59 60 // function executed in case of undefined syscall 60 61 ////////////////////////////////////////////////////////////////////////////// 61 void _sys_ukn() 62 { 63 unsigned int epc; 64 asm volatile("mfc0 %0, $14" : "=r"(epc)); 62 void _sys_ukn() { 63 unsigned int epc; 64 asm volatile("mfc0 %0, $14" : "=r" (epc)); 65 65 66 66 _puts("\n\n!!! Undefined System Call !!!\n"); 67 67 _puts("\nEPC = "); 68 _putx( epc);68 _putx(epc); 69 69 _exit(); 70 70 } 71 72 71 73 //////////////////////////////////////////////////////////////////////////// 72 74 // _exit() 73 75 // Task suicide... after printing a death message. 74 76 //////////////////////////////////////////////////////////////////////////// 75 void _exit() 76 { 77 unsigned int date = _proctime(); 77 void _exit() { 78 unsigned int date = _proctime(); 78 79 unsigned int proc_id = _procid(); 79 80 unsigned int task_id = _get_current_task_id(); 80 81 81 82 // print death message 82 83 _get_lock(&_tty_put_lock); 83 84 _puts("\n[GIET] Exit task "); 84 _putd( task_id);85 _putd(task_id); 85 86 _puts(" on processor "); 86 _putd( proc_id);87 _putd(proc_id); 87 88 _puts(" at cycle "); 88 _putd( date);89 _putd(date); 89 90 _puts("\n\n"); 90 91 _release_lock(&_tty_put_lock); 91 92 92 93 // goes to sleeping state 93 _set_context_slot( task_id, CTX_RUN_ID, 0 94 94 _set_context_slot( task_id, CTX_RUN_ID, 0); 95 95 96 // deschedule 96 97 _ctx_switch(); 97 98 } 99 100 98 101 ////////////////////////////////////////////////////////////////////////////// 99 102 // _procid() … … 101 104 // Max number or processors is 1024. 102 105 ////////////////////////////////////////////////////////////////////////////// 103 unsigned int _procid() 104 { 105 unsigned int ret; 106 asm volatile("mfc0 %0, $15, 1" : "=r"(ret)); 106 unsigned int _procid() { 107 unsigned int ret; 108 asm volatile("mfc0 %0, $15, 1" : "=r" (ret)); 107 109 return (ret & 0xFFF); 108 110 } 111 112 109 113 ////////////////////////////////////////////////////////////////////////////// 110 114 // _proctime() 111 115 // Access CP0 and returns current processor's elapsed clock cycles since boot. 112 116 ////////////////////////////////////////////////////////////////////////////// 113 unsigned int _proctime() 114 { 115 unsigned int ret; 116 asm volatile("mfc0 %0, $9" : "=r"(ret)); 117 unsigned int _proctime() { 118 unsigned int ret; 119 asm volatile("mfc0 %0, $9" : "=r" (ret)); 117 120 return ret; 118 121 } 122 123 119 124 ////////////////////////////////////////////////////////////////////////////// 120 125 // _procnumber() … … 122 127 // specified by the cluster_id argument. 123 128 ////////////////////////////////////////////////////////////////////////////// 124 unsigned int _procs_number( unsigned int cluster_id, 125 unsigned int* buffer) 126 { 127 mapping_header_t* header = (mapping_header_t*)&seg_mapping_base; 128 mapping_cluster_t* cluster = _get_cluster_base( header ); 129 130 if ( cluster_id < header->clusters ) 131 { 129 unsigned int _procs_number(unsigned int cluster_id, unsigned int * buffer) { 130 mapping_header_t * header = (mapping_header_t *) &seg_mapping_base; 131 mapping_cluster_t * cluster = _get_cluster_base(header); 132 133 if (cluster_id < header->clusters) { 132 134 *buffer = cluster[cluster_id].procs; 133 135 return 0; 134 136 } 135 else 136 { 137 return 1; 138 } 139 } 140 141 int _get_vobj( char* vspace_name, char* vobj_name, unsigned int vobj_type, mapping_vobj_t** res_vobj) 142 { 143 mapping_header_t* header = (mapping_header_t*)&seg_mapping_base; 144 mapping_vspace_t* vspace = _get_vspace_base( header ); 145 mapping_vobj_t* vobj = _get_vobj_base( header ); 146 147 unsigned int vspace_id; 148 unsigned int vobj_id; 149 137 else { 138 return 1; 139 } 140 } 141 142 143 int _get_vobj(char * vspace_name, char * vobj_name, unsigned int vobj_type, mapping_vobj_t ** res_vobj) { 144 mapping_header_t * header = (mapping_header_t *) &seg_mapping_base; 145 mapping_vspace_t * vspace = _get_vspace_base(header); 146 mapping_vobj_t * vobj = _get_vobj_base(header); 147 148 unsigned int vspace_id; 149 unsigned int vobj_id; 150 150 151 151 152 // scan vspaces 152 for ( vspace_id = 0 ; vspace_id < header->vspaces ; vspace_id++ ) 153 { 154 if ( _strncmp( vspace[vspace_id].name, vspace_name, 31) == 0 ) 155 { 153 for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) { 154 if (_strncmp( vspace[vspace_id].name, vspace_name, 31) == 0) { 156 155 // scan vobjs 157 for (vobj_id = vspace[vspace_id].vobj_offset;156 for (vobj_id = vspace[vspace_id].vobj_offset; 158 157 vobj_id < (vspace[vspace_id].vobj_offset + vspace[vspace_id].vobjs); 159 vobj_id++) 160 { 161 162 if ( _strncmp( vobj[vobj_id].name, vobj_name, 31) == 0 ) 163 { 164 if(vobj[vobj_id].type != vobj_type) 165 return -1; //wrong type 166 158 vobj_id++) { 159 160 if (_strncmp(vobj[vobj_id].name, vobj_name, 31) == 0) { 161 if (vobj[vobj_id].type != vobj_type) { 162 _get_lock(&_tty_put_lock); 163 _puts("*** Error in _get_obj: wrong type\n"); 164 _release_lock(&_tty_put_lock); 165 return -1; //wrong type 166 } 167 167 *res_vobj = &vobj[vobj_id]; 168 169 168 return 0; 170 169 } … … 172 171 } 173 172 } 174 return -2; //not found 175 176 } 173 _get_lock(&_tty_put_lock); 174 _puts("*** Error in _get_obj: object not found\n"); 175 _release_lock(&_tty_put_lock); 176 177 return -2; //not found 178 } 179 180 177 181 ///////////////////////////////////////////////////////////////////////////// 178 182 // _vobj_get_vbase() … … 182 186 // returns 0: success, else: failed. 183 187 ///////////////////////////////////////////////////////////////////////////// 184 unsigned int _vobj_get_vbase( char* vspace_name, 185 char* vobj_name, 186 unsigned int vobj_type, 187 unsigned int* vobj_vaddr ) 188 { 189 mapping_vobj_t* res_vobj; 190 unsigned int ret; 191 if( (ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj)) ) 192 { 188 unsigned int _vobj_get_vbase( 189 char * vspace_name, 190 char * vobj_name, 191 unsigned int vobj_type, 192 unsigned int * vobj_vaddr) { 193 mapping_vobj_t * res_vobj; 194 unsigned int ret; 195 if ((ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj))) { 193 196 return ret; 194 197 } 195 198 196 199 *vobj_vaddr = res_vobj->vaddr; 197 198 200 return 0; 199 201 } 202 200 203 201 204 ///////////////////////////////////////////////////////////////////////////// … … 206 209 // returns 0: success, else: failed. 207 210 ///////////////////////////////////////////////////////////////////////////// 208 unsigned int _vobj_get_length(char* vspace_name, 209 char* vobj_name, 210 unsigned int vobj_type, 211 unsigned int* vobj_length ) 212 { 213 214 mapping_vobj_t* res_vobj; 215 unsigned int ret; 216 if( (ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj)) ) 217 { 211 unsigned int _vobj_get_length( 212 char * vspace_name, 213 char * vobj_name, 214 unsigned int vobj_type, 215 unsigned int * vobj_length) { 216 217 mapping_vobj_t * res_vobj; 218 unsigned int ret; 219 if ((ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj))) { 218 220 return ret; 219 221 } 220 222 221 223 *vobj_length = res_vobj->length; 222 224 223 225 return 0; 224 226 } 227 228 229 //////////////////////////////////////////////////////////////// 230 // _context_switch() 231 // This functions masks interruptions before calling _ctx_switch 232 // (They are usually masked when we receive a isr_switch interrupt 233 // because we execute isrs with interrupt masked) 234 //////////////////////////////////////////////////////////////// 235 void _context_switch() { 236 _it_mask(); 237 _ctx_switch(); 238 _it_restore(); 239 } 240 241 242 // Local Variables: 243 // tab-width: 4 244 // c-basic-offset: 4 245 // c-file-offsets:((innamespace . 0)(inline-open . 0)) 246 // indent-tabs-mode: nil 247 // End: 248 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 249 -
soft/giet_vm/sys/sys_handler.h
r160 r228 10 10 11 11 ////////////////////////////////////////////////////////////////////////////////// 12 // 12 // Syscall Vector Table (indexed by syscall index) 13 13 ////////////////////////////////////////////////////////////////////////////////// 14 14 15 extern const void * _syscall_vector[32];15 extern const void * _syscall_vector[32]; 16 16 17 17 ////////////////////////////////////////////////////////////////////////////////// … … 19 19 ////////////////////////////////////////////////////////////////////////////////// 20 20 21 void _sys_ukn(); 21 void _sys_ukn(); 22 void _exit(); 23 void _context_switch(); 24 unsigned int _procid(); 25 unsigned int _proctime(); 26 unsigned int _procs_number(unsigned int cluster_id, unsigned int * buffer ); 27 unsigned int _vobj_get_vbase(char * vspace_name, char * vobj_name, unsigned vobj_type, unsigned int * vobj_buffer); 22 28 23 void _exit(); 29 #endif 24 30 25 unsigned int _procid(); 31 // Local Variables: 32 // tab-width: 4 33 // c-basic-offset: 4 34 // c-file-offsets:((innamespace . 0)(inline-open . 0)) 35 // indent-tabs-mode: nil 36 // End: 37 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 26 38 27 unsigned int _proctime();28 29 unsigned int _procs_number( unsigned int cluster_id,30 unsigned int* buffer );31 32 unsigned int _vobj_get_vbase( char* vspace_name, char* vobj_name,33 unsigned vobj_type, unsigned int* vobj_buffer);34 #endif -
soft/giet_vm/sys/vm_handler.c
r207 r228 20 20 21 21 ///////////////////////////////////////////////////////////////////////////// 22 // 22 // Global variable : IOMMU page table 23 23 ///////////////////////////////////////////////////////////////////////////// 24 24 25 __attribute__((section (".iommu"))) page_table_t 25 __attribute__((section (".iommu"))) page_table_t _iommu_ptab; 26 26 27 27 ////////////////////////////////////////////////////////////////////////////// 28 28 // _iommu_add_pte2() 29 29 ////////////////////////////////////////////////////////////////////////////// 30 void _iommu_add_pte2( unsigned int ix1,31 unsigned int ix2,32 unsigned int ppn,33 unsigned int flags )34 {35 unsigned int 36 unsigned int *pt_ppn;37 unsigned int *pt_flags;30 void _iommu_add_pte2( 31 unsigned int ix1, 32 unsigned int ix2, 33 unsigned int ppn, 34 unsigned int flags) { 35 unsigned int ptba; 36 unsigned int * pt_ppn; 37 unsigned int * pt_flags; 38 38 39 39 // get pointer on iommu page table 40 page_table_t * pt = &_iommu_ptab;40 page_table_t * pt = &_iommu_ptab; 41 41 42 42 // get ptba and update PT2 43 if ( (pt->pt1[ix1] & PTE_V) == 0 ) 44 { 43 if ((pt->pt1[ix1] & PTE_V) == 0) { 45 44 _puts("\n[GIET ERROR] in iommu_add_pte2 function\n"); 46 45 _puts("the IOMMU PT1 entry is not mapped / ix1 = "); … … 49 48 _exit(); 50 49 } 51 else 52 { 53 ptba = pt->pt1[ix1] << 12; 54 pt_flags = (unsigned int*)(ptba + 8*ix2); 55 pt_ppn = (unsigned int*)(ptba + 8*ix2 + 4); 50 else { 51 ptba = pt->pt1[ix1] << 12; 52 pt_flags = (unsigned int *) (ptba + 8 * ix2); 53 pt_ppn = (unsigned int *) (ptba + 8 * ix2 + 4); 56 54 *pt_flags = flags; 57 *pt_ppn 55 *pt_ppn = ppn; 58 56 } 59 57 } // end _iommu_add_pte2() 58 60 59 61 60 ////////////////////////////////////////////////////////////////////////////// 62 61 // _iommu_inval_pte2() 63 62 ////////////////////////////////////////////////////////////////////////////// 64 void _iommu_inval_pte2( unsigned int ix1, 65 unsigned int ix2 ) 66 { 67 unsigned int ptba; 68 unsigned int* pt_flags; 63 void _iommu_inval_pte2(unsigned int ix1, unsigned int ix2) { 64 unsigned int ptba; 65 unsigned int * pt_flags; 69 66 70 67 // get pointer on iommu page table 71 page_table_t * pt = &_iommu_ptab;68 page_table_t * pt = &_iommu_ptab; 72 69 73 70 // get ptba and inval PTE2 74 if ( (pt->pt1[ix1] & PTE_V) == 0 ) 75 { 71 if ((pt->pt1[ix1] & PTE_V) == 0) { 76 72 _puts("\n[GIET ERROR] in iommu_inval_pte2 function\n"); 77 73 _puts("the IOMMU PT1 entry is not mapped / ix1 = "); … … 80 76 _exit(); 81 77 } 82 else 83 { 84 ptba = pt->pt1[ix1] << 12; 85 pt_flags = (unsigned int*)(ptba + 8*ix2); 78 else { 79 ptba = pt->pt1[ix1] << 12; 80 pt_flags = (unsigned int *) (ptba + 8 * ix2); 86 81 *pt_flags = 0; 87 82 } 88 83 } // end _iommu_inval_pte2() 84 89 85 90 86 ////////////////////////////////////////////////////////////////////////////// … … 92 88 // Returns 0 if success, 1 if PTE1 or PTE2 unmapped 93 89 ////////////////////////////////////////////////////////////////////////////// 94 unsigned int _v2p_translate( page_table_t* pt, 95 unsigned int vpn, 96 unsigned int* ppn, 97 unsigned int* flags ) 98 { 99 unsigned int ptba; 90 unsigned int _v2p_translate( 91 page_table_t * pt, 92 unsigned int vpn, 93 unsigned int * ppn, 94 unsigned int * flags) { 95 unsigned int ptba; 96 register unsigned int * pte2; 97 register unsigned int flags_value; 98 register unsigned int ppn_value; 100 99 101 register unsigned int* pte2; 102 register unsigned int flags_value; 103 register unsigned int ppn_value; 104 105 unsigned int ix1 = vpn >> 9; 106 unsigned int ix2 = vpn & 0x1FF; 107 /* 108 _puts("\n\n********************** entering v2p_translate"); 109 _puts("\n - pt = "); 110 _putx( (unsigned int)pt ); 111 _puts("\n - vpn = "); 112 _putx( vpn << 12 ); 113 _puts("\n - ptba = "); 114 _putx( pt->pt1[ix1] << 12 ) ; 115 _puts("\n - &pte2 = "); 116 _putx( (pt->pt1[ix1] << 12) + 8*ix2 ); 117 _puts("\n - flags = "); 118 _putx( *(unsigned int*)((pt->pt1[ix1] << 12) + 8*ix2) ); 119 _puts("\n"); 120 */ 100 unsigned int ix1 = vpn >> 9; 101 unsigned int ix2 = vpn & 0x1FF; 102 /* 103 _puts("\n\n********************** entering v2p_translate"); 104 _puts("\n - pt = "); 105 _putx( (unsigned int)pt ); 106 _puts("\n - vpn = "); 107 _putx( vpn << 12 ); 108 _puts("\n - ptba = "); 109 _putx( pt->pt1[ix1] << 12 ) ; 110 _puts("\n - &pte2 = "); 111 _putx( (pt->pt1[ix1] << 12) + 8*ix2 ); 112 _puts("\n - flags = "); 113 _putx( *(unsigned int*)((pt->pt1[ix1] << 12) + 8*ix2) ); 114 _puts("\n"); 115 */ 121 116 // check PTE1 mapping 122 if ( (pt->pt1[ix1] & PTE_V) == 0 ) 123 { 117 if ((pt->pt1[ix1] & PTE_V) == 0) { 124 118 return 1; 125 119 } 126 else 127 { 120 else { 128 121 // get physical addresses of pte2 129 122 ptba = pt->pt1[ix1] << 12; 130 pte2 = (unsigned int *)(ptba + 8*ix2);123 pte2 = (unsigned int *) (ptba + 8 * ix2); 131 124 132 125 // gets ppn_value and flags_value, after temporary DTLB desactivation 133 asm volatile ( "li $27, 0xFFFFFFFE \n" /* Mask for IE bits */ 134 "mfc0 $26, $12 \n" /* save SR */ 135 "and $27, $26, $27 \n" 136 "mtc0 $27, $12 \n" /* disable Interrupts */ 126 asm volatile ( 127 "li $27, 0xFFFFFFFE \n" /* Mask for IE bits */ 128 "mfc0 $26, $12 \n" /* save SR */ 129 "and $27, $26, $27 \n" 130 "mtc0 $27, $12 \n" /* disable Interrupts */ 137 131 138 139 132 "li $27, 0xB \n" 133 "mtc2 $27, $1 \n" /* DTLB unactivated */ 140 134 141 142 143 135 "move $27, %2 \n" /* $27 <= pte2 */ 136 "lw %0, 0($27) \n" /* read flags */ 137 "lw %1, 4($27) \n" /* read ppn */ 144 138 145 146 139 "li $27, 0xF \n" 140 "mtc2 $27, $1 \n" /* DTLB activated */ 147 141 148 149 :"=r"(flags_value), "=r"(ppn_value)150 :"r"(pte2)151 :"$26","$27","$8");142 "mtc0 $26, $12 \n" /* restore SR */ 143 : "=r" (flags_value), "=r" (ppn_value) 144 : "r" (pte2) 145 : "$26","$27","$8"); 152 146 153 147 // check PTE2 mapping 154 if ( (flags_value & PTE_V) == 0 ) 155 { 148 if ((flags_value & PTE_V) == 0) { 156 149 return 1; 157 150 } 158 151 159 152 // set return values 160 *ppn 161 *flags 153 *ppn = ppn_value; 154 *flags = flags_value; 162 155 } 163 156 return 0; 164 } 157 } // end _v2p_translate() 165 158 166 159 // Local Variables: … … 170 163 // indent-tabs-mode: nil 171 164 // End: 165 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 172 166 173 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4174 167 -
soft/giet_vm/sys/vm_handler.h
r195 r228 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 7 8 #ifndef 9 #define 8 #ifndef _VM_HANDLER_H_ 9 #define _VM_HANDLER_H_ 10 10 11 #include 12 #include 11 #include <giet_config.h> 12 #include <mapping_info.h> 13 13 14 14 ///////////////////////////////////////////////////////////////////////////////////// … … 16 16 ///////////////////////////////////////////////////////////////////////////////////// 17 17 18 #define 19 #define 18 #define PT1_SIZE 8192 19 #define PT2_SIZE 4096 20 20 21 21 ///////////////////////////////////////////////////////////////////////////////////// … … 23 23 ///////////////////////////////////////////////////////////////////////////////////// 24 24 25 #define PTE_V0x8000000026 #define PTE_T0x4000000027 #define PTE_L0x2000000028 #define PTE_R0x1000000029 #define PTE_C0x0800000030 #define PTE_W0x0400000031 #define PTE_X0x0200000032 #define PTE_U0x0100000033 #define PTE_G0x0080000034 #define PTE_D0x0040000025 #define PTE_V 0x80000000 26 #define PTE_T 0x40000000 27 #define PTE_L 0x20000000 28 #define PTE_R 0x10000000 29 #define PTE_C 0x08000000 30 #define PTE_W 0x04000000 31 #define PTE_X 0x02000000 32 #define PTE_U 0x01000000 33 #define PTE_G 0x00800000 34 #define PTE_D 0x00400000 35 35 36 36 ///////////////////////////////////////////////////////////////////////////////////// … … 38 38 ///////////////////////////////////////////////////////////////////////////////////// 39 39 40 #define MMU_ERR_PT1_UNMAPPED 0x001// Page fault on Table1 (invalid PTE)41 #define MMU_ERR_PT2_UNMAPPED 0x002// Page fault on Table 2 (invalid PTE)42 #define MMU_ERR_PRIVILEGE_VIOLATION 0x004// Protected access in user mode43 #define MMU_ERR_WRITE_VIOLATION 0x008// Write access to a non write page44 #define MMU_ERR_EXEC_VIOLATION 0x010// Exec access to a non exec page45 #define MMU_ERR_UNDEFINED_XTN 0x020// Undefined external access address46 #define MMU_ERR_PT1_ILLEGAL_ACCESS 0x040// Bus Error in Table1 access47 #define MMU_ERR_PT2_ILLEGAL_ACCESS 0x080// Bus Error in Table2 access48 #define MMU_ERR_CACHE_ILLEGAL_ACCESS 0x100// Bus Error during the cache access40 #define MMU_ERR_PT1_UNMAPPED 0x001 // Page fault on Table1 (invalid PTE) 41 #define MMU_ERR_PT2_UNMAPPED 0x002 // Page fault on Table 2 (invalid PTE) 42 #define MMU_ERR_PRIVILEGE_VIOLATION 0x004 // Protected access in user mode 43 #define MMU_ERR_WRITE_VIOLATION 0x008 // Write access to a non write page 44 #define MMU_ERR_EXEC_VIOLATION 0x010 // Exec access to a non exec page 45 #define MMU_ERR_UNDEFINED_XTN 0x020 // Undefined external access address 46 #define MMU_ERR_PT1_ILLEGAL_ACCESS 0x040 // Bus Error in Table1 access 47 #define MMU_ERR_PT2_ILLEGAL_ACCESS 0x080 // Bus Error in Table2 access 48 #define MMU_ERR_CACHE_ILLEGAL_ACCESS 0x100 // Bus Error during the cache access 49 49 50 50 ///////////////////////////////////////////////////////////////////////////////////// 51 51 // Page table structure definition 52 52 ///////////////////////////////////////////////////////////////////////////////////// 53 typedef struct PageTable 54 { 55 unsigned int pt1[PT1_SIZE/4]; // PT1 (index is ix1) 56 unsigned int pt2[1][PT2_SIZE/4]; // PT2s (index is 2*ix2) 53 typedef struct PageTable { 54 unsigned int pt1[PT1_SIZE / 4]; // PT1 (index is ix1) 55 unsigned int pt2[1][PT2_SIZE / 4]; // PT2s (index is 2*ix2) 57 56 } page_table_t; 58 57 … … 68 67 //////////////////////////////////////////////////////////////////////////////////// 69 68 70 void _iommu_add_pte2( unsigned int ix1, 71 unsigned int ix2, 72 unsigned int ppn, 73 unsigned int flags ); 74 75 void _iommu_inval_pte2( unsigned int ix1, 76 unsigned int ix2 ); 77 78 unsigned int _v2p_translate( page_table_t* pt, 79 unsigned int vpn, 80 unsigned int* ppn, 81 unsigned int* flags ); 69 void _iommu_add_pte2(unsigned int ix1, unsigned int ix2, unsigned int ppn, unsigned int flags); 70 void _iommu_inval_pte2(unsigned int ix1, unsigned int ix2); 71 unsigned int _v2p_translate(page_table_t * pt, unsigned int vpn, unsigned int * ppn, unsigned int * flags); 82 72 83 73 #endif … … 89 79 // indent-tabs-mode: nil 90 80 // End: 81 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 91 82 92 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Note: See TracChangeset
for help on using the changeset viewer.