- Timestamp:
- May 29, 2013, 1:24:09 AM (12 years ago)
- Location:
- soft/giet_vm
- Files:
-
- 1 added
- 33 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/Makefile
r232 r238 5 5 DU = mipsel-unknown-elf-objdump 6 6 7 MAP_XML = mappings/4c_1p_ four.xml7 MAP_XML = mappings/4c_1p_40.xml 8 8 9 9 SYS_OBJS = build/sys/vm_handler.o \ -
soft/giet_vm/boot/boot_init.c
r236 r238 7 7 // The boot_init.c file is part of the GIET-VM nano-kernel. 8 8 // This code is executed in the boot phase by proc[0] to initialize the 9 // 9 // peripherals and the kernel data structures: 10 10 // - pages tables for the various vspaces 11 11 // - shedulers for processors (including the tasks contexts and interrupt vectors) 12 // 13 // This nano-kernel has been written for the MIPS32 processor. 14 // The virtual adresses are on 32 bits and use the (unsigned int) type, but the 15 // physicals addresses can have up to 40 bits, and use the (unsigned long long) type. 12 16 // 13 17 // The GIET-VM uses the paged virtual memory and the MAPPING_INFO binary file … … 20 24 // The MAPPING_INFO binary data structure must be loaded in the the seg_boot_mapping 21 25 // segment (at address seg_mapping_base). 22 // This MAPPING_INFO data structure defines both the hardware architecture 23 // and the mapping: 24 // - physical segmentation of the physical address space, 25 // - virtual spaces definition (one multi-task application per vspace), 26 // - placement of virtual objects (vobj) in the virtual segments (vseg). 27 // - placement of virtual segments (vseg) in the physical segments (pseg). 28 // - placement of tasks on the processors, 26 // This MAPPING_INFO data structure defines 27 // - the hardware architecture: number of clusters, number or processors, 28 // size of the memory segments, and peripherals in each cluster. 29 // - The structure of the various multi-threaded software applications: 30 // number of tasks, communication channels. 31 // - The mapping: placement of virtual objects (vobj) in the virtual segments (vseg), 32 // placement of virtual segments (vseg) in the physical segments (pseg), placement 33 // of software tasks on the processors, 29 34 // 30 35 // The page table are statically build in the boot phase, and they do not … … 35 40 // The max number of virtual spaces (GIET_NB_VSPACE_MAX) is a configuration parameter. 36 41 // 37 // Each page table (one page table per virtual space) is monolithic, and 38 // contains one PT1 and(GIET_NB_PT2_MAX) PT2s. The PT1 is addressed using the ix1 field42 // Each page table (one page table per virtual space) is monolithic, and contains 43 // one PT1 and up to (GIET_NB_PT2_MAX) PT2s. The PT1 is addressed using the ix1 field 39 44 // (11 bits) of the VPN, and the selected PT2 is addressed using the ix2 field (9 bits). 40 // - PT1[2048] : a first 8K aligned array of unsigned int, indexed by the(ix1) field of VPN.45 // - PT1[2048] : a first 8K aligned array of unsigned int, indexed by (ix1) field of VPN. 41 46 // Each entry in the PT1 contains a 32 bits PTD. The MSB bit PTD[31] is 42 47 // the PTD valid bit, and LSB bits PTD[19:0] are the 20 MSB bits of the physical base … … 44 49 // The PT1 contains 2048 PTD of 4 bytes => 8K bytes. 45 50 // - PT2[1024][GIET_NB_PT2_MAX] : an array of array of unsigned int. 46 // Each PT2[1024] must be 4K aligned, andeach entry in a PT2 contains two unsigned int:51 // Each PT2[1024] must be 4K aligned, each entry in a PT2 contains two unsigned int: 47 52 // the first word contains the protection flags, and the second word contains the PPN. 48 53 // Each PT2 contains 512 PTE2 of 8bytes => 4K bytes. … … 64 69 #include <stdarg.h> 65 70 66 67 71 #if !defined(NB_CLUSTERS) 68 72 # error The NB_CLUSTERS value must be defined in the 'giet_config.h' file ! … … 79 83 //////////////////////////////////////////////////////////////////////////// 80 84 // Global variables for boot code 81 // As both the page tables and the schedulers are physically distributed, 82 // these global variables are just arrays of pointers. 85 // Both the page tables for the various virtual spaces, and the schedulers 86 // for the processors are physically distributed on the clusters. 87 // These global variables are just arrays of pointers. 83 88 //////////////////////////////////////////////////////////////////////////// 84 89 85 // Page table pointers array86 pa ge_table_t * boot_ptabs_vaddr[GIET_NB_VSPACE_MAX];87 page_table_t * boot_ptabs_paddr[GIET_NB_VSPACE_MAX];88 89 // Scheduler pointers array 90 static_scheduler_t * boot_schedulers_paddr[NB_CLUSTERS * NB_PROCS_MAX];90 // Page table addresses arrays 91 paddr_t boot_ptabs_paddr[GIET_NB_VSPACE_MAX]; 92 unsigned int boot_ptabs_vaddr[GIET_NB_VSPACE_MAX]; 93 94 // Scheduler pointers array (virtual addresses) 95 static_scheduler_t* boot_schedulers[NB_CLUSTERS * NB_PROCS_MAX]; 91 96 92 97 // Next free PT2 index array … … 102 107 // boot_procid() 103 108 ////////////////////////////////////////////////////////////////////////////// 104 inline unsigned int boot_procid() { 109 inline unsigned int boot_procid() 110 { 105 111 unsigned int ret; 106 112 asm volatile ("mfc0 %0, $15, 1":"=r" (ret)); … … 108 114 } 109 115 110 111 116 ////////////////////////////////////////////////////////////////////////////// 112 117 // boot_proctime() 113 118 ////////////////////////////////////////////////////////////////////////////// 114 inline unsigned int boot_proctime() { 119 inline unsigned int boot_proctime() 120 { 115 121 unsigned int ret; 116 122 asm volatile ("mfc0 %0, $9":"=r" (ret)); … … 118 124 } 119 125 120 121 126 ////////////////////////////////////////////////////////////////////////////// 122 127 // boot_exit() 123 128 ////////////////////////////////////////////////////////////////////////////// 124 void boot_exit() { 125 while (1) { 126 asm volatile ("nop"); 127 } 128 } 129 129 void boot_exit() 130 { 131 while (1) { asm volatile ("nop"); } 132 } 130 133 131 134 ////////////////////////////////////////////////////////////////////////////// … … 134 137 // in all task contexts (when the task has never been executed. 135 138 /////////////////////////////////"///////////////////////////////////////////// 136 void boot_eret() { 139 void boot_eret() 140 { 137 141 asm volatile ("eret"); 138 142 } 139 143 140 141 ////////////////////////////////////////////////////////////////////////////// 142 // boot_scheduler_set_context() 143 // This function set a context slot in a scheduler, after a temporary 144 // desactivation of the DTLB (because we use the scheduler physical address). 145 // - gpid : global processor/scheduler index 146 // - ltid : local task index 147 // - slotid : context slot index 148 // - value : value to be written 149 ////////////////////////////////////////////////////////////////////////////// 150 inline void boot_scheduler_set_context(unsigned int gpid, 151 unsigned int ltid, 152 unsigned int slotid, 153 unsigned int value) { 154 // get scheduler physical address 155 static_scheduler_t * psched = boot_schedulers_paddr[gpid]; 156 157 // get slot physical address 158 unsigned int * pslot = &(psched->context[ltid][slotid]); 159 160 asm volatile ("li $26, 0xB \n" 161 "mtc2 $26, $1 \n" /* desactivate DTLB */ 162 "sw %1, 0(%0) \n" /* *pslot <= value */ 163 "li $26, 0xF \n" 164 "mtc2 $26, $1 \n" /* activate DTLB */ 144 //////////////////////////////////////////////////////////////////////////// 145 // boot_physical_read() 146 // This function makes a physical read access to a 32 bits word in memory, 147 // after a temporary DTLB de-activation and paddr extension. 148 //////////////////////////////////////////////////////////////////////////// 149 unsigned int boot_physical_read(paddr_t paddr) 150 { 151 unsigned int value; 152 unsigned int lsb = (unsigned int)paddr; 153 unsigned int msb = (unsigned int)(paddr >> 32); 154 155 asm volatile( 156 "mfc2 $2, $1 \n" /* $2 <= MMU_MODE */ 157 "andi $3, $2, 0xb \n" 158 "mtc2 $3, $1 \n" /* DTLB off */ 159 160 "mtc2 %2, $24 \n" /* PADDR_EXT <= msb */ 161 "lw %0, 0(%1) \n" /* value <= *paddr */ 162 "mtc2 $0, $24 \n" /* PADDR_EXT <= 0 */ 163 164 "mtc2 $2, $1 \n" /* restore MMU_MODE */ 165 : "=r" (value) 166 : "r" (lsb), "r" (msb) 167 : "$2", "$3"); 168 return value; 169 } 170 171 //////////////////////////////////////////////////////////////////////////// 172 // boot_physical_write() 173 // This function makes a physical write access to a 32 bits word in memory, 174 // after a temporary DTLB de-activation and paddr extension. 175 //////////////////////////////////////////////////////////////////////////// 176 void boot_physical_write(paddr_t paddr, 177 unsigned int value) 178 { 179 unsigned int lsb = (unsigned int)paddr; 180 unsigned int msb = (unsigned int)(paddr >> 32); 181 182 asm volatile( 183 "mfc2 $2, $1 \n" /* $2 <= MMU_MODE */ 184 "andi $3, $2, 0xb \n" 185 "mtc2 $3, $1 \n" /* DTLB off */ 186 187 "mtc2 %2, $24 \n" /* PADDR_EXT <= msb */ 188 "sw %0, 0(%1) \n" /* *paddr <= value */ 189 "mtc2 $0, $24 \n" /* PADDR_EXT <= 0 */ 190 191 "mtc2 $2, $1 \n" /* restore MMU_MODE */ 165 192 : 166 :"r" (pslot), "r"(value) 167 :"$26"); 168 } 169 170 171 ////////////////////////////////////////////////////////////////////////////// 172 // boot_scheduler_set_itvector() 173 // This function set an interrupt vector slot in a scheduler, after a temporary 174 // desactivation of the DTLB (because we use the scheduler physical address). 175 // - gpid : global processor/scheduler index 176 // - slotid : context slot index 177 // - value : value to be written 178 ////////////////////////////////////////////////////////////////////////////// 179 inline void boot_scheduler_set_itvector(unsigned int gpid, 180 unsigned int slotid, 181 unsigned int value) { 182 // get scheduler physical address 183 static_scheduler_t * psched = boot_schedulers_paddr[gpid]; 184 185 // get slot physical address 186 unsigned int * pslot = &(psched->interrupt_vector[slotid]); 187 188 asm volatile ("li $26, 0xB \n" 189 "mtc2 $26, $1 \n" /* desactivate DTLB */ 190 "sw %1, 0(%0) \n" /* *pslot <= value */ 191 "li $26, 0xF \n" 192 "mtc2 $26, $1 \n" /* activate DTLB */ 193 : 194 :"r" (pslot), "r"(value) 195 :"$26"); 196 } 197 198 199 ////////////////////////////////////////////////////////////////////////////// 200 // boot_scheduler_get_itvector() 201 // This function get an interrupt vector slot in a scheduler, after a temporary 202 // desactivation of the DTLB (because we use the scheduler physical address). 203 // - gpid : global processor/scheduler index 204 // - slotid : context slot index 205 // - return the content of the slot 206 ////////////////////////////////////////////////////////////////////////////// 207 unsigned int boot_scheduler_get_itvector(unsigned int gpid, unsigned int slotid) { 208 unsigned int value; 209 210 // get scheduler physical address 211 static_scheduler_t * psched = boot_schedulers_paddr[gpid]; 212 213 // get slot physical address 214 unsigned int * pslot = &(psched->interrupt_vector[slotid]); 215 216 asm volatile ("li $26, 0xB \n" 217 "mtc2 $26, $1 \n" /* desactivate DTLB */ 218 "lw %0, 0(%1) \n" /* *pslot <= value */ 219 "li $26, 0xF \n" 220 "mtc2 $26, $1 \n" /* activate DTLB */ 221 :"=r" (value) 222 :"r"(pslot) 223 :"$26"); 224 return value; 225 } 226 227 228 ////////////////////////////////////////////////////////////////////////////// 229 // boot_scheduler_get_tasks() 230 // This function returns the "tasks" field of a scheduler, after temporary 231 // desactivation of the DTLB (because we use the scheduler physical address). 232 // - gpid : global processor/scheduler index 233 ////////////////////////////////////////////////////////////////////////////// 234 inline unsigned int boot_scheduler_get_tasks(unsigned int gpid) { 235 unsigned int ret; 236 237 // get scheduler physical address 238 static_scheduler_t * psched = boot_schedulers_paddr[gpid]; 239 240 // get tasks physical address 241 unsigned int * ptasks = &(psched->tasks); 242 243 asm volatile ("li $26, 0xB \n" 244 "mtc2 $26, $1 \n" /* desactivate DTLB */ 245 "lw %0, 0(%1) \n" /* ret <= *ptasks */ 246 "li $26, 0xF \n" 247 "mtc2 $26, $1 \n" /* activate DTLB */ 248 :"=r" (ret) 249 :"r"(ptasks) 250 :"$26"); 251 return ret; 252 } 253 254 255 ////////////////////////////////////////////////////////////////////////////// 256 // boot_scheduler_set_tasks() 257 // This function set the "tasks" field of a scheduler, after temporary 258 // desactivation of the DTLB (because we use the scheduler physical address). 259 // - gpid : global processor/scheduler index 260 // - value : value to be written 261 ////////////////////////////////////////////////////////////////////////////// 262 inline void boot_scheduler_set_tasks(unsigned int gpid, unsigned int value) { 263 // get scheduler physical address 264 static_scheduler_t * psched = boot_schedulers_paddr[gpid]; 265 266 // get tasks physical address 267 unsigned int * ptasks = &(psched->tasks); 268 269 asm volatile ("li $26, 0xB \n" 270 "mtc2 $26, $1 \n" /* desactivate DTLB */ 271 "sw %1, 0(%0) \n" /* *ptasks <= value */ 272 "li $26, 0xF \n" 273 "mtc2 $26, $1 \n" /* activate DTLB */ 274 : 275 :"r" (ptasks), "r"(value) 276 :"$26"); 277 } 278 279 280 ////////////////////////////////////////////////////////////////////////////// 281 // boot_scheduler_set_current() 282 // This function set the "current" field of a scheduler, after temporary 283 // desactivation of the DTLB (because we use the scheduler physical address). 284 // - gpid : global processor/scheduler index 285 // - value : value to be written 286 ////////////////////////////////////////////////////////////////////////////// 287 inline void boot_scheduler_set_current(unsigned int gpid, unsigned int value) { 288 // get scheduler physical address 289 static_scheduler_t *psched = boot_schedulers_paddr[gpid]; 290 291 // get tasks physical address 292 unsigned int * pcur = &(psched->current); 293 294 asm volatile ("li $26, 0xB \n" 295 "mtc2 $26, $1 \n" /* desactivate DTLB */ 296 "sw %1, 0(%0) \n" /* *pcur <= value */ 297 "li $26, 0xF \n" 298 "mtc2 $26, $1 \n" /* activate DTLB */ 299 : 300 :"r" (pcur), "r"(value) 301 :"$26"); 302 } 303 193 : "r" (value), "r" (lsb), "r" (msb) 194 : "$2", "$3"); 195 } 304 196 305 197 ////////////////////////////////////////////////////////////////////////////// … … 307 199 // This function set a new value for the MMU PTPR register. 308 200 ////////////////////////////////////////////////////////////////////////////// 309 inline void boot_set_mmu_ptpr(unsigned int val) { 201 inline void boot_set_mmu_ptpr(unsigned int val) 202 { 310 203 asm volatile ("mtc2 %0, $0"::"r" (val)); 311 204 } 312 313 205 314 206 ////////////////////////////////////////////////////////////////////////////// … … 316 208 // This function set a new value for the MMU MODE register. 317 209 ////////////////////////////////////////////////////////////////////////////// 318 inline void boot_set_mmu_mode(unsigned int val) { 210 inline void boot_set_mmu_mode(unsigned int val) 211 { 319 212 asm volatile ("mtc2 %0, $1"::"r" (val)); 320 213 } 321 322 214 323 215 //////////////////////////////////////////////////////////////////////////// 324 216 // boot_puts() 325 // (it uses TTY0)217 // display a string on TTY0 326 218 //////////////////////////////////////////////////////////////////////////// 327 void boot_puts(const char * buffer) { 219 void boot_puts(const char * buffer) 220 { 328 221 unsigned int *tty_address = (unsigned int *) &seg_tty_base; 329 222 unsigned int n; 330 223 331 for (n = 0; n < 100; n++) { 332 if (buffer[n] == 0) { 333 break; 334 } 224 for (n = 0; n < 100; n++) 225 { 226 if (buffer[n] == 0) break; 335 227 tty_address[TTY_WRITE] = (unsigned int) buffer[n]; 336 228 } 337 229 } 338 339 230 340 231 //////////////////////////////////////////////////////////////////////////// 341 232 // boot_putx() 342 // (it uses TTY0)233 // display a 32 bits unsigned int as an hexadecimal string on TTY0 343 234 //////////////////////////////////////////////////////////////////////////// 344 void boot_putx(unsigned int val) { 235 void boot_putx(unsigned int val) 236 { 345 237 static const char HexaTab[] = "0123456789ABCDEF"; 346 238 char buf[11]; … … 351 243 buf[10] = 0; 352 244 353 for (c = 0; c < 8; c++) { 245 for (c = 0; c < 8; c++) 246 { 354 247 buf[9 - c] = HexaTab[val & 0xF]; 355 248 val = val >> 4; … … 358 251 } 359 252 253 //////////////////////////////////////////////////////////////////////////// 254 // boot_putl() 255 // display a 64 bits unsigned long as an hexadecimal string on TTY0 256 //////////////////////////////////////////////////////////////////////////// 257 void boot_putl(paddr_t val) 258 { 259 static const char HexaTab[] = "0123456789ABCDEF"; 260 char buf[19]; 261 unsigned int c; 262 263 buf[0] = '0'; 264 buf[1] = 'x'; 265 buf[18] = 0; 266 267 for (c = 0; c < 16; c++) 268 { 269 buf[17 - c] = HexaTab[(unsigned int)val & 0xF]; 270 val = val >> 4; 271 } 272 boot_puts(buf); 273 } 360 274 361 275 //////////////////////////////////////////////////////////////////////////// 362 276 // boot_putd() 363 // (it uses TTY0)277 // display a 32 bits unsigned int as a decimal string on TTY0 364 278 //////////////////////////////////////////////////////////////////////////// 365 void boot_putd(unsigned int val) { 279 void boot_putd(unsigned int val) 280 { 366 281 static const char DecTab[] = "0123456789"; 367 282 char buf[11]; … … 371 286 buf[10] = 0; 372 287 373 for (i = 0; i < 10; i++) { 374 if ((val != 0) || (i == 0)) { 288 for (i = 0; i < 10; i++) 289 { 290 if ((val != 0) || (i == 0)) 291 { 375 292 buf[9 - i] = DecTab[val % 10]; 376 293 first = 9 - i; 377 294 } 378 else { 295 else 296 { 379 297 break; 380 298 } … … 384 302 } 385 303 386 387 304 ///////////////////////////////////////////////////////////////////////////// 388 305 // mapping_info data structure access functions 389 306 ///////////////////////////////////////////////////////////////////////////// 390 inline mapping_cluster_t *boot_get_cluster_base(mapping_header_t * header) { 307 inline mapping_cluster_t *boot_get_cluster_base(mapping_header_t * header) 308 { 391 309 return (mapping_cluster_t *) ((char *) header + MAPPING_HEADER_SIZE); 392 310 } 393 394 395 311 ///////////////////////////////////////////////////////////////////////////// 396 inline mapping_pseg_t *boot_get_pseg_base(mapping_header_t * header) { 312 inline mapping_pseg_t *boot_get_pseg_base(mapping_header_t * header) 313 { 397 314 return (mapping_pseg_t *) ((char *) header + 398 315 MAPPING_HEADER_SIZE + 399 316 MAPPING_CLUSTER_SIZE * header->clusters); 400 317 } 401 402 403 318 ///////////////////////////////////////////////////////////////////////////// 404 inline mapping_vspace_t *boot_get_vspace_base(mapping_header_t * header) { 319 inline mapping_vspace_t *boot_get_vspace_base(mapping_header_t * header) 320 { 405 321 return (mapping_vspace_t *) ((char *) header + 406 322 MAPPING_HEADER_SIZE + … … 408 324 MAPPING_PSEG_SIZE * header->psegs); 409 325 } 410 411 412 326 ///////////////////////////////////////////////////////////////////////////// 413 inline mapping_vseg_t *boot_get_vseg_base(mapping_header_t * header) { 327 inline mapping_vseg_t *boot_get_vseg_base(mapping_header_t * header) 328 { 414 329 return (mapping_vseg_t *) ((char *) header + 415 330 MAPPING_HEADER_SIZE + … … 418 333 MAPPING_VSPACE_SIZE * header->vspaces); 419 334 } 420 421 422 335 ///////////////////////////////////////////////////////////////////////////// 423 inline mapping_vobj_t *boot_get_vobj_base(mapping_header_t * header) { 336 inline mapping_vobj_t *boot_get_vobj_base(mapping_header_t * header) 337 { 424 338 return (mapping_vobj_t *) ((char *) header + 425 339 MAPPING_HEADER_SIZE + … … 429 343 MAPPING_VSEG_SIZE * header->vsegs); 430 344 } 431 432 433 345 ///////////////////////////////////////////////////////////////////////////// 434 inline mapping_task_t *boot_get_task_base(mapping_header_t * header) { 346 inline mapping_task_t *boot_get_task_base(mapping_header_t * header) 347 { 435 348 return (mapping_task_t *) ((char *) header + 436 349 MAPPING_HEADER_SIZE + … … 441 354 MAPPING_VOBJ_SIZE * header->vobjs); 442 355 } 443 444 445 356 ///////////////////////////////////////////////////////////////////////////// 446 inline mapping_proc_t *boot_get_proc_base(mapping_header_t * header) { 357 inline mapping_proc_t *boot_get_proc_base(mapping_header_t * header) 358 { 447 359 return (mapping_proc_t *) ((char *) header + 448 360 MAPPING_HEADER_SIZE + … … 454 366 MAPPING_TASK_SIZE * header->tasks); 455 367 } 456 457 458 368 ///////////////////////////////////////////////////////////////////////////// 459 inline mapping_irq_t *boot_get_irq_base(mapping_header_t * header) { 369 inline mapping_irq_t *boot_get_irq_base(mapping_header_t * header) 370 { 460 371 return (mapping_irq_t *) ((char *) header + 461 372 MAPPING_HEADER_SIZE + … … 468 379 MAPPING_PROC_SIZE * header->procs); 469 380 } 470 471 472 381 ///////////////////////////////////////////////////////////////////////////// 473 inline mapping_coproc_t *boot_get_coproc_base(mapping_header_t * header) { 382 inline mapping_coproc_t *boot_get_coproc_base(mapping_header_t * header) 383 { 474 384 return (mapping_coproc_t *) ((char *) header + 475 385 MAPPING_HEADER_SIZE + … … 483 393 MAPPING_IRQ_SIZE * header->irqs); 484 394 } 485 486 487 395 /////////////////////////////////////////////////////////////////////////////////// 488 inline mapping_cp_port_t *boot_get_cp_port_base(mapping_header_t * header) { 396 inline mapping_cp_port_t *boot_get_cp_port_base(mapping_header_t * header) 397 { 489 398 return (mapping_cp_port_t *) ((char *) header + 490 399 MAPPING_HEADER_SIZE + … … 499 408 MAPPING_COPROC_SIZE * header->coprocs); 500 409 } 501 502 503 410 /////////////////////////////////////////////////////////////////////////////////// 504 inline mapping_periph_t *boot_get_periph_base(mapping_header_t * header) { 411 inline mapping_periph_t *boot_get_periph_base(mapping_header_t * header) 412 { 505 413 return (mapping_periph_t *) ((char *) header + 506 414 MAPPING_HEADER_SIZE + … … 517 425 } 518 426 519 520 427 ////////////////////////////////////////////////////////////////////////////// 521 428 // boot_pseg_get() … … 523 430 // identified by the pseg index. 524 431 ////////////////////////////////////////////////////////////////////////////// 525 mapping_pseg_t *boot_pseg_get(unsigned int seg_id) { 432 mapping_pseg_t *boot_pseg_get(unsigned int seg_id) 433 { 526 434 mapping_header_t * header = (mapping_header_t *) & seg_mapping_base; 527 435 mapping_pseg_t * pseg = boot_get_pseg_base(header); 528 436 529 437 // checking argument 530 if (seg_id >= header->psegs) { 438 if (seg_id >= header->psegs) 439 { 531 440 boot_puts("\n[BOOT ERROR] : seg_id argument too large\n"); 532 441 boot_puts(" in function boot_pseg_get()\n"); … … 535 444 536 445 return &pseg[seg_id]; 537 } // end boot_pseg_get() 538 446 } 539 447 540 448 ////////////////////////////////////////////////////////////////////////////// 541 449 // boot_add_pte() 542 // This function registers a new PTE in the page table pointed450 // This function registers a new PTE in the page table defined 543 451 // by the vspace_id argument, and updates both PT1 and PT2. 544 452 // A new PT2 is used when required. 545 453 // As the set of PT2s is implemented as a fixed size array (no dynamic 546 454 // allocation), this function checks a possible overflow of the PT2 array. 547 //548 // The global parameter is a boolean indicating wether a global vseg is549 // being mapped.550 455 ////////////////////////////////////////////////////////////////////////////// 551 456 void boot_add_pte(unsigned int vspace_id, 552 unsigned int vpn, unsigned int flags, unsigned int ppn) { 457 unsigned int vpn, 458 unsigned int flags, 459 unsigned int ppn, 460 unsigned int verbose) 461 { 553 462 unsigned int ix1; 554 463 unsigned int ix2; 555 unsigned int ptba; // PT2 base address 556 unsigned int pt2_id; // PT2 index 557 unsigned int *pt_flags; // pointer on the pte_flags = &PT2[2*ix2] 558 unsigned int *pt_ppn; // pointer on the pte_ppn = &PT2[2*ix2+1] 464 paddr_t pt1_pbase; // PT1 physical base address 465 paddr_t pt2_pbase; // PT2 physical base address 466 paddr_t pte_paddr; // PTE physucal address 467 unsigned int pt2_id; // PT2 index 468 unsigned int ptd; // PTD : entry in PT1 469 unsigned int max_pt2; // max number of PT2s for a given vspace 559 470 560 471 ix1 = vpn >> 9; // 11 bits … … 562 473 563 474 // check that the boot_max_pt2[vspace_id] has been set 564 unsigned int max_pt2 = boot_max_pt2[vspace_id]; 565 566 if (max_pt2 == 0) { 567 boot_puts("Unfound page table for vspace "); 475 max_pt2 = boot_max_pt2[vspace_id]; 476 477 if (max_pt2 == 0) 478 { 479 boot_puts("Undefined page table for vspace "); 568 480 boot_putd(vspace_id); 569 481 boot_puts("\n"); 570 482 boot_exit(); 571 483 } 572 // get page table physical address 573 page_table_t *pt = boot_ptabs_paddr[vspace_id]; 574 575 if ((pt->pt1[ix1] & PTE_V) == 0) { // set a new PTD in PT1 484 485 // get page table physical base address 486 pt1_pbase = boot_ptabs_paddr[vspace_id]; 487 488 // get ptd in PT1 489 ptd = boot_physical_read( pt1_pbase + 4*ix1 ); 490 491 if ((ptd & PTE_V) == 0) // invalid PTD: compute PT2 base address, 492 // and set a new PTD in PT1 493 { 576 494 pt2_id = boot_next_free_pt2[vspace_id]; 577 if (pt2_id == max_pt2) { 495 if (pt2_id == max_pt2) 496 { 578 497 boot_puts("\n[BOOT ERROR] in boot_add_pte() function\n"); 579 498 boot_puts("the length of the ptab vobj is too small\n"); 580 499 boot_exit(); 581 500 } 582 else { 583 ptba = (unsigned int) pt + PT1_SIZE + PT2_SIZE * pt2_id; 584 pt->pt1[ix1] = PTE_V | PTE_T | (ptba >> 12); 501 else 502 { 503 pt2_pbase = pt1_pbase + PT1_SIZE + PT2_SIZE * pt2_id; 504 ptd = PTE_V | PTE_T | (unsigned int)(pt2_pbase >> 12); 505 boot_physical_write( pt1_pbase + 4*ix1 , ptd); 585 506 boot_next_free_pt2[vspace_id] = pt2_id + 1; 586 507 } 587 508 } 588 else { 589 ptba = pt->pt1[ix1] << 12; 590 } 591 592 // set PTE2 593 pt_flags = (unsigned int *) (ptba + 8 * ix2); 594 pt_ppn = (unsigned int *) (ptba + 8 * ix2 + 4); 595 596 *pt_flags = flags; 597 *pt_ppn = ppn; 598 599 /* 600 if ( vpn == 0x00000300) 601 { 602 boot_puts("vpn = "); 603 boot_putx( vpn ); 604 boot_puts("\n"); 605 boot_puts("pt_flags = "); 606 boot_putx( (unsigned int)pt_flags ); 607 boot_puts("\n"); 608 boot_puts("*pt_flags = "); 609 boot_putx( *pt_flags ); 610 boot_puts("\n"); 611 boot_exit(); 612 } 613 614 if ((*pt_flags & PTE_V) != 0) { // page already mapped 615 boot_puts("\n[BOOT ERROR] double mapping in vspace "); 616 boot_putd(vspace_id); 617 boot_puts(" for vpn = "); 618 boot_putx(vpn); 619 boot_puts("\n"); 620 boot_exit(); 621 } 622 */ 623 } // end boot_add_pte() 509 else // valid PTD: compute PT2 base address 510 { 511 pt2_pbase = ((paddr_t)(ptd & 0x0FFFFFFF)) << 12; 512 } 513 514 // set PTE in PT2 : flags & PPN in two 32 bits words 515 pte_paddr = pt2_pbase + 8*ix2; 516 boot_physical_write( pte_paddr , flags); 517 boot_physical_write( pte_paddr + 4 , ppn); 518 519 if ( verbose ) 520 { 521 boot_puts(" / pt1_pbase = "); 522 boot_putl( pt1_pbase ); 523 boot_puts(" / ptd = "); 524 boot_putl( ptd ); 525 boot_puts(" / pt2_pbase = "); 526 boot_putl( pt2_pbase ); 527 boot_puts(" / pte_paddr = "); 528 boot_putl( pte_paddr ); 529 boot_puts(" / ppn = "); 530 boot_putx( ppn ); 531 boot_puts("/\n"); 532 } 533 534 } // end boot_add_pte() 624 535 625 536 … … 627 538 // This function build the page table for a given vspace. 628 539 // The physical base addresses for all vsegs (global and private) 629 // must have been previously computed .540 // must have been previously computed and stored in the mapping. 630 541 // It initializes the MWMR channels. 631 542 ///////////////////////////////////////////////////////////////////// 632 void boot_vspace_pt_build(unsigned int vspace_id) { 543 void boot_vspace_pt_build(unsigned int vspace_id) 544 { 633 545 unsigned int vseg_id; 634 546 unsigned int npages; … … 637 549 unsigned int flags; 638 550 unsigned int page_id; 551 unsigned int verbose = 0; // can be used to activate trace in add_pte() 639 552 640 553 mapping_header_t * header = (mapping_header_t *) & seg_mapping_base; 641 554 mapping_vspace_t * vspace = boot_get_vspace_base(header); 642 mapping_vseg_t * vseg= boot_get_vseg_base(header);555 mapping_vseg_t * vseg = boot_get_vseg_base(header); 643 556 644 557 // private segments 645 558 for (vseg_id = vspace[vspace_id].vseg_offset; 646 vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs); 647 vseg_id++) { 559 vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs); 560 vseg_id++) 561 { 648 562 vpn = vseg[vseg_id].vbase >> 12; 649 ppn = vseg[vseg_id].pbase >> 12;563 ppn = (unsigned int)(vseg[vseg_id].pbase >> 12); 650 564 npages = vseg[vseg_id].length >> 12; 651 if ((vseg[vseg_id].length & 0xFFF) != 0) { 652 npages++; 653 } 565 if ((vseg[vseg_id].length & 0xFFF) != 0) npages++; 654 566 655 567 flags = PTE_V; 656 if (vseg[vseg_id].mode & C_MODE_MASK) { 657 flags = flags | PTE_C; 658 } 659 if (vseg[vseg_id].mode & X_MODE_MASK) { 660 flags = flags | PTE_X; 661 } 662 if (vseg[vseg_id].mode & W_MODE_MASK) { 663 flags = flags | PTE_W; 664 } 665 if (vseg[vseg_id].mode & U_MODE_MASK) { 666 flags = flags | PTE_U; 667 } 568 if (vseg[vseg_id].mode & C_MODE_MASK) flags = flags | PTE_C; 569 if (vseg[vseg_id].mode & X_MODE_MASK) flags = flags | PTE_X; 570 if (vseg[vseg_id].mode & W_MODE_MASK) flags = flags | PTE_W; 571 if (vseg[vseg_id].mode & U_MODE_MASK) flags = flags | PTE_U; 668 572 669 573 #if BOOT_DEBUG_PT … … 674 578 boot_putd(npages); 675 579 boot_puts(" / pbase = "); 676 boot_put x(vseg[vseg_id].pbase);580 boot_putl(vseg[vseg_id].pbase); 677 581 boot_puts("\n"); 678 582 #endif 679 583 // loop on 4K pages 680 for (page_id = 0; page_id < npages; page_id++) { 681 boot_add_pte(vspace_id, vpn, flags, ppn); 584 for (page_id = 0; page_id < npages; page_id++) 585 { 586 boot_add_pte(vspace_id, vpn, flags, ppn, verbose); 682 587 vpn++; 683 588 ppn++; … … 686 591 687 592 // global segments 688 for (vseg_id = 0; vseg_id < header->globals; vseg_id++) { 593 for (vseg_id = 0; vseg_id < header->globals; vseg_id++) 594 { 689 595 vpn = vseg[vseg_id].vbase >> 12; 690 ppn = vseg[vseg_id].pbase >> 12;596 ppn = (unsigned int)(vseg[vseg_id].pbase >> 12); 691 597 npages = vseg[vseg_id].length >> 12; 692 if ((vseg[vseg_id].length & 0xFFF) != 0) { 693 npages++; 694 } 598 if ((vseg[vseg_id].length & 0xFFF) != 0) npages++; 695 599 696 600 flags = PTE_V; 697 if (vseg[vseg_id].mode & C_MODE_MASK) { 698 flags = flags | PTE_C; 699 } 700 if (vseg[vseg_id].mode & X_MODE_MASK) { 701 flags = flags | PTE_X; 702 } 703 if (vseg[vseg_id].mode & W_MODE_MASK) { 704 flags = flags | PTE_W; 705 } 706 if (vseg[vseg_id].mode & U_MODE_MASK) { 707 flags = flags | PTE_U; 708 } 601 if (vseg[vseg_id].mode & C_MODE_MASK) flags = flags | PTE_C; 602 if (vseg[vseg_id].mode & X_MODE_MASK) flags = flags | PTE_X; 603 if (vseg[vseg_id].mode & W_MODE_MASK) flags = flags | PTE_W; 604 if (vseg[vseg_id].mode & U_MODE_MASK) flags = flags | PTE_U; 709 605 710 606 #if BOOT_DEBUG_PT 711 607 boot_puts(vseg[vseg_id].name); 712 boot_puts(" /flags = ");608 boot_puts(" : flags = "); 713 609 boot_putx(flags); 714 610 boot_puts(" / npages = "); 715 611 boot_putd(npages); 716 612 boot_puts(" / pbase = "); 717 boot_put x(vseg[vseg_id].pbase);613 boot_putl(vseg[vseg_id].pbase); 718 614 boot_puts("\n"); 719 615 #endif 720 616 // loop on 4K pages 721 for (page_id = 0; page_id < npages; page_id++) { 722 boot_add_pte(vspace_id, vpn, flags, ppn); 617 for (page_id = 0; page_id < npages; page_id++) 618 { 619 boot_add_pte(vspace_id, vpn, flags, ppn, verbose); 723 620 vpn++; 724 621 ppn++; 725 622 } 726 623 } 727 } 624 } // end boot_vspace_pt_build() 728 625 729 626 730 627 /////////////////////////////////////////////////////////////////////////// 731 // Align the value "toAlign" to the required alignement indicated by732 // alignPow2 ( the logarithme of 2 thealignement).628 // Align the value of paddr or vaddr to the required alignement, 629 // defined by alignPow2 == L2(alignement). 733 630 /////////////////////////////////////////////////////////////////////////// 734 unsigned int align_to(unsigned int toAlign, unsigned int alignPow2) { 631 paddr_t paddr_align_to(paddr_t paddr, unsigned int alignPow2) 632 { 633 paddr_t mask = (1 << alignPow2) - 1; 634 return ((paddr + mask) & ~mask); 635 } 636 637 unsigned int vaddr_align_to(unsigned int vaddr, unsigned int alignPow2) 638 { 735 639 unsigned int mask = (1 << alignPow2) - 1; 736 return ((toAlign + mask) & ~mask); 737 } 738 640 return ((vaddr + mask) & ~mask); 641 } 739 642 740 643 /////////////////////////////////////////////////////////////////////////// 741 // This function compute the physical base address for a vseg644 // This function computes the physical base address for a vseg 742 645 // as specified in the mapping info data structure. 743 646 // It updates the pbase and the length fields of the vseg. … … 747 650 // It is a global vseg if vspace_id = (-1). 748 651 /////////////////////////////////////////////////////////////////////////// 749 void boot_vseg_map(mapping_vseg_t * vseg, unsigned int vspace_id) { 652 void boot_vseg_map(mapping_vseg_t * vseg, unsigned int vspace_id) 653 { 750 654 unsigned int vobj_id; 751 655 unsigned int cur_vaddr; 752 unsigned int cur_paddr; 656 paddr_t cur_paddr; 657 unsigned int offset; 658 753 659 mapping_header_t * header = (mapping_header_t *) & seg_mapping_base; 754 mapping_vobj_t * vobj= boot_get_vobj_base(header);660 mapping_vobj_t * vobj = boot_get_vobj_base(header); 755 661 756 662 // get physical segment pointer 757 mapping_pseg_t 663 mapping_pseg_t* pseg = boot_pseg_get(vseg->psegid); 758 664 759 665 // compute vseg physical base address 760 if (vseg->ident != 0) { // identity mapping required 666 if (vseg->ident != 0) // identity mapping required 667 { 761 668 vseg->pbase = vseg->vbase; 762 669 } 763 else { // unconstrained mapping 670 else // unconstrained mapping 671 { 764 672 vseg->pbase = pseg->next_base; 765 673 766 674 // test alignment constraint 767 if (vobj[vseg->vobj_offset].align) { 768 vseg->pbase = align_to(vseg->pbase, vobj[vseg->vobj_offset].align); 675 if (vobj[vseg->vobj_offset].align) 676 { 677 vseg->pbase = paddr_align_to(vseg->pbase, vobj[vseg->vobj_offset].align); 769 678 } 770 679 } … … 778 687 cur_paddr = vseg->pbase; 779 688 780 for (vobj_id = vseg->vobj_offset; vobj_id < (vseg->vobj_offset + vseg->vobjs); vobj_id++) { 781 if (vobj[vobj_id].align) { 782 cur_paddr = align_to(cur_paddr, vobj[vobj_id].align); 783 cur_vaddr = align_to(cur_vaddr, vobj[vobj_id].align); 689 for (vobj_id = vseg->vobj_offset; 690 vobj_id < (vseg->vobj_offset + vseg->vobjs); vobj_id++) 691 { 692 if (vobj[vobj_id].align) 693 { 694 cur_paddr = paddr_align_to(cur_paddr, vobj[vobj_id].align); 695 cur_vaddr = vaddr_align_to(cur_vaddr, vobj[vobj_id].align); 784 696 } 785 697 // set vaddr/paddr for current vobj … … 787 699 vobj[vobj_id].paddr = cur_paddr; 788 700 789 // initialise boot_ptabs_vaddr[] if current vobj is a PTAB 790 if (vobj[vobj_id].type == VOBJ_TYPE_PTAB) { 791 if (vspace_id == ((unsigned int) -1)) { // global vseg 701 // initialise boot_ptabs_vaddr[] & boot_ptabs-paddr[] if PTAB 702 if (vobj[vobj_id].type == VOBJ_TYPE_PTAB) 703 { 704 if (vspace_id == ((unsigned int) -1)) // global vseg 705 { 792 706 boot_puts("\n[BOOT ERROR] in boot_vseg_map() function: "); 793 707 boot_puts("a PTAB vobj cannot be global"); 794 708 boot_exit(); 795 709 } 796 // we need at least one PT2 => ( boot_max_pt2[vspace_id] >= 1) 797 if (vobj[vobj_id].length < (PT1_SIZE + PT2_SIZE)) { 710 // we need at least one PT2 711 if (vobj[vobj_id].length < (PT1_SIZE + PT2_SIZE)) 712 { 798 713 boot_puts("\n[BOOT ERROR] in boot_vseg_map() function, "); 799 714 boot_puts("PTAB too small, minumum size is: "); … … 802 717 } 803 718 // register both physical and virtual page table address 804 boot_ptabs_vaddr[vspace_id] = (page_table_t *) vobj[vobj_id].vaddr; 805 boot_ptabs_paddr[vspace_id] = (page_table_t *) vobj[vobj_id].paddr; 806 807 /* computing the number of second level page */ 719 boot_ptabs_vaddr[vspace_id] = vobj[vobj_id].vaddr; 720 boot_ptabs_paddr[vspace_id] = vobj[vobj_id].paddr; 721 722 // reset all valid bits in PT1 723 for ( offset = 0 ; offset < 8192 ; offset = offset + 4) 724 { 725 boot_physical_write( cur_paddr + offset, 0); 726 } 727 728 // computing the number of second level pages 808 729 boot_max_pt2[vspace_id] = (vobj[vobj_id].length - PT1_SIZE) / PT2_SIZE; 809 730 } 731 810 732 // set next vaddr/paddr 811 cur_vaddr += vobj[vobj_id].length; 812 cur_paddr += vobj[vobj_id].length; 813 733 cur_vaddr = cur_vaddr + vobj[vobj_id].length; 734 cur_paddr = cur_paddr + vobj[vobj_id].length; 814 735 } // end for vobjs 815 736 816 737 //set the vseg length 817 vseg->length = align_to((cur_paddr - vseg->pbase), 12);738 vseg->length = vaddr_align_to((unsigned int)(cur_paddr - vseg->pbase), 12); 818 739 819 740 // checking pseg overflow 820 741 if ((vseg->pbase < pseg->base) || 821 ((vseg->pbase + vseg->length) > (pseg->base + pseg->length))) { 742 ((vseg->pbase + vseg->length) > (pseg->base + pseg->length))) 743 { 822 744 boot_puts("\n[BOOT ERROR] in boot_vseg_map() function\n"); 823 745 boot_puts("impossible mapping for virtual segment: "); … … 825 747 boot_puts("\n"); 826 748 boot_puts("vseg pbase = "); 827 boot_put x(vseg->pbase);749 boot_putl(vseg->pbase); 828 750 boot_puts("\n"); 829 751 boot_puts("vseg length = "); … … 831 753 boot_puts("\n"); 832 754 boot_puts("pseg pbase = "); 833 boot_put x(pseg->base);755 boot_putl(pseg->base); 834 756 boot_puts("\n"); 835 757 boot_puts("pseg length = "); 836 boot_put x(pseg->length);758 boot_putl(pseg->length); 837 759 boot_puts("\n"); 838 760 boot_exit(); … … 846 768 boot_putx(vseg->vbase); 847 769 boot_puts(" / pbase = "); 848 boot_put x(vseg->pbase);770 boot_putl(vseg->pbase); 849 771 boot_puts("\n"); 850 772 #endif 851 773 852 // set the next_base field in vseg 853 if (vseg->ident == 0 && pseg->type != PSEG_TYPE_PERI) { 774 // set the next_base field in pseg when it's a RAM 775 if ( pseg->type == PSEG_TYPE_RAM ) 776 { 854 777 pseg->next_base = vseg->pbase + vseg->length; 855 778 } 856 857 } // end boot_vseg_map() 779 } // end boot_vseg_map() 858 780 859 781 ///////////////////////////////////////////////////////////////////// … … 861 783 // structure (soft), and the giet_config file (hard). 862 784 ///////////////////////////////////////////////////////////////////// 863 void boot_check_mapping() { 785 void boot_check_mapping() 786 { 864 787 mapping_header_t * header = (mapping_header_t *) & seg_mapping_base; 865 788 mapping_cluster_t * cluster = boot_get_cluster_base(header); … … 867 790 868 791 // checking mapping availability 869 if (header->signature != IN_MAPPING_SIGNATURE) { 792 if (header->signature != IN_MAPPING_SIGNATURE) 793 { 870 794 boot_puts("\n[BOOT ERROR] Illegal mapping signature: "); 871 795 boot_putx(header->signature); … … 874 798 } 875 799 // checking number of clusters 876 if (header->clusters != NB_CLUSTERS) { 800 if (header->clusters != NB_CLUSTERS) 801 { 877 802 boot_puts("\n[BOOT ERROR] Incoherent NB_CLUSTERS"); 878 803 boot_puts("\n - In giet_config, value = "); … … 884 809 } 885 810 // checking number of virtual spaces 886 if (header->vspaces > GIET_NB_VSPACE_MAX) { 811 if (header->vspaces > GIET_NB_VSPACE_MAX) 812 { 887 813 boot_puts("\n[BOOT ERROR] : number of vspaces > GIET_NB_VSPACE_MAX\n"); 888 814 boot_puts("\n"); … … 894 820 unsigned int tty_found = 0; 895 821 unsigned int nic_found = 0; 896 for (cluster_id = 0; cluster_id < NB_CLUSTERS; cluster_id++) { 822 for (cluster_id = 0; cluster_id < NB_CLUSTERS; cluster_id++) 823 { 897 824 // NB_PROCS_MAX 898 if (cluster[cluster_id].procs > NB_PROCS_MAX) { 825 if (cluster[cluster_id].procs > NB_PROCS_MAX) 826 { 899 827 boot_puts("\n[BOOT ERROR] too many processors in cluster "); 900 828 boot_putd(cluster_id); … … 907 835 for (periph_id = cluster[cluster_id].periph_offset; 908 836 periph_id < cluster[cluster_id].periph_offset + cluster[cluster_id].periphs; 909 periph_id++) { 910 // NB_TTYS 911 if (periph[periph_id].type == PERIPH_TYPE_TTY) { 912 if (tty_found) { 837 periph_id++) 838 { 839 // NB_TTY_CHANNELS 840 if (periph[periph_id].type == PERIPH_TYPE_TTY) 841 { 842 if (tty_found) 843 { 913 844 boot_puts("\n[BOOT ERROR] TTY component should not be replicated\n"); 914 845 boot_exit(); 915 846 } 916 if (periph[periph_id].channels > NB_TTYS) { 917 boot_puts("\n[BOOT ERROR] Wrong NB_TTYS in cluster "); 847 if (periph[periph_id].channels > NB_TTY_CHANNELS) 848 { 849 boot_puts("\n[BOOT ERROR] Wrong NB_TTY_CHANNELS in cluster "); 918 850 boot_putd(cluster_id); 919 851 boot_puts(" : ttys = "); … … 924 856 tty_found = 1; 925 857 } 926 // NB_NICS 927 if (periph[periph_id].type == PERIPH_TYPE_NIC) { 928 if (nic_found) { 858 // NB_NIC_CHANNELS 859 if (periph[periph_id].type == PERIPH_TYPE_NIC) 860 { 861 if (nic_found) 862 { 929 863 boot_puts("\n[BOOT ERROR] NIC component should not be replicated\n"); 930 864 boot_exit(); 931 865 } 932 if (periph[periph_id].channels != NB_NICS) { 933 boot_puts("\n[BOOT ERROR] Wrong NB_NICS in cluster "); 866 if (periph[periph_id].channels != NB_NIC_CHANNELS) 867 { 868 boot_puts("\n[BOOT ERROR] Wrong NB_NIC_CHANNELS in cluster "); 934 869 boot_putd(cluster_id); 935 870 boot_puts(" : nics = "); … … 941 876 } 942 877 // NB_TIMERS 943 if (periph[periph_id].type == PERIPH_TYPE_TIM) { 944 if (periph[periph_id].channels > NB_TIMERS_MAX) { 878 if (periph[periph_id].type == PERIPH_TYPE_TIM) 879 { 880 if (periph[periph_id].channels > NB_TIM_CHANNELS) 881 { 945 882 boot_puts("\n[BOOT ERROR] Too much user timers in cluster "); 946 883 boot_putd(cluster_id); … … 952 889 } 953 890 // NB_DMAS 954 if (periph[periph_id].type == PERIPH_TYPE_DMA) { 955 if (periph[periph_id].channels != NB_DMAS_MAX) { 891 if (periph[periph_id].type == PERIPH_TYPE_DMA) 892 { 893 if (periph[periph_id].channels != NB_DMA_CHANNELS) 894 { 956 895 boot_puts("\n[BOOT ERROR] Too much DMA channels in cluster "); 957 896 boot_putd(cluster_id); 958 897 boot_puts(" : channels = "); 959 898 boot_putd(periph[periph_id].channels); 960 boot_puts(" - NB_DMA S_MAX: ");961 boot_putd(NB_DMA S_MAX);899 boot_puts(" - NB_DMA_CHANNELS : "); 900 boot_putd(NB_DMA_CHANNELS); 962 901 boot_puts("\n"); 963 902 boot_exit(); … … 968 907 } // end boot_check_mapping() 969 908 970 971 909 ///////////////////////////////////////////////////////////////////// 972 910 // This function initialises the physical pages table allocators 973 911 // for all psegs (i.e. next_base field of the pseg). 974 // In each cluster containing processors, it reserve space for the975 // schedulers in the first RAM pseg found (4k bytes per processor).976 912 ///////////////////////////////////////////////////////////////////// 977 void boot_psegs_init() {978 mapping_header_t * header = (mapping_header_t *) &seg_mapping_base; 979 980 mapping_cluster_t 981 mapping_pseg_t * pseg= boot_get_pseg_base(header);913 void boot_psegs_init() 914 { 915 mapping_header_t* header = (mapping_header_t *) &seg_mapping_base; 916 mapping_cluster_t* cluster = boot_get_cluster_base(header); 917 mapping_pseg_t* pseg = boot_get_pseg_base(header); 982 918 983 919 unsigned int cluster_id; 984 920 unsigned int pseg_id; 985 unsigned int found;986 921 987 922 #if BOOT_DEBUG_PT 988 boot_puts 989 ("\n[BOOT DEBUG] ****** psegs allocators nitialisation ******\n"); 990 #endif 991 992 for (cluster_id = 0; cluster_id < header->clusters; cluster_id++) { 993 if (cluster[cluster_id].procs > NB_PROCS_MAX) { 923 boot_puts ("\n[BOOT DEBUG] ****** psegs allocators initialisation ******\n"); 924 #endif 925 926 for (cluster_id = 0; cluster_id < header->clusters; cluster_id++) 927 { 928 if (cluster[cluster_id].procs > NB_PROCS_MAX) 929 { 994 930 boot_puts("\n[BOOT ERROR] The number of processors in cluster "); 995 931 boot_putd(cluster_id); … … 998 934 } 999 935 1000 found = 0;1001 1002 936 for (pseg_id = cluster[cluster_id].pseg_offset; 1003 937 pseg_id < cluster[cluster_id].pseg_offset + cluster[cluster_id].psegs; 1004 pseg_id++) { 1005 unsigned int free = pseg[pseg_id].base; 1006 1007 if ((pseg[pseg_id].type == PSEG_TYPE_RAM) && (found == 0)) { 1008 free = free + (cluster[cluster_id].procs << 12); 1009 found = 1; 1010 } 1011 pseg[pseg_id].next_base = free; 938 pseg_id++) 939 { 940 pseg[pseg_id].next_base = pseg[pseg_id].base; 1012 941 1013 942 #if BOOT_DEBUG_PT 1014 1015 1016 1017 1018 1019 boot_putx(pseg[pseg_id].next_base);1020 943 boot_puts("cluster "); 944 boot_putd(cluster_id); 945 boot_puts(" / pseg "); 946 boot_puts(pseg[pseg_id].name); 947 boot_puts(" : next_base = "); 948 boot_putl(pseg[pseg_id].next_base); 949 boot_puts("\n"); 1021 950 #endif 1022 951 } 1023 952 } 1024 953 } // end boot_psegs_init() 1025 1026 954 1027 955 ///////////////////////////////////////////////////////////////////// 1028 956 // This function builds the page tables for all virtual spaces 1029 // defined in the mapping_info data structure. 1030 // For each virtual space, it maps both the global vsegs 1031 // (replicated in all vspaces), and the private vsegs. 957 // defined in the mapping_info data structure, in three steps: 958 // - step 1 : It computes the physical base address for global vsegs 959 // and for all associated vobjs. 960 // - step 2 : It computes the physical base address for all private 961 // vsegs and all vobjs in each virtual space. 962 // - step 3 : It actually fill the page table for each vspace. 1032 963 ///////////////////////////////////////////////////////////////////// 1033 void boot_pt_init() { 964 void boot_pt_init() 965 { 1034 966 mapping_header_t * header = (mapping_header_t *) &seg_mapping_base; 1035 1036 967 mapping_vspace_t * vspace = boot_get_vspace_base(header); 1037 mapping_vseg_t * vseg= boot_get_vseg_base(header);968 mapping_vseg_t * vseg = boot_get_vseg_base(header); 1038 969 1039 970 unsigned int vspace_id; … … 1041 972 1042 973 #if BOOT_DEBUG_PT 1043 boot_puts("\n[BOOT DEBUG] ****** mapping global vsegs ******\n"); 1044 #endif 1045 1046 // step 1 : first loop on virtual spaces to map global vsegs 1047 for (vseg_id = 0; vseg_id < header->globals; vseg_id++) { 974 boot_puts("\n[BOOT DEBUG] ****** mapping global vsegs ******\n"); 975 #endif 976 977 // step 1 : loop on virtual spaces to map global vsegs 978 for (vseg_id = 0; vseg_id < header->globals; vseg_id++) 979 { 1048 980 boot_vseg_map(&vseg[vseg_id], ((unsigned int) (-1))); 1049 981 } 1050 982 1051 983 // step 2 : loop on virtual vspaces to map private vsegs 1052 for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) { 984 for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 985 { 1053 986 1054 987 #if BOOT_DEBUG_PT 1055 1056 1057 988 boot_puts("\n[BOOT DEBUG] ****** mapping private vsegs in vspace "); 989 boot_puts(vspace[vspace_id].name); 990 boot_puts(" ******\n"); 1058 991 #endif 1059 992 1060 993 for (vseg_id = vspace[vspace_id].vseg_offset; 1061 994 vseg_id < (vspace[vspace_id].vseg_offset + vspace[vspace_id].vsegs); 1062 vseg_id++) { 995 vseg_id++) 996 { 1063 997 boot_vseg_map(&vseg[vseg_id], vspace_id); 1064 998 } … … 1066 1000 1067 1001 // step 3 : loop on the vspaces to build the page tables 1068 for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) {1069 1002 for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 1003 { 1070 1004 #if BOOT_DEBUG_PT 1071 boot_puts("\n[BOOT DEBUG] ****** building page table for vspace "); 1072 boot_puts(vspace[vspace_id].name); 1073 boot_puts(" ******\n"); 1074 #endif 1075 1005 boot_puts("\n[BOOT DEBUG] ****** building page table for vspace "); 1006 boot_puts(vspace[vspace_id].name); 1007 boot_puts(" ******\n"); 1008 #endif 1076 1009 boot_vspace_pt_build(vspace_id); 1077 1010 1078 1011 #if BOOT_DEBUG_PT 1079 1080 boot_putx((unsigned int)boot_ptabs_paddr[vspace_id]);1081 boot_puts(", page tablenumber of PT2 = ");1082 1083 1012 boot_puts("\n>>> page table physical address = "); 1013 boot_putl(boot_ptabs_paddr[vspace_id]); 1014 boot_puts(", number of PT2 = "); 1015 boot_putd((unsigned int) boot_max_pt2[vspace_id]); 1016 boot_puts("\n"); 1084 1017 #endif 1085 1018 } 1086 1019 } // end boot_pt_init() 1087 1088 1020 1089 1021 /////////////////////////////////////////////////////////////////////////////// … … 1091 1023 // such as mwmr channels, barriers and locks, because these vobjs 1092 1024 // are not known, and not initialized by the compiler. 1025 // Warning : The MMU is supposed to be activated... 1093 1026 /////////////////////////////////////////////////////////////////////////////// 1094 void boot_vobjs_init() { 1095 mapping_header_t * header = (mapping_header_t *) & seg_mapping_base; 1096 mapping_vspace_t * vspace = boot_get_vspace_base(header); 1097 mapping_vobj_t * vobj = boot_get_vobj_base(header); 1027 void boot_vobjs_init() 1028 { 1029 mapping_header_t* header = (mapping_header_t *) & seg_mapping_base; 1030 mapping_vspace_t* vspace = boot_get_vspace_base(header); 1031 mapping_vobj_t* vobj = boot_get_vobj_base(header); 1098 1032 1099 1033 unsigned int vspace_id; 1100 1034 unsigned int vobj_id; 1101 1035 1102 // loop on the vspaces 1103 for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) { 1036 // loop on the vspaces 1037 for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 1038 { 1104 1039 1105 1040 #if BOOT_DEBUG_VOBJS 1106 1107 1108 1041 boot_puts("\n[BOOT DEBUG] ****** vobjs initialisation in vspace "); 1042 boot_puts(vspace[vspace_id].name); 1043 boot_puts(" ******\n"); 1109 1044 #endif 1110 1045 … … 1113 1048 // loop on the vobjs 1114 1049 for (vobj_id = vspace[vspace_id].vobj_offset; 1115 vobj_id < (vspace[vspace_id].vobj_offset + vspace[vspace_id].vobjs); 1116 vobj_id++) { 1117 switch (vobj[vobj_id].type) { 1050 vobj_id < (vspace[vspace_id].vobj_offset + vspace[vspace_id].vobjs); 1051 vobj_id++) 1052 { 1053 switch (vobj[vobj_id].type) 1054 { 1118 1055 case VOBJ_TYPE_MWMR: // storage capacity is (vobj.length/4 - 5) words 1119 1056 { 1120 mwmr_channel_t * mwmr = (mwmr_channel_t *) (vobj[vobj_id].paddr);1057 mwmr_channel_t* mwmr = (mwmr_channel_t *) (vobj[vobj_id].vaddr); 1121 1058 mwmr->ptw = 0; 1122 1059 mwmr->ptr = 0; … … 1126 1063 mwmr->lock = 0; 1127 1064 #if BOOT_DEBUG_VOBJS 1128 1129 1130 1131 1132 1133 1134 1065 boot_puts("MWMR : "); 1066 boot_puts(vobj[vobj_id].name); 1067 boot_puts(" / depth = "); 1068 boot_putd(mwmr->depth); 1069 boot_puts(" / width = "); 1070 boot_putd(mwmr->width); 1071 boot_puts("\n"); 1135 1072 #endif 1136 1073 break; … … 1139 1076 { 1140 1077 #if BOOT_DEBUG_VOBJS 1141 1142 1143 1144 1145 1078 boot_puts("ELF : "); 1079 boot_puts(vobj[vobj_id].name); 1080 boot_puts(" / length = "); 1081 boot_putx(vobj[vobj_id].length); 1082 boot_puts("\n"); 1146 1083 #endif 1147 1084 break; … … 1150 1087 { 1151 1088 #if BOOT_DEBUG_VOBJS 1152 1153 1154 1155 1156 1089 boot_puts("BLOB : "); 1090 boot_puts(vobj[vobj_id].name); 1091 boot_puts(" / length = "); 1092 boot_putx(vobj[vobj_id].length); 1093 boot_puts("\n"); 1157 1094 #endif 1158 1095 break; … … 1160 1097 case VOBJ_TYPE_BARRIER: // init is the number of participants 1161 1098 { 1162 giet_barrier_t * barrier = (giet_barrier_t *) (vobj[vobj_id].paddr);1099 giet_barrier_t* barrier = (giet_barrier_t *) (vobj[vobj_id].vaddr); 1163 1100 barrier->count = vobj[vobj_id].init; 1164 1101 barrier->init = vobj[vobj_id].init; 1165 1102 #if BOOT_DEBUG_VOBJS 1166 1167 1168 1169 1170 1103 boot_puts("BARRIER : "); 1104 boot_puts(vobj[vobj_id].name); 1105 boot_puts(" / init_value = "); 1106 boot_putd(barrier->init); 1107 boot_puts("\n"); 1171 1108 #endif 1172 1109 break; 1173 1110 } 1174 case VOBJ_TYPE_LOCK: // init is "not taken"1175 { 1176 unsigned int * lock = (unsigned int *) (vobj[vobj_id].paddr);1111 case VOBJ_TYPE_LOCK: // init value is "not taken" 1112 { 1113 unsigned int* lock = (unsigned int *) (vobj[vobj_id].vaddr); 1177 1114 *lock = 0; 1178 1115 #if BOOT_DEBUG_VOBJS 1179 1180 1181 1116 boot_puts("LOCK : "); 1117 boot_puts(vobj[vobj_id].name); 1118 boot_puts("\n"); 1182 1119 #endif 1183 1120 break; … … 1186 1123 { 1187 1124 #if BOOT_DEBUG_VOBJS 1188 1189 1190 1191 1192 1193 1194 1125 boot_puts("BUFFER : "); 1126 boot_puts(vobj[vobj_id].name); 1127 boot_puts(" / paddr = "); 1128 boot_putx(vobj[vobj_id].paddr); 1129 boot_puts(" / length = "); 1130 boot_putx(vobj[vobj_id].length); 1131 boot_puts("\n"); 1195 1132 #endif 1196 1133 break; … … 1198 1135 case VOBJ_TYPE_MEMSPACE: 1199 1136 { 1200 giet_memspace_t * memspace = (giet_memspace_t *) vobj[vobj_id].paddr;1137 giet_memspace_t* memspace = (giet_memspace_t *) vobj[vobj_id].vaddr; 1201 1138 memspace->buffer = (void *) vobj[vobj_id].vaddr + 8; 1202 1139 memspace->size = vobj[vobj_id].length - 8; 1203 1140 #if BOOT_DEBUG_VOBJS 1204 boot_puts("MEMSPACE : "); 1205 boot_puts(vobj[vobj_id].name); 1206 boot_puts(" / paddr = "); 1207 boot_putx(vobj[vobj_id].paddr); 1208 boot_puts(" / vaddr = "); 1209 boot_putx(vobj[vobj_id].vaddr); 1210 boot_puts(" / length = "); 1211 boot_putx(vobj[vobj_id].length); 1212 boot_puts(" / buffer = "); 1213 boot_putx(memspace->buffer); 1214 boot_puts(" / size = "); 1215 boot_putx(memspace->size); 1216 boot_puts("\n"); 1141 boot_puts("MEMSPACE : "); 1142 boot_puts(vobj[vobj_id].name); 1143 boot_puts(" / vaddr = "); 1144 boot_putx(vobj[vobj_id].vaddr); 1145 boot_puts(" / length = "); 1146 boot_putx(vobj[vobj_id].length); 1147 boot_puts(" / buffer = "); 1148 boot_putx((unsigned int)memspace->buffer); 1149 boot_puts(" / size = "); 1150 boot_putx(memspace->size); 1151 boot_puts("\n"); 1217 1152 #endif 1218 1153 break; … … 1222 1157 ptab_found = 1; 1223 1158 #if BOOT_DEBUG_VOBJS 1224 1225 1226 1227 1228 1159 boot_puts("PTAB : "); 1160 boot_puts(vobj[vobj_id].name); 1161 boot_puts(" / length = "); 1162 boot_putx(vobj[vobj_id].length); 1163 boot_puts("\n"); 1229 1164 #endif 1230 1165 break; … … 1232 1167 case VOBJ_TYPE_CONST: 1233 1168 { 1234 unsigned int *addr = (unsigned int *) vobj[vobj_id].paddr;1169 unsigned int* addr = (unsigned int *) vobj[vobj_id].vaddr; 1235 1170 *addr = vobj[vobj_id].init; 1236 1171 #if BOOT_DEBUG_VOBJS 1237 1238 1239 1240 1241 1242 1243 1172 boot_puts("CONST : "); 1173 boot_puts(vobj[vobj_id].name); 1174 boot_puts(" / Paddr :"); 1175 boot_putx(vobj[vobj_id].paddr); 1176 boot_puts(" / init = "); 1177 boot_putx(*addr); 1178 boot_puts("\n"); 1244 1179 #endif 1245 1180 break; … … 1247 1182 default: 1248 1183 { 1249 boot_puts("\n[ INIT ERROR] illegal vobj type: ");1184 boot_puts("\n[BOOT ERROR] illegal vobj type: "); 1250 1185 boot_putd(vobj[vobj_id].type); 1251 1186 boot_puts("\n"); … … 1254 1189 } // end switch type 1255 1190 } // end loop on vobjs 1256 if (ptab_found == 0) { 1257 boot_puts("\n[INIT ERROR] Missing PTAB for vspace "); 1191 if (ptab_found == 0) 1192 { 1193 boot_puts("\n[BOOT ERROR] Missing PTAB for vspace "); 1258 1194 boot_putd(vspace_id); 1259 1195 boot_exit(); … … 1262 1198 } // end boot_vobjs_init() 1263 1199 1264 1265 void mwmr_hw_init(void * coproc, enum mwmrPortDirection way, 1266 unsigned int no, const mwmr_channel_t * pmwmr) { 1267 volatile unsigned int *cbase = (unsigned int *) coproc; 1268 1269 cbase[MWMR_CONFIG_FIFO_WAY] = way; 1270 cbase[MWMR_CONFIG_FIFO_NO] = no; 1271 cbase[MWMR_CONFIG_STATUS_ADDR] = (unsigned int) pmwmr; 1272 cbase[MWMR_CONFIG_WIDTH] = pmwmr->width; 1273 cbase[MWMR_CONFIG_DEPTH] = pmwmr->depth; 1274 cbase[MWMR_CONFIG_BUFFER_ADDR] = (unsigned int) &pmwmr->data; 1275 cbase[MWMR_CONFIG_RUNNING] = 1; 1276 } 1277 1200 //////////////////////////////////////////////////////////////////////////////// 1201 // This function initializes one MWMR controller channel. 1202 // - coproc_pbase : physical base address of the Coproc configuration segment 1203 // - channel_pbase : physical base address of the MWMR channel segment 1204 // Warning : the channel physical base address should be on 32 bits, as the 1205 // MWMR controller configuration registers are 32 bits. 1206 // TODO : Introduce a MWMR_CONFIG_PADDR_EXT register in the MWMR coprocessor 1207 // To support addresses > 32 bits and remove this limitation... 1208 /////////////////////////////////////////////////////////////////////////////// 1209 void mwmr_hw_init(paddr_t coproc_pbase, 1210 enum mwmrPortDirection way, 1211 unsigned int no, 1212 paddr_t channel_pbase) 1213 { 1214 if ( (channel_pbase>>32) != 0 ) 1215 { 1216 boot_puts("\n[BOOT ERROR] MWMR controller does not support address > 32 bits\n"); 1217 boot_exit(); 1218 } 1219 1220 unsigned int lsb = (unsigned int)channel_pbase; 1221 // unsigned int msb = (unsigned int)(channel_pbase>>32); 1222 1223 unsigned int depth = boot_physical_read( channel_pbase + 16 ); 1224 unsigned int width = boot_physical_read( channel_pbase + 20 ); 1225 1226 boot_physical_write( coproc_pbase + MWMR_CONFIG_FIFO_WAY*4, way ); 1227 boot_physical_write( coproc_pbase + MWMR_CONFIG_FIFO_NO*4, no ); 1228 boot_physical_write( coproc_pbase + MWMR_CONFIG_WIDTH*4, width); 1229 boot_physical_write( coproc_pbase + MWMR_CONFIG_DEPTH*4, depth); 1230 boot_physical_write( coproc_pbase + MWMR_CONFIG_STATUS_ADDR*4, lsb); 1231 boot_physical_write( coproc_pbase + MWMR_CONFIG_BUFFER_ADDR*4, lsb + 24 ); 1232 // boot_physical_write( coproc_pbase + MWMR_CONFIG_PADDR_EXT*4, msb); 1233 boot_physical_write( coproc_pbase + MWMR_CONFIG_RUNNING*4, 1 ); 1234 } 1278 1235 1279 1236 //////////////////////////////////////////////////////////////////////////////// … … 1281 1238 // in the mapping_info file. 1282 1239 //////////////////////////////////////////////////////////////////////////////// 1283 void boot_peripherals_init() { 1240 void boot_peripherals_init() 1241 { 1284 1242 mapping_header_t * header = (mapping_header_t *) & seg_mapping_base; 1285 1243 mapping_cluster_t * cluster = boot_get_cluster_base(header); … … 1297 1255 unsigned int channel_id; 1298 1256 1299 for (cluster_id = 0; cluster_id < header->clusters; cluster_id++) { 1257 for (cluster_id = 0; cluster_id < header->clusters; cluster_id++) 1258 { 1300 1259 1301 1260 #if BOOT_DEBUG_PERI 1302 boot_puts 1303 ("\n[BOOT DEBUG] ****** peripheral initialisation in cluster "); 1304 boot_putd(cluster_id); 1305 boot_puts(" ******\n"); 1261 boot_puts("\n[BOOT DEBUG] ****** peripherals initialisation in cluster "); 1262 boot_putd(cluster_id); 1263 boot_puts(" ******\n"); 1306 1264 #endif 1307 1265 1308 1266 for (periph_id = cluster[cluster_id].periph_offset; 1309 periph_id < cluster[cluster_id].periph_offset + 1310 cluster[cluster_id].periphs; periph_id++) { 1267 periph_id < cluster[cluster_id].periph_offset + 1268 cluster[cluster_id].periphs; periph_id++) 1269 { 1311 1270 unsigned int type = periph[periph_id].type; 1312 1271 unsigned int channels = periph[periph_id].channels; 1313 1272 unsigned int pseg_id = periph[periph_id].psegid; 1314 1273 1315 unsigned int * pseg_base = (unsigned int *)pseg[pseg_id].base;1274 paddr_t pbase = pseg[pseg_id].base; 1316 1275 1317 1276 #if BOOT_DEBUG_PERI 1318 boot_puts("- peripheral type : "); 1319 boot_putd(type); 1320 boot_puts(" / address = "); 1321 boot_putx((unsigned int) pseg_base); 1322 boot_puts(" / channels = "); 1323 boot_putd(channels); 1324 boot_puts("\n"); 1325 #endif 1326 1327 switch (type) { 1277 boot_puts("- peripheral type : "); 1278 boot_putd(type); 1279 boot_puts(" / pbase = "); 1280 boot_putl(pbase); 1281 boot_puts(" / channels = "); 1282 boot_putd(channels); 1283 boot_puts("\n"); 1284 #endif 1285 1286 switch (type) 1287 { 1328 1288 case PERIPH_TYPE_IOC: // vci_block_device component 1329 pseg_base[BLOCK_DEVICE_IRQ_ENABLE] = 1; 1289 { 1290 paddr_t paddr = pbase + BLOCK_DEVICE_IRQ_ENABLE*4; 1291 boot_physical_write(paddr, 1); 1330 1292 #if BOOT_DEBUG_PERI 1331 1332 #endif 1333 break;1334 1293 boot_puts("- IOC initialised\n"); 1294 #endif 1295 } 1296 break; 1335 1297 case PERIPH_TYPE_DMA: // vci_multi_dma component 1336 for (channel_id = 0; channel_id < channels; channel_id++) { 1337 pseg_base[DMA_IRQ_DISABLE + channel_id * DMA_SPAN] = 0; 1298 for (channel_id = 0; channel_id < channels; channel_id++) 1299 { 1300 paddr_t paddr = pbase + (channel_id*DMA_SPAN + DMA_IRQ_DISABLE) * 4; 1301 boot_physical_write(paddr, 0); 1338 1302 } 1339 1303 #if BOOT_DEBUG_PERI 1340 boot_puts("- DMA initialised\n"); 1341 #endif 1342 break; 1343 1304 boot_puts("- DMA initialised\n"); 1305 #endif 1306 break; 1344 1307 case PERIPH_TYPE_NIC: // vci_multi_nic component 1345 for (channel_id = 0; channel_id < channels; channel_id++) { 1308 for (channel_id = 0; channel_id < channels; channel_id++) 1309 { 1346 1310 // TODO 1347 1311 } 1348 1312 #if BOOT_DEBUG_PERI 1349 boot_puts("- NIC initialised\n"); 1350 #endif 1351 break; 1352 1313 boot_puts("- NIC initialised\n"); 1314 #endif 1315 break; 1353 1316 case PERIPH_TYPE_TTY: // vci_multi_tty component 1354 1317 #if BOOT_DEBUG_PERI 1355 boot_puts("- TTY initialised\n"); 1356 #endif 1357 break; 1358 1318 boot_puts("- TTY initialised\n"); 1319 #endif 1320 break; 1359 1321 case PERIPH_TYPE_IOB: // vci_io_bridge component 1360 if (IOMMU_ACTIVE) { 1322 if (IOMMU_ACTIVE) 1323 { 1361 1324 // TODO 1362 1325 // get the iommu page table physical address … … 1368 1331 } 1369 1332 #if BOOT_DEBUG_PERI 1370 1371 #endif 1372 1373 } 1374 } 1333 boot_puts("- IOB initialised\n"); 1334 #endif 1335 break; 1336 } // end switch periph type 1337 } // end for periphs 1375 1338 1376 1339 #if BOOT_DEBUG_PERI 1377 boot_puts 1378 ("\n[BOOT DEBUG] ****** coprocessors initialisation in cluster "); 1379 boot_putd(cluster_id); 1380 boot_puts(" ******\n"); 1340 boot_puts("\n[BOOT DEBUG] ****** coprocessors initialisation in cluster "); 1341 boot_putd(cluster_id); 1342 boot_puts(" ******\n"); 1381 1343 #endif 1382 1344 1383 1345 for (coproc_id = cluster[cluster_id].coproc_offset; 1384 coproc_id < cluster[cluster_id].coproc_offset + 1385 cluster[cluster_id].coprocs; coproc_id++) { 1386 unsigned no_fifo_to = 0; //FIXME: should it be the map.xml who define the order? 1346 coproc_id < cluster[cluster_id].coproc_offset + 1347 cluster[cluster_id].coprocs; coproc_id++) 1348 { 1349 unsigned no_fifo_to = 0; //FIXME: should the map.xml define the order? 1387 1350 unsigned no_fifo_from = 0; 1388 unsigned int cpseg = pseg[coproc[coproc_id].psegid].base; 1351 1352 // Get physical base address for MWMR controler 1353 paddr_t coproc_pbase = pseg[coproc[coproc_id].psegid].base; 1389 1354 1390 1355 #if BOOT_DEBUG_PERI 1391 1392 1393 1394 1395 1356 boot_puts("- coprocessor name : "); 1357 boot_puts(coproc[coproc_id].name); 1358 boot_puts(" / nb ports = "); 1359 boot_putd((unsigned int) coproc[coproc_id].ports); 1360 boot_puts("\n"); 1396 1361 #endif 1397 1362 1398 1363 for (cp_port_id = coproc[coproc_id].port_offset; 1399 1400 cp_port_id++) {1401 //FIXME: the vspace_id should be the same for all ports: put it in the coproc?1364 cp_port_id < coproc[coproc_id].port_offset + coproc[coproc_id].ports; 1365 cp_port_id++) 1366 { 1402 1367 unsigned int vspace_id = cp_port[cp_port_id].vspaceid; 1403 unsigned int vobj_id = cp_port[cp_port_id].mwmr_vobjid + vspace[vspace_id].vobj_offset; 1404 1405 mwmr_channel_t * pmwmr = (mwmr_channel_t *) (vobj[vobj_id].paddr); 1406 1407 if (cp_port[cp_port_id].direction == PORT_TO_COPROC) { 1368 unsigned int vobj_id = cp_port[cp_port_id].mwmr_vobjid + 1369 vspace[vspace_id].vobj_offset; 1370 1371 // Get MWMR channel base address 1372 paddr_t channel_pbase = vobj[vobj_id].paddr; 1373 1374 if (cp_port[cp_port_id].direction == PORT_TO_COPROC) 1375 { 1408 1376 #if BOOT_DEBUG_PERI 1409 boot_puts(" port direction: PORT_TO_COPROC"); 1410 #endif 1411 mwmr_hw_init((void *) cpseg, PORT_TO_COPROC, no_fifo_to, pmwmr); 1377 boot_puts(" port direction: PORT_TO_COPROC"); 1378 #endif 1379 mwmr_hw_init(coproc_pbase, 1380 PORT_TO_COPROC, 1381 no_fifo_to, 1382 channel_pbase); 1412 1383 no_fifo_to++; 1413 1384 } 1414 else { 1385 else 1386 { 1415 1387 #if BOOT_DEBUG_PERI 1416 boot_puts(" port direction: PORT_FROM_COPROC"); 1417 #endif 1418 mwmr_hw_init((void *) cpseg, PORT_FROM_COPROC, no_fifo_from, pmwmr); 1388 boot_puts(" port direction: PORT_FROM_COPROC"); 1389 #endif 1390 mwmr_hw_init(coproc_pbase, 1391 PORT_FROM_COPROC, 1392 no_fifo_from, 1393 channel_pbase); 1419 1394 no_fifo_from++; 1420 1395 } 1421 1396 #if BOOT_DEBUG_PERI 1422 1423 1424 1425 1426 #endif 1427 } 1397 boot_puts(", with mwmr: "); 1398 boot_puts(vobj[vobj_id].name); 1399 boot_puts(" of vspace: "); 1400 boot_puts(vspace[vspace_id].name); 1401 #endif 1402 } // end for cp_ports 1428 1403 } // end for coprocs 1429 1404 } // end for clusters 1430 1405 } // end boot_peripherals_init() 1431 1406 1407 /////////////////////////////////////////////////////////////////////////////// 1408 // This function returns in the vbase and length buffers the virtual base 1409 // address and the length of the segment allocated to the schedulers array 1410 // in the cluster defined by the clusterid argument. 1411 /////////////////////////////////////////////////////////////////////////////// 1412 void boot_get_sched_vaddr( unsigned int cluster_id, 1413 unsigned int* vbase, 1414 unsigned int* length ) 1415 { 1416 mapping_header_t* header = (mapping_header_t *) & seg_mapping_base; 1417 mapping_vobj_t* vobj = boot_get_vobj_base(header); 1418 mapping_vseg_t* vseg = boot_get_vseg_base(header); 1419 mapping_pseg_t* pseg = boot_get_pseg_base(header); 1420 1421 unsigned int vseg_id; 1422 unsigned int found = 0; 1423 1424 for ( vseg_id = 0 ; (vseg_id < header->vsegs) && (found == 0) ; vseg_id++ ) 1425 { 1426 if ( (vobj[vseg[vseg_id].vobj_offset].type == VOBJ_TYPE_SCHED) && 1427 (pseg[vseg[vseg_id].psegid].cluster == cluster_id ) ) 1428 { 1429 *vbase = vseg[vseg_id].vbase; 1430 *length = vobj[vseg[vseg_id].vobj_offset].length; 1431 found = 1; 1432 } 1433 } 1434 if ( found == 0 ) 1435 { 1436 boot_puts("\n[BOOT ERROR] No vobj of type SCHED in cluster "); 1437 boot_putd(cluster_id); 1438 boot_puts("\n"); 1439 boot_exit(); 1440 } 1441 } // end boot_get_sched_vaddr() 1432 1442 1433 1443 /////////////////////////////////////////////////////////////////////////////// 1434 1444 // This function initialises all processors schedulers. 1435 1445 // This is done by processor 0, and the MMU must be activated. 1436 // It initialises the boot_ schedulers_paddr[gpid] pointers array.1446 // It initialises the boot_chedulers[gpid] pointers array. 1437 1447 // Finally, it scan all tasks in all vspaces to initialise the tasks contexts, 1438 1448 // as specified in the mapping_info data structure. 1439 1449 // For each task, a TTY channel, a TIMER channel, a FBDMA channel, and a NIC 1440 // channel can be allocated if required.1450 // channel are allocated if required. 1441 1451 /////////////////////////////////////////////////////////////////////////////// 1442 void boot_schedulers_init() { 1443 mapping_header_t * header = (mapping_header_t *) & seg_mapping_base; 1444 mapping_cluster_t * cluster = boot_get_cluster_base(header); 1445 mapping_pseg_t * pseg = boot_get_pseg_base(header); 1446 mapping_vspace_t * vspace = boot_get_vspace_base(header); 1447 mapping_task_t * task = boot_get_task_base(header); 1448 mapping_vobj_t * vobj = boot_get_vobj_base(header); 1449 mapping_proc_t * proc = boot_get_proc_base(header); 1450 mapping_irq_t * irq = boot_get_irq_base(header); 1451 1452 unsigned int alloc_tty_channel; // TTY channel allocator 1453 unsigned int alloc_nic_channel; // NIC channel allocator 1452 void boot_schedulers_init() 1453 { 1454 mapping_header_t* header = (mapping_header_t *) & seg_mapping_base; 1455 mapping_cluster_t* cluster = boot_get_cluster_base(header); 1456 mapping_vspace_t* vspace = boot_get_vspace_base(header); 1457 mapping_task_t* task = boot_get_task_base(header); 1458 mapping_vobj_t* vobj = boot_get_vobj_base(header); 1459 mapping_proc_t* proc = boot_get_proc_base(header); 1460 mapping_irq_t* irq = boot_get_irq_base(header); 1461 1462 unsigned int cluster_id; // cluster index in mapping_info 1463 unsigned int proc_id; // processor index in mapping_info 1464 unsigned int irq_id; // irq index in mapping_info 1465 unsigned int vspace_id; // vspace index in mapping_info 1466 unsigned int task_id; // task index in mapping_info 1467 1468 unsigned int alloc_tty_channel = 1; // TTY channel allocator 1469 unsigned int alloc_nic_channel = 0; // NIC channel allocator 1470 unsigned int alloc_cma_channel = 0; // CMA channel allocator 1471 unsigned int alloc_ioc_channel = 0; // IOC channel allocator 1454 1472 unsigned int alloc_dma_channel[NB_CLUSTERS]; // DMA channel allocators 1455 unsigned int alloc_timer_channel[NB_CLUSTERS]; // user TIMER allocators 1456 1457 unsigned int cluster_id; // cluster global index 1458 unsigned int proc_id; // processor global index 1459 unsigned int irq_id; // irq global index 1460 unsigned int pseg_id; // pseg global index 1461 unsigned int vspace_id; // vspace global index 1462 unsigned int task_id; // task global index; 1463 1464 // Step 0 : TTY, NIC, TIMERS and DMA channels allocators initialisation 1465 // global_id = cluster_id*NB_*_MAX + loc_id 1466 // - TTY[0] is reserved for the kernel 1467 // - In all clusters the first NB_PROCS_MAX timers 1468 // are reserved for the kernel (context switch) 1469 1470 alloc_tty_channel = 1; 1471 alloc_nic_channel = 0; 1472 1473 for (cluster_id = 0; cluster_id < header->clusters; cluster_id++) { 1473 unsigned int alloc_tim_channel[NB_CLUSTERS]; // user TIMER allocators 1474 1475 ///////////////////////////////////////////////////////////////////////// 1476 // Step 1 : loop on the clusters and on the processors 1477 // to initialize the schedulers[] array of pointers and 1478 // the interrupt vectors. 1479 // Implementation note: 1480 // We need to use both proc_id to scan the mapping info structure, 1481 // and lpid to access the schedulers array. 1482 // - the boot_schedulers[] array of pointers can contain "holes", because 1483 // it is indexed by the global pid = cluster_id*NB_PROCS_MAX + ltid 1484 // - the mapping info array of processors is contiguous, it is indexed 1485 // by proc_id, and use an offset specific in each cluster. 1486 1487 for (cluster_id = 0; cluster_id < header->clusters; cluster_id++) 1488 { 1489 1490 #if BOOT_DEBUG_SCHED 1491 boot_puts("\n[BOOT DEBUG] Initialise schedulers in cluster "); 1492 boot_putd(cluster_id); 1493 boot_puts("\n"); 1494 #endif 1495 1496 // TTY, NIC, CMA, IOC, TIM and DMA channels allocators 1497 // - TTY[0] is reserved for the kernel 1498 // - In all clusters the first NB_PROCS_MAX timers 1499 // are reserved for the kernel (context switch) 1500 1474 1501 alloc_dma_channel[cluster_id] = 0; 1475 alloc_timer_channel[cluster_id] = 0; 1476 } 1477 1478 // Step 1 : loop on the clusters and on the processors 1479 // - initialise the boot_schedulers_paddr[] pointers array 1480 // - initialise the interrupt vectors for each processor. 1481 1482 for (cluster_id = 0; cluster_id < header->clusters; cluster_id++) { 1483 1484 #if BOOT_DEBUG_SCHED 1485 boot_puts("\n[BOOT DEBUG] Initialise schedulers / IT vector in cluster "); 1486 boot_putd(cluster_id); 1487 boot_puts("\n"); 1488 #endif 1489 unsigned int found = 0; 1490 unsigned int pseg_pbase; // pseg base address 1491 unsigned int lpid; // processor local index 1492 1493 // get the physical base address of the first PSEG_TYPE_RAM pseg in cluster 1494 for (pseg_id = cluster[cluster_id].pseg_offset; 1495 pseg_id < cluster[cluster_id].pseg_offset + cluster[cluster_id].psegs; 1496 pseg_id++) { 1497 if (pseg[pseg_id].type == PSEG_TYPE_RAM) { 1498 pseg_pbase = pseg[pseg_id].base; 1499 found = 1; 1500 break; 1501 } 1502 } 1503 1504 if ((cluster[cluster_id].procs > 0) && (found == 0)) { 1505 boot_puts("\n[BOOT ERROR] Missing RAM pseg in cluster "); 1502 alloc_tim_channel[cluster_id] = NB_PROCS_MAX; 1503 1504 unsigned int lpid; // processor local index in cluster 1505 unsigned int sched_vbase; // schedulers segment virtual base address 1506 unsigned int sched_length; // schedulers segment length 1507 unsigned int nprocs; // number of processors in cluster 1508 1509 nprocs = cluster[cluster_id].procs; 1510 1511 // checking processors number 1512 if ( nprocs > NB_PROCS_MAX ) 1513 { 1514 boot_puts("\n[BOOT ERROR] Too much processors in cluster "); 1506 1515 boot_putd(cluster_id); 1507 1516 boot_puts("\n"); 1508 1517 boot_exit(); 1509 1518 } 1510 // 4 Kbytes per scheduler 1511 for (lpid = 0; lpid < cluster[cluster_id].procs; lpid++) { 1512 boot_schedulers_paddr[cluster_id * NB_PROCS_MAX + lpid] = (static_scheduler_t *) (pseg_pbase + (lpid << 12)); 1519 1520 // get scheduler array virtual base address for cluster_id 1521 boot_get_sched_vaddr( cluster_id, &sched_vbase, &sched_length ); 1522 1523 // each processor scheduler requires 1 Kbytes 1524 if ( sched_length < (nprocs<<10) ) 1525 { 1526 boot_puts("\n[BOOT ERROR] Schedulers segment too small in cluster "); 1527 boot_putd(cluster_id); 1528 boot_puts("\n"); 1529 boot_exit(); 1513 1530 } 1514 1531 1515 for (proc_id = cluster[cluster_id].proc_offset; 1516 proc_id < cluster[cluster_id].proc_offset + cluster[cluster_id].procs; 1517 proc_id++) { 1532 for ( proc_id = cluster[cluster_id].proc_offset, lpid = 0 ; 1533 proc_id < cluster[cluster_id].proc_offset + cluster[cluster_id].procs; 1534 proc_id++, lpid++ ) 1535 { 1536 // set the schedulers pointers array 1537 boot_schedulers[cluster_id * NB_PROCS_MAX + lpid] = 1538 (static_scheduler_t*)( sched_vbase + (lpid<<10) ); 1518 1539 1519 1540 #if BOOT_DEBUG_SCHED 1520 boot_puts("\nProc "); 1521 boot_putd(proc_id); 1522 boot_puts(" : scheduler pbase = "); 1523 boot_putx(pseg_pbase + (proc_id << 12)); 1524 boot_puts("\n"); 1525 #endif 1526 // initialise the "tasks" variable in scheduler 1527 boot_scheduler_set_tasks(proc_id, 0); 1541 boot_puts("\nProc "); 1542 boot_putd(lpid); 1543 boot_puts(" : scheduler virtual base address = "); 1544 boot_putx( sched_vbase + (lpid<<10) ); 1545 boot_puts("\n"); 1546 #endif 1547 // current processor scheduler pointer : psched 1548 static_scheduler_t* psched = (static_scheduler_t*)(sched_vbase+(lpid<<10)); 1549 1550 // initialise the "tasks" variable 1551 psched->tasks = 0; 1528 1552 1529 1553 // initialise the interrupt_vector with ISR_DEFAULT 1530 1554 unsigned int slot; 1531 for (slot = 0; slot < 32; slot++) { 1532 boot_scheduler_set_itvector(proc_id, slot, 0); 1533 } 1555 for (slot = 0; slot < 32; slot++) psched->interrupt_vector[slot] = 0; 1534 1556 1535 1557 // scan the IRQs actually allocated to current processor 1536 1558 for (irq_id = proc[proc_id].irq_offset; 1537 irq_id < proc[proc_id].irq_offset + proc[proc_id].irqs; 1538 irq_id++) { 1559 irq_id < proc[proc_id].irq_offset + proc[proc_id].irqs; 1560 irq_id++) 1561 { 1539 1562 unsigned int type = irq[irq_id].type; 1540 1563 unsigned int icu_id = irq[irq_id].icuid; … … 1542 1565 unsigned int channel = irq[irq_id].channel; 1543 1566 unsigned int value = isr_id | (type << 8) | (channel << 16); 1544 boot_scheduler_set_itvector(proc_id, icu_id, value);1567 psched->interrupt_vector[icu_id] = value; 1545 1568 1546 1569 #if BOOT_DEBUG_SCHED 1547 boot_puts("- IRQ : icu = "); 1548 boot_putd(icu_id); 1549 boot_puts(" / type = "); 1550 boot_putd(type); 1551 boot_puts(" / isr = "); 1552 boot_putd(isr_id); 1553 boot_puts(" / channel = "); 1554 boot_putd(channel); 1555 boot_puts("\n"); 1570 boot_puts("- IRQ : icu = "); 1571 boot_putd(icu_id); 1572 boot_puts(" / type = "); 1573 boot_putd(type); 1574 boot_puts(" / isr = "); 1575 boot_putd(isr_id); 1576 boot_puts(" / channel = "); 1577 boot_putd(channel); 1578 boot_puts(" => vector_entry = "); 1579 boot_putx( value ); 1580 boot_puts("\n"); 1556 1581 #endif 1557 1582 } … … 1559 1584 } // end for clusters 1560 1585 1586 /////////////////////////////////////////////////////////////////// 1561 1587 // Step 2 : loop on the vspaces and the tasks 1562 1588 // to initialise the schedulers and the task contexts. 1563 1564 for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) { 1589 // Implementation note: 1590 // This function initialises the task context for all tasks. 1591 // For each processor, the scheduler virtual base address 1592 // is written in the CP0_SCHED register in reset.S 1593 1594 for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 1595 { 1565 1596 1566 1597 #if BOOT_DEBUG_SCHED 1567 boot_puts 1568 ("\n[BOOT DEBUG] Initialise schedulers / task contexts for vspace "); 1569 boot_puts(vspace[vspace_id].name); 1570 boot_puts("\n"); 1598 boot_puts("\n[BOOT DEBUG] Initialise task contexts for vspace "); 1599 boot_puts(vspace[vspace_id].name); 1600 boot_puts("\n"); 1571 1601 #endif 1572 1602 // We must set the PTPR depending on the vspace, because the start_vector 1573 1603 // and the stack address are defined in virtual space. 1574 boot_set_mmu_ptpr( (unsigned int) boot_ptabs_paddr[vspace_id] >> 13);1604 boot_set_mmu_ptpr( (unsigned int)(boot_ptabs_paddr[vspace_id] >> 13) ); 1575 1605 1576 1606 // loop on the tasks in vspace (task_id is the global index) 1577 1607 for (task_id = vspace[vspace_id].task_offset; 1578 task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks); 1579 task_id++) { 1608 task_id < (vspace[vspace_id].task_offset + vspace[vspace_id].tasks); 1609 task_id++) 1610 { 1611 // compute gpid (global processor index) and scheduler base address 1612 unsigned int gpid = task[task_id].clusterid * NB_PROCS_MAX + 1613 task[task_id].proclocid; 1614 static_scheduler_t* psched = boot_schedulers[gpid]; 1615 1580 1616 // ctx_ra : the return address is &boot_eret() 1581 1617 unsigned int ctx_ra = (unsigned int) &boot_eret; … … 1585 1621 1586 1622 // ctx_ptpr : page table physical base address (shifted by 13 bit) 1587 unsigned int ctx_ptpr = (unsigned int) boot_ptabs_paddr[vspace_id] >> 13; 1588 1589 // compute gpid = global processor index 1590 unsigned int gpid = task[task_id].clusterid * NB_PROCS_MAX + task[task_id].proclocid; 1623 unsigned int ctx_ptpr = (unsigned int)(boot_ptabs_paddr[vspace_id] >> 13); 1591 1624 1592 1625 // ctx_ptab : page_table virtual base address 1593 unsigned int ctx_ptab = (unsigned int)boot_ptabs_vaddr[vspace_id];1594 1595 // ctx_tty : terminal global index provided by aglobal allocator1626 unsigned int ctx_ptab = boot_ptabs_vaddr[vspace_id]; 1627 1628 // ctx_tty : terminal global index provided by the global allocator 1596 1629 unsigned int ctx_tty = 0xFFFFFFFF; 1597 if (task[task_id].use_tty) { 1598 if (alloc_tty_channel >= NB_TTYS) { 1630 if (task[task_id].use_tty) 1631 { 1632 if (alloc_tty_channel >= NB_TTY_CHANNELS) 1633 { 1599 1634 boot_puts("\n[BOOT ERROR] TTY index too large for task "); 1600 1635 boot_puts(task[task_id].name); … … 1607 1642 alloc_tty_channel++; 1608 1643 } 1609 // ctx_nic : NIC channel global index provided by aglobal allocator1644 // ctx_nic : NIC channel global index provided by the global allocator 1610 1645 unsigned int ctx_nic = 0xFFFFFFFF; 1611 if (task[task_id].use_nic) { 1612 if (alloc_nic_channel >= NB_NICS) { 1646 if (task[task_id].use_nic) 1647 { 1648 if (alloc_nic_channel >= NB_NIC_CHANNELS) 1649 { 1613 1650 boot_puts("\n[BOOT ERROR] NIC channel index too large for task "); 1614 1651 boot_puts(task[task_id].name); … … 1621 1658 alloc_nic_channel++; 1622 1659 } 1623 // ctx_timer : user TIMER global index provided by a cluster allocator 1624 unsigned int ctx_timer = 0xFFFFFFFF; 1625 if (task[task_id].use_timer) { 1660 // ctx_cma : CMA channel global index provided by the global allocator 1661 unsigned int ctx_cma = 0xFFFFFFFF; 1662 if (task[task_id].use_cma) 1663 { 1664 if (alloc_cma_channel >= NB_CMA_CHANNELS) 1665 { 1666 boot_puts("\n[BOOT ERROR] CMA channel index too large for task "); 1667 boot_puts(task[task_id].name); 1668 boot_puts(" in vspace "); 1669 boot_puts(vspace[vspace_id].name); 1670 boot_puts("\n"); 1671 boot_exit(); 1672 } 1673 ctx_cma = alloc_cma_channel; 1674 alloc_cma_channel++; 1675 } 1676 // ctx_ioc : IOC channel global index provided by the global allocator 1677 unsigned int ctx_ioc = 0xFFFFFFFF; 1678 if (task[task_id].use_ioc) 1679 { 1680 if (alloc_ioc_channel >= NB_IOC_CHANNELS) 1681 { 1682 boot_puts("\n[BOOT ERROR] IOC channel index too large for task "); 1683 boot_puts(task[task_id].name); 1684 boot_puts(" in vspace "); 1685 boot_puts(vspace[vspace_id].name); 1686 boot_puts("\n"); 1687 boot_exit(); 1688 } 1689 ctx_ioc = alloc_ioc_channel; 1690 alloc_ioc_channel++; 1691 } 1692 // ctx_tim : TIMER local channel index provided by the cluster allocator 1693 unsigned int ctx_tim = 0xFFFFFFFF; 1694 if (task[task_id].use_tim) 1695 { 1626 1696 unsigned int cluster_id = task[task_id].clusterid; 1627 unsigned int allocated = alloc_timer_channel[cluster_id]; 1628 1629 if (allocated >= NB_TIMERS_MAX){1697 1698 if ( alloc_tim_channel[cluster_id] >= NB_TIM_CHANNELS ) 1699 { 1630 1700 boot_puts("\n[BOOT ERROR] local TIMER index too large for task "); 1631 1701 boot_puts(task[task_id].name); … … 1635 1705 boot_exit(); 1636 1706 } 1637 //assert(allocated >= 0); 1638 char found = 0;1639 for (irq_id = 0; irq_id < 32; irq_id++) { //look at the isr_timer isr channel1640 unsigned int isr = boot_scheduler_get_itvector(gpid, irq_id) & 0x000000FF;1641 if (isr == ISR_TIMER){1642 if (allocated == 0) {1643 found = 1;1644 alloc_timer_channel[cluster_id]++;1645 ctx_timer = cluster_id * NB_TIMERS_MAX + alloc_timer_channel[cluster_id];1646 break;1647 }1648 else {1649 allocated--;1650 }1707 1708 // checking that there is a well defined ISR_TIMER installed 1709 unsigned int found = 0; 1710 for ( irq_id = 0 ; irq_id < 32 ; irq_id++ ) 1711 { 1712 unsigned int entry = psched->interrupt_vector[irq_id]; 1713 unsigned int isr = entry & 0x000000FF; 1714 unsigned int channel = entry>>16; 1715 if ( (isr == ISR_TIMER) && (channel == alloc_tim_channel[cluster_id]) ) 1716 { 1717 found = 1; 1718 ctx_tim = alloc_tim_channel[cluster_id]; 1719 alloc_tim_channel[cluster_id]++; 1720 break; 1651 1721 } 1652 1722 } 1653 1654 if (!found){1655 boot_puts("\n[BOOT ERROR] No user timer availablefor task ");1723 if (!found) 1724 { 1725 boot_puts("\n[BOOT ERROR] No ISR_TIMER installed for task "); 1656 1726 boot_puts(task[task_id].name); 1657 1727 boot_puts(" in vspace "); … … 1660 1730 boot_exit(); 1661 1731 } 1662 1663 1732 } 1664 // ctx_dma : DMA global index provided by a cluster allocator 1733 // ctx_dma : the local channel index is defined by the cluster allocator 1734 // but the ctx_dma value is a global index 1665 1735 unsigned int ctx_dma = 0xFFFFFFFF; 1666 if (task[task_id].use_fbdma || task[task_id].use_nic) { 1736 if ( task[task_id].use_dma ) 1737 { 1667 1738 unsigned int cluster_id = task[task_id].clusterid; 1668 if (alloc_dma_channel[cluster_id] >= NB_DMAS_MAX) { 1739 1740 if (alloc_dma_channel[cluster_id] >= NB_DMA_CHANNELS) 1741 { 1669 1742 boot_puts("\n[BOOT ERROR] local DMA index too large for task "); 1670 1743 boot_puts(task[task_id].name); … … 1674 1747 boot_exit(); 1675 1748 } 1676 ctx_dma = cluster_id * NB_DMA S_MAX+ alloc_dma_channel[cluster_id];1749 ctx_dma = cluster_id * NB_DMA_CHANNELS + alloc_dma_channel[cluster_id]; 1677 1750 alloc_dma_channel[cluster_id]++; 1678 1751 } 1679 1752 // ctx_epc : Get the virtual address of the start function 1680 mapping_vobj_t * pvobj = &vobj[vspace[vspace_id].vobj_offset + vspace[vspace_id].start_offset]; 1681 unsigned int * start_vector_vbase = (unsigned int *) pvobj->vaddr; 1753 mapping_vobj_t* pvobj = &vobj[vspace[vspace_id].vobj_offset + 1754 vspace[vspace_id].start_offset]; 1755 unsigned int* start_vector_vbase = (unsigned int *) pvobj->vaddr; 1682 1756 unsigned int ctx_epc = start_vector_vbase[task[task_id].startid]; 1683 1757 … … 1686 1760 unsigned int ctx_sp = vobj[vobj_id].vaddr + vobj[vobj_id].length; 1687 1761 1688 // In the code below, we access the scheduler with specific access 1689 // functions, because we only have the physical address of the scheduler, 1690 // and these functions must temporary desactivate the DTLB... 1691 1692 // get local task index in scheduler[gpid] 1693 unsigned int ltid = boot_scheduler_get_tasks(gpid); 1694 1695 if (ltid >= IDLE_TASK_INDEX) { 1762 // get local task index in scheduler 1763 unsigned int ltid = psched->tasks; 1764 1765 if (ltid >= IDLE_TASK_INDEX) 1766 { 1696 1767 boot_puts("\n[BOOT ERROR] : "); 1697 1768 boot_putd(ltid); … … 1701 1772 boot_exit(); 1702 1773 } 1703 // update the "tasks" field in scheduler[gpid] 1704 boot_scheduler_set_tasks(gpid, ltid + 1); 1705 1706 // update the "current" field in scheduler[gpid] 1707 boot_scheduler_set_current(gpid, 0); 1708 1709 // initializes the task context in scheduler[gpid] 1710 boot_scheduler_set_context(gpid, ltid, CTX_SR_ID, ctx_sr); 1711 boot_scheduler_set_context(gpid, ltid, CTX_SP_ID, ctx_sp); 1712 boot_scheduler_set_context(gpid, ltid, CTX_RA_ID, ctx_ra); 1713 boot_scheduler_set_context(gpid, ltid, CTX_EPC_ID, ctx_epc); 1714 boot_scheduler_set_context(gpid, ltid, CTX_PTPR_ID, ctx_ptpr); 1715 boot_scheduler_set_context(gpid, ltid, CTX_TTY_ID, ctx_tty); 1716 boot_scheduler_set_context(gpid, ltid, CTX_DMA_ID, ctx_dma); 1717 boot_scheduler_set_context(gpid, ltid, CTX_NIC_ID, ctx_nic); 1718 boot_scheduler_set_context(gpid, ltid, CTX_TIMER_ID, ctx_timer); 1719 boot_scheduler_set_context(gpid, ltid, CTX_PTAB_ID, ctx_ptab); 1720 boot_scheduler_set_context(gpid, ltid, CTX_LTID_ID, ltid); 1721 boot_scheduler_set_context(gpid, ltid, CTX_VSID_ID, vspace_id); 1722 boot_scheduler_set_context(gpid, ltid, CTX_GTID_ID, task_id); 1723 boot_scheduler_set_context(gpid, ltid, CTX_RUN_ID, 1); 1774 // update the "tasks" field in scheduler 1775 psched->tasks = ltid + 1; 1776 1777 // update the "current" field in scheduler 1778 psched->current = 0; 1779 1780 // initializes the task context in scheduler 1781 psched->context[ltid][CTX_SR_ID] = ctx_sr; 1782 psched->context[ltid][CTX_SP_ID] = ctx_sp; 1783 psched->context[ltid][CTX_RA_ID] = ctx_ra; 1784 psched->context[ltid][CTX_EPC_ID] = ctx_epc; 1785 psched->context[ltid][CTX_PTPR_ID] = ctx_ptpr; 1786 psched->context[ltid][CTX_TTY_ID] = ctx_tty; 1787 psched->context[ltid][CTX_CMA_ID] = ctx_cma; 1788 psched->context[ltid][CTX_IOC_ID] = ctx_ioc; 1789 psched->context[ltid][CTX_NIC_ID] = ctx_nic; 1790 psched->context[ltid][CTX_TIM_ID] = ctx_tim; 1791 psched->context[ltid][CTX_DMA_ID] = ctx_dma; 1792 psched->context[ltid][CTX_PTAB_ID] = ctx_ptab; 1793 psched->context[ltid][CTX_LTID_ID] = ltid; 1794 psched->context[ltid][CTX_GTID_ID] = task_id; 1795 psched->context[ltid][CTX_VSID_ID] = vspace_id; 1796 psched->context[ltid][CTX_RUN_ID] = 1; 1724 1797 1725 1798 #if BOOT_DEBUG_SCHED 1726 boot_puts("\nTask "); 1727 boot_puts(task[task_id].name); 1728 boot_puts(" ("); 1729 boot_putd(task_id); 1730 boot_puts(") allocated to processor "); 1731 boot_putd(gpid); 1732 boot_puts("\n - ctx[LTID] = "); 1733 boot_putd(ltid); 1734 boot_puts("\n - ctx[SR] = "); 1735 boot_putx(ctx_sr); 1736 boot_puts("\n - ctx[SR] = "); 1737 boot_putx(ctx_sp); 1738 boot_puts("\n - ctx[RA] = "); 1739 boot_putx(ctx_ra); 1740 boot_puts("\n - ctx[EPC] = "); 1741 boot_putx(ctx_epc); 1742 boot_puts("\n - ctx[PTPR] = "); 1743 boot_putx(ctx_ptpr); 1744 boot_puts("\n - ctx[TTY] = "); 1745 boot_putd(ctx_tty); 1746 boot_puts("\n - ctx[NIC] = "); 1747 boot_putd(ctx_nic); 1748 boot_puts("\n - ctx[TIMER] = "); 1749 boot_putd(ctx_timer); 1750 boot_puts("\n - ctx[DMA] = "); 1751 boot_putd(ctx_dma); 1752 boot_puts("\n - ctx[PTAB] = "); 1753 boot_putx(ctx_ptab); 1754 boot_puts("\n - ctx[VSID] = "); 1755 boot_putd(vspace_id); 1756 boot_puts("\n"); 1799 boot_puts("\nTask "); 1800 boot_puts(task[task_id].name); 1801 boot_puts(" ("); 1802 boot_putd(task_id); 1803 boot_puts(") allocated to processor "); 1804 boot_putd(gpid); 1805 boot_puts("\n - ctx[LTID] = "); 1806 boot_putd(ltid); 1807 boot_puts("\n - ctx[SR] = "); 1808 boot_putx(ctx_sr); 1809 boot_puts("\n - ctx[SR] = "); 1810 boot_putx(ctx_sp); 1811 boot_puts("\n - ctx[RA] = "); 1812 boot_putx(ctx_ra); 1813 boot_puts("\n - ctx[EPC] = "); 1814 boot_putx(ctx_epc); 1815 boot_puts("\n - ctx[PTPR] = "); 1816 boot_putx(ctx_ptpr); 1817 boot_puts("\n - ctx[TTY] = "); 1818 boot_putd(ctx_tty); 1819 boot_puts("\n - ctx[NIC] = "); 1820 boot_putd(ctx_nic); 1821 boot_puts("\n - ctx[CMA] = "); 1822 boot_putd(ctx_cma); 1823 boot_puts("\n - ctx[IOC] = "); 1824 boot_putd(ctx_ioc); 1825 boot_puts("\n - ctx[TIM] = "); 1826 boot_putd(ctx_tim); 1827 boot_puts("\n - ctx[DMA] = "); 1828 boot_putd(ctx_dma); 1829 boot_puts("\n - ctx[PTAB] = "); 1830 boot_putx(ctx_ptab); 1831 boot_puts("\n - ctx[GTID] = "); 1832 boot_putd(task_id); 1833 boot_puts("\n - ctx[VSID] = "); 1834 boot_putd(vspace_id); 1835 boot_puts("\n"); 1757 1836 #endif 1758 1837 … … 1765 1844 // This function is executed by P[0] to wakeup all processors. 1766 1845 ////////////////////////////////////////////////////////////////////////////////// 1767 void boot_start_all_procs() { 1846 void boot_start_all_procs() 1847 { 1768 1848 mapping_header_t * header = (mapping_header_t *) &seg_mapping_base; 1769 1849 header->signature = OUT_MAPPING_SIGNATURE; … … 1786 1866 boot_psegs_init(); 1787 1867 1788 boot_puts 1789 ("\n[BOOT] Pseg allocators initialisation completed at cycle "); 1868 boot_puts("\n[BOOT] Pseg allocators initialisation completed at cycle "); 1790 1869 boot_putd(boot_proctime()); 1791 1870 boot_puts("\n"); … … 1798 1877 boot_puts("\n"); 1799 1878 1879 // mmu activation ( with page table [Ã] ) 1880 boot_set_mmu_ptpr( (unsigned int)(boot_ptabs_paddr[0] >> 13) ); 1881 boot_set_mmu_mode(0xF); 1882 1883 boot_puts("\n[BOOT] Proc 0 MMU activation at cycle "); 1884 boot_putd(boot_proctime()); 1885 boot_puts("\n"); 1886 1800 1887 // vobjs initialisation 1801 1888 boot_vobjs_init(); … … 1809 1896 1810 1897 boot_puts("\n[BOOT] Peripherals initialisation completed at cycle "); 1811 boot_putd(boot_proctime());1812 boot_puts("\n");1813 1814 // mmu activation1815 boot_set_mmu_ptpr((unsigned int) boot_ptabs_paddr[0] >> 13);1816 boot_set_mmu_mode(0xF);1817 1818 boot_puts("\n[BOOT] MMU activation completed at cycle ");1819 1898 boot_putd(boot_proctime()); 1820 1899 boot_puts("\n"); -
soft/giet_vm/boot/reset.S
r234 r238 182 182 boot_to_kernel_init: 183 183 184 # all processors initialise SCHED register with boot_schedulers_paddr[pid] 184 # all processors initialise the CP0 SCHED register 185 # SCHED contains the schedulers array virtual base address 185 186 mfc0 k0, CP0_PROCID 186 187 andi k0, k0, 0xFFF 187 188 sll k0, k0, 2 # k0 <= 4*pid 188 la k1, boot_schedulers_paddr 189 addu k1, k1, k0 # k1 <= &boot_scheduler_paddr[pid] 190 lw k1, 0(k1) 191 mtc0 k1, CP0_SCHED 192 193 # all processors initialize PTPR register with boot_ptabs_paddr[0] 189 la k1, boot_schedulers 190 addu k1, k1, k0 # k1 <= &boot_schedulers[pid] 191 lw k0, 0(k1) 192 mtc0 k0, CP0_SCHED 193 194 # all processors initialize the CP2 PTPR register 195 # At this stage, all PTPR registers contain the physical base 196 # address (13 bits right shifted) of the page table for vspace[0] 194 197 la k1, boot_ptabs_paddr 195 lw k1, 0(k1) 196 srl k1, k1, 13 197 mtc2 k1, CP2_PTPR 198 199 # all processors activate MMU 198 lw k0, 0(k1) # k0 <= paddr_lsb 199 lw k1, 4(k1) # k1 <= paddr_msb 200 srl k0, k0, 13 # k0 <= paddr_lsb shifted 201 sll k1, k1, 19 # k1 <= paddr_msb shifted 202 or k0, k0, k1 203 mtc2 k0, CP2_PTPR 204 205 # all processors activate MMU (already done for processor 0) 200 206 li k1, 0xF 201 207 mtc2 k1, CP2_MODE -
soft/giet_vm/display/main.c
r218 r238 18 18 if ( x ) 19 19 { 20 giet_tty_printf("echec giet_ioc_read %d at date : %d\n", x , giet_proctime() );20 giet_tty_printf("echec giet_ioc_read = %d at date : %d\n", x , giet_proctime() ); 21 21 giet_exit(); 22 22 } … … 24 24 if ( x ) 25 25 { 26 giet_tty_printf("echec giet_ioc_completed %d at date : %d\n", x, giet_proctime() );26 giet_tty_printf("echec giet_ioc_completed = %d at date : %d\n", x, giet_proctime() ); 27 27 giet_exit(); 28 28 } … … 33 33 if ( x ) 34 34 { 35 giet_tty_printf("echec giet_fb_write %d at date : %d\n", x, giet_proctime() );35 giet_tty_printf("echec giet_fb_write = %d at date : %d\n", x, giet_proctime() ); 36 36 giet_exit(); 37 37 } … … 42 42 if ( x ) 43 43 { 44 giet_tty_printf("echec giet_fb_completed %d at date : %d\n", x, giet_proctime() );44 giet_tty_printf("echec giet_fb_completed = %d at date : %d\n", x, giet_proctime() ); 45 45 giet_exit(); 46 46 } -
soft/giet_vm/giet_config.h
r232 r238 2 2 /* File : giet_config.h */ 3 3 /* Author : Alain Greiner */ 4 /* Date : 26/03/201 2*/4 /* Date : 26/03/2013 */ 5 5 /********************************************************************************/ 6 6 /* Define various configuration parameters for the GIET */ 7 7 /********************************************************************************/ 8 8 9 #ifndef _ CONFIG_H10 #define _ CONFIG_H9 #ifndef _GIET_CONFIG_H 10 #define _GIET_CONFIG_H 11 11 12 12 /* hardware parameters */ 13 13 #include "hard_config.h" 14 14 15 16 15 /* Debug parameters */ 17 16 18 #define BOOT_DEBUG_PERI 0/* trace peripherals initialisation */19 #define BOOT_DEBUG_PT 0/* trace page tables initialisation */20 #define BOOT_DEBUG_VOBJS 0/* trace vobjs initialisation */21 #define BOOT_DEBUG_SCHED 0/* trace schedulers initialisation */17 #define BOOT_DEBUG_PERI 1 /* trace peripherals initialisation */ 18 #define BOOT_DEBUG_PT 1 /* trace page tables initialisation */ 19 #define BOOT_DEBUG_VOBJS 1 /* trace vobjs initialisation */ 20 #define BOOT_DEBUG_SCHED 1 /* trace schedulers initialisation */ 22 21 23 #define GIET_DEBUG_INIT 0 /* trace parallel kernel initialisation */ 24 #define GIET_DEBUG_SWITCH 0 /* trace context switchs */ 22 #define GIET_DEBUG_INIT 0 /* trace parallel kernel initialisation */ 23 #define GIET_DEBUG_SWITCH 0 /* trace context switchs */ 24 #define GIET_DEBUG_IOC_DRIVER 0 /* trace IOC accesses */ 25 #define GIET_DEBUG_DMA_DRIVER 0 /* trace DMA accesses */ 25 26 26 27 #define CONFIG_SRL_VERBOSITY TRACE … … 28 29 /* software parameters */ 29 30 30 #define GIET_NB_VSPACE_MAX 64 /* max number of virtual spaces */ 31 #define GIET_TICK_VALUE 0x100000 /* context switch period (number of cycles) */ 31 #define GIET_CLUSTER_INCREMENT 0x100000 /* address increment for replicated peripherals */ 32 #define GIET_NB_VSPACE_MAX 64 /* max number of virtual spaces */ 33 #define GIET_TICK_VALUE 0x100000 /* context switch period (number of cycles) */ 32 34 33 35 #endif -
soft/giet_vm/libs/memspace.h
r228 r238 13 13 /////////////////////////////////////////////////////////////////////////////////// 14 14 15 typedef struct _srl_memspace_s { 15 typedef struct _giet_memspace_s 16 { 16 17 void * buffer; 17 18 unsigned int size; -
soft/giet_vm/libs/stdio.c
r237 r238 103 103 // This function returns the local processor time (clock cycles since boot) 104 104 //////////////////////////////////////////////////////////////////////////////////// 105 unsigned int giet_proctime() { 105 unsigned int giet_proctime() 106 { 106 107 return sys_call(SYSCALL_PROCTIME, 0, 0, 0, 0); 107 108 } … … 118 119 // - Returns 1 if the character has been written, 0 otherwise. 119 120 //////////////////////////////////////////////////////////////////////////////////// 120 unsigned int giet_tty_putc(char byte) { 121 unsigned int giet_tty_putc(char byte) 122 { 121 123 return sys_call(SYSCALL_TTY_WRITE, (unsigned int) (&byte), 1, 0, 0); 122 124 } … … 132 134 // - Returns the number of written characters. 133 135 //////////////////////////////////////////////////////////////////////////////////// 134 unsigned int giet_tty_puts(char * buf) { 136 unsigned int giet_tty_puts(char * buf) 137 { 135 138 unsigned int length = 0; 136 while (buf[length] != 0) { 137 length++; 138 } 139 while (buf[length] != 0) { length++; } 139 140 return sys_call(SYSCALL_TTY_WRITE, (unsigned int) buf, length, 0, 0); 140 141 } … … 149 150 // Returns the number of written characters (should be equal to ten). 150 151 //////////////////////////////////////////////////////////////////////////////////// 151 unsigned int giet_tty_putw(unsigned int val) { 152 unsigned int giet_tty_putw(unsigned int val) 153 { 152 154 char buf[10]; 153 155 unsigned int i; 154 for (i = 0; i < 10; i++) { 156 for (i = 0; i < 10; i++) 157 { 155 158 buf[9 - i] = (val % 10) + 0x30; 156 159 val = val / 10; … … 168 171 // - Returns 0 when completed. 169 172 //////////////////////////////////////////////////////////////////////////////////// 170 unsigned int giet_tty_getc(char * byte) { 173 unsigned int giet_tty_getc(char * byte) 174 { 171 175 unsigned int ret = 0; 172 while (ret == 0) { 176 while (ret == 0) 177 { 173 178 ret = sys_call(SYSCALL_TTY_READ, (unsigned int)byte, 1, 0, 0); 174 179 } … … 187 192 // will be copied into buffer, and the string is always completed by a NUL 188 193 // character. 189 // - The <LF> character is interpreted, a sthe function close the string with a194 // - The <LF> character is interpreted, and the function close the string with a 190 195 // NUL character if <LF> is read. 191 196 // - The <DEL> character is interpreted, and the corresponding character(s) are 192 197 // removed from the target buffer. 193 198 //////////////////////////////////////////////////////////////////////////////////// 194 unsigned int giet_tty_gets(char * buf, unsigned int bufsize) { 199 unsigned int giet_tty_gets( char* buf, 200 unsigned int bufsize) 201 { 195 202 unsigned int ret; 196 203 unsigned char byte; 197 204 unsigned int index = 0; 198 205 199 while (index < (bufsize - 1)) { 200 do { 201 ret = sys_call(SYSCALL_TTY_READ, (unsigned int) (&byte), 1, 0, 0); 202 } while (ret != 1); 203 204 if (byte == 0x0A) { 205 break; /* LF */ 206 } 207 else if ((byte == 0x7F) && (index > 0)) { 208 index--; /* DEL */ 209 } 210 else { 206 while (index < (bufsize - 1)) 207 { 208 do { ret = sys_call(SYSCALL_TTY_READ, (unsigned int) (&byte), 1, 0, 0); } 209 while (ret != 1); 210 211 if (byte == 0x0A) /* LF */ 212 { 213 break; 214 } 215 else if ((byte == 0x7F) && (index > 0)) /* DEL */ 216 { 217 index--; 218 } 219 else 220 { 211 221 buf[index] = byte; 212 222 index++; … … 236 246 // bits range, the zero value is returned. 237 247 //////////////////////////////////////////////////////////////////////////////////// 238 unsigned int giet_tty_getw(unsigned int * val) { 248 unsigned int giet_tty_getw(unsigned int * val) 249 { 239 250 unsigned char buf[32]; 240 251 unsigned char byte; … … 247 258 unsigned int ret; 248 259 249 while (done == 0) {250 do{251 ret = sys_call(SYSCALL_TTY_READ, (unsigned int) (&byte), 1, 0, 0);252 }while (ret != 1);253 254 if ((byte > 0x2F) && (byte < 0x3A)) {255 /* decimal character */260 while (done == 0) 261 { 262 do { ret = sys_call(SYSCALL_TTY_READ, (unsigned int) (&byte), 1, 0, 0); } 263 while (ret != 1); 264 265 if ((byte > 0x2F) && (byte < 0x3A)) /* decimal character */ 266 { 256 267 buf[max] = byte; 257 268 max++; 258 269 giet_tty_putc(byte); 259 270 } 260 else if ((byte == 0x0A) || (byte == 0x0D)) {261 /* LF or CR character */271 else if ((byte == 0x0A)) /* LF */ 272 { 262 273 done = 1; 263 274 } 264 else if (byte == 0x7F) { 265 /* DEL character */ 266 if (max > 0) { 267 max--; /* cancel the character */ 275 else if (byte == 0x7F) /* DEL */ 276 { 277 if (max > 0) 278 { 279 max--; /* cancel the character */ 268 280 giet_tty_putc(0x08); 269 281 giet_tty_putc(0x20); … … 271 283 } 272 284 } 273 if (max == 32) { 274 /* decimal string overflow */ 275 for (i = 0; i < max; i++) { 285 if (max == 32) /* decimal string overflow */ 286 { 287 for (i = 0; i < max; i++) 288 { 276 289 /* cancel the string */ 277 290 giet_tty_putc(0x08); … … 280 293 } 281 294 giet_tty_putc(0x30); 282 *val = 0; /* return 0 value */295 *val = 0; /* return 0 value */ 283 296 return 0; 284 297 } … … 286 299 287 300 /* string conversion */ 288 for (i = 0; i < max; i++) { 301 for (i = 0; i < max; i++) 302 { 289 303 dec = dec * 10 + (buf[i] - 0x30); 290 if (dec < save) { 291 overflow = 1; 292 } 304 if (dec < save) overflow = 1; 293 305 save = dec; 294 306 } 295 307 296 308 /* check overflow */ 297 if (overflow == 0) { 309 if (overflow == 0) 310 { 298 311 *val = dec; /* return decimal value */ 299 312 } 300 else { 301 for (i = 0; i < max; i++) { 313 else 314 { 315 for (i = 0; i < max; i++) 316 { 302 317 /* cancel the string */ 303 318 giet_tty_putc(0x08); … … 306 321 } 307 322 giet_tty_putc(0x30); 308 *val = 0; /* return 0 value */323 *val = 0; /* return 0 value */ 309 324 } 310 325 return 0; … … 326 341 // - Returns 0 if success, > 0 if error. 327 342 //////////////////////////////////////////////////////////////////////////////////// 328 unsigned int giet_tty_printf(char * format, ...) { 343 unsigned int giet_tty_printf(char * format, ...) 344 { 329 345 va_list ap; 330 346 va_start(ap, format); … … 333 349 printf_text: 334 350 335 while (*format) { 351 while (*format) 352 { 336 353 unsigned int i; 337 354 for (i = 0; format[i] && format[i] != '%'; i++); 338 if (i) { 355 if (i) 356 { 339 357 ret = sys_call(SYSCALL_TTY_WRITE, (unsigned int) format, i, 0, 0); 340 if (ret != i) { 341 return 1; /* return error */ 342 } 358 if (ret != i) return 1; /* return error */ 343 359 format += i; 344 360 } 345 if (*format == '%') { 361 if (*format == '%') 362 { 346 363 format++; 347 364 goto printf_arguments; -
soft/giet_vm/memo/TODO
r163 r238 1 1 + Support for debug info 2 2 + Search the sections by name, the name should correspond to vobj->name and the adresse should correspond to vseg->addresse 3 + Documentation -
soft/giet_vm/memo/include/libelfpp/elfpp/elfpp_object.hh
r163 r238 59 59 60 60 /** Copy all header fields of obj and set the access_ variable*/ 61 void copy_info(object& obj );61 void copy_info(object& obj, size_t word_width = 0); 62 62 63 63 ~object(); -
soft/giet_vm/memo/include/memo.h
r212 r238 1 1 /* -*- c++ -*- 2 2 * 3 * SOCLIB_LGPL_HEADER_BEGIN3 * GIET_VM_LGPL_HEADER_BEGIN 4 4 * 5 * This file is part of SoCLib, GNU LGPLv2.1.5 * This file is part of GIET_VM, GNU LGPLv2.1. 6 6 * 7 * SoCLibis free software; you can redistribute it and/or modify it7 * GIET_VM is free software; you can redistribute it and/or modify it 8 8 * under the terms of the GNU Lesser General Public License as published 9 9 * by the Free Software Foundation; version 2.1 of the License. 10 10 * 11 * SoCLibis distributed in the hope that it will be useful, but11 * GIET_VM is distributed in the hope that it will be useful, but 12 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU … … 15 15 * 16 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with SoCLib; if not, write to the Free Software17 * License along with GIET_VM; if not, write to the Free Software 18 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 19 * 02110-1301 USA 20 20 * 21 * SOCLIB_LGPL_HEADER_END21 * GIET_VM_LGPL_HEADER_END 22 22 * 23 23 * Copyright (c) UPMC, Lip6, SoC … … 25 25 * 26 26 */ 27 #ifndef _MEMO_H_ 28 #define _MEMO_H_ 27 28 #ifndef GIET_VM_MEMO_H 29 #define GIET_VM_MEMO_H 29 30 30 31 #include <stdlib.h> … … 57 58 class MeMo 58 59 { 60 // TODO: make the name defined in the map_info relative to this wd. 59 61 60 std::string m_path; //map_info path name61 std::string m_wd; //map_info path to directory TODO: make the name defined in the map_info relative to this wd.62 std::string m_simpleName; //map_info filename TODO63 void* m_data; //map_info structure64 uintptr_t m_addr; //map_info address (virtual)65 size_t m_size; //size of the structure62 std::string m_path; // map_info path name 63 std::string m_wd; // map_info directory TODO 64 std::string m_simpleName; // map_info filename TODO 65 void* m_data; // map_info structure 66 uintptr_t m_addr; // map_info address (virtual) 67 size_t m_size; // size of the structure 66 68 mutable std::map<std::string, elfpp::object*> m_loaders; 67 PSegHandler m_psegh; 68 PathHandler m_pathHandler; 69 70 bool m_ginit; 71 elfpp::object* m_generator; 69 PSegHandler m_psegh; 70 PathHandler m_pathHandler; 71 bool m_ginit; 72 elfpp::object* m_generator; 72 73 73 74 size_t load_bin(std::string filename, void* buffer); … … 78 79 public: 79 80 80 MeMo( const std::string &name, const size_t pageSize = 4096); 81 MeMo( const std::string &name, 82 const size_t pageSize = 4096); 83 81 84 ~MeMo(); 82 85 … … 93 96 } 94 97 98 // The following functions handle the map.bin structure 99 // They must keep synchronised with functions defined in boot_init.c. 95 100 96 //The following functions handle the map.bin structure97 //inspired from the boot_init.c of the GIET98 101 mapping_cluster_t* get_cluster_base( mapping_header_t* header ); 99 102 mapping_pseg_t* get_pseg_base( mapping_header_t* header ); … … 108 111 109 112 110 #endif /* _MEMO_H_*/113 #endif /* GIET_VM_MEMO_H */ 111 114 112 115 // Local Variables: -
soft/giet_vm/memo/include/pseg.h
r210 r238 1 1 /* -*- c++ -*- 2 2 * 3 * SOCLIB_LGPL_HEADER_BEGIN3 * GIET-VM_LGPL_HEADER_BEGIN 4 4 * 5 * This file is part of SoCLib, GNU LGPLv2.1.5 * This file is part of the GIET-VMS, GNU LGPLv2.1. 6 6 * 7 * SoCLibis free software; you can redistribute it and/or modify it7 * The GIET-VM is free software; you can redistribute it and/or modify it 8 8 * under the terms of the GNU Lesser General Public License as published 9 9 * by the Free Software Foundation; version 2.1 of the License. 10 10 * 11 * SoCLibis distributed in the hope that it will be useful, but11 * THe GIET-VM is distributed in the hope that it will be useful, but 12 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU … … 19 19 * 02110-1301 USA 20 20 * 21 * SOCLIB_LGPL_HEADER_END21 * GIET-VM_LGPL_HEADER_END 22 22 * 23 23 * Copyright (c) UPMC, Lip6, SoC … … 25 25 * 26 26 */ 27 #ifndef SOCLIB_PSEG_H_28 #define SOCLIB_PSEG_H_27 #ifndef GIET_MEMO_PSEG_H 28 #define GIET_MEMO_PSEG_H 29 29 30 30 #include <string> … … 39 39 class MeMo; 40 40 41 ////////// 41 42 class VSeg 42 43 { … … 45 46 friend class MeMo; 46 47 47 std::string m_name; 48 std::string m_file; 49 uintptr_t m_vma; //The address of the section to load in the binary file. 50 uintptr_t m_lma; //Physical address to which we load the seg (getted from the associated PSeg), setted by PSeg::add/addIdent. 51 size_t m_length; 52 size_t m_type; 53 bool m_loadable; // wether this is a loadable vseg ( code, data...) 48 typedef unsigned long long paddr_t; 49 50 std::string m_name; // vseg name 51 std::string m_file; // file name 52 uintptr_t m_vma; // Virtual address of the section to load in the binary file. 53 paddr_t m_lma; // Physical address 54 size_t m_length; 55 size_t m_type; 56 bool m_loadable; // loadable vseg ( code, data...) 54 57 55 58 public: 56 bool m_ident;//Indicate if the idententy mapping is activited. used by PSegHandler::makeIdent() 59 60 bool m_ident; // identity mapping required if true 57 61 58 62 const std::string& name() const; 59 63 const std::string& file() const; 60 64 uintptr_t vma() const; 61 uintptr_t lma() const;65 paddr_t lma() const; 62 66 size_t length() const; 63 67 size_t type() const; … … 75 79 VSeg(); 76 80 VSeg( const VSeg &ref ); 77 VSeg(std::string& binaryName, std::string& name, uintptr_t vma, size_t length, bool loadable, bool ident); 81 VSeg(std::string& binaryName, 82 std::string& name, 83 uintptr_t vma, 84 size_t length, 85 bool loadable, 86 bool ident); 78 87 79 88 ~VSeg(); 80 89 }; 81 90 82 91 ////////// 83 92 class PSeg 84 93 { 85 std::string m_name;86 uintptr_tm_lma;87 size_tm_length;88 size_t m_type;94 std::string m_name; 95 paddr_t m_lma; 96 paddr_t m_length; 97 size_t m_type; 89 98 90 uintptr_t m_pageLimit; //The end (m_lma + m_length) address of the segment pageSize aligned91 uintptr_t m_nextLma; //next free base99 paddr_t m_pageLimit; // m_lma + m_length aligned on page size 100 paddr_t m_nextLma; // next free base 92 101 93 void confNextLma(); //check that m_nextLma has a correct value:whithin the seg limits102 void confNextLma(); // check m_nextLma is whithin the seg limits 94 103 95 104 public: 105 96 106 std::vector<VSeg> m_vsegs; 97 uintptr_t m_limit;// m_lma + m_length98 107 108 paddr_t m_limit; // m_lma + m_length 99 109 100 110 const std::string& name() const; 101 uintptr_t lma() const;102 size_t length() const;111 paddr_t lma() const; 112 paddr_t length() const; 103 113 size_t type() const; 104 uintptr_t limit() const;105 uintptr_t nextLma() const;114 paddr_t limit() const; 115 paddr_t nextLma() const; 106 116 107 117 void check() const; 108 118 109 119 void setName(std::string& name); 110 void setLma( uintptr_t lma);111 void setLength( size_t length);120 void setLma( paddr_t lma); 121 void setLength(paddr_t length); 112 122 113 static size_t align( unsigned toAlign, unsigned alignPow2); 114 static size_t pageAlign( size_t toAlign ); 123 static paddr_t align( paddr_t toAlign, unsigned alignPow2); 124 static paddr_t pageAlign( paddr_t toAlign ); 125 115 126 static void setPageSize(size_t pg); 127 116 128 static size_t& pageSize(); 117 129 118 void add( VSeg& vseg ); //add a VSeg130 void add( VSeg& vseg ); //add a VSeg 119 131 void addIdent( VSeg& vseg ); 120 132 121 void setNextLma( uintptr_t nextLma);122 void incNextLma( size_t inc _next);133 void setNextLma( paddr_t nextLma); 134 void incNextLma( size_t inc); 123 135 124 136 void print( std::ostream &o ) const; … … 134 146 PSeg( const PSeg &ref ); 135 147 PSeg( const std::string &name); 136 PSeg( const uintptr_t lma);148 PSeg( const paddr_t lma); 137 149 PSeg( const std::string &name, 138 uintptr_t lma,139 size_t length,140 150 paddr_t lma, 151 paddr_t length, 152 size_t type); 141 153 ~PSeg(); 142 154 }; 143 155 144 156 145 #endif /* SOCLIB_PSEG_H_*/157 #endif /* GIET_MEMO_PSEG_H */ -
soft/giet_vm/memo/src/libelfpp/elfpp_object.cc
r163 r238 129 129 130 130 131 void object::copy_info(object& obj) 132 { 133 this->word_width_ = obj.word_width_ ; 131 void object::copy_info(object& obj, size_t word_width) 132 { 133 134 if(word_width == 32) 135 this->word_width_ = ELFCLASS32; 136 else if(word_width == 64) 137 this->word_width_ = ELFCLASS64; 138 else 139 this->word_width_ = obj.word_width_ ; 140 134 141 this->byteorder_ = obj.byteorder_ ; 135 142 this->machine_ = obj.machine_ ; -
soft/giet_vm/memo/src/memo.cpp
r215 r238 1 1 /* -*- c++ -*- 2 2 * 3 * SOCLIB_LGPL_HEADER_BEGIN3 * GIET_VM_LGPL_HEADER_BEGIN 4 4 * 5 * This file is part of SoCLib, GNU LGPLv2.1.5 * This file is part of GIET_VM, GNU LGPLv2.1. 6 6 * 7 * SoCLib is free software; you can redistribute vSO and/or modify vSO7 * GIET_VM is free software; you can redistribute it and/or modify it 8 8 * under the terms of the GNU Lesser General Public License as published 9 9 * by the Free Software Foundation; version 2.1 of the License. 10 10 * 11 * SoCLib is distributed in the hope that vSOwill be useful, but11 * GIET_VM is distributed in the hope that it will be useful, but 12 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU … … 15 15 * 16 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with SoCLib; if not, write to the Free Software17 * License along with GIET_VM; if not, write to the Free Software 18 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 19 * 02110-1301 USA 20 20 * 21 * SOCLIB_LGPL_HEADER_END21 * GIET_VM_LGPL_HEADER_END 22 22 * 23 23 * Copyright (c) UPMC, Lip6, SoC … … 41 41 //#define MOVER_DEBUG 42 42 43 MeMo::MeMo( const std::string &filename, 44 const size_t pageSize) 45 :m_path(filename),46 m_pathHandler(filename),47 m_ginit(false),48 m_generator(new elfpp::object())49 { 50 43 //////////////////////////////////////////// 44 MeMo::MeMo( const std::string &filename, 45 const size_t pageSize) 46 : m_path(filename), 47 m_pathHandler(filename), 48 m_ginit(false), 49 m_generator(new elfpp::object()) 50 { 51 51 PSeg::setPageSize(pageSize); 52 52 53 / * loading map_info blob */53 // loading map_info blob 54 54 m_data = std::malloc(bin_size(m_path)); 55 55 if ( !m_data ) … … 58 58 m_size = load_bin(m_path, m_data); 59 59 60 / * checking signature */60 // checking signature 61 61 mapping_header_t* header = (mapping_header_t*)m_data; 62 //assert((IN_MAPPING_SIGNATURE == header->signature) and "wrong signature");63 62 if((IN_MAPPING_SIGNATURE != header->signature)) 64 63 { 65 std::cout << "wrong signature " << std::hex <<header->signature << ", should be:"<< IN_MAPPING_SIGNATURE << std::endl; 64 std::cout << "wrong signature " 65 << std::hex <<header->signature 66 << ", should be:"<< IN_MAPPING_SIGNATURE << std::endl; 66 67 exit(1); 67 68 } 68 69 70 69 71 70 #ifdef MOVER_DEBUG … … 92 91 } 93 92 93 ///////////////////////////////////////// 94 94 void MeMo::print( std::ostream &o ) const 95 95 { … … 102 102 } 103 103 104 //////////////////////////////// 104 105 void MeMo::print_mapping() const 105 106 { … … 107 108 } 108 109 110 //////////////////////////////////////////////////////////////////////////////// 109 111 elfpp::section* MeMo::get_sect_by_addr(elfpp::object *loader, unsigned int addr) 110 112 { … … 123 125 } 124 126 125 127 ///////////////////////////////////////////////// 126 128 void MeMo::buildSoft(const std::string &filename) 127 129 { … … 133 135 } 134 136 135 /* Load the content of filename in buffer, and send the size */ 136 //////////////////////////////////////////////////////// 137 ///////////////////////////////////////////////////////// 137 138 size_t MeMo::load_bin(std::string filename, void* buffer) 138 139 { 139 140 140 141 #ifdef MOVER_DEBUG 141 std::cout << " Trying to load thebinary blob from file '" << filename << "'" << std::endl;142 std::cout << "Loading binary blob from file '" << filename << "'" << std::endl; 142 143 #endif 143 144 … … 339 340 void MeMo::vseg_map( mapping_vseg_t* vseg) 340 341 { 341 mapping_vobj_t* 342 PSeg *ps = &(m_psegh.get(vseg->psegid));// get physical segment pointer(PSegHandler::get)343 elfpp::section* sect = NULL;344 size_t cur_vaddr;345 size_tcur_paddr;346 bool first = true;347 bool aligned = false;348 349 VSeg *vSO = new VSeg;342 mapping_vobj_t* vobj = get_vobj_base( (mapping_header_t*) m_data ); 343 PSeg *ps = &(m_psegh.get(vseg->psegid)); 344 elfpp::section* sect = NULL; 345 size_t cur_vaddr; 346 paddr_t cur_paddr; 347 bool first = true; 348 bool aligned = false; 349 VSeg* vSO = new VSeg; 350 mapping_vobj_t* cur_vobj; 350 351 351 352 vSO->m_name = std::string(vseg->name); 352 vSO->m_vma = vseg->vbase;353 vSO->m_lma = ps->nextLma();353 vSO->m_vma = vseg->vbase; 354 vSO->m_lma = ps->nextLma(); 354 355 355 356 cur_vaddr = vseg->vbase; 356 357 cur_paddr = ps->nextLma(); 357 358 358 mapping_vobj_t* cur_vobj;359 359 size_t simple_size = 0; //for debug 360 360 361 361 #ifdef MOVER_DEBUG 362 std::cout << "--------------------vseg_map "<< vseg->name <<"---------------------" << std::endl; 363 #endif 364 365 for ( size_t vobj_id = vseg->vobj_offset ; vobj_id < (vseg->vobj_offset + vseg->vobjs) ; vobj_id++ ) 362 std::cout << "--------------- vseg_map "<< vseg->name <<" ------------------" << std::endl; 363 #endif 364 365 for ( size_t vobj_id = vseg->vobj_offset ; 366 vobj_id < (vseg->vobj_offset + vseg->vobjs) ; vobj_id++ ) 366 367 { 367 368 cur_vobj = &vobj[vobj_id]; 368 369 369 370 #ifdef MOVER_DEBUG 370 std::cout << std::hex << "current vobj("<< vobj_id <<"): " << cur_vobj->name << " (" <<cur_vobj->vaddr << ")" 371 << " size: "<< cur_vobj->length << " type: " << cur_vobj->type << std::endl; 371 std::cout << std::hex << "current vobj("<< vobj_id <<"): " << cur_vobj->name 372 << " (" <<cur_vobj->vaddr << ")" 373 << " size: "<< cur_vobj->length 374 << " type: " << cur_vobj->type << std::endl; 372 375 #endif 373 376 if(cur_vobj->type == VOBJ_TYPE_BLOB) … … 377 380 378 381 #ifdef MOVER_DEBUG 379 380 #endif 381 382 if(!filePath.compare(m_path)) // local blob: map_info382 std::cout << std::hex << "Handling: " << filePath << " ..." << std::endl; 383 #endif 384 385 if(!filePath.compare(m_path)) // local blob: map_info 383 386 { 384 387 #ifdef MOVER_DEBUG 385 388 std::cout << "Found the vseg of the mapping info" << std::endl; 386 389 #endif 387 390 blob_size = this->m_size; … … 391 394 { 392 395 #ifdef MOVER_DEBUG 393 396 std::cout << "Found an BLOB vseg" << std::endl; 394 397 #endif 395 398 blob_size = bin_size(filePath); 396 399 } 397 400 398 399 /**creating a new section */ 401 // creating a new section 400 402 sect = new elfpp::section(*m_generator, elfpp::SHT_PROGBITS); 401 403 402 404 sect->set_name(std::string(cur_vobj->name)); 403 405 sect->set_flags(elfpp::SHF_ALLOC | elfpp::SHF_WRITE); 404 sect->set_size(blob_size); //do the malloc for the get_content fonction406 sect->set_size(blob_size); //do the malloc for the get_content fonction 405 407 406 408 assert(sect->get_content());//check allocation … … 459 461 /** Initailising the header of the generator from the first binary, 460 462 ** we suppose that the header is the same for all the binarys **/ 461 m_generator->copy_info(*loader );463 m_generator->copy_info(*loader, 64); 462 464 m_ginit=true; 463 465 } … … 512 514 vSO->m_ident = vseg->ident; 513 515 514 //should we check that we have the same type for the pseg and vobj? 515 if(ps->type() != PSEG_TYPE_PERI)//take into acount only vseg who are not of the peri type 516 { 517 //set the lma 518 if ( vseg->ident != 0 ) // identity mapping required 519 ps->addIdent( *vSO ); 520 else 521 ps->add( *vSO ); 522 } 523 if(!sect) 524 return; 516 //set the lma for vseg that are not peripherals 517 if(ps->type() != PSEG_TYPE_PERI) 518 { 519 if ( vseg->ident != 0 ) ps->addIdent( *vSO ); 520 else ps->add( *vSO ); 521 } 522 523 // increment NextLma if required 524 if(ps->type() == PSEG_TYPE_RAM) 525 { 526 ps->incNextLma( vSO->m_length ); 527 } 528 529 if(!sect) return; 525 530 526 531 #ifdef MOVER_DEBUG … … 550 555 #endif 551 556 552 #ifdef DISTRIBUTED_SCHEDULERS553 char found;554 #endif555 556 557 for ( size_t cluster_id = 0 ; cluster_id < header->clusters ; cluster_id++ ) 557 558 { 558 559 #ifdef DISTRIBUTED_SCHEDULERS560 found = 0;561 #endif562 563 559 for ( size_t pseg_id = cluster[cluster_id].pseg_offset ; 564 560 pseg_id < cluster[cluster_id].pseg_offset + cluster[cluster_id].psegs ; 565 561 pseg_id++ ) 566 562 { 567 //build pseg568 563 std::string name(pseg[pseg_id].name); 569 PSeg *ps = new PSeg(name, pseg[pseg_id].base, pseg[pseg_id].length, pseg[pseg_id].type); 570 571 #ifdef DISTRIBUTED_SCHEDULERS 572 if ( (pseg[pseg_id].type == PSEG_TYPE_RAM) && (found == 0) ) 573 { 574 ps->incNextLma( (cluster[cluster_id].procs << 12) ); 575 found = 1; 576 } 577 if(!found){/* we could imagine a cluster without proc, let the giet choose*/ } 578 #endif 564 PSeg *ps = new PSeg( name, 565 pseg[pseg_id].base, 566 pseg[pseg_id].length, 567 pseg[pseg_id].type ); 579 568 m_psegh.m_pSegs.push_back(*ps); 580 581 569 } 582 570 } -
soft/giet_vm/memo/src/pseg.cpp
r227 r238 1 1 /* -*- c++ -*- 2 2 * 3 * SOCLIB_LGPL_HEADER_BEGIN3 * GIET_VM_LGPL_HEADER_BEGIN 4 4 * 5 5 * This file is part of SoCLib, GNU LGPLv2.1. … … 19 19 * 02110-1301 USA 20 20 * 21 * SOCLIB_LGPL_HEADER_END21 * GIET_VM_LGPL_HEADER_END 22 22 * 23 23 * Copyright (c) UPMC, Lip6, SoC … … 43 43 */ 44 44 45 ////////////////////////////////////// 45 46 const std::string & VSeg::name() const 46 47 { … … 48 49 } 49 50 51 ////////////////////////////////////// 50 52 const std::string & VSeg::file() const 51 53 { … … 53 55 } 54 56 57 /////////////////////////// 55 58 uintptr_t VSeg::vma() const 56 59 { … … 58 61 } 59 62 60 uintptr_t VSeg::lma() const 63 ///////////////////////// 64 paddr_t VSeg::lma() const 61 65 { 62 66 return m_lma; 63 67 } 64 68 69 /////////////////////////// 65 70 size_t VSeg::length() const 66 71 { … … 68 73 } 69 74 75 ///////////////////////// 70 76 size_t VSeg::type() const 71 77 { … … 73 79 } 74 80 81 ///////////////////////////////////////// 75 82 void VSeg::print( std::ostream &o ) const 76 83 { … … 79 86 << std::setw (8) << std::setfill('0') 80 87 << m_vma << ", to(paddr) 0x" 81 << std::setw ( 8) << std::setfill('0')88 << std::setw (16) << std::setfill('0') 82 89 << m_lma << ", size: 0x" 83 90 << std::setw (8) << std::setfill('0') … … 87 94 } 88 95 96 ///////////// 89 97 VSeg::~VSeg() 90 98 { 91 // std::cout << "Deleted VSeg " << *this << std::endl; 92 } 93 99 } 100 101 ///////////////////////////////////////// 94 102 VSeg & VSeg::operator=( const VSeg &ref ) 95 103 { … … 97 105 return *this; 98 106 99 //std::cout << "Copying " << ref << " to " << *this << std::endl;100 107 m_name = ref.m_name, 101 108 m_file = ref.m_file; … … 107 114 } 108 115 116 //////////// 109 117 VSeg::VSeg() 110 118 : m_name("No Name"), … … 115 123 m_ident(0) 116 124 { 117 //std::cout << "New empty VSeg " << *this << std::endl; 118 } 119 120 VSeg::VSeg(std::string& binaryName, std::string& name, uintptr_t vma, size_t length, bool loadable, bool ident) 125 } 126 127 //////////////////////////////////// 128 VSeg::VSeg(std::string& binaryName, 129 std::string& name, 130 uintptr_t vma, 131 size_t length, 132 bool loadable, 133 bool ident) 121 134 : m_name(name), 122 135 m_file(binaryName), … … 126 139 m_ident(ident) 127 140 { 128 //std::cout << "New VSeg " << *this << std::endl; 129 } 130 141 } 142 143 ///////////////////////////// 131 144 VSeg::VSeg( const VSeg &ref ) 132 145 : m_name("To be copied"), … … 137 150 m_ident(0) 138 151 { 139 //std::cout << "New VSeg " << *this << " copied from " << ref << std::endl;140 152 (*this) = ref; 141 153 } 142 143 144 154 145 155 … … 147 157 * PSeg 148 158 */ 149 uintptr_t PSeg::lma() const 159 160 ///////////////////////// 161 paddr_t PSeg::lma() const 150 162 { 151 163 return m_lma; 152 164 } 153 165 154 uintptr_t PSeg::limit() const 166 /////////////////////////// 167 paddr_t PSeg::limit() const 155 168 { 156 169 return m_limit; 157 170 } 158 171 159 size_t PSeg::length() const 172 ///////////////////////////// 173 paddr_t PSeg::length() const 160 174 { 161 175 return m_length; 162 176 } 163 177 178 ///////////////////////// 164 179 size_t PSeg::type() const 165 180 { … … 167 182 } 168 183 169 uintptr_t PSeg::nextLma() const 184 ///////////////////////////// 185 paddr_t PSeg::nextLma() const 170 186 { 171 187 return m_nextLma; 172 188 } 173 189 190 ////////////////////////////////////// 174 191 const std::string & PSeg::name() const 175 192 { … … 177 194 } 178 195 196 //////////////////////// initialisation used[][] ??? (AG) 179 197 void PSeg::check() const 180 198 { … … 184 202 185 203 std::vector<VSeg>::const_iterator it; 186 size_t size = m_vsegs.size();187 size_t used[size][2];//lma, lma+length188 size_t i,j,error=0;204 size_t size = m_vsegs.size(); 205 paddr_t used[size][2]; // lma, lma+length 206 size_t i,j,error=0; 189 207 190 for(it = m_vsegs.begin(), i= 0 ; it < m_vsegs.end(); it++, i++)208 for(it = m_vsegs.begin(), i= 0 ; it < m_vsegs.end() ; it++, i++) 191 209 { 192 size_t it_limit = (*it).lma() + (*it).length();210 paddr_t it_limit = (*it).lma() + (*it).length(); 193 211 for(j=0; j< i; j++) 194 212 { 195 if( (used[j][0] == (*it).lma() /*and (*it).length()?*/) ) //not the same lma ,213 if( used[j][0] == (*it).lma() ) //not the same lma , 196 214 { 197 215 error = 1; 198 216 std::cout << "ok \n"; 199 217 } 200 if( (used[j][1] == it_limit /*and (*it).legth()?*/)) // and not the same limit218 if( used[j][1] == it_limit ) // and not the same limit 201 219 { 202 220 error = 2; 203 221 } 204 if( ((used[j][0] < (*it).lma()) and ((*it).lma() < used[j][1] )) ) //lma within the used slice222 if( (used[j][0] < (*it).lma()) and ((*it).lma() < used[j][1]) ) // lma within 205 223 { 206 224 error = 3; 207 225 } 208 if( ((used[j][0] < it_limit) and (it_limit < used[j][1] )) )//limit not within the used slice226 if( ((used[j][0] < it_limit) and (it_limit < used[j][1] )) ) // limit no within 209 227 { 210 228 error = 4; … … 228 246 } 229 247 248 ////////////////////////////////////// 230 249 void PSeg::setName(std::string& name ) 231 250 { … … 233 252 } 234 253 235 size_t PSeg::align( unsigned toAlign, unsigned alignPow2) 236 { 237 return ((toAlign + (1 << alignPow2) - 1 ) >> alignPow2) << alignPow2;//page aligned 238 } 239 240 241 size_t PSeg::pageAlign( size_t toAlign ) 254 ///////////////////////////////////////////////////////// 255 paddr_t PSeg::align( paddr_t toAlign, unsigned alignPow2) 256 { 257 return ((toAlign + (1 << alignPow2) - 1 ) >> alignPow2) << alignPow2; 258 } 259 260 ////////////////////////////////////////// 261 paddr_t PSeg::pageAlign( paddr_t toAlign ) 242 262 { 243 263 size_t pgs = pageSize(); 244 264 size_t pageSizePow2 = __builtin_ctz(pgs); 245 265 246 return align(toAlign, pageSizePow2); //page aligned247 248 } 249 250 void PSeg::setLma( uintptr_t lma )266 return align(toAlign, pageSizePow2); 267 } 268 269 //////////////////////////////// 270 void PSeg::setLma( paddr_t lma ) 251 271 { 252 272 m_lma = lma; 253 273 254 m_nextLma = pageAlign(lma); //page aligned274 m_nextLma = pageAlign(lma); 255 275 256 276 m_pageLimit = pageAlign(m_lma+m_length); 257 277 258 278 m_limit = (m_lma + m_length); 259 260 } 261 262 void PSeg::setLength( size_t length )279 } 280 281 ///////////////////////////////////// 282 void PSeg::setLength( paddr_t length ) 263 283 { 264 284 m_length = length; … … 267 287 268 288 m_limit = (m_lma + m_length); 269 270 //std::cout << std::hex << " length seted, m_limit: " << m_limit << std::endl; 271 //std::cout << *this <<std::endl; 272 } 273 289 } 290 291 //////////////////////////// 274 292 void PSeg::add( VSeg& vseg ) 275 293 { 276 294 vseg.m_lma = m_nextLma; 277 incNextLma(vseg.length());//for the next vseg295 // incNextLma(vseg.length()); //for the next vseg 278 296 m_vsegs.push_back(vseg); 279 297 } 280 298 299 ///////////////////////////////// 281 300 void PSeg::addIdent( VSeg& vseg ) 282 301 { 283 302 vseg.m_lma = vseg.m_vma; 284 //incNextLma(vseg.length());//to keep track of space used285 303 m_vsegs.push_back(vseg); 286 304 } 287 305 288 void PSeg::setNextLma( uintptr_t nextLma) 306 ///////////////////////////////////////// 307 void PSeg::setNextLma( paddr_t nextLma) 289 308 { 290 309 m_nextLma = nextLma; 291 292 310 confNextLma(); 293 311 } 294 312 295 void PSeg::incNextLma( size_t inc_next) 296 { 297 298 m_nextLma += inc_next; 299 313 ////////////////////////////////// 314 void PSeg::incNextLma( size_t inc) 315 { 316 m_nextLma += inc; 300 317 confNextLma(); 301 318 } 302 319 320 //////////////////////// 303 321 void PSeg::confNextLma() 304 322 { … … 322 340 } 323 341 342 ///////////////////////////////// 324 343 void PSeg::setPageSize(size_t pg) 325 344 { … … 332 351 } 333 352 353 //////////////////////// 334 354 size_t& PSeg::pageSize() 335 355 { … … 338 358 } 339 359 360 ///////////////////////////////////////// 340 361 PSeg & PSeg::operator=( const PSeg &ref ) 341 362 { 342 363 if ( &ref == this ) 343 364 return *this; 344 345 //std::cout << "Copying " << ref << " to " << *this << std::endl;346 365 347 366 m_name = ref.m_name; … … 357 376 } 358 377 378 ////////////////////////////////////////// 359 379 void PSeg::print( std::ostream &o ) const 360 380 { … … 374 394 } 375 395 396 //////////////////////////////////// 376 397 PSeg::PSeg( const std::string &name, 377 uintptr_tlma,378 size_tlength,379 size_ttype)398 paddr_t lma, 399 paddr_t length, 400 size_t type) 380 401 { 381 402 m_name = name; … … 384 405 385 406 setLma(lma); 386 //std::cout <<"New PSeg :"<< *this ; 387 } 388 407 } 408 409 //////////////////////////////////// 389 410 PSeg::PSeg( const std::string &name): 390 411 m_lma(0), … … 396 417 } 397 418 398 PSeg::PSeg( uintptr_t lma): 419 //////////////////////// 420 PSeg::PSeg( paddr_t lma): 399 421 m_name("No name"), 400 422 m_lma(0), … … 406 428 } 407 429 408 430 //////////// 409 431 PSeg::PSeg() 410 432 : … … 415 437 m_limit(0) 416 438 { 417 //std::cout << "New empty PSeg " << *this << std::endl; 418 } 419 439 } 440 441 ///////////////////////////// 420 442 PSeg::PSeg( const PSeg &ref ) 421 443 : m_name("To be copied"), … … 425 447 m_limit(0) 426 448 { 427 //std::cout << "New PSeg " << *this << " copied from " << ref << std::endl;428 449 (*this) = ref; 429 450 } … … 431 452 PSeg::~PSeg() 432 453 { 433 // std::cout << "Deleted PSeg " << *this << std::endl;434 454 } 435 455 -
soft/giet_vm/memo/src/pseg_handler.cpp
r163 r238 1 1 /* -*- c++ -*- 2 2 * 3 * SOCLIB_LGPL_HEADER_BEGIN3 * GIET_VM_LGPL_HEADER_BEGIN 4 4 * 5 * This file is part of SoCLib, GNU LGPLv2.1.5 * This file is part of GIET_VM, GNU LGPLv2.1. 6 6 * 7 * SoCLibis free software; you can redistribute it and/or modify it7 * GIET_VM is free software; you can redistribute it and/or modify it 8 8 * under the terms of the GNU Lesser General Public License as published 9 9 * by the Free Software Foundation; version 2.1 of the License. 10 10 * 11 * SoCLibis distributed in the hope that it will be useful, but11 * GIET_VM is distributed in the hope that it will be useful, but 12 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU … … 15 15 * 16 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with SoCLib; if not, write to the Free Software17 * License along with GIET_VM; if not, write to the Free Software 18 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19 19 * 02110-1301 USA 20 20 * 21 * SOCLIB_LGPL_HEADER_END21 * GIET_VM_LGPL_HEADER_END 22 22 * 23 23 * Copyright (c) UPMC, Lip6, SoC … … 37 37 #include "exception.h" 38 38 39 40 41 39 /* 42 40 * PSegHandler 43 41 */ 44 42 43 ///////////////////////////////////// 45 44 PSeg& PSegHandler::get( size_t pos ) 46 45 { … … 55 54 } 56 55 56 ////////////////////////////////////////////////////////////// 57 57 const PSeg& PSegHandler::getByAddr(uintptr_t segAddress) const 58 58 { … … 60 60 for(it = m_pSegs.begin(); it < m_pSegs.end(); it++) 61 61 { 62 uintptr_t lma = (*it).lma();62 paddr_t lma = (*it).lma(); 63 63 if( lma == segAddress ) 64 64 return *it; … … 71 71 } 72 72 73 /////////////////////////////// 73 74 void PSegHandler::check() const 74 75 { -
soft/giet_vm/sys/common.c
r232 r238 20 20 /////////////////////////////////////////////////////////////////////////////////// 21 21 22 // current context cache TODO23 24 22 // SR save (used by _it_mask() / it_restore() 25 23 unsigned int _status_register_save[NB_CLUSTERS*NB_PROCS_MAX]; … … 27 25 /////////////////////////////////////////////////////////////////////////////////// 28 26 // _get_sched() 29 // Access CP0 and returns scheduler physical address. 30 /////////////////////////////////////////////////////////////////////////////////// 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 27 // Access CP0 and returns a pointer (virtual address) on the calling 28 // processor scheduler (taking into account the processor local index). 29 /////////////////////////////////////////////////////////////////////////////////// 30 static_scheduler_t* _get_sched() 31 { 32 static_scheduler_t* psched; 33 unsigned int vaddr; 34 unsigned int lpid = _procid() % NB_PROCS_MAX; 35 36 asm volatile( 37 "mfc0 %0, $22 \n" 38 : "=r"(vaddr) ); 39 40 psched = (static_scheduler_t*)vaddr; 41 return (psched + lpid); 42 } 39 43 40 44 /////////////////////////////////////////////////////////////////////////////////// … … 42 46 // Access CP2 and returns PTPR register. 43 47 /////////////////////////////////////////////////////////////////////////////////// 44 inline unsigned int _get_ptpr() { 48 inline unsigned int _get_ptpr() 49 { 45 50 unsigned int ret; 46 51 asm volatile( … … 50 55 } 51 56 52 53 57 /////////////////////////////////////////////////////////////////////////////////// 54 58 // _get_epc() 55 59 // Access CP0 and returns EPC register. 56 60 /////////////////////////////////////////////////////////////////////////////////// 57 inline unsigned int _get_epc() { 61 inline unsigned int _get_epc() 62 { 58 63 unsigned int ret; 59 64 asm volatile("mfc0 %0, $14" … … 62 67 } 63 68 64 65 69 /////////////////////////////////////////////////////////////////////////////////// 66 70 // _get_bar() 67 71 // Access CP0 and returns BAR register. 68 72 /////////////////////////////////////////////////////////////////////////////////// 69 inline unsigned int _get_bvar() { 73 inline unsigned int _get_bvar() 74 { 70 75 unsigned int ret; 71 76 asm volatile( … … 75 80 } 76 81 77 78 82 /////////////////////////////////////////////////////////////////////////////////// 79 83 // _get_cr() 80 84 // Access CP0 and returns CR register. 81 85 /////////////////////////////////////////////////////////////////////////////////// 82 inline unsigned int _get_cause() { 86 inline unsigned int _get_cause() 87 { 83 88 unsigned int ret; 84 89 asm volatile("mfc0 %0, $13" … … 87 92 } 88 93 89 90 94 /////////////////////////////////////////////////////////////////////////////////// 91 95 // _get_sr() 92 96 // Access CP0 and returns SR register. 93 97 /////////////////////////////////////////////////////////////////////////////////// 94 inline unsigned int _get_sr() { 98 inline unsigned int _get_sr() 99 { 95 100 unsigned int ret; 96 101 asm volatile( … … 106 111 // This function is NOT USED and NOT TESTED 107 112 /////////////////////////////////////////////////////////////////////////////////// 108 inline void _it_mask() { 113 inline void _it_mask() 114 { 109 115 unsigned int sr_value; 110 116 unsigned int proc_id; … … 121 127 } 122 128 123 124 129 /////////////////////////////////////////////////////////////////////////////////// 125 130 // _it_restore() … … 128 133 // This function is NOT USED and NOT TESTED 129 134 /////////////////////////////////////////////////////////////////////////////////// 130 inline void _it_restore() { 135 inline void _it_restore() 136 { 131 137 unsigned int proc_id; 132 138 // get the processor id to index the _status_register_save table … … 140 146 // Access CP0 and disables IRQs 141 147 /////////////////////////////////////////////////////////////////////////////////// 142 inline void _it_disable() { 148 inline void _it_disable() 149 { 143 150 asm volatile( 144 151 "li $3, 0xFFFFFFFE \n" … … 153 160 // Access CP0 and enables IRQs 154 161 /////////////////////////////////////////////////////////////////////////////////// 155 inline void _it_enable() { 162 inline void _it_enable() 163 { 156 164 asm volatile( 157 165 "li $3, 0x00000001 \n" … … 162 170 } 163 171 164 165 172 //////////////////////////////////////////////////////////////////////////// 166 173 // _get_lock() … … 169 176 // (delay average value = 100 cycles) 170 177 //////////////////////////////////////////////////////////////////////////// 171 inline void _get_lock(unsigned int * plock) { 178 inline void _get_lock(unsigned int * plock) 179 { 172 180 register unsigned int delay = ( _proctime() ^ _procid() << 4) & 0xFF; 173 181 … … 191 199 } 192 200 193 194 201 //////////////////////////////////////////////////////////////////////////// 195 202 // _release_lock() 196 203 //////////////////////////////////////////////////////////////////////////// 197 inline void _release_lock(unsigned int * plock) { 204 inline void _release_lock(unsigned int * plock) 205 { 198 206 asm volatile ( 199 207 "sync\n" /* necessary because of the consistency model in tsar */ … … 202 210 } 203 211 204 205 212 //////////////////////////////////////////////////////////////////////////// 206 213 // _puts() 207 214 // display a string on TTY0 / used for system code debug and log 208 215 //////////////////////////////////////////////////////////////////////////// 209 void _puts(char * buffer) { 216 void _puts(char * buffer) 217 { 210 218 unsigned int * tty_address = (unsigned int *) &seg_tty_base; 211 219 unsigned int n; 212 220 213 for (n = 0; n < 100; n++) { 214 if (buffer[n] == 0) { 215 break; 216 } 221 for (n = 0; n < 100; n++) 222 { 223 if (buffer[n] == 0) break; 217 224 tty_address[TTY_WRITE] = (unsigned int) buffer[n]; 218 225 } 219 226 } 220 227 221 222 228 //////////////////////////////////////////////////////////////////////////// 223 229 // _putx() 224 // display an int (hexa) on TTY0 / used for system code debug and log 225 //////////////////////////////////////////////////////////////////////////// 226 void _putx(unsigned int val) { 230 // display a 32 bits unsigned int as an hexadecimal string on TTY0 231 //////////////////////////////////////////////////////////////////////////// 232 void _putx(unsigned int val) 233 { 227 234 static const char HexaTab[] = "0123456789ABCDEF"; 228 235 char buf[11]; … … 233 240 buf[10] = 0; 234 241 235 for (c = 0; c < 8; c++) { 242 for (c = 0; c < 8; c++) 243 { 236 244 buf[9 - c] = HexaTab[val & 0xF]; 237 245 val = val >> 4; … … 240 248 } 241 249 250 //////////////////////////////////////////////////////////////////////////// 251 // _putl() 252 // display a 64 bits unsigned long as an hexadecimal string on TTY0 253 //////////////////////////////////////////////////////////////////////////// 254 void _putl(paddr_t val) 255 { 256 static const char HexaTab[] = "0123456789ABCDEF"; 257 char buf[19]; 258 unsigned int c; 259 260 buf[0] = '0'; 261 buf[1] = 'x'; 262 buf[18] = 0; 263 264 for (c = 0; c < 16; c++) 265 { 266 buf[17 - c] = HexaTab[(unsigned int)val & 0xF]; 267 val = val >> 4; 268 } 269 _puts(buf); 270 } 242 271 243 272 //////////////////////////////////////////////////////////////////////////// … … 266 295 } 267 296 268 269 297 //////////////////////////////////////////////////////////////////////////// 270 298 // _strncmp() … … 284 312 } 285 313 286 287 314 //////////////////////////////////////////////////////////////////////////// 288 315 // _dcache_buf_invalidate() … … 310 337 } 311 338 312 313 //////////////////////////////////////////////////////////////////////////// 314 // _physical_read_access() 315 // This function makes a physical read access to a 32 bits word in memory, 316 // after a temporary DTLB desactivation. 317 //////////////////////////////////////////////////////////////////////////// 318 unsigned int _physical_read_access(unsigned int * paddr) { 319 unsigned int value; 320 321 asm volatile( 322 "li $3, 0xFFFFFFFE \n" 323 "mfc0 $2, $12 \n" /* $2 <= SR */ 324 "and $3, $3, $2 \n" 325 "mtc0 $3, $12 \n" /* interrupt masked */ 326 "li $3, 0xB \n" 327 "mtc2 $3, $1 \n" /* DTLB off */ 328 329 "lw %0, 0(%1) \n" /* entry <= *pslot */ 330 331 "li $3, 0xF \n" 332 "mtc2 $3, $1 \n" /* DTLB on */ 333 "mtc0 $2, $12 \n" /* restore SR */ 334 : "=r" (value) 335 : "r" (paddr) 336 : "$2", "$3"); 337 return value; 338 } 339 340 341 //////////////////////////////////////////////////////////////////////////// 342 // _physical_write_access() 343 // This function makes a physical write access to a 32 bits word in memory, 344 // after a temporary DTLB desactivation. 345 //////////////////////////////////////////////////////////////////////////// 346 void _physical_write_access(unsigned int * paddr, unsigned int value) { 347 asm volatile( 348 "li $3, 0xFFFFFFFE \n" 349 "mfc0 $2, $12 \n" /* $26 <= SR */ 350 "and $3, $3, $2 \n" 351 "mtc0 $3, $12 \n" /* interrupt masked */ 352 "li $3, 0xB \n" 353 "mtc2 $3, $1 \n" /* DTLB off */ 354 355 "sw %0, 0(%1) \n" /* entry <= *pslot */ 356 357 "li $3, 0xF \n" 358 "mtc2 $3, $1 \n" /* DTLB on */ 359 "mtc0 $2, $12 \n" /* restore SR */ 360 : 361 : "r" (value), "r" (paddr) 362 : "$2", "$3"); 363 } 364 365 366 //////////////////////////////////////////////////////////////////////////// 367 // _get_tasks_number() 368 // This function returns the number of tasks allocated to processor. 369 //////////////////////////////////////////////////////////////////////////// 370 unsigned int _get_tasks_number() { 371 static_scheduler_t * psched = (static_scheduler_t *) _get_sched(); 372 return _physical_read_access(&(psched->tasks)); 373 } 374 375 376 //////////////////////////////////////////////////////////////////////////// 377 // _get_proc_task_id() 378 // This function returns the index of the currently running task. 379 //////////////////////////////////////////////////////////////////////////// 380 unsigned int _get_proc_task_id() { 381 static_scheduler_t * psched = (static_scheduler_t *) _get_sched(); 382 return _physical_read_access(&(psched->current)); 383 } 384 385 386 //////////////////////////////////////////////////////////////////////////// 387 // _set_proc_task_id() 388 // This function returns the index of the currently running task. 389 //////////////////////////////////////////////////////////////////////////// 390 void _set_proc_task_id(unsigned int value) { 391 static_scheduler_t * psched = (static_scheduler_t *) _get_sched(); 392 _physical_write_access(&(psched->current), value); 393 } 394 395 396 //////////////////////////////////////////////////////////////////////////// 397 // _get_global_task_id() 398 // This function returns the global index of the running task. 399 //////////////////////////////////////////////////////////////////////////// 400 unsigned int _get_global_task_id() { 401 return _get_context_slot(_get_proc_task_id(), CTX_GTID_ID); 402 } 403 404 405 /////////////////////////////////////////////////////////////////////////////// 406 // _get_context_slot() 407 // This function returns a slot content for the task defined by task_id. 408 /////////////////////////////////////////////////////////////////////////////// 409 unsigned int _get_context_slot(unsigned int task_id, unsigned int slot_id) { 410 static_scheduler_t * psched = (static_scheduler_t *) _get_sched(); 411 return _physical_read_access(&(psched->context[task_id][slot_id])); 412 } 413 414 415 /////////////////////////////////////////////////////////////////////////////// 416 // _set_context_slot() 417 // This function returns a slot content for the task defined by task_id. 418 /////////////////////////////////////////////////////////////////////////////// 419 void _set_context_slot( unsigned int task_id, 420 unsigned int slot_id, 421 unsigned int value) { 422 static_scheduler_t * psched = (static_scheduler_t *) _get_sched(); 423 _physical_write_access(&(psched->context[task_id][slot_id]), value); 424 } 425 426 427 //////////////////////////////////////////////////////////////////////////////// 428 // _get_interrupt_vector_entry() 429 // This function returns the interrupt_vector entry defined by argument index. 430 //////////////////////////////////////////////////////////////////////////////// 431 unsigned int _get_interrupt_vector_entry(unsigned int index) { 432 static_scheduler_t * psched = (static_scheduler_t *) _get_sched(); 433 return _physical_read_access( &(psched->interrupt_vector[index])); 434 } 435 339 ///////////////////////////////////////////////////////////////////////////// 340 // _get_task_slot() 341 // This function returns the content of a context slot 342 // for the task identified by the ltid argument (local index). 343 ///////////////////////////////////////////////////////////////////////////// 344 unsigned int _get_task_slot( unsigned int ltid, 345 unsigned int slot ) 346 { 347 static_scheduler_t* psched = _get_sched(); 348 return psched->context[ltid][slot]; 349 } 350 351 ///////////////////////////////////////////////////////////////////////////// 352 // _set_task_slot() 353 // This function updates the content of a context slot 354 // for the task identified by the ltid argument (local index). 355 ///////////////////////////////////////////////////////////////////////////// 356 void _set_task_slot( unsigned int ltid, 357 unsigned int slot, 358 unsigned int value ) 359 { 360 static_scheduler_t* psched = _get_sched(); 361 psched->context[ltid][slot] = value; 362 } 363 364 ///////////////////////////////////////////////////////////////////////////// 365 // _get_context_slot() 366 // This function returns the content of a context slot 367 // for the running task (defined by the scheduler current field). 368 ///////////////////////////////////////////////////////////////////////////// 369 unsigned int _get_context_slot( unsigned int slot ) 370 { 371 static_scheduler_t* psched = _get_sched(); 372 unsigned int task_id = psched->current; 373 return psched->context[task_id][slot]; 374 } 375 376 ///////////////////////////////////////////////////////////////////////////// 377 // _set_context_slot() 378 // This function updates the content of a context slot for the running task. 379 ///////////////////////////////////////////////////////////////////////////// 380 void _set_context_slot( unsigned int slot, 381 unsigned int value ) 382 { 383 static_scheduler_t* psched = _get_sched(); 384 unsigned int task_id = psched->current; 385 psched->context[task_id][slot] = value; 386 } 436 387 437 388 ///////////////////////////////////////////////////////////////////////////// 438 389 // access functions to mapping_info data structure 439 390 ///////////////////////////////////////////////////////////////////////////// 440 mapping_cluster_t * _get_cluster_base(mapping_header_t * header) { 391 mapping_cluster_t * _get_cluster_base(mapping_header_t * header) 392 { 441 393 return (mapping_cluster_t *) ((char *) header + 442 394 MAPPING_HEADER_SIZE); 443 395 } 444 445 446 ///////////////////////////////////////////////////////////////////////////// 447 mapping_pseg_t * _get_pseg_base(mapping_header_t * header) { 396 ///////////////////////////////////////////////////////////////////////////// 397 mapping_pseg_t * _get_pseg_base(mapping_header_t * header) 398 { 448 399 return (mapping_pseg_t *) ((char *) header + 449 400 MAPPING_HEADER_SIZE + … … 451 402 } 452 403 ///////////////////////////////////////////////////////////////////////////// 453 mapping_vspace_t * _get_vspace_base(mapping_header_t * header) { 404 mapping_vspace_t * _get_vspace_base(mapping_header_t * header) 405 { 454 406 return (mapping_vspace_t *) ((char *) header + 455 407 MAPPING_HEADER_SIZE + … … 471 423 472 424 ///////////////////////////////////////////////////////////////////////////// 473 mapping_vobj_t * _get_vobj_base(mapping_header_t * header) { 425 mapping_vobj_t * _get_vobj_base(mapping_header_t * header) 426 { 474 427 return (mapping_vobj_t *) ((char *) header + 475 428 MAPPING_HEADER_SIZE + … … 482 435 483 436 ///////////////////////////////////////////////////////////////////////////// 484 mapping_task_t * _get_task_base(mapping_header_t * header) { 437 mapping_task_t * _get_task_base(mapping_header_t * header) 438 { 485 439 return (mapping_task_t *) ((char *) header + 486 440 MAPPING_HEADER_SIZE + -
soft/giet_vm/sys/common.h
r232 r238 11 11 #include <mapping_info.h> 12 12 #include <giet_config.h> 13 #include <ctx_handler.h> 13 14 14 15 /////////////////////////////////////////////////////////////////////////////////// … … 34 35 /////////////////////////////////////////////////////////////////////////////////// 35 36 36 void _puts(char *string); 37 void _putx(unsigned int val); 38 void _putd(unsigned int val); 37 void _puts(char *string); 38 void _putx(unsigned int val); 39 void _putd(unsigned int val); 40 void _putl(paddr_t val); 39 41 40 unsigned int _strncmp(const char * s1, const char * s2, unsigned int n); 41 void _dcache_buf_invalidate(const void * buffer, unsigned int size); 42 unsigned int _strncmp(const char * s1, 43 const char * s2, 44 unsigned int n); 42 45 43 void _dtlb_off(void);44 void _dtlb_on(void);46 void _dcache_buf_invalidate(const void * buffer, 47 unsigned int size); 45 48 46 void _it_mask(void); 47 void _it_restore(void); 48 void _it_disable(void); 49 void _it_enable(void); 49 void _dtlb_off(void); 50 void _dtlb_on(void); 50 51 51 unsigned int _get_epc(void); 52 unsigned int _get_ptpr(void); 53 unsigned int _get_bvar(void); 54 unsigned int _get_cr(void); 55 unsigned int _get_sched(void); 52 void _it_mask(void); 53 void _it_restore(void); 54 void _it_disable(void); 55 void _it_enable(void); 56 56 57 unsigned int _get_context_slot(unsigned int task_id, unsigned int slot_id); 58 void _set_context_slot(unsigned int task_id, unsigned int slot_id, unsigned int value); 57 unsigned int _get_epc(void); 58 unsigned int _get_ptpr(void); 59 unsigned int _get_bvar(void); 60 unsigned int _get_cr(void); 59 61 60 unsigned int _get_interrupt_vector_entry(unsigned int index);62 static_scheduler_t* _get_sched(void); 61 63 62 unsigned int _get_proc_task_id(void); 63 void _set_proc_task_id(unsigned int value); 64 unsigned int _get_context_slot( unsigned int slot ); 64 65 65 unsigned int _get_global_task_id(void); 66 void _set_context_slot( unsigned int slot, 67 unsigned int value ); 66 68 69 unsigned int _get_task_slot( unsigned int ltid, 70 unsigned int slot ); 67 71 68 unsigned int _get_tasks_number(void); 72 void _set_task_slot( unsigned int ltid, 73 unsigned int slot, 74 unsigned int value ); 69 75 70 void _get_lock(unsigned int * lock);71 void _release_lock(unsigned int * lock);76 void _get_lock(unsigned int * lock); 77 void _release_lock(unsigned int * lock); 72 78 73 mapping_cluster_t * _get_cluster_base(mapping_header_t* header);74 mapping_pseg_t * _get_pseg_base(mapping_header_t* header);75 mapping_vspace_t * _get_vspace_base(mapping_header_t* header);76 mapping_vseg_t * _get_vseg_base(mapping_header_t* header);77 mapping_vobj_t * _get_vobj_base(mapping_header_t* header);78 mapping_task_t * _get_task_base(mapping_header_t* header);79 mapping_cluster_t * _get_cluster_base(mapping_header_t* header); 80 mapping_pseg_t * _get_pseg_base(mapping_header_t* header); 81 mapping_vspace_t * _get_vspace_base(mapping_header_t* header); 82 mapping_vseg_t * _get_vseg_base(mapping_header_t* header); 83 mapping_vobj_t * _get_vobj_base(mapping_header_t* header); 84 mapping_task_t * _get_task_base(mapping_header_t* header); 79 85 80 86 -
soft/giet_vm/sys/ctx_handler.c
r232 r238 25 25 // A task context is an array of 64 words = 256 bytes. 26 26 // It contains copies of processor registers (when the task is preempted): 27 // - GPR[i], generally stored in slot (i). $0, *26 & $27 are not saved.27 // - GPR[i], generally stored in slot (i). $0, $26 & $27 are not saved. 28 28 // - HI & LO registers 29 29 // - CP0 registers: EPC, SR, CR, BVAR 30 30 // - CP2 registers : PTPR 31 31 // It contains some general informations associated to the task: 32 // - TTY : terminal global index 33 // - FBDMA : DMA channel global index 32 // - TTY : TTY channel global index 34 33 // - NIC : NIC channel global index 35 // - TIMER : Timer global index 34 // - CMA : CMA channel global index 35 // - IOC : IOC channel global index 36 // - DMA : DMA channel local index 37 // - TIM : TIM channel local index 36 38 // - PTAB : page table virtual base address 37 // - LTID 39 // - LTID : Task local index (in scheduler) 38 40 // - VSID : Virtual space index 39 41 // - RUN : Task state (0 => sleeping / 1 => runable ) … … 42 44 // ctx[1]<- $1 |ctx[9] <- $9 |ctx[17]<- $17|ctx[25]<- $25|ctx[33]<- CR |ctx[41]<- DMA 43 45 // ctx[2]<- $2 |ctx[10]<- $10|ctx[18]<- $18|ctx[26]<- LO |ctx[34]<- SR |ctx[42]<- NIC 44 // ctx[3]<- $3 |ctx[11]<- $11|ctx[19]<- $19|ctx[27]<- HI |ctx[35]<- BVAR |ctx[43]<- TIM ER45 // ctx[4]<- $4 |ctx[12]<- $12|ctx[20]<- $20|ctx[28]<- $28|ctx[36]<- *** |ctx[44]<- PTAB46 // ctx[5]<- $5 |ctx[13]<- $13|ctx[21]<- $21|ctx[29]<- SP |ctx[37]<- *** |ctx[45]<- LTID47 // ctx[6]<- $6 |ctx[14]<- $14|ctx[22]<- $22|ctx[30]<- $30|ctx[38]<- *** |ctx[46]<- VSID46 // ctx[3]<- $3 |ctx[11]<- $11|ctx[19]<- $19|ctx[27]<- HI |ctx[35]<- BVAR |ctx[43]<- TIM 47 // ctx[4]<- $4 |ctx[12]<- $12|ctx[20]<- $20|ctx[28]<- $28|ctx[36]<- PTAB |ctx[44]<- IOC 48 // ctx[5]<- $5 |ctx[13]<- $13|ctx[21]<- $21|ctx[29]<- SP |ctx[37]<- LTID |ctx[45]<- CMA 49 // ctx[6]<- $6 |ctx[14]<- $14|ctx[22]<- $22|ctx[30]<- $30|ctx[38]<- VSID |ctx[46]<- GTID 48 50 // ctx[7]<- $7 |ctx[15]<- $15|ctx[23]<- $23|ctx[31]<- RA |ctx[39]<- PTPR |ctx[47]<- RUN 49 51 ////////////////////////////////////////////////////////////////////////////////////////// … … 60 62 // If there is no runable task, the scheduler switch to the default "idle" task. 61 63 // 62 // Implementation notes: 63 // - As we only have the scheduler physical address (in CP0_SCHED register), 64 // this function must use specific assess functions to access the scheduler. 65 // - All the context switch procedure is executed with interrupts masked. 66 // - The return address contained in $31 is saved in the current task context 67 // (in the ctx[31] slot), and the function actually returns to the address 68 // contained in the ctx[31] slot of the next task context. 64 // Implementation note 65 // The return address contained in $31 is saved in the current task context 66 // (in the ctx[31] slot), and the function actually returns to the address 67 // contained in the ctx[31] slot of the next task context. 69 68 ///////////////////////////////////////////////////////////////////////////////// 70 void _ctx_switch() { 71 // get scheduler physical address 72 static_scheduler_t * psched = (static_scheduler_t *) _get_sched(); 69 void _ctx_switch() 70 { 71 // get scheduler address 72 static_scheduler_t* psched = _get_sched(); 73 73 74 74 // get number of tasks allocated to scheduler 75 unsigned int tasks = _get_tasks_number();75 unsigned int tasks = psched->tasks; 76 76 77 77 // get current task index 78 unsigned int curr_task_id = _get_proc_task_id();78 unsigned int curr_task_id = psched->current; 79 79 80 80 // select the next task using a round-robin policy … … 83 83 unsigned int found = 0; 84 84 85 for (tid = curr_task_id + 1; tid < curr_task_id + 1 + tasks; tid++) { 85 for (tid = curr_task_id + 1; tid < curr_task_id + 1 + tasks; tid++) 86 { 86 87 next_task_id = tid % tasks; 87 88 88 // test if the task is runable 89 if (_get_context_slot(next_task_id, CTX_RUN_ID)) { 89 if ( psched->context[next_task_id][CTX_RUN_ID] ) 90 { 90 91 found = 1; 91 92 break; … … 94 95 95 96 // launch "idle" task if no runable task 96 if (found == 0) { 97 if (found == 0) 98 { 97 99 next_task_id = IDLE_TASK_INDEX; 98 100 } 99 101 100 102 // no switch if no change 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]); 103 if (curr_task_id != next_task_id) 104 { 105 unsigned int* curr_ctx_vaddr = &(psched->context[curr_task_id][0]); 106 unsigned int* next_ctx_vaddr = &(psched->context[next_task_id][0]); 104 107 105 _set_proc_task_id(next_task_id); 106 //_timer_reset_irq_cpt(cluster_id, local_id); // commented until not properly supported in soclib 108 // set current task index 109 psched->current = next_task_id; 110 111 //_timer_reset_irq_cpt(cluster_id, local_id); 112 // commented until not properly supported in soclib 107 113 // (the function is not yet present in drivers.c) 108 _task_switch(curr_ctx_paddr, next_ctx_paddr); 114 115 _task_switch(curr_ctx_vaddr, next_ctx_vaddr); 109 116 110 117 #if GIET_DEBUG_SWITCH 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 118 _get_lock(&_tty_put_lock); 119 _puts("\n[GIET DEBUG] Context switch for processor "); 120 _putd(_procid()); 121 _puts(" at cycle "); 122 _putd(_proctime()); 123 _puts("\n"); 124 _puts(" - tasks = "); 125 _putd(tasks); 126 _puts("\n"); 127 _puts(" - curr_task_id = "); 128 _putd( curr_task_id ); 129 _puts("\n"); 130 _puts(" - next_task_id = "); 131 _putd(next_task_id); 132 _puts("\n"); 133 _release_lock( &_tty_put_lock); 127 134 #endif 128 135 … … 133 140 // This function is executed as the"idle" task when no other task can be executed 134 141 ///////////////////////////////////////////////////////////////////////////////////// 135 void _ctx_idle() { 142 void _ctx_idle() 143 { 136 144 unsigned int delay = 1000000; 137 145 … … 164 172 // in the "idle" task context. 165 173 ///////////////////////////////////////////////////////////////////////////////// 166 void _ctx_eret() { 174 void _ctx_eret() 175 { 167 176 asm volatile("eret"); 168 177 } -
soft/giet_vm/sys/ctx_handler.h
r232 r238 8 8 ///////////////////////////////////////////////////////////////////////////////// 9 9 10 typedef struct static_scheduler_s { 10 typedef struct static_scheduler_s 11 { 11 12 unsigned int context[15][64]; // at most 15 task contexts 12 13 unsigned int tasks; // actual number of tasks … … 29 30 #define CTX_RA_ID 31 30 31 31 #define CTX_EPC_ID 32 32 #define CTX_CR_ID 33 33 #define CTX_SR_ID 34 34 #define CTX_BVAR_ID 35 32 #define CTX_EPC_ID 32 // Exception Program Counter (CP0) 33 #define CTX_CR_ID 33 // Cause Register (CP0) 34 #define CTX_SR_ID 34 // Status Register (CP0) 35 #define CTX_BVAR_ID 35 // Bad Virtual Address Register (CP0) 35 36 36 #define CTX_PTPR_ID 39 37 #define CTX_PTAB_ID 36 // Page Table Virtual address 38 #define CTX_LTID_ID 37 // Local Task Index (in scheduler) 39 #define CTX_VSID_ID 38 // Vspace Index 40 #define CTX_PTPR_ID 39 // Page Table Pointer Register (PADDR>>13) 37 41 38 #define CTX_TTY_ID 40 // Integer : global TTY terminal index 39 #define CTX_DMA_ID 41 // Integer : global DMA channel index 40 #define CTX_NIC_ID 42 // Integer : global NIC channel index 41 #define CTX_TIMER_ID 43 // Integer : user level timer index / UNUSED 42 #define CTX_PTAB_ID 44 // Pointer : page table virtual base adress 43 #define CTX_LTID_ID 45 // Integer : local task index (in scheduler) / UNUSED 44 #define CTX_VSID_ID 46 // Integer : vspace index 45 #define CTX_RUN_ID 47 // Boolean : task runable 46 #define CTX_GTID_ID 48 // Integer : Global task id 42 #define CTX_TTY_ID 40 // global TTY terminal 43 #define CTX_DMA_ID 41 // local DMA channel 44 #define CTX_NIC_ID 42 // global NIC channel 45 #define CTX_TIM_ID 43 // local TIMER channel 46 #define CTX_IOC_ID 44 // global IOC channel 47 #define CTX_CMA_ID 45 // global CMA channel index (in scheduler) / UNUSED 48 #define CTX_GTID_ID 46 // Global Task Index 49 #define CTX_RUN_ID 47 // Boolean: task runable 47 50 48 51 ////////////////////////////////////////////////////////////////////////////////// -
soft/giet_vm/sys/drivers.c
r237 r238 1 1 /////////////////////////////////////////////////////////////////////////////////// 2 2 // File : drivers.c 3 // Date : 01/04/20123 // Date : 23/05/2013 4 4 // Author : alain greiner 5 5 // Copyright (c) UPMC-LIP6 … … 16 16 // - vci_block_device 17 17 // 18 // The following global parameters must be defined in the giet_config.h file: 19 // - CLUSTER_SIZE 18 // For the peripherals replicated in each cluster (ICU, TIMER, DMA), 19 // the corresponding (virtual) base addresses must be completed by an offset 20 // depending on the cluster index. 21 // 22 // The following global parameter must be defined in the giet_config.h file: 23 // - GIET_CLUSTER_INCREMENT 24 // 25 // The following global parameters must be defined in the hard_config.h file: 20 26 // - NB_CLUSTERS 21 27 // - NB_PROCS_MAX 22 // - NB_TIM ERS_MAX23 // - NB_DMA S_MAX24 // - NB_TTY S28 // - NB_TIM_CHANNELS 29 // - NB_DMA_CHANNELS 30 // - NB_TTY_CHANNELS_MAX 25 31 // 26 32 // The following virtual base addresses must be defined in the giet_vsegs.ld file: 27 33 // - seg_icu_base 28 34 // - seg_tim_base 35 // - seg_dma_base 29 36 // - seg_tty_base 30 37 // - seg_gcd_base 31 // - seg_dma_base32 38 // - seg_fbf_base 33 39 // - seg_ioc_base 34 40 // - seg_nic_base 35 // As some peripherals can be replicated in the clusters (ICU, TIMER, DMA)36 // These addresses must be completed by an offset depending on the cluster index37 // full_base_address = seg_***_base + cluster_id * CLUSTER_SIZE41 // - seg_cma_base 42 // - seg_iob_base 43 // 38 44 /////////////////////////////////////////////////////////////////////////////////// 39 45 … … 48 54 49 55 #if !defined(NB_CLUSTERS) 50 # error: You must define NB_CLUSTERS in the configsfile56 # error: You must define NB_CLUSTERS in the hard_config.h file 51 57 #endif 52 58 53 59 #if !defined(NB_PROCS_MAX) 54 # error: You must define NB_PROCS_MAX in the configsfile60 # error: You must define NB_PROCS_MAX in the hard_config.h file 55 61 #endif 56 62 … … 59 65 #endif 60 66 61 #if !defined(CLUSTER_SIZE) 62 # error: You must define CLUSTER_SIZE in the configs file 63 #endif 64 65 #if !defined(NB_TTYS) 66 # error: You must define NB_TTYS in the configs file 67 #endif 68 69 #if (NB_TTYS < 1) 70 # error: NB_TTYS cannot be smaller than 1! 71 #endif 72 73 #if !defined(NB_DMAS_MAX) 74 #define NB_DMAS_MAX 0 75 #endif 76 77 #if !defined(NB_TIMERS_MAX) 78 #define NB_TIMERS_MAX 0 79 #endif 80 81 #if ( (NB_TIMERS_MAX) > 32 ) 82 # error: NB_TIMERS_MAX + NB_PROCS_MAX cannot be larger than 32 83 #endif 84 85 #if !defined(NB_IOCS) 86 # error: You must define NB_IOCS in the configs file 87 #endif 88 89 #if ( NB_IOCS > 1 ) 90 # error: NB_IOCS cannot be larger than 1 67 #if !defined(GIET_CLUSTER_INCREMENT) 68 # error: You must define GIET_CLUSTER_INCREMENT in the giet_config.h file 69 #endif 70 71 #if !defined(NB_TTY_CHANNELS) 72 # error: You must define NB_TTY_CHANNELS in the hard_config.h file 73 #endif 74 75 #if (NB_TTY_CHANNELS < 1) 76 # error: NB_TTY_CHANNELS cannot be smaller than 1! 77 #endif 78 79 #if !defined(NB_DMA_CHANNELS) 80 # error: You must define NB_DMA_CHANNELS in the hard_config.h file 81 #endif 82 83 #if (NB_DMA_CHANNELS > 8) 84 # error: NB_DMA_CHANNELS cannot be smaller than 8! 85 #endif 86 87 #if !defined(NB_TIM_CHANNELS) 88 #define NB_TIM_CHANNELS 0 89 #endif 90 91 #if ( (NB_TIM_CHANNELS + NB_PROC_MAX) > 32 ) 92 # error: NB_TIM_CHANNELS + NB_PROCS_MAX cannot be larger than 32 93 #endif 94 95 #if !defined(NB_IOC_CHANNELS) 96 # error: You must define NB_IOC_CHANNELS in the hard_config.h file 97 #endif 98 99 #if ( NB_IOC_CHANNELS > 8 ) 100 # error: NB_IOC_CHANNELS cannot be larger than 8 101 #endif 102 103 #if !defined(NB_NIC_CHANNELS) 104 # error: You must define NB_NIC_CHANNELS in the hard_config.h file 105 #endif 106 107 #if ( NB_NIC_CHANNELS > 8 ) 108 # error: NB_NIC_CHANNELS cannot be larger than 8 109 #endif 110 111 #if !defined(NB_CMA_CHANNELS) 112 # error: You must define NB_CMA_CHANNELS in the hard_config.h file 113 #endif 114 115 #if ( NB_CMA_CHANNELS > 8 ) 116 # error: NB_CMA_CHANNELS cannot be larger than 8 91 117 #endif 92 118 93 119 #if !defined( USE_XICU ) 94 # error: You must define USE_XICU in the configsfile120 # error: You must define USE_XICU in the hard_config.h file 95 121 #endif 96 122 97 123 #if !defined( IOMMU_ACTIVE ) 98 # error: You must define IOMMU_ACTIVE in the configsfile124 # error: You must define IOMMU_ACTIVE in the hard_config.h file 99 125 #endif 100 126 … … 105 131 // Timers driver 106 132 ////////////////////////////////////////////////////////////////////////////// 133 // This peripheral is replicated in all clusters. 107 134 // The timers can be implemented in a vci_timer component or in a vci_xicu 108 135 // component (depending on the USE_XICU parameter). … … 113 140 // - "user" timers : requested by the task in the mapping_info data structure. 114 141 // For each user timer, the timer_id is stored in the context of the task. 115 // The global index is cluster_id * (NB_PROCS_MAX+NB_TIM ERS_MAX) + local_id142 // The global index is cluster_id * (NB_PROCS_MAX+NB_TIM_CHANNELS) + local_id 116 143 ////////////////////////////////////////////////////////////////////////////// 144 // The (virtual) base address of the associated segment is: 145 // 146 // timer_address = seg_icu_base + cluster_id * GIET_CLUSTER_INCREMENT 147 // 148 // - cluster id is an explicit argument of all access functions 149 // - seg_icu_base must be defined in the giet_vsegs.ld file 150 // - GIET_CLUSTER_INCREMENT must be defined in the giet_config.h file 151 //////////////////////////////////////////////////////////////////////////////// 117 152 118 153 // User Timer signaling variables 119 154 120 #if (NB_TIM ERS_MAX> 0)121 in_unckdata volatile unsigned char _user_timer_event[NB_CLUSTERS * NB_TIM ERS_MAX]122 = { [0 ... ((NB_CLUSTERS * NB_TIM ERS_MAX) - 1)] = 0 };155 #if (NB_TIM_CHANNELS > 0) 156 in_unckdata volatile unsigned char _user_timer_event[NB_CLUSTERS * NB_TIM_CHANNELS] 157 = { [0 ... ((NB_CLUSTERS * NB_TIM_CHANNELS) - 1)] = 0 }; 123 158 #endif 124 159 … … 131 166 // Returns 0 if success, > 0 if error. 132 167 ////////////////////////////////////////////////////////////////////////////// 133 unsigned int _timer_start(unsigned int cluster_id, unsigned int local_id, unsigned int period) { 168 unsigned int _timer_start( unsigned int cluster_id, 169 unsigned int local_id, 170 unsigned int period) 171 { 134 172 // parameters checking 135 if (cluster_id >= NB_CLUSTERS) { 136 return 1; 137 } 138 if (local_id >= NB_TIMERS_MAX) { 139 return 2; 140 } 173 if (cluster_id >= NB_CLUSTERS) return 1; 174 if (local_id >= NB_TIM_CHANNELS) return 2; 141 175 142 176 #if USE_XICU 143 unsigned int * timer_address = (unsigned int *) ((char *) &seg_icu_base + (cluster_id * CLUSTER_SIZE)); 177 unsigned int * timer_address = (unsigned int *) ((char *) &seg_icu_base + 178 (cluster_id * GIET_CLUSTER_INCREMENT)); 144 179 145 180 timer_address[XICU_REG(XICU_PTI_PER, local_id)] = period; 146 181 #else 147 unsigned int* timer_address = (unsigned int *) ((char *) &seg_tim_base + (cluster_id * CLUSTER_SIZE)); 182 unsigned int* timer_address = (unsigned int *) ((char *) &seg_tim_base + 183 (cluster_id * GIET_CLUSTER_INCREMENT)); 148 184 149 185 timer_address[local_id * TIMER_SPAN + TIMER_PERIOD] = period; … … 152 188 return 0; 153 189 } 154 155 190 156 191 ////////////////////////////////////////////////////////////////////////////// … … 160 195 // Returns 0 if success, > 0 if error. 161 196 ////////////////////////////////////////////////////////////////////////////// 162 unsigned int _timer_stop(unsigned int cluster_id, unsigned int local_id) { 197 unsigned int _timer_stop( unsigned int cluster_id, 198 unsigned int local_id) 199 { 163 200 // parameters checking 164 if (cluster_id >= NB_CLUSTERS) { 165 return 1; 166 } 167 if (local_id >= NB_TIMERS_MAX) { 168 return 2; 169 } 201 if (cluster_id >= NB_CLUSTERS) return 1; 202 if (local_id >= NB_TIM_CHANNELS) return 2; 170 203 171 204 #if USE_XICU 172 unsigned int * timer_address = (unsigned int *) ((char *) &seg_icu_base + (cluster_id * CLUSTER_SIZE)); 205 unsigned int * timer_address = (unsigned int *) ((char *) &seg_icu_base + 206 (cluster_id * GIET_CLUSTER_INCREMENT)); 173 207 174 208 timer_address[XICU_REG(XICU_PTI_PER, local_id)] = 0; 175 209 #else 176 unsigned int* timer_address = (unsigned int *) ((char *) &seg_tim_base + (cluster_id * CLUSTER_SIZE)); 210 unsigned int* timer_address = (unsigned int *) ((char *) &seg_tim_base + 211 (cluster_id * GIET_CLUSTER_INCREMENT)); 212 177 213 timer_address[local_id * TIMER_SPAN + TIMER_MODE] = 0; 178 214 #endif … … 189 225 // Returns 0 if success, > 0 if error. 190 226 ////////////////////////////////////////////////////////////////////////////// 191 unsigned int _timer_reset_irq(unsigned int cluster_id, unsigned int local_id) { 227 unsigned int _timer_reset_irq( unsigned int cluster_id, 228 unsigned int local_id ) 229 { 192 230 // parameters checking 193 if (cluster_id >= NB_CLUSTERS) { 194 return 1; 195 } 196 if (local_id >= NB_TIMERS_MAX) { 197 return 2; 198 } 231 if (cluster_id >= NB_CLUSTERS) return 1; 232 if (local_id >= NB_TIM_CHANNELS) return 2; 199 233 200 234 #if USE_XICU 201 235 unsigned int * timer_address = (unsigned int *) ((char *) &seg_icu_base + 202 (cluster_id * (unsigned) CLUSTER_SIZE));236 (cluster_id * GIET_CLUSTER_INCREMENT)); 203 237 204 238 unsigned int bloup = timer_address[XICU_REG(XICU_PTI_ACK, local_id)]; … … 206 240 #else 207 241 unsigned int * timer_address = (unsigned int *) ((char *) &seg_tim_base + 208 (cluster_id * CLUSTER_SIZE));242 (cluster_id * GIET_CLUSTER_INCREMENT)); 209 243 210 244 timer_address[local_id * TIMER_SPAN + TIMER_RESETIRQ] = 0; 211 245 #endif 212 213 246 return 0; 214 247 } … … 223 256 // return 1; 224 257 // } 225 // if (local_id >= NB_TIM ERS_MAX) {258 // if (local_id >= NB_TIM_CHANNELS) { 226 259 // return 2; 227 260 // } … … 230 263 //#error // not implemented 231 264 //#else 232 // unsigned int * timer_address = (unsigned int *) ((char *) &seg_tim_base + (cluster_id * CLUSTER_SIZE));265 // unsigned int * timer_address = (unsigned int *) ((char *) &seg_tim_base + (cluster_id * GIET_CLUSTER_INCREMENT)); 233 266 // unsigned int timer_period = timer_address[local_id * TIMER_SPAN + TIMER_PERIOD]; 234 267 // … … 244 277 ///////////////////////////////////////////////////////////////////////////////// 245 278 // There is only one multi_tty controler in the architecture. 246 // The total number of TTYs is defined by the configuration parameter NB_TTY S.279 // The total number of TTYs is defined by the configuration parameter NB_TTY_CHANNELS. 247 280 // The "system" terminal is TTY[0]. 248 281 // The "user" TTYs are allocated to applications by the GIET in the boot phase, … … 253 286 254 287 // TTY variables 255 in_unckdata volatile unsigned char _tty_get_buf[NB_TTYS]; 256 in_unckdata volatile unsigned char _tty_get_full[NB_TTYS] = { [0 ... NB_TTYS - 1] = 0 }; 288 in_unckdata volatile unsigned char _tty_get_buf[NB_TTY_CHANNELS]; 289 in_unckdata volatile unsigned char _tty_get_full[NB_TTY_CHANNELS] 290 = { [0 ... NB_TTY_CHANNELS - 1] = 0 }; 257 291 in_unckdata unsigned int _tty_put_lock = 0; // protect kernel TTY[0] 258 292 … … 260 294 // _tty_error() 261 295 //////////////////////////////////////////////////////////////////////////////// 262 void _tty_error(unsigned int tty_id, unsigned int task_id) { 296 void _tty_error(unsigned int tty_id, unsigned int task_id) 297 { 263 298 unsigned int proc_id = _procid(); 264 299 … … 287 322 // The function returns the number of characters that have been written. 288 323 ///////////////////////////////////////////////////////////////////////////////// 289 unsigned int _tty_write(const char * buffer, unsigned int length) { 324 unsigned int _tty_write(const char * buffer, 325 unsigned int length) 326 { 290 327 unsigned int nwritten; 291 unsigned int task_id = _get_proc_task_id(); 292 unsigned int tty_id = _get_context_slot(task_id, CTX_TTY_ID); 293 294 if (tty_id >= NB_TTYS) { 295 _tty_error(tty_id , task_id); 296 return 0; 297 } 298 299 unsigned int * tty_address = (unsigned int *) &seg_tty_base; 300 301 for (nwritten = 0; nwritten < length; nwritten++) { 328 unsigned int tty_id = _get_context_slot(CTX_TTY_ID); 329 unsigned int* tty_address = (unsigned int *) &seg_tty_base; 330 331 for (nwritten = 0; nwritten < length; nwritten++) 332 { 302 333 // check tty's status 303 if ((tty_address[tty_id * TTY_SPAN + TTY_STATUS] & 0x2) == 0x2) { 304 break; 305 } 306 else { 307 // write character 308 tty_address[tty_id * TTY_SPAN + TTY_WRITE] = (unsigned int) buffer[nwritten]; 309 } 334 if ((tty_address[tty_id * TTY_SPAN + TTY_STATUS] & 0x2) == 0x2) break; 335 tty_address[tty_id * TTY_SPAN + TTY_WRITE] = (unsigned int) buffer[nwritten]; 310 336 } 311 337 return nwritten; 312 338 } 313 314 339 315 340 ////////////////////////////////////////////////////////////////////////////// … … 324 349 // Returns 0 if the kernel buffer is empty, 1 if the buffer is full. 325 350 ////////////////////////////////////////////////////////////////////////////// 326 unsigned int _tty_read(char * buffer, unsigned int length) { 327 unsigned int task_id = _get_proc_task_id(); 328 unsigned int tty_id = _get_context_slot(task_id, CTX_TTY_ID); 329 330 if (tty_id >= NB_TTYS) { 331 _tty_error(tty_id, task_id); 351 unsigned int _tty_read(char * buffer, 352 unsigned int length) 353 { 354 unsigned int tty_id = _get_context_slot(CTX_TTY_ID); 355 356 if (_tty_get_full[tty_id] == 0) 357 { 332 358 return 0; 333 359 } 334 335 if (_tty_get_full[tty_id] == 0) { 336 return 0; 337 } 338 else { 360 else 361 { 339 362 *buffer = _tty_get_buf[tty_id]; 340 363 _tty_get_full[tty_id] = 0; … … 342 365 } 343 366 } 344 345 367 346 368 //////////////////////////////////////////////////////////////////////////////// … … 351 373 // Returns 0 if success, 1 if tty_id too large. 352 374 //////////////////////////////////////////////////////////////////////////////// 353 unsigned int _tty_get_char(unsigned int tty_id, unsigned char * buffer) { 375 unsigned int _tty_get_char(unsigned int tty_id, 376 unsigned char * buffer) 377 { 354 378 // checking argument 355 if (tty_id >= NB_TTYS) { 356 return 1; 357 } 379 if (tty_id >= NB_TTY_CHANNELS) { return 1; } 358 380 359 381 // compute terminal base address … … 366 388 367 389 //////////////////////////////////////////////////////////////////////////////// 368 // VciMultiIcu and VciXicu drivers 369 //////////////////////////////////////////////////////////////////////////////// 390 // VciMultiIcu or VciXicu driver 391 //////////////////////////////////////////////////////////////////////////////// 392 // This hardware component is replicated in all clusters. 370 393 // There is one vci_multi_icu (or vci_xicu) component per cluster, 371 394 // and the number of independant ICUs is equal to NB_PROCS_MAX, 372 // because there is one private interrupr controler per processor. 395 // because there is one private interrupt controler per processor. 396 //////////////////////////////////////////////////////////////////////////////// 397 // The (virtual) base address of the associated segment is: 398 // 399 // icu_address = seg_icu_base + cluster_id * GIET_CLUSTER_INCREMENT 400 // 401 // - cluster id is an explicit argument of all access functions 402 // - seg_icu_base must be defined in the giet_vsegs.ld file 403 // - GIET_CLUSTER_INCREMENT must be defined in the giet_config.h file 373 404 //////////////////////////////////////////////////////////////////////////////// 374 405 … … 380 411 // Returns 0 if success, > 0 if error. 381 412 //////////////////////////////////////////////////////////////////////////////// 382 unsigned int _icu_set_mask( 383 unsigned int cluster_id,384 unsigned int proc_id,385 unsigned int value,386 unsigned int is_timer){413 unsigned int _icu_set_mask( unsigned int cluster_id, 414 unsigned int proc_id, 415 unsigned int value, 416 unsigned int is_timer) 417 { 387 418 // parameters checking 388 if (cluster_id >= NB_CLUSTERS) { 389 return 1; 390 } 391 if (proc_id >= NB_PROCS_MAX) { 392 return 1; 393 } 419 if (cluster_id >= NB_CLUSTERS) return 1; 420 if (proc_id >= NB_PROCS_MAX) return 1; 394 421 395 422 unsigned int * icu_address = (unsigned int *) ((char *) &seg_icu_base + 396 (cluster_id * (unsigned) CLUSTER_SIZE));423 (cluster_id * GIET_CLUSTER_INCREMENT)); 397 424 #if USE_XICU 398 if (is_timer) { 425 if (is_timer) 426 { 399 427 icu_address[XICU_REG(XICU_MSK_PTI_ENABLE, proc_id)] = value; 400 428 } 401 else { 429 else 430 { 402 431 icu_address[XICU_REG(XICU_MSK_HWI_ENABLE, proc_id)] = value; 403 432 } … … 405 434 icu_address[proc_id * ICU_SPAN + ICU_MASK_SET] = value; 406 435 #endif 407 408 436 return 0; 409 437 } … … 417 445 // Returns 0 if success, > 0 if error. 418 446 //////////////////////////////////////////////////////////////////////////////// 419 unsigned int _icu_get_index(unsigned int cluster_id, unsigned int proc_id, unsigned int * buffer) { 447 unsigned int _icu_get_index( unsigned int cluster_id, 448 unsigned int proc_id, 449 unsigned int * buffer) 450 { 420 451 // parameters checking 421 if (cluster_id >= NB_CLUSTERS) { 422 return 1; 423 } 424 if (proc_id >= NB_PROCS_MAX) { 425 return 1; 426 } 452 if (cluster_id >= NB_CLUSTERS) return 1; 453 if (proc_id >= NB_PROCS_MAX) return 1; 427 454 428 455 unsigned int * icu_address = (unsigned int *) ((char *) &seg_icu_base + 429 (cluster_id * (unsigned) CLUSTER_SIZE));456 (cluster_id * GIET_CLUSTER_INCREMENT)); 430 457 #if USE_XICU 431 458 unsigned int prio = icu_address[XICU_REG(XICU_PRIO, proc_id)]; … … 436 463 unsigned int hwi_id = (prio & 0x001F0000) >> 16; 437 464 unsigned int swi_id = (prio & 0x1F000000) >> 24; 438 if (pti_ok) { 439 *buffer = pti_id; 440 } 441 else if (hwi_ok) { 442 *buffer = hwi_id; 443 } 444 else if (swi_ok) { 445 *buffer = swi_id; 446 } 447 else { 448 *buffer = 32; 449 } 465 if (pti_ok) { *buffer = pti_id; } 466 else if (hwi_ok) { *buffer = hwi_id; } 467 else if (swi_ok) { *buffer = swi_id; } 468 else { *buffer = 32; } 450 469 #else 451 470 *buffer = icu_address[proc_id * ICU_SPAN + ICU_IT_VECTOR]; 452 471 #endif 453 454 472 return 0; 455 473 } … … 469 487 // Returns 0 if success, > 0 if error. 470 488 //////////////////////////////////////////////////////////////////////////////// 471 unsigned int _gcd_write(unsigned int register_index, unsigned int value) { 489 unsigned int _gcd_write( unsigned int register_index, 490 unsigned int value) 491 { 472 492 // parameters checking 473 if (register_index >= GCD_END) { 474 return 1; 475 } 493 if (register_index >= GCD_END) return 1; 476 494 477 495 unsigned int * gcd_address = (unsigned int *) &seg_gcd_base; … … 487 505 // Returns 0 if success, > 0 if error. 488 506 //////////////////////////////////////////////////////////////////////////////// 489 unsigned int _gcd_read(unsigned int register_index, unsigned int * buffer) { 507 unsigned int _gcd_read( unsigned int register_index, 508 unsigned int * buffer ) 509 { 490 510 // parameters checking 491 if (register_index >= GCD_END) { 492 return 1; 493 } 511 if (register_index >= GCD_END) return 1; 494 512 495 513 unsigned int * gcd_address = (unsigned int *) &seg_gcd_base; … … 567 585 // Returns 0 if success, > 0 if error. 568 586 /////////////////////////////////////////////////////////////////////////////// 569 unsigned int _ioc_access( 570 unsigned int to_mem, 571 unsigned int lba, 572 unsigned int user_vaddr, 573 unsigned int count) { 574 unsigned int user_vpn_min; // first virtuel page index in user space 575 unsigned int user_vpn_max; // last virtual page index in user space 576 unsigned int vpn; // current virtual page index in user space 577 unsigned int ppn; // physical page number 578 unsigned int flags; // page protection flags 579 unsigned int ix2; // page index in IOMMU PT1 page table 580 unsigned int addr; // buffer address for IOC peripheral 581 unsigned int ppn_first; // first physical page number for user buffer 582 587 unsigned int _ioc_access( unsigned int to_mem, 588 unsigned int lba, 589 unsigned int user_vaddr, 590 unsigned int count) 591 { 592 unsigned int user_vpn_min; // first virtuel page index in user space 593 unsigned int user_vpn_max; // last virtual page index in user space 594 unsigned int vpn; // current virtual page index in user space 595 unsigned int ppn; // physical page number 596 unsigned int flags; // page protection flags 597 unsigned int ix2; // page index in IOMMU PT1 page table 598 unsigned int ppn_first; // first physical page number for user buffer 599 unsigned int buf_xaddr = 0; // user buffer virtual address in IO space (if IOMMU) 600 paddr_t buf_paddr = 0; // user buffer physical address (if no IOMMU), 601 583 602 // check buffer alignment 584 if ((unsigned int) user_vaddr & 0x3) { 585 return 1; 603 if ((unsigned int) user_vaddr & 0x3) 604 { 605 _get_lock(&_tty_put_lock); 606 _puts("[GIET ERROR] in _ioc_access() : user buffer not word aligned\n"); 607 _release_lock(&_tty_put_lock); 608 return 1; 586 609 } 587 610 … … 592 615 593 616 // get user space page table virtual address 594 unsigned int task_id = _get_proc_task_id(); 595 unsigned int user_pt_vbase = _get_context_slot(task_id, CTX_PTAB_ID); 617 unsigned int user_pt_vbase = _get_context_slot(CTX_PTAB_ID); 596 618 597 619 user_vpn_min = user_vaddr >> 12; 598 620 user_vpn_max = (user_vaddr + length - 1) >> 12; 599 ix2 = 0;600 621 601 622 // loop on all virtual pages covering the user buffer 602 for (vpn = user_vpn_min; vpn <= user_vpn_max; vpn++) { 623 for (vpn = user_vpn_min, ix2 = 0 ; 624 vpn <= user_vpn_max ; 625 vpn++, ix2++ ) 626 { 603 627 // get ppn and flags for each vpn 604 unsigned int ko = _v2p_translate((page_table_t *) user_pt_vbase, vpn, &ppn, &flags); 605 628 unsigned int ko = _v2p_translate( (page_table_t*)user_pt_vbase, 629 vpn, 630 &ppn, 631 &flags); 606 632 // check access rights 607 if (ko) { 608 return 2; // unmapped 633 if (ko) 634 { 635 _get_lock(&_tty_put_lock); 636 _puts("[GIET ERROR] in _ioc_access() : user buffer unmapped\n"); 637 _release_lock(&_tty_put_lock); 638 return 1; 609 639 } 610 if ((flags & PTE_U) == 0) { 611 return 3; // not in user space 640 if ((flags & PTE_U) == 0) 641 { 642 _get_lock(&_tty_put_lock); 643 _puts("[GIET ERROR] in _ioc_access() : user buffer not in user space\n"); 644 _release_lock(&_tty_put_lock); 645 return 1; 612 646 } 613 if (((flags & PTE_W) == 0 ) && to_mem) { 614 return 4; // not writable 647 if (((flags & PTE_W) == 0 ) && to_mem) 648 { 649 _get_lock(&_tty_put_lock); 650 _puts("[GIET ERROR] in _ioc_access() : user buffer not writable\n"); 651 _release_lock(&_tty_put_lock); 652 return 1; 615 653 } 616 654 617 655 // save first ppn value 618 if (ix2 == 0) { 619 ppn_first = ppn; 656 if (ix2 == 0) ppn_first = ppn; 657 658 if (IOMMU_ACTIVE) // the user buffer must be remapped in the I/0 space 659 { 660 // check buffer length < 2 Mbytes 661 if (ix2 > 511) 662 { 663 _get_lock(&_tty_put_lock); 664 _puts("[GIET ERROR] in _ioc_access() : user buffer > 2 Mbytes\n"); 665 _release_lock(&_tty_put_lock); 666 return 1; 667 } 668 669 // map the physical page in IOMMU page table 670 _iommu_add_pte2( _ioc_iommu_ix1, // PT1 index 671 ix2, // PT2 index 672 ppn, // Physical page number 673 flags); // Protection flags 674 675 // compute user buffer virtual adress in IO space 676 buf_xaddr = (_ioc_iommu_ix1) << 21 | (user_vaddr & 0xFFF); 620 677 } 621 622 if (IOMMU_ACTIVE) { 623 // the user buffer must be remapped in the I/0 space 624 // check buffer length < 2 Mbytes 625 if (ix2 > 511) { 626 return 2; 678 else // No IOMMU 679 { 680 // check that physical pages are contiguous 681 if ((ppn - ppn_first) != ix2) 682 { 683 _get_lock(&_tty_put_lock); 684 _puts("[GIET ERROR] in _ioc_access() : split physical user buffer\n"); 685 _release_lock(&_tty_put_lock); 686 return 1; 627 687 } 628 688 629 // map the physical page in IOMMU page table 630 _iommu_add_pte2( 631 _ioc_iommu_ix1, // PT1 index 632 ix2, // PT2 index 633 ppn, // Physical page number 634 flags); // Protection flags 689 // compute user buffer physical adress 690 buf_paddr = (((paddr_t)ppn_first) << 12) | (user_vaddr & 0xFFF); 635 691 } 636 else {637 // no IOMMU : check that physical pages are contiguous638 if ((ppn - ppn_first) != ix2) {639 return 5; // split physical buffer640 }641 }642 643 // increment page index644 ix2++;645 692 } // end for vpn 646 693 … … 649 696 650 697 // invalidate data cache in case of memory write 651 if (to_mem) { 652 _dcache_buf_invalidate((void *) user_vaddr, length); 653 } 654 655 // compute buffer base address for IOC depending on IOMMU activation 656 if (IOMMU_ACTIVE) { 657 addr = (_ioc_iommu_ix1) << 21 | (user_vaddr & 0xFFF); 658 } 659 else { 660 addr = (ppn_first << 12) | (user_vaddr & 0xFFF); 661 } 698 if (to_mem) _dcache_buf_invalidate((void *) user_vaddr, length); 699 700 #if GIET_DEBUG_IOC_DRIVER 701 _get_lock(&_tty_put_lock); 702 _puts("\n[GIET DEBUG] IOC_ACCESS at cycle "); 703 _putd( _proctime() ); 704 _puts("\n - proc_id = "); 705 _putd( _procid() ); 706 _puts("\n - ioc_vbase = "); 707 _putx( (unsigned int)ioc_address ); 708 _puts("\n - psched_vbase = "); 709 _putx( (unsigned int)_get_sched() ); 710 _puts("\n - pt_vbase = "); 711 _putx( user_pt_vbase ); 712 _puts("\n - user_buf_vbase = "); 713 _putx( user_vaddr ); 714 _puts("\n - user_buf_length = "); 715 _putx( length ); 716 _puts("\n - user_buf_paddr = "); 717 _putl( buf_paddr ); 718 _puts("\n - user_buf_xaddr = "); 719 _putx( buf_xaddr ); 720 _puts("\n"); 721 _release_lock(&_tty_put_lock); 722 #endif 662 723 663 724 // get the lock on ioc device … … 665 726 666 727 // peripheral configuration 667 ioc_address[BLOCK_DEVICE_BUFFER] = addr; 728 if ( IOMMU_ACTIVE ) 729 { 730 ioc_address[BLOCK_DEVICE_BUFFER] = buf_xaddr; 731 } 732 else 733 { 734 ioc_address[BLOCK_DEVICE_BUFFER] = (unsigned int)buf_paddr; 735 ioc_address[BLOCK_DEVICE_BUFFER_EXT] = (unsigned int)(buf_paddr>>32); 736 } 668 737 ioc_address[BLOCK_DEVICE_COUNT] = count; 669 738 ioc_address[BLOCK_DEVICE_LBA] = lba; 670 if (to_mem == 0) { 739 if (to_mem == 0) 740 { 671 741 ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_WRITE; 672 742 } 673 else { 743 else 744 { 674 745 ioc_address[BLOCK_DEVICE_OP] = BLOCK_DEVICE_READ; 675 746 } 676 677 return 0; 678 } 679 747 return 0; 748 } 680 749 681 750 ///////////////////////////////////////////////////////////////////////////////// … … 688 757 // Returns 0 if success, > 0 if error. 689 758 ///////////////////////////////////////////////////////////////////////////////// 690 unsigned int _ioc_completed() { 759 unsigned int _ioc_completed() 760 { 691 761 unsigned int ret; 692 762 unsigned int ix2; 693 763 694 764 // busy waiting 695 while (_ioc_done == 0) { 696 asm volatile("nop"); 697 } 765 while (_ioc_done == 0) { asm volatile("nop"); } 766 767 #if GIET_DEBUG_IOC_DRIVER 768 _get_lock(&_tty_put_lock); 769 _puts("\n[GIET DEBUG] IOC_COMPLETED at cycle "); 770 _putd( _proctime() ); 771 _puts("\n - proc_id = "); 772 _putd( _procid() ); 773 _puts("\n"); 774 _release_lock(&_tty_put_lock); 775 #endif 698 776 699 777 // unmap the buffer from IOMMU page table if IOMMU is activated 700 if (IOMMU_ACTIVE) { 778 if (IOMMU_ACTIVE) 779 { 701 780 unsigned int * iob_address = (unsigned int *) &seg_iob_base; 702 781 703 for (ix2 = 0; ix2 < _ioc_iommu_npages; ix2++) { 782 for (ix2 = 0; ix2 < _ioc_iommu_npages; ix2++) 783 { 704 784 // unmap the page in IOMMU page table 705 785 _iommu_inval_pte2( … … 714 794 // test IOC status 715 795 if ((_ioc_status != BLOCK_DEVICE_READ_SUCCESS) 716 && (_ioc_status != BLOCK_DEVICE_WRITE_SUCCESS)) { 717 ret = 1; // error 718 } 719 else { 720 ret = 0; // success 721 } 796 && (_ioc_status != BLOCK_DEVICE_WRITE_SUCCESS)) ret = 1; // error 797 else ret = 0; // success 722 798 723 799 // reset synchronization variables … … 738 814 // Returns 0 if success, > 0 if error. 739 815 /////////////////////////////////////////////////////////////////////////////// 740 unsigned int _ioc_read(unsigned int lba, void * buffer, unsigned int count) { 816 unsigned int _ioc_read( unsigned int lba, 817 void * buffer, 818 unsigned int count) 819 { 741 820 return _ioc_access( 742 821 1, // read access … … 755 834 // Returns 0 if success, > 0 if error. 756 835 /////////////////////////////////////////////////////////////////////////////// 757 unsigned int _ioc_write(unsigned int lba, const void * buffer, unsigned int count) { 836 unsigned int _ioc_write( unsigned int lba, 837 const void * buffer, 838 unsigned int count) 839 { 758 840 return _ioc_access( 759 841 0, // write access … … 769 851 // Returns 0 if success, > 0 if error. 770 852 /////////////////////////////////////////////////////////////////////////////// 771 unsigned int _ioc_get_status(unsigned int * status) { 853 unsigned int _ioc_get_status(unsigned int * status) 854 { 772 855 // get IOC base address 773 856 unsigned int * ioc_address = (unsigned int *) &seg_ioc_base; … … 782 865 // This function returns the block_size with which the IOC has been configured. 783 866 /////////////////////////////////////////////////////////////////////////////// 784 unsigned int _ioc_get_block_size() { 867 unsigned int _ioc_get_block_size() 868 { 785 869 // get IOC base address 786 870 unsigned int * ioc_address = (unsigned int *) &seg_ioc_base; … … 794 878 ////////////////////////////////////////////////////////////////////////////////// 795 879 // The DMA controllers are physically distributed in the clusters. 796 // There is (NB_CLUSTERS * NB_DMA S_MAX) channels, indexed by a global index:797 // dma_id = cluster_id * NB_DMA_ MAX+ loc_id798 // 799 // As a DMA channel can be used by several tasks, each DMA channel is protected800 // by a specific lock: _dma_lock[dma_id]880 // There is (NB_CLUSTERS * NB_DMA_CHANNELS) channels, indexed by a global index: 881 // dma_id = cluster_id * NB_DMA_CHANNELS + loc_id 882 // 883 // As a DMA channel is a private ressource allocated to a task, 884 // there is no lock protecting exclusive access to the channel. 801 885 // The signalisation between the OS and the DMA uses the _dma_done[dma_id] 802 886 // synchronisation variables (set by the ISR, and reset by the OS). 803 887 // The transfer status is copied by the ISR in the _dma_status[dma_id] variables. 804 // 805 // These DMA channels can be used by the FB driver, or by the NIC driver. 806 ////////////////////////////////////////////////////////////////////////////////// 807 808 #if NB_DMAS_MAX > 0 809 in_unckdata unsigned int _dma_lock[NB_DMAS_MAX * NB_CLUSTERS] = { 810 [0 ... (NB_DMAS_MAX * NB_CLUSTERS) - 1] = 0 811 }; 812 813 in_unckdata volatile unsigned int _dma_done[NB_DMAS_MAX * NB_CLUSTERS] = { 814 [0 ... (NB_DMAS_MAX * NB_CLUSTERS) - 1] = 0 815 }; 816 817 in_unckdata volatile unsigned int _dma_status[NB_DMAS_MAX * NB_CLUSTERS]; 888 ////////////////////////////////////////////////////////////////////////////////// 889 // The (virtual) base address of the associated segment is: 890 // 891 // dma_address = seg_dma_base + cluster_id * GIET_CLUSTER_INCREMENT 892 // 893 // - seg_dma_base must be defined in the giet_vsegs.ld file 894 // - GIET_CLUSTER_INCREMENT must be defined in the giet_config.h file 895 //////////////////////////////////////////////////////////////////////////////// 896 897 #if NB_DMA_CHANNELS > 0 898 899 // in_unckdata unsigned int _dma_lock[NB_DMA_CHANNELS * NB_CLUSTERS] 900 // = { [0 ... (NB_DMA_CHANNELS * NB_CLUSTERS) - 1] = 0 }; 901 902 in_unckdata volatile unsigned int _dma_done[NB_DMA_CHANNELS * NB_CLUSTERS] 903 = { [0 ... (NB_DMA_CHANNELS * NB_CLUSTERS) - 1] = 0 }; 904 in_unckdata volatile unsigned int _dma_status[NB_DMA_CHANNELS * NB_CLUSTERS]; 818 905 in_unckdata unsigned int _dma_iommu_ix1 = 1; 819 in_unckdata unsigned int _dma_iommu_npages[NB_DMA S_MAX* NB_CLUSTERS];906 in_unckdata unsigned int _dma_iommu_npages[NB_DMA_CHANNELS * NB_CLUSTERS]; 820 907 #endif 821 908 … … 823 910 // _dma_reset_irq() 824 911 ////////////////////////////////////////////////////////////////////////////////// 825 unsigned int _dma_reset_irq(unsigned int cluster_id, unsigned int channel_id) { 826 #if NB_DMAS_MAX > 0 912 unsigned int _dma_reset_irq( unsigned int cluster_id, 913 unsigned int channel_id) 914 { 915 #if NB_DMA_CHANNELS > 0 827 916 // parameters checking 828 if (cluster_id >= NB_CLUSTERS) { 829 return 1; 830 } 831 if (channel_id >= NB_DMAS_MAX) { 832 return 1; 833 } 917 if (cluster_id >= NB_CLUSTERS) return 1; 918 if (channel_id >= NB_DMA_CHANNELS) return 1; 834 919 835 920 // compute DMA base address 836 921 unsigned int * dma_address = (unsigned int *) ((char *) &seg_dma_base + 837 (cluster_id * (unsigned) CLUSTER_SIZE));922 (cluster_id * GIET_CLUSTER_INCREMENT)); 838 923 839 924 dma_address[channel_id * DMA_SPAN + DMA_RESET] = 0; … … 848 933 // _dma_get_status() 849 934 ////////////////////////////////////////////////////////////////////////////////// 850 unsigned int _dma_get_status(unsigned int cluster_id, unsigned int channel_id, unsigned int * status) { 851 #if NB_DMAS_MAX > 0 935 unsigned int _dma_get_status( unsigned int cluster_id, 936 unsigned int channel_id, 937 unsigned int * status) 938 { 939 #if NB_DMA_CHANNELS > 0 852 940 // parameters checking 853 if (cluster_id >= NB_CLUSTERS) { 854 return 1; 855 } 856 if (channel_id >= NB_DMAS_MAX) { 857 return 1; 858 } 941 if (cluster_id >= NB_CLUSTERS) return 1; 942 if (channel_id >= NB_DMA_CHANNELS) return 1; 859 943 860 944 // compute DMA base address 861 945 unsigned int * dma_address = (unsigned int *) ((char *) &seg_dma_base + 862 (cluster_id * (unsigned) CLUSTER_SIZE));946 (cluster_id * GIET_CLUSTER_INCREMENT)); 863 947 864 948 *status = dma_address[channel_id * DMA_SPAN + DMA_LEN]; … … 873 957 // _dma_transfer() 874 958 // Transfer data between a user buffer and a device buffer using DMA. 875 // Two devices types are supported: Frame Buffer if dev_type == 0 876 // Multi-Nic if dev_type != 0 959 // Only one device type is supported: Frame Buffer (dev_type == 0) 877 960 // Arguments are: 878 961 // - dev_type : device type. … … 882 965 // - length : number of bytes to be transfered. 883 966 // 884 // The DMA channel is obtained from task context (CTX_FBDMA_ID / CTX_NIDMA_ID.967 // The cluster_id and channel_id are obtained from task context (CTX_DMA_ID). 885 968 // The user buffer must be mapped in user address space and word-aligned. 886 969 // The user buffer length must be multiple of 4 bytes. 887 // Me mustcompute the physical base addresses for both the device buffer970 // We compute the physical base addresses for both the device buffer 888 971 // and the user buffer before programming the DMA transfer. 889 972 // The GIET being fully static, we don't need to split the transfer in 4 Kbytes … … 891 974 // Returns 0 if success, > 0 if error. 892 975 ////////////////////////////////////////////////////////////////////////////////// 893 unsigned int _dma_transfer( 894 unsigned int dev_type,895 unsigned int to_user,896 unsigned int offset,897 unsigned int user_vaddr,898 unsigned int length){899 #if NB_DMA S_MAX> 0976 unsigned int _dma_transfer( unsigned int dev_type, 977 unsigned int to_user, 978 unsigned int offset, 979 unsigned int user_vaddr, 980 unsigned int length ) 981 { 982 #if NB_DMA_CHANNELS > 0 900 983 unsigned int ko; // unsuccessfull V2P translation 984 unsigned int device_vbase; // device buffer vbase address 901 985 unsigned int flags; // protection flags 902 986 unsigned int ppn; // physical page number 903 unsigned int user_pbase; // user buffer pbase address 904 unsigned int device_pbase; // frame buffer pbase address 905 unsigned int device_vaddr; // device buffer vbase address 987 paddr_t user_pbase; // user buffer pbase address 988 paddr_t device_pbase; // frame buffer pbase address 906 989 907 990 // check user buffer address and length alignment 908 if ((user_vaddr & 0x3) || (length & 0x3)) { 991 if ((user_vaddr & 0x3) || (length & 0x3)) 992 { 909 993 _get_lock(&_tty_put_lock); 910 994 _puts("\n[GIET ERROR] in _dma_transfer : user buffer not word aligned\n"); … … 914 998 915 999 // get DMA channel and compute DMA vbase address 916 unsigned int task_id = _get_proc_task_id(); 917 unsigned int dma_id = _get_context_slot(task_id, CTX_DMA_ID); 918 unsigned int cluster_id = dma_id / NB_DMAS_MAX; 919 unsigned int loc_id = dma_id % NB_DMAS_MAX; 920 unsigned int * dma_base = (unsigned int *) ((char *) &seg_dma_base + 921 (cluster_id * (unsigned) CLUSTER_SIZE)); 922 1000 unsigned int dma_id = _get_context_slot(CTX_DMA_ID); 1001 if ( dma_id == 0xFFFFFFFF ) 1002 { 1003 _get_lock(&_tty_put_lock); 1004 _puts("\n[GIET ERROR] in _dma_transfer : no DMA channel allocated\n"); 1005 _release_lock(&_tty_put_lock); 1006 return 1; 1007 } 1008 unsigned int cluster_id = dma_id / NB_DMA_CHANNELS; 1009 unsigned int channel_id = dma_id % NB_DMA_CHANNELS; 1010 unsigned int * dma_vbase = (unsigned int *) ((char *) &seg_dma_base + 1011 (cluster_id * GIET_CLUSTER_INCREMENT)); 923 1012 // get page table address 924 unsigned int user_ptab = _get_context_slot(task_id, CTX_PTAB_ID); 925 926 // get peripheral buffer virtual address 927 if (dev_type) { 928 device_vaddr = (unsigned int) &seg_nic_base + offset; 929 } 930 else { 931 device_vaddr = (unsigned int) &seg_fbf_base + offset; 1013 unsigned int user_ptab = _get_context_slot(CTX_PTAB_ID); 1014 1015 // get devic buffer virtual address, depending on peripheral type 1016 if (dev_type == 0) 1017 { 1018 device_vbase = (unsigned int) &seg_fbf_base + offset; 1019 } 1020 else 1021 { 1022 _get_lock(&_tty_put_lock); 1023 _puts("\n[GIET ERROR] in _dma_transfer : device type not supported\n"); 1024 _release_lock(&_tty_put_lock); 1025 return 1; 932 1026 } 933 1027 934 1028 // get device buffer physical address 935 ko = _v2p_translate((page_table_t *) user_ptab, (device_vaddr >> 12), &ppn, &flags); 936 if (ko) { 1029 ko = _v2p_translate( (page_table_t*) user_ptab, 1030 (device_vbase >> 12), 1031 &ppn, 1032 &flags ); 1033 if (ko) 1034 { 937 1035 _get_lock(&_tty_put_lock); 938 1036 _puts("\n[GIET ERROR] in _dma_transfer : device buffer unmapped\n"); 939 1037 _release_lock(&_tty_put_lock); 940 return 2;941 } 942 device_pbase = ( ppn << 12) | (device_vaddr& 0x00000FFF);1038 return 1; 1039 } 1040 device_pbase = ((paddr_t)ppn << 12) | (device_vbase & 0x00000FFF); 943 1041 944 1042 // Compute user buffer physical address 945 ko = _v2p_translate((page_table_t*) user_ptab, (user_vaddr >> 12), &ppn, &flags); 946 if (ko) { 1043 ko = _v2p_translate( (page_table_t*) user_ptab, 1044 (user_vaddr >> 12), 1045 &ppn, 1046 &flags ); 1047 if (ko) 1048 { 947 1049 _get_lock(&_tty_put_lock); 948 1050 _puts("\n[GIET ERROR] in _dma_transfer() : user buffer unmapped\n"); 949 1051 _release_lock(&_tty_put_lock); 950 return 3;1052 return 1; 951 1053 } 952 if ((flags & PTE_U) == 0) { 1054 if ((flags & PTE_U) == 0) 1055 { 953 1056 _get_lock(&_tty_put_lock); 954 1057 _puts("[GIET ERROR] in _dma_transfer() : user buffer not in user space\n"); 955 1058 _release_lock(&_tty_put_lock); 956 return 4; 957 } 958 if (((flags & PTE_W) == 0 ) && to_user) { 1059 return 1; 1060 } 1061 if (((flags & PTE_W) == 0 ) && to_user) 1062 { 959 1063 _get_lock(&_tty_put_lock); 960 1064 _puts("\n[GIET ERROR] in _dma_transfer() : user buffer not writable\n"); 961 1065 _release_lock(&_tty_put_lock); 962 return 5;963 } 964 user_pbase = ( ppn<< 12) | (user_vaddr & 0x00000FFF);965 966 1066 return 1; 1067 } 1068 user_pbase = (((paddr_t)ppn) << 12) | (user_vaddr & 0x00000FFF); 1069 1070 /* This is a draft for IOMMU support 967 1071 968 1072 // loop on all virtual pages covering the user buffer … … 1014 1118 1015 1119 // invalidate data cache in case of memory write 1016 if (to_user) { 1017 _dcache_buf_invalidate((void *) user_vaddr, length); 1018 } 1019 1020 // get the lock 1021 _get_lock(&_dma_lock[dma_id]); 1120 if (to_user) _dcache_buf_invalidate((void *) user_vaddr, length); 1121 1122 // get the lock 1123 // _get_lock(&_dma_lock[dma_id]); 1124 1125 #if GIET_DEBUG_DMA_DRIVER 1126 _get_lock(&_tty_put_lock); 1127 _puts("\n[GIET DEBUG] DMA TRANSFER at cycle "); 1128 _putd( _proctime() ); 1129 _puts("\n - cluster_id = "); 1130 _putx( cluster_id ); 1131 _puts("\n - channel_id = "); 1132 _putx( channel_id ); 1133 _puts("\n - dma_vbase = "); 1134 _putx( (unsigned int)dma_vbase ); 1135 _puts("\n - device_buf_vbase = "); 1136 _putx( device_vbase ); 1137 _puts("\n - device_buf_pbase = "); 1138 _putl( device_pbase ); 1139 _puts("\n - user_buf_vbase = "); 1140 _putx( user_vaddr ); 1141 _puts("\n - user_buf_pbase = "); 1142 _putl( user_pbase ); 1143 _puts("\n"); 1144 _release_lock(&_tty_put_lock); 1145 #endif 1022 1146 1023 1147 // DMA configuration 1024 if (to_user) { 1025 dma_base[loc_id * DMA_SPAN + DMA_SRC] = (unsigned int) device_pbase; 1026 dma_base[loc_id * DMA_SPAN + DMA_DST] = (unsigned int) user_pbase; 1027 } 1028 else { 1029 dma_base[loc_id * DMA_SPAN + DMA_SRC] = (unsigned int) user_pbase; 1030 dma_base[loc_id * DMA_SPAN + DMA_DST] = (unsigned int) device_pbase; 1031 } 1032 dma_base[loc_id * DMA_SPAN + DMA_LEN] = (unsigned int) length; 1033 1034 return 0; 1035 #else //NB_DMAS_MAX == 0 1036 return -1; 1037 #endif 1148 if (to_user) 1149 { 1150 dma_vbase[channel_id * DMA_SPAN + DMA_SRC] = (unsigned int)(device_pbase); 1151 dma_vbase[channel_id * DMA_SPAN + DMA_SRC_EXT] = (unsigned int)(device_pbase>>32); 1152 dma_vbase[channel_id * DMA_SPAN + DMA_DST] = (unsigned int)(user_pbase); 1153 dma_vbase[channel_id * DMA_SPAN + DMA_DST_EXT] = (unsigned int)(user_pbase>>32); 1154 } 1155 else 1156 { 1157 dma_vbase[channel_id * DMA_SPAN + DMA_SRC] = (unsigned int)(user_pbase); 1158 dma_vbase[channel_id * DMA_SPAN + DMA_SRC_EXT] = (unsigned int)(user_pbase>>32); 1159 dma_vbase[channel_id * DMA_SPAN + DMA_DST] = (unsigned int)(device_pbase); 1160 dma_vbase[channel_id * DMA_SPAN + DMA_DST_EXT] = (unsigned int)(device_pbase>>32); 1161 } 1162 dma_vbase[channel_id * DMA_SPAN + DMA_LEN] = (unsigned int) length; 1163 1164 return 0; 1165 1166 #else // NB_DMA_CHANNELS == 0 1167 _get_lock(&_tty_put_lock); 1168 _puts("\n[GIET ERROR] in _dma_transfer() : NB_DMA_CHANNELS == 0"); 1169 _release_lock(&_tty_put_lock); 1170 return 1; 1171 #endif 1172 1038 1173 } // end _dma_transfer() 1039 1174 … … 1047 1182 // (1 == read error / 2 == DMA idle error / 3 == write error) 1048 1183 ////////////////////////////////////////////////////////////////////////////////// 1049 unsigned int _dma_completed() {1050 #if NB_DMAS_MAX > 0 1051 unsigned int task_id = _get_proc_task_id(); 1052 unsigned int dma_id = _get_context_slot( task_id,CTX_DMA_ID);1184 unsigned int _dma_completed() 1185 { 1186 #if NB_DMA_CHANNELS > 0 1187 unsigned int dma_id = _get_context_slot(CTX_DMA_ID); 1053 1188 unsigned int dma_ret; 1054 1189 1055 1190 // busy waiting with a pseudo random delay between bus access 1056 while (_dma_done[dma_id] == 0) { 1191 while (_dma_done[dma_id] == 0) 1192 { 1057 1193 unsigned int delay = (( _proctime() ^ _procid() << 4) & 0x3F) + 1; 1058 1194 asm volatile( … … 1067 1203 } 1068 1204 1069 /* draft support for IOMMU 1070 // unmap the buffer from IOMMU page table if IOMMU is activated 1071 if ( GIET_IOMMU_ACTIVE ) 1072 { 1073 unsigned int* iob_address = (unsigned int*)&seg_iob_base; 1074 1075 unsigned int ix1 = _dma_iommu_ix1 + dma_id; 1076 unsigned int ix2; 1077 1078 for ( ix2 = 0 ; ix2 < _dma_iommu_npages[dma_id] ; ix2++ ) 1079 { 1080 // unmap the page in IOMMU page table 1081 _iommu_inval_pte2( ix1, // PT1 index 1082 ix2 ); // PT2 index 1083 1084 // clear IOMMU TLB 1085 iob_address[IOB_INVAL_PTE] = (ix1 << 21) | (ix2 << 12); 1086 } 1087 } 1088 */ 1205 #if GIET_DEBUG_DMA_DRIVER 1206 _get_lock(&_tty_put_lock); 1207 _puts("\n[GIET DEBUG] DMA COMPLETED at cycle "); 1208 _putd( _proctime() ); 1209 _puts("\n - cluster_id = "); 1210 _putx( dma_id/NB_DMA_CHANNELS ); 1211 _puts("\n - channel_id = "); 1212 _putx( dma_id%NB_DMA_CHANNELS ); 1213 _puts("\n"); 1214 _release_lock(&_tty_put_lock); 1215 #endif 1089 1216 1090 1217 // reset synchronization variables … … 1092 1219 dma_ret = _dma_status[dma_id]; 1093 1220 asm volatile("sync\n"); 1094 _dma_lock[dma_id] = 0; 1221 1222 // _dma_lock[dma_id] = 0; 1095 1223 1096 1224 return dma_ret; 1097 1225 1098 #else // NB_DMAS_MAX== 01226 #else // NB_DMA_CHANNELS == 0 1099 1227 return -1; 1100 1228 #endif 1229 1101 1230 } // end _dma_completed 1231 1102 1232 1103 1233 ////////////////////////////////////////////////////////////////////////////////// … … 1113 1243 // The '_fb_write()', '_fb_read()' and '_fb_completed()' functions use the 1114 1244 // VciMultiDma components (distributed in the clusters) to transfer data 1115 // between the user buffer and the frame buffer. A FBDMA channel is1245 // between the user buffer and the frame buffer. A DMA channel is 1116 1246 // allocated to each task requesting it in the mapping_info data structure. 1117 1247 ////////////////////////////////////////////////////////////////////////////////// … … 1124 1254 // - length : number of bytes to be transfered. 1125 1255 ////////////////////////////////////////////////////////////////////////////////// 1126 unsigned int _fb_sync_write(unsigned int offset, const void * buffer, unsigned int length) { 1127 unsigned char * fb_address = (unsigned char *) &seg_fbf_base + offset; 1256 unsigned int _fb_sync_write( unsigned int offset, 1257 const void* buffer, 1258 unsigned int length) 1259 { 1260 unsigned char* fb_address = (unsigned char *) &seg_fbf_base + offset; 1128 1261 memcpy((void *) fb_address, (void *) buffer, length); 1129 1262 return 0; … … 1138 1271 // - length : number of bytes to be transfered. 1139 1272 ////////////////////////////////////////////////////////////////////////////////// 1140 unsigned int _fb_sync_read(unsigned int offset, const void * buffer, unsigned int length) { 1141 unsigned char * fb_address = (unsigned char *) &seg_fbf_base + offset; 1273 unsigned int _fb_sync_read( unsigned int offset, 1274 const void* buffer, 1275 unsigned int length) 1276 { 1277 unsigned char* fb_address = (unsigned char *) &seg_fbf_base + offset; 1142 1278 memcpy((void *) buffer, (void *) fb_address, length); 1143 1279 return 0; … … 1153 1289 // Returns 0 if success, > 0 if error. 1154 1290 ////////////////////////////////////////////////////////////////////////////////// 1155 unsigned int _fb_write(unsigned int offset, const void * buffer, unsigned int length) { 1156 return _dma_transfer( 1157 0, // frame buffer 1158 0, // write 1159 offset, 1160 (unsigned int) buffer, 1161 length); 1291 unsigned int _fb_write( unsigned int offset, 1292 const void* buffer, 1293 unsigned int length) 1294 { 1295 return _dma_transfer( 0, // frame buffer 1296 0, // write 1297 offset, 1298 (unsigned int) buffer, 1299 length ); 1162 1300 } 1163 1301 … … 1171 1309 // Returns 0 if success, > 0 if error. 1172 1310 ////////////////////////////////////////////////////////////////////////////////// 1173 unsigned int _fb_read(unsigned int offset, const void * buffer, unsigned int length) { 1174 return _dma_transfer( 1175 0, // frame buffer 1176 1, // read 1177 offset, 1178 (unsigned int) buffer, 1179 length); 1311 unsigned int _fb_read( unsigned int offset, 1312 const void* buffer, 1313 unsigned int length ) 1314 { 1315 return _dma_transfer( 0, // frame buffer 1316 1, // read 1317 offset, 1318 (unsigned int) buffer, 1319 length ); 1180 1320 } 1181 1321 … … 1188 1328 // (1 == read error / 2 == DMA idle error / 3 == write error) 1189 1329 ////////////////////////////////////////////////////////////////////////////////// 1190 unsigned int _fb_completed() { 1330 unsigned int _fb_completed() 1331 { 1191 1332 return _dma_completed(); 1192 1333 } … … 1215 1356 // - length : number of bytes to be transfered. 1216 1357 ////////////////////////////////////////////////////////////////////////////////// 1217 unsigned int _nic_sync_write(unsigned int offset, const void * buffer, unsigned int length) { 1218 unsigned char * nic_address = (unsigned char *) &seg_nic_base + offset; 1358 unsigned int _nic_sync_write( unsigned int offset, 1359 const void* buffer, 1360 unsigned int length ) 1361 { 1362 unsigned char* nic_address = (unsigned char *) &seg_nic_base + offset; 1219 1363 memcpy((void *) nic_address, (void *) buffer, length); 1220 1364 return 0; … … 1279 1423 // (1 == read error / 2 == DMA idle error / 3 == write error) 1280 1424 ////////////////////////////////////////////////////////////////////////////////// 1281 unsigned int _nic_completed() { 1425 unsigned int _nic_completed() 1426 { 1282 1427 return _dma_completed(); 1283 1428 } … … 1286 1431 // _heap_info() 1287 1432 // This function returns the information associated to a heap (size and vaddr) 1288 // It uses the global task i d(CTX_GTID_ID, unique for each giet task) and the1289 // vspace i d (CTX_VSID_ID) defined in the context1433 // It uses the global task index (CTX_GTID_ID, unique for each giet task) and the 1434 // vspace index (CTX_VSID_ID) defined in the task context. 1290 1435 /////////////////////////////////////////////////////////////////////////////////// 1291 unsigned int _heap_info(unsigned int * vaddr, unsigned int * size) { 1436 unsigned int _heap_info( unsigned int* vaddr, 1437 unsigned int* size ) 1438 { 1292 1439 mapping_header_t * header = (mapping_header_t *) (&seg_mapping_base); 1293 1440 mapping_task_t * tasks = _get_task_base(header); 1294 1441 mapping_vobj_t * vobjs = _get_vobj_base(header); 1295 1442 mapping_vspace_t * vspaces = _get_vspace_base(header); 1296 unsigned int taskid = _get_context_slot(_get_proc_task_id(), CTX_GTID_ID); 1297 unsigned int vspaceid = _get_context_slot(_get_proc_task_id(), CTX_VSID_ID); 1443 1444 unsigned int taskid = _get_context_slot(CTX_GTID_ID); 1445 unsigned int vspaceid = _get_context_slot(CTX_VSID_ID); 1446 1298 1447 int heap_local_vobjid = tasks[taskid].heap_vobjid; 1299 if (heap_local_vobjid != -1) { 1448 if (heap_local_vobjid != -1) 1449 { 1300 1450 unsigned int vobjheapid = heap_local_vobjid + vspaces[vspaceid].vobj_offset; 1301 1451 *vaddr = vobjs[vobjheapid].vaddr; … … 1303 1453 return 0; 1304 1454 } 1305 else { 1455 else 1456 { 1306 1457 *vaddr = 0; 1307 1458 *size = 0; -
soft/giet_vm/sys/exc_handler.c
r232 r238 67 67 68 68 69 static void _display_cause(unsigned int type) { 69 static void _display_cause(unsigned int type) 70 { 70 71 _get_lock(&_tty_put_lock); 71 72 _puts("\n[GIET] Exception for task "); 72 _putd(_get_ proc_task_id());73 _putd(_get_context_slot(CTX_LTID_ID)); 73 74 _puts(" on processor "); 74 75 _putd(_procid()); … … 86 87 87 88 // goes to sleeping state 88 unsigned int task_id = _get_proc_task_id(); 89 _set_context_slot( task_id, CTX_RUN_ID, 0); 89 _set_context_slot(CTX_RUN_ID, 0); 90 90 91 91 // deschedule -
soft/giet_vm/sys/hwr_mapping.h
r228 r238 7 7 8 8 /* IOC (block device) */ 9 enum IOC_registers { 9 enum IOC_registers 10 { 10 11 BLOCK_DEVICE_BUFFER, 11 12 BLOCK_DEVICE_LBA, … … 16 17 BLOCK_DEVICE_SIZE, 17 18 BLOCK_DEVICE_BLOCK_SIZE, 19 BLOCK_DEVICE_BUFFER_EXT, 18 20 }; 19 enum IOC_operations { 21 enum IOC_operations 22 { 20 23 BLOCK_DEVICE_NOOP, 21 24 BLOCK_DEVICE_READ, 22 25 BLOCK_DEVICE_WRITE, 23 26 }; 24 enum IOC_status{ 27 enum IOC_status 28 { 25 29 BLOCK_DEVICE_IDLE, 26 30 BLOCK_DEVICE_BUSY, … … 33 37 34 38 /* DMA */ 35 enum DMA_registers { 39 enum DMA_registers 40 { 36 41 DMA_SRC = 0, 37 42 DMA_DST = 1, … … 39 44 DMA_RESET = 3, 40 45 DMA_IRQ_DISABLE = 4, 46 DMA_SRC_EXT = 5, 47 DMA_DST_EXT = 6, 41 48 /**/ 42 DMA_END = 5,49 DMA_END = 7, 43 50 DMA_SPAN = 8, 44 51 }; 45 52 46 53 /* GCD */ 47 enum GCD_registers { 54 enum GCD_registers 55 { 48 56 GCD_OPA = 0, 49 57 GCD_OPB = 1, … … 55 63 56 64 /* ICU */ 57 enum ICU_registers { 65 enum ICU_registers 66 { 58 67 ICU_INT = 0, 59 68 ICU_MASK = 1, … … 65 74 ICU_SPAN = 8, 66 75 }; 67 enum Xicu_registers { 76 enum Xicu_registers 77 { 68 78 XICU_WTI_REG = 0, 69 79 XICU_PTI_PER = 1, … … 92 102 93 103 /* TIMER */ 94 enum TIMER_registers { 104 enum TIMER_registers 105 { 95 106 TIMER_VALUE = 0, 96 107 TIMER_MODE = 1, … … 102 113 103 114 /* TTY */ 104 enum TTY_registers { 115 enum TTY_registers 116 { 105 117 TTY_WRITE = 0, 106 118 TTY_STATUS = 1, … … 112 124 113 125 /* IOB */ 114 enum IOB_registers { 126 enum IOB_registers 127 { 115 128 IOB_IOMMU_PTPR = 0, /* R/W : Page Table Pointer Register */ 116 129 IOB_IOMMU_ACTIVE = 1, /* R/W : IOMMU activated if not 0 */ … … 125 138 126 139 /* MWMR */ 127 enum SoclibMwmrRegisters { 140 enum SoclibMwmrRegisters 141 { 128 142 MWMR_IOREG_MAX = 16, 129 143 MWMR_RESET = MWMR_IOREG_MAX, … … 138 152 }; 139 153 140 enum SoclibMwmrWay { 154 enum SoclibMwmrWay 155 { 141 156 MWMR_TO_COPROC, 142 157 MWMR_FROM_COPROC, -
soft/giet_vm/sys/irq_handler.c
r237 r238 19 19 #include <hwr_mapping.h> 20 20 21 #if NB_TIM ERS_MAX22 extern volatile unsigned char _user_timer_event[NB_CLUSTERS * NB_TIM ERS_MAX] ;21 #if NB_TIM_CHANNELS 22 extern volatile unsigned char _user_timer_event[NB_CLUSTERS * NB_TIM_CHANNELS] ; 23 23 #endif 24 24 … … 33 33 // 34 34 // There is one interrupt vector per processor (stored in the scheduler associated 35 // to the processor. Each interrupt vector entry contains two 16 bits fields: 36 // - isr_id : defines the type of ISR to be executed. 35 // to the processor. Each interrupt vector entry contains three bits fields: 36 // - isr_id : defines the type of ISR to be executed. 37 // - type_id : HWI if zero / PTI if non zero 37 38 // - channel_id : defines the specific channel for multi-channels peripherals. 38 39 // … … 40 41 // a global index : channel_id = cluster_id * NB_CHANNELS_MAX + loc_id 41 42 /////////////////////////////////////////////////////////////////////////////////// 42 void _irq_demux() { 43 void _irq_demux() 44 { 43 45 unsigned int pid = _procid(); 44 46 unsigned int irq_id; 45 47 46 47 48 // get the highest priority active IRQ index 48 if (_icu_get_index( pid / NB_PROCS_MAX, pid % NB_PROCS_MAX, &irq_id)) { 49 if (_icu_get_index( pid / NB_PROCS_MAX, pid % NB_PROCS_MAX, &irq_id)) 50 { 49 51 _get_lock(&_tty_put_lock); 50 52 _puts("\n[GIET ERROR] Strange... Wrong _icu_read in _irq_demux()\n"); … … 52 54 } 53 55 54 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 type_id = (entry >> 8) & 0x000000FF; 60 unsigned int channel_id = (entry >> 16) & 0x0000FFFF; 56 // do nothing if no interrupt active 57 if (irq_id < 32) 58 { 59 static_scheduler_t* psched = _get_sched(); 60 unsigned int entry = psched->interrupt_vector[irq_id]; 61 unsigned int isr_id = entry & 0x000000FF; 62 unsigned int type_id = (entry >> 8) & 0x000000FF; 63 unsigned int channel_id = (entry >> 16) & 0x0000FFFF; 64 61 65 if(type_id == 0) // HARD irq type 62 66 { … … 76 80 } 77 81 78 79 82 /////////////////////////////////////////////////////////////////////////////////// 80 83 // _isr_default() … … 82 85 // interrupt vector. It simply displays an error message on kernel TTY[0]. 83 86 /////////////////////////////////////////////////////////////////////////////////// 84 void _isr_default() { 87 void _isr_default() 88 { 85 89 _get_lock(&_tty_put_lock); 86 90 _puts("\n[GIET ERROR] Strange... Default ISR activated for processor "); … … 96 100 // The multi_dma components can be distributed in the clusters. 97 101 // The channel_id argument is the local DMA channel index. 98 // dma_global_id = cluster_id*NB_DMA S_MAX+ channel_id102 // dma_global_id = cluster_id*NB_DMA_CHANNELS + channel_id 99 103 // - The ISR saves the transfert status in _dma_status[dma_global_id]. 100 104 // - It acknowledges the interrupt to reinitialize the DMA controler. 101 105 // - it resets the synchronisation variable _dma_busy[dma_global_id]. 102 106 /////////////////////////////////////////////////////////////////////////////////// 103 void _isr_dma(unsigned int channel_id) { 104 #if NB_DMAS_MAX > 0 107 void _isr_dma(unsigned int channel_id) 108 { 109 #if NB_DMA_CHANNELS > 0 105 110 // compute cluster_id 106 111 unsigned int cluster_id = _procid() / NB_PROCS_MAX; 107 112 108 113 // compute dma_global_id 109 unsigned int dma_global_id = cluster_id * NB_DMA S_MAX+ channel_id;114 unsigned int dma_global_id = cluster_id * NB_DMA_CHANNELS + channel_id; 110 115 111 116 // save DMA channel status 112 117 if (_dma_get_status(cluster_id, channel_id, 113 (unsigned int *) &_dma_status[dma_global_id])) { 118 (unsigned int *) &_dma_status[dma_global_id])) 119 { 114 120 _get_lock(&_tty_put_lock); 115 121 _puts("[GIET ERROR] illegal DMA channel detected by _isr_dma\n"); … … 119 125 120 126 // reset DMA channel irq 121 if (_dma_reset_irq(cluster_id, channel_id)) { 127 if (_dma_reset_irq(cluster_id, channel_id)) 128 { 122 129 _get_lock(&_tty_put_lock); 123 130 _puts("[GIET ERROR] illegal DMA channel detected by _isr_dma\n"); … … 128 135 // release DMA channel 129 136 _dma_done[dma_global_id] = 1; 137 130 138 #else 131 _puts("[GIET ERROR] NB_DMAS_MAX is set to zero\n"); 132 139 _get_lock(&_tty_put_lock); 140 _puts("[GIET ERROR] NB_DMA_CHANNELS is set to zero\n"); 141 _release_lock(&_tty_put_lock); 133 142 #endif 134 143 } … … 140 149 // - It sets the _ioc_done variable to signal completion. 141 150 /////////////////////////////////////////////////////////////////////////////////// 142 void _isr_ioc() { 151 void _isr_ioc() 152 { 143 153 // save status & reset IRQ 144 if (_ioc_get_status((unsigned int *) &_ioc_status )) { 154 if (_ioc_get_status((unsigned int *) &_ioc_status )) 155 { 145 156 _get_lock(&_tty_put_lock); 146 157 _puts("[GIET ERROR] bad access to IOC status detected by _isr_ioc\n"); … … 161 172 // in a vci_multi_timer component, or in a vci_xicu component. 162 173 // The timer_id argument is the user timer local index. 163 // timer_globa_id = cluster_id*(NB_TIM ERS_MAX) + timer_id174 // timer_globa_id = cluster_id*(NB_TIM_CHANNELS) + timer_id 164 175 // The ISR acknowledges the IRQ and registers the event in the proper entry 165 176 // of the _timer_event[] array, and a log message is displayed on kernel terminal. 166 177 /////////////////////////////////////////////////////////////////////////////////// 167 void _isr_timer(unsigned int timer_id) { 178 void _isr_timer(unsigned int timer_id) 179 { 168 180 // compute cluster_id 169 181 unsigned int cluster_id = _procid() / NB_PROCS_MAX; 170 182 171 183 // aknowledge IRQ 172 if (_timer_reset_irq( cluster_id, timer_id)) { 184 if (_timer_reset_irq( cluster_id, timer_id)) 185 { 173 186 _get_lock(&_tty_put_lock); 174 187 _puts("[GIET ERROR] illegal timer index detected by _isr_timer\n"); … … 177 190 } 178 191 179 #if NB_TIM ERS_MAX192 #if NB_TIM_CHANNELS 180 193 // register the event 181 unsigned int timer_global_id = cluster_id * NB_TIM ERS_MAX+ timer_id;194 unsigned int timer_global_id = cluster_id * NB_TIM_CHANNELS + timer_id; 182 195 _user_timer_event[timer_global_id] = 1; 183 196 #endif … … 207 220 // A character is lost if the buffer is full when the ISR is executed. 208 221 /////////////////////////////////////////////////////////////////////////////////// 209 void _isr_tty(unsigned int tty_id) { 222 void _isr_tty(unsigned int tty_id) 223 { 210 224 // save character and reset IRQ 211 if (_tty_get_char( tty_id, (unsigned char *) &_tty_get_buf[tty_id])) { 225 if (_tty_get_char( tty_id, (unsigned char *) &_tty_get_buf[tty_id])) 226 { 212 227 _get_lock(&_tty_put_lock); 213 228 _puts("[GIET ERROR] illegal tty index detected by _isr_tty\n"); … … 229 244 // The ISR acknowledges the IRQ and calls the _ctx_switch() function. 230 245 ///////////////////////////////////////////////////////////////////////////////////// 231 void _isr_switch( unsigned int timer_id) { 246 void _isr_switch( unsigned int timer_id) 247 { 232 248 // get cluster index and proc local index 233 249 unsigned int cluster_id = _procid() / NB_PROCS_MAX; 234 250 235 251 // acknowledge IRQ 236 if (_timer_reset_irq(cluster_id, timer_id)) { 252 if (_timer_reset_irq(cluster_id, timer_id)) 253 { 237 254 _get_lock(&_tty_put_lock); 238 255 _puts("[GIET ERROR] illegal proc index detected by _isr_switch\n"); -
soft/giet_vm/sys/irq_handler.h
r228 r238 2 2 #define _IRQ_HANDLER_H 3 3 4 enum 4 enum isr_type_t 5 5 { 6 6 ISR_DEFAULT = 0, -
soft/giet_vm/sys/kernel_init.c
r228 r238 33 33 34 34 /////////////////////////////////////////////////////////////////////////////////// 35 // array of pointers on the page tables ( both virtual and physical addresses)35 // array of pointers on the page tables (virtual addresses) 36 36 /////////////////////////////////////////////////////////////////////////////////// 37 37 38 38 __attribute__((section (".kdata"))) 39 unsigned int _ptabs_paddr[GIET_NB_VSPACE_MAX]; 39 unsigned int _ptabs[GIET_NB_VSPACE_MAX]; // virtual addresses 40 41 __attribute__((section (".kdata"))) 42 unsigned int _ptprs[GIET_NB_VSPACE_MAX]; // physical addresses >> 13 43 44 /////////////////////////////////////////////////////////////////////////////////// 45 // array of pointers on the schedulers (physical addresses) 46 /////////////////////////////////////////////////////////////////////////////////// 40 47 41 48 __attribute__((section (".kdata"))) 42 unsigned int _ptabs_vaddr[GIET_NB_VSPACE_MAX];43 44 /////////////////////////////////////////////////////////////////////////////////// 45 // array of pointers on the schedulers (physical addresses)49 static_scheduler_t* _schedulers[NB_CLUSTERS * NB_PROCS_MAX]; 50 51 /////////////////////////////////////////////////////////////////////////////////// 52 // staks for the "idle" tasks (256 bytes for each processor) 46 53 /////////////////////////////////////////////////////////////////////////////////// 47 54 48 55 __attribute__((section (".kdata"))) 49 static_scheduler_t * _schedulers_paddr[NB_CLUSTERS * NB_PROCS_MAX]; 50 51 /////////////////////////////////////////////////////////////////////////////////// 52 // staks for the "idle" tasks (256 bytes for each processor) 53 /////////////////////////////////////////////////////////////////////////////////// 54 55 __attribute__((section (".kdata"))) 56 unsigned int _idle_stack[NB_CLUSTERS*NB_PROCS_MAX * 64]; 57 58 void _sys_exit() { 56 unsigned int _idle_stack[NB_CLUSTERS * NB_PROCS_MAX * 64]; 57 58 //////////////// 59 void _sys_exit() 60 { 59 61 while (1); 60 62 } … … 63 65 ////////////////////////////////////////////////////////////////////////////////// 64 66 // This function is the entry point for the last step of the boot sequence. 67 // that is done in parallel by all processors, with MMU activated. 65 68 ////////////////////////////////////////////////////////////////////////////////// 66 __attribute__((section (".kinit"))) void _kernel_init() { 67 // compute cluster and local processor index 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; 71 72 // Step 0 : Compute number of tasks allocated to proc 73 74 unsigned int tasks = _get_tasks_number(); 75 76 #if GIET_DEBUG_INIT 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); 84 #endif 85 86 // step 1 : Initialise scheduler physical addresses array 87 // get scheduler physical address (from CP0 register) 88 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); 100 #endif 101 102 // step 2 : initialise page table addresse arrays 69 __attribute__((section (".kinit"))) void _kernel_init() 70 { 71 // Step 1 : get processor index, 72 // get scheduler address 73 // initialise _schedulers[] array 74 75 unsigned int global_pid = _procid(); 76 unsigned int cluster_id = global_pid / NB_PROCS_MAX; 77 unsigned int proc_id = global_pid % NB_PROCS_MAX; 78 static_scheduler_t* psched = _get_sched(); 79 unsigned int tasks = psched->tasks; 80 81 _schedulers[global_pid] = psched; 82 83 #if GIET_DEBUG_INIT 84 _get_lock(&_tty_put_lock); 85 _puts("\n[GIET DEBUG] step 1 for processor "); 86 _putd(global_pid); 87 _puts(" : tasks = "); 88 _putd(tasks); 89 _puts(" / scheduler vbase = "); 90 _putx((unsigned int) psched); 91 _puts("\n"); 92 _release_lock(&_tty_put_lock); 93 #endif 94 95 // step 2 : initialise ptabs[] & ptprs[] arrays 103 96 // each processor scans all tasks contexts in its 104 97 // private scheduler and get VSID, PTAB and PTPR values … … 106 99 unsigned int ltid; 107 100 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; 112 113 _ptabs_vaddr[vspace_id] = ptab_vaddr; 114 _ptabs_paddr[vspace_id] = ptab_paddr; 115 116 #if GIET_DEBUG_INIT 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); 101 for (ltid = 0; ltid < tasks; ltid++) 102 { 103 unsigned int vsid = _get_task_slot(ltid , CTX_VSID_ID); 104 unsigned int ptab = _get_task_slot(ltid , CTX_PTAB_ID); 105 unsigned int ptpr = _get_task_slot(ltid , CTX_PTPR_ID); 106 107 _ptabs[vsid] = ptab; 108 _ptprs[vsid] = ptpr; 109 110 #if GIET_DEBUG_INIT 111 _get_lock(&_tty_put_lock); 112 _puts("\n[GIET DEBUG] step 2 for processor "); 113 _putd(global_pid); 114 _puts(" / vspace "); 115 _putd(vsid); 116 _puts("\n- ptab = "); 117 _putx(ptab); 118 _puts("\n- ptpr = "); 119 _putx(ptpr); 120 _puts("\n"); 121 _release_lock(&_tty_put_lock); 128 122 #endif 129 123 130 124 } 131 132 unsigned int isr_switch_channel = 0xFFFFFFFF;133 125 134 126 // step 3 : compute and set ICU masks … … 136 128 // software interrupts are not supported yet 137 129 138 unsigned int irq_id; 130 unsigned int isr_switch_channel = 0xFFFFFFFF; 131 unsigned int irq_id; // IN_IRQ index 139 132 unsigned int hwi_mask = 0; 140 133 unsigned int pti_mask = 0; 141 134 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)) { 135 for (irq_id = 0; irq_id < 32; irq_id++) 136 { 137 unsigned int entry = psched->interrupt_vector[irq_id]; 138 unsigned int isr = entry & 0x000000FF; 139 140 if ((isr == ISR_DMA) || (isr == ISR_IOC) || (isr == ISR_TTY)) 141 { 147 142 hwi_mask = hwi_mask | 0x1 << irq_id; 148 143 } 149 else if ((isr == ISR_SWITCH)) { 144 else if ((isr == ISR_SWITCH)) 145 { 150 146 pti_mask = pti_mask | 0x1 << irq_id; 151 147 isr_switch_channel = irq_id; 152 148 } 153 else if ((isr == ISR_TIMER)) { 149 else if ((isr == ISR_TIMER)) 150 { 154 151 pti_mask = pti_mask | 0x1 << irq_id; 155 152 } 156 153 } 154 155 #if GIET_DEBUG_INIT 156 _get_lock(&_tty_put_lock); 157 _puts("\n[GIET DEBUG] step 3 for processor "); 158 _putd(global_pid); 159 _puts("\n - ICU HWI_MASK = "); 160 _putx(hwi_mask); 161 _puts("\n - ICU PTI_MASK = "); 162 _putx(pti_mask); 163 _puts("\n"); 164 _release_lock(&_tty_put_lock); 165 #endif 166 157 167 _icu_set_mask(cluster_id, proc_id, hwi_mask, 0); // set HWI_MASK 158 168 _icu_set_mask(cluster_id, proc_id, pti_mask, 1); // set PTI_MASK 159 169 160 #if GIET_DEBUG_INIT161 _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);170 #endif171 172 170 // step 4 : start TICK timer if more than one task 173 if (tasks > 1) { 174 if (isr_switch_channel == 0xFFFFFFFF) { 171 if (tasks > 1) 172 { 173 if (isr_switch_channel == 0xFFFFFFFF) 174 { 175 175 _get_lock(&_tty_put_lock); 176 176 _puts("\n[GIET ERROR] ISR_SWITCH not found on proc "); … … 181 181 } 182 182 183 if (_timer_start( cluster_id, isr_switch_channel, GIET_TICK_VALUE)) { 183 if (_timer_start( cluster_id, isr_switch_channel, GIET_TICK_VALUE)) 184 { 184 185 _get_lock(&_tty_put_lock); 185 186 _puts("\n[GIET ERROR] ISR_SWITCH init error for proc "); … … 191 192 192 193 #if GIET_DEBUG_INIT 193 194 195 196 197 194 _get_lock(&_tty_put_lock); 195 _puts("\n[GIET DEBUG] Step 4 for processor "); 196 _putd(global_pid); 197 _puts(" / context switch activated\n"); 198 _release_lock(&_tty_put_lock); 198 199 #endif 199 200 … … 206 207 // the stack size is 256 bytes 207 208 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); 209 unsigned int stack = (unsigned int)_idle_stack + ((global_pid + 1)<<8); 210 211 _set_task_slot( IDLE_TASK_INDEX, CTX_RUN_ID, 1); 212 _set_task_slot( IDLE_TASK_INDEX, CTX_SR_ID, 0xFF03); 213 _set_task_slot( IDLE_TASK_INDEX, CTX_SP_ID, stack); 214 _set_task_slot( IDLE_TASK_INDEX, CTX_RA_ID, (unsigned int) &_ctx_eret); 215 _set_task_slot( IDLE_TASK_INDEX, CTX_EPC_ID, (unsigned int) &_ctx_idle); 216 _set_task_slot( IDLE_TASK_INDEX, CTX_LTID_ID, IDLE_TASK_INDEX); 217 _set_task_slot( IDLE_TASK_INDEX, CTX_PTPR_ID, _ptprs[0]); 218 219 #if GIET_DEBUG_INIT 220 _get_lock(&_tty_put_lock); 221 _puts("\n[GIET DEBUG] Step 5 for processor "); 222 _putd(global_pid); 223 _puts(" / idle task context set\n"); 224 _release_lock(&_tty_put_lock); 222 225 #endif 223 226 … … 226 229 // and starts the "idle" task if there is no task allocated. 227 230 228 unsigned int task_id; 229 230 if (tasks == 0) { 231 task_id = IDLE_TASK_INDEX; 231 ltid = 0; 232 233 if (tasks == 0) 234 { 235 ltid = IDLE_TASK_INDEX; 232 236 233 237 _get_lock(&_tty_put_lock); … … 237 241 _release_lock (&_tty_put_lock); 238 242 } 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); 266 #endif 243 244 unsigned int sp_value = _get_task_slot(ltid, CTX_SP_ID); 245 unsigned int sr_value = _get_task_slot(ltid, CTX_SR_ID); 246 unsigned int ptpr_value = _get_task_slot(ltid, CTX_PTPR_ID); 247 unsigned int epc_value = _get_task_slot(ltid, CTX_EPC_ID); 248 249 _set_task_slot( ltid, CTX_LTID_ID, ltid); 250 251 #if GIET_DEBUG_INIT 252 _get_lock(&_tty_put_lock); 253 _puts("\n[GIET DEBUG] step 6 for processor "); 254 _putd(global_pid); 255 _puts(" / registers initialised \n"); 256 _puts("- sp = "); 257 _putx(sp_value); 258 _puts("\n"); 259 _puts("- sr = "); 260 _putx(sr_value); 261 _puts("\n"); 262 _puts("- ptpr = "); 263 _putx(ptpr_value); 264 _puts("\n"); 265 _puts("- epc = "); 266 _putx(epc_value); 267 _puts("\n"); 268 _release_lock(&_tty_put_lock); 269 #endif 270 271 _get_lock(&_tty_put_lock); 272 _puts("\n[GIET] Processor "); 273 _putd( global_pid ); 274 _puts(" starting user code at cycle "); 275 _putd( _proctime() ); 276 _puts("\n"); 277 _release_lock(&_tty_put_lock); 267 278 268 279 // set registers and jump to user code -
soft/giet_vm/sys/mips32_registers.h
r228 r238 47 47 /* CP0 registers */ 48 48 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 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,0 56 #define CP0_SCHED_EXT $22,1 56 57 57 58 /* CP2 registers */ -
soft/giet_vm/sys/switch.s
r199 r238 1 1 /****************************************************************************** 2 2 * This function receives two arguments that are the current task context 3 * physical addresses and the next task context physical address. 4 * The DTLB is temporary desactivated... 3 * (virtual) addresses and the next task context (virtual) address. 5 4 ******************************************************************************/ 6 5 … … 10 9 11 10 _task_switch: 12 13 /* desactivate DTLB */14 ori $27, $0, 0xB15 mtc2 $27, $1 /* DTLB desactivated */16 11 17 12 /* save _current task context */ … … 113 108 mtc2 $26, $0 /* restore PTPR */ 114 109 115 /* activate DTLB */116 ori $27, $0, 0xF117 mtc2 $27, $1118 119 110 /* returns to caller */ 120 111 jr $31 -
soft/giet_vm/sys/sys_handler.c
r237 r238 31 31 &_gcd_read, /* 0x07 */ 32 32 &_heap_info, /* 0x08 */ 33 &_ get_proc_task_id,/* 0x09 */34 &_g et_global_task_id,/* 0x0A */33 &_local_task_id, /* 0x09 */ 34 &_global_task_id, /* 0x0A */ 35 35 &_sys_ukn, /* 0x0B */ 36 36 &_sys_ukn, /* 0x0C */ … … 69 69 } 70 70 71 72 71 //////////////////////////////////////////////////////////////////////////// 73 72 // _exit() … … 77 76 unsigned int date = _proctime(); 78 77 unsigned int proc_id = _procid(); 79 unsigned int task_id = _get_ proc_task_id();78 unsigned int task_id = _get_context_slot(CTX_LTID_ID); 80 79 81 80 // print death message … … 91 90 92 91 // goes to sleeping state 93 _set_context_slot( task_id,CTX_RUN_ID, 0);92 _set_context_slot(CTX_RUN_ID, 0); 94 93 95 94 // deschedule … … 97 96 } 98 97 99 100 98 ////////////////////////////////////////////////////////////////////////////// 101 99 // _procid() … … 103 101 // Max number or processors is 1024. 104 102 ////////////////////////////////////////////////////////////////////////////// 105 unsigned int _procid() { 103 unsigned int _procid() 104 { 106 105 unsigned int ret; 107 106 asm volatile("mfc0 %0, $15, 1" : "=r" (ret)); … … 109 108 } 110 109 111 112 110 ////////////////////////////////////////////////////////////////////////////// 113 111 // _proctime() 114 112 // Access CP0 and returns current processor's elapsed clock cycles since boot. 115 113 ////////////////////////////////////////////////////////////////////////////// 116 unsigned int _proctime() { 114 unsigned int _proctime() 115 { 117 116 unsigned int ret; 118 117 asm volatile("mfc0 %0, $9" : "=r" (ret)); … … 120 119 } 121 120 122 123 121 ////////////////////////////////////////////////////////////////////////////// 124 122 // _procnumber() … … 126 124 // specified by the cluster_id argument. 127 125 ////////////////////////////////////////////////////////////////////////////// 128 unsigned int _procs_number(unsigned int cluster_id, unsigned int * buffer) { 126 unsigned int _procs_number(unsigned int cluster_id, 127 unsigned int* buffer) 128 { 129 129 mapping_header_t * header = (mapping_header_t *) &seg_mapping_base; 130 130 mapping_cluster_t * cluster = _get_cluster_base(header); … … 139 139 } 140 140 141 142 int _get_vobj(char * vspace_name, char * vobj_name, unsigned int vobj_type, mapping_vobj_t ** res_vobj) { 141 ///////////////////////////////////////////////////////////////////////////// 142 // _local_task_id() 143 // Returns current task local index. 144 ///////////////////////////////////////////////////////////////////////////// 145 unsigned int _local_task_id() 146 { 147 return _get_context_slot(CTX_LTID_ID); 148 } 149 150 ///////////////////////////////////////////////////////////////////////////// 151 // _global_task_id() 152 // Returns current task global index. 153 ///////////////////////////////////////////////////////////////////////////// 154 unsigned int _global_task_id() 155 { 156 return _get_context_slot(CTX_GTID_ID); 157 } 158 159 ///////////////////////////////////////////////////////////////////////////// 160 // _get_vobj() 161 // This function writes in res_vobj a pointer on a vobj 162 // identified by the (vspace_name / vobj_name ) couple. 163 // The vobj_type argument is here only for the purpose of checking . 164 // returns 0: success, else: failed. 165 ///////////////////////////////////////////////////////////////////////////// 166 int _get_vobj( char* vspace_name, 167 char* vobj_name, 168 unsigned int vobj_type, 169 mapping_vobj_t** res_vobj ) 170 { 143 171 mapping_header_t * header = (mapping_header_t *) &seg_mapping_base; 144 172 mapping_vspace_t * vspace = _get_vspace_base(header); 145 mapping_vobj_t * vobj = _get_vobj_base(header);173 mapping_vobj_t * vobj = _get_vobj_base(header); 146 174 147 175 unsigned int vspace_id; … … 149 177 150 178 // scan vspaces 151 for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) { 152 if (_strncmp( vspace[vspace_id].name, vspace_name, 31) == 0) { 179 for (vspace_id = 0; vspace_id < header->vspaces; vspace_id++) 180 { 181 if (_strncmp( vspace[vspace_id].name, vspace_name, 31) == 0) 182 { 153 183 // scan vobjs 154 184 for (vobj_id = vspace[vspace_id].vobj_offset; 155 185 vobj_id < (vspace[vspace_id].vobj_offset + vspace[vspace_id].vobjs); 156 vobj_id++) { 157 158 if (_strncmp(vobj[vobj_id].name, vobj_name, 31) == 0) { 159 if (vobj[vobj_id].type != vobj_type) { 186 vobj_id++) 187 { 188 if (_strncmp(vobj[vobj_id].name, vobj_name, 31) == 0) 189 { 190 if (vobj[vobj_id].type != vobj_type) 191 { 160 192 _get_lock(&_tty_put_lock); 161 193 _puts("*** Error in _get_obj: wrong type\n"); … … 176 208 } 177 209 178 179 210 ///////////////////////////////////////////////////////////////////////////// 180 211 // _vobj_get_vbase() … … 184 215 // returns 0: success, else: failed. 185 216 ///////////////////////////////////////////////////////////////////////////// 186 unsigned int _vobj_get_vbase( 187 char * vspace_name, 188 char * vobj_name, 189 unsigned int vobj_type, 190 unsigned int * vobj_vaddr) { 191 mapping_vobj_t * res_vobj; 192 unsigned int ret; 193 if ((ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj))) { 217 unsigned int _vobj_get_vbase( char* vspace_name, 218 char* vobj_name, 219 unsigned int vobj_type, 220 unsigned int* vobj_vaddr ) 221 { 222 mapping_vobj_t* res_vobj; 223 unsigned int ret; 224 if ((ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj))) 225 { 194 226 return ret; 195 227 } 196 197 228 *vobj_vaddr = res_vobj->vaddr; 198 229 return 0; 199 230 } 200 201 231 202 232 ///////////////////////////////////////////////////////////////////////////// … … 207 237 // returns 0: success, else: failed. 208 238 ///////////////////////////////////////////////////////////////////////////// 209 unsigned int _vobj_get_length( 210 char * vspace_name, 211 char * vobj_name, 212 unsigned int vobj_type, 213 unsigned int * vobj_length) { 214 239 unsigned int _vobj_get_length( char* vspace_name, 240 char* vobj_name, 241 unsigned int vobj_type, 242 unsigned int* vobj_length ) 243 { 215 244 mapping_vobj_t * res_vobj; 216 245 unsigned int ret; 217 if ((ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj))) { 246 if ((ret = _get_vobj(vspace_name, vobj_name, vobj_type, &res_vobj))) 247 { 218 248 return ret; 219 249 } 220 221 250 *vobj_length = res_vobj->length; 222 223 251 return 0; 224 252 } … … 229 257 // This functions masks interruptions before calling _ctx_switch 230 258 // (They are usually masked when we receive a isr_switch interrupt 231 // because we execute isrs with interrupt masked)259 // because we execute ISRs with interrupt masked) 232 260 //////////////////////////////////////////////////////////////// 233 void _context_switch() { 261 void _context_switch() 262 { 234 263 _it_disable(); 235 264 _ctx_switch(); -
soft/giet_vm/sys/sys_handler.h
r228 r238 19 19 ////////////////////////////////////////////////////////////////////////////////// 20 20 21 void _sys_ukn();22 void _exit();23 void _context_switch();21 void _sys_ukn(); 22 void _exit(); 23 void _context_switch(); 24 24 unsigned int _procid(); 25 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); 26 unsigned int _local_task_id(); 27 unsigned int _global_task_id(); 28 29 unsigned int _procs_number( unsigned int cluster_id, 30 unsigned int* buffer ); 31 32 unsigned int _vobj_get_vbase( char* vspace_name, 33 char* vobj_name, 34 unsigned vobj_type, 35 unsigned int* vobj_buffer); 28 36 29 37 #endif -
soft/giet_vm/sys/vm_handler.c
r228 r238 8 8 // They contains the kernel data structures and functions used to dynamically 9 9 // handle the iommu page table. 10 //11 // TODO : We must transfer here the functions used to statically build12 // the page tables associated to the various vspaces (now in boot_handler.c)13 //14 10 /////////////////////////////////////////////////////////////////////////////////// 15 11 … … 18 14 #include <common.h> 19 15 #include <giet_config.h> 16 #include <drivers.h> 20 17 21 18 ///////////////////////////////////////////////////////////////////////////// … … 88 85 // Returns 0 if success, 1 if PTE1 or PTE2 unmapped 89 86 ////////////////////////////////////////////////////////////////////////////// 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; 87 unsigned int _v2p_translate( page_table_t* pt, 88 unsigned int vpn, 89 unsigned int* ppn, 90 unsigned int* flags ) 91 { 92 paddr_t ptba; 93 paddr_t pte2; 94 95 register unsigned int pte2_msb; 96 register unsigned int pte2_lsb; 97 register unsigned int flags_value; 98 register unsigned int ppn_value; 99 99 100 100 unsigned int ix1 = vpn >> 9; 101 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 */ 102 116 103 // check PTE1 mapping 117 if ((pt->pt1[ix1] & PTE_V) == 0) { 118 return 1; 119 } 120 else { 104 if ((pt->pt1[ix1] & PTE_V) == 0) return 1; 105 else 106 { 121 107 // get physical addresses of pte2 122 ptba = pt->pt1[ix1] << 12; 123 pte2 = (unsigned int *) (ptba + 8 * ix2); 108 ptba = (paddr_t)(pt->pt1[ix1] & 0x0FFFFFFF) << 12; 109 pte2 = ptba + 8*ix2; 110 pte2_lsb = (unsigned int)pte2; 111 pte2_msb = (unsigned int)(pte2 >> 32); 124 112 125 113 // gets ppn_value and flags_value, after temporary DTLB desactivation 126 114 asm volatile ( 127 "li $2 7,0xFFFFFFFE \n" /* Mask for IE bits */128 "mfc0 $ 26, $12 \n" /* save SR*/129 "and $2 7, $26, $27\n"130 "mtc0 $2 7,$12 \n" /* disable Interrupts */115 "li $2, 0xFFFFFFFE \n" /* Mask for IE bits */ 116 "mfc0 $4, $12 \n" /* $4 <= SR */ 117 "and $2, $2, $4 \n" 118 "mtc0 $2, $12 \n" /* disable Interrupts */ 131 119 132 "li $ 27,0xB \n"133 "mtc2 $ 27,$1 \n" /* DTLB unactivated */120 "li $3, 0xB \n" 121 "mtc2 $3, $1 \n" /* DTLB unactivated */ 134 122 135 "move $27, %2 \n" /* $27 <= pte2 */ 136 "lw %0, 0($27) \n" /* read flags */ 137 "lw %1, 4($27) \n" /* read ppn */ 123 "mtc2 %2, $24 \n" /* PADDR_EXT <= msb */ 124 "lw %0, 0(%3) \n" /* read flags */ 125 "lw %1, 4(%3) \n" /* read ppn */ 126 "mtc2 $0, $24 \n" /* PADDR_EXT <= 0 */ 138 127 139 "li $ 27,0xF \n"140 "mtc2 $ 27,$1 \n" /* DTLB activated */128 "li $3, 0xF \n" 129 "mtc2 $3, $1 \n" /* DTLB activated */ 141 130 142 "mtc0 $ 26,$12 \n" /* restore SR */131 "mtc0 $4, $12 \n" /* restore SR */ 143 132 : "=r" (flags_value), "=r" (ppn_value) 144 : "r" (pte2 )145 : "$2 6","$27","$8");133 : "r" (pte2_msb), "r" (pte2_lsb) 134 : "$2","$3","$4"); 146 135 147 136 // check PTE2 mapping 148 if ((flags_value & PTE_V) == 0) { 149 return 1; 150 } 137 if ((flags_value & PTE_V) == 0) return 1; 151 138 152 139 // set return values -
soft/giet_vm/xml/mapping_info.h
r232 r238 50 50 #define OUT_MAPPING_SIGNATURE 0xBABEF00D 51 51 52 enum vobjType { 53 VOBJ_TYPE_ELF = 0, // loadable code/data object of elf files 54 VOBJ_TYPE_BLOB = 1, // loadable blob object 55 VOBJ_TYPE_PTAB = 2, // page table 56 VOBJ_TYPE_PERI = 3, // hardware component 57 VOBJ_TYPE_MWMR = 4, // MWMR channel 58 VOBJ_TYPE_LOCK = 5, // Lock 59 VOBJ_TYPE_BUFFER = 6, // Any "no initialization needed" objects (stacks...) 60 VOBJ_TYPE_BARRIER = 7, // Barrier 61 VOBJ_TYPE_CONST = 8, // Constant 62 VOBJ_TYPE_MEMSPACE = 9, // Memspace; different from buffer because we add infos at the beginning 63 }; 64 65 66 enum psegType { 52 typedef unsigned long long paddr_t; 53 54 enum vobjType 55 { 56 VOBJ_TYPE_ELF = 0, // loadable code/data object of elf files 57 VOBJ_TYPE_BLOB = 1, // loadable blob object 58 VOBJ_TYPE_PTAB = 2, // page table 59 VOBJ_TYPE_PERI = 3, // hardware component 60 VOBJ_TYPE_MWMR = 4, // MWMR channel 61 VOBJ_TYPE_LOCK = 5, // Lock 62 VOBJ_TYPE_BUFFER = 6, // Any "no initialization" objects (stacks...) 63 VOBJ_TYPE_BARRIER = 7, // Barrier 64 VOBJ_TYPE_CONST = 8, // Constant 65 VOBJ_TYPE_MEMSPACE = 9, // Memspace (descriptor must be initialised) 66 VOBJ_TYPE_SCHED = 10, // Array of schedulers (one per cluster) 67 }; 68 69 70 enum psegType 71 { 67 72 PSEG_TYPE_RAM = 0, 68 73 PSEG_TYPE_ROM = 1, … … 71 76 72 77 73 enum periphType { 74 PERIPH_TYPE_ICU = 0, 75 PERIPH_TYPE_TIM = 1, 76 PERIPH_TYPE_XICU = 2, 77 PERIPH_TYPE_DMA = 3, 78 PERIPH_TYPE_IOC = 4, 79 PERIPH_TYPE_TTY = 5, 80 PERIPH_TYPE_FBF = 6, 81 PERIPH_TYPE_NIC = 7, 82 PERIPH_TYPE_IOB = 8, 83 }; 84 85 86 enum mwmrPortDirection { 78 enum periphType 79 { 80 PERIPH_TYPE_ICU = 0, 81 PERIPH_TYPE_TIM = 1, 82 PERIPH_TYPE_DMA = 2, 83 PERIPH_TYPE_CMA = 3, 84 PERIPH_TYPE_IOC = 4, 85 PERIPH_TYPE_TTY = 5, 86 PERIPH_TYPE_FBF = 6, 87 PERIPH_TYPE_NIC = 7, 88 PERIPH_TYPE_IOB = 8, 89 PERIPH_TYPE_GCD = 9, 90 PERIPH_TYPE_MAX_VALUE = 10, 91 }; 92 93 94 enum mwmrPortDirection 95 { 87 96 PORT_TO_COPROC = 0, // status register 88 97 PORT_FROM_COPROC = 1, // config register … … 92 101 /////////////////////////////// 93 102 94 typedef struct mapping_header_s { 95 unsigned int signature; // must contain MAPPING_SIGNATURE 96 unsigned int clusters; // number of clusters 97 unsigned int cluster_x; // number of cluster on the abcsisse axe 98 unsigned int cluster_y; // number of cluster on the ordinate axe 99 unsigned int globals; // number of vsegs mapped in all vspaces 100 unsigned int vspaces; // number of virtual spaces 101 102 unsigned int tty_clusterid; // index of cluster containing TTY controler 103 unsigned int ioc_clusterid; // index of cluster containing IOC controler 104 unsigned int nic_clusterid; // index of cluster containing NIC controler 105 unsigned int fbf_clusterid; // index of cluster containing FBF controler 106 107 unsigned int psegs; // total number of physical segments (for all clusters) 108 unsigned int vsegs; // total number of virtual segments (for all vspaces) 109 unsigned int vobjs; // total number of virtual objects (for all vspaces) 110 unsigned int tasks; // total number of tasks (for all vspaces) 111 unsigned int procs; // total number of procs (for all clusters) 112 unsigned int irqs; // total number of irqs (for all processors) 113 unsigned int coprocs; // total number of coprocs (for all clusters) 114 unsigned int cp_ports; // total number of cp_ports (for all coprocs) 115 unsigned int periphs; // total number of peripherals (for all clusters) 116 117 char name[32]; // mapping name 103 typedef struct mapping_header_s 104 { 105 unsigned int signature; // must contain MAPPING_SIGNATURE 106 unsigned int clusters; // number of clusters 107 unsigned int cluster_x; // number of cluster in a row 108 unsigned int cluster_y; // number of cluster in a column 109 unsigned int globals; // number of vsegs mapped in all vspaces 110 unsigned int vspaces; // number of virtual spaces 111 112 unsigned int tty_cluster; // index of cluster containing TTY controler 113 unsigned int tty_cluster_bis; // index of cluster containing second TTY controler 114 unsigned int ioc_cluster; // index of cluster containing IOC controler 115 unsigned int ioc_cluster_bis; // index of cluster containing second IOC controler 116 unsigned int nic_cluster; // index of cluster containing NIC controler 117 unsigned int nic_cluster_bis; // index of cluster containing second NIC controler 118 unsigned int fbf_cluster; // index of cluster containing FBF controler 119 unsigned int fbf_cluster_bis; // index of cluster containing second FBF controler 120 unsigned int cma_cluster; // index of cluster containing CMA controler 121 unsigned int cma_cluster_bis; // index of cluster containing second CMA controler 122 unsigned int iob_cluster; // index of cluster containing IOB controler 123 unsigned int iob_cluster_bis; // index of cluster containing second IOB controler 124 125 unsigned int psegs; // total number of physical segments (for all clusters) 126 unsigned int vsegs; // total number of virtual segments (for all vspaces) 127 unsigned int vobjs; // total number of virtual objects (for all vspaces) 128 unsigned int tasks; // total number of tasks (for all vspaces) 129 unsigned int procs; // total number of procs (for all clusters) 130 unsigned int irqs; // total number of irqs (for all processors) 131 unsigned int coprocs; // total number of coprocs (for all clusters) 132 unsigned int cp_ports; // total number of cp_ports (for all coprocs) 133 unsigned int periphs; // total number of peripherals (for all clusters) 134 135 char name[32]; // mapping name 118 136 } mapping_header_t; 119 137 120 138 121 139 //////////////////////////////// 122 typedef struct mapping_cluster_s { 140 typedef struct mapping_cluster_s 141 { 123 142 unsigned int psegs; // number of psegs in cluster 124 143 unsigned int pseg_offset; // index of first pseg in pseg set … … 136 155 137 156 ///////////////////////////// 138 typedef struct mapping_pseg_s { 139 char name[32]; // pseg name (unique in a cluster) 140 unsigned int base; // base address in physical space 141 unsigned int length; // size (bytes) 157 typedef struct mapping_pseg_s 158 { 159 char name[32]; // pseg name (unique in a cluster) 160 paddr_t base; // base address in physical space 161 paddr_t length; // size (bytes) 142 162 unsigned int type; // RAM / ROM / PERI 143 163 unsigned int cluster; // index of cluster containing pseg 144 unsigned intnext_base; // first free page base address164 paddr_t next_base; // first free page base address 145 165 } mapping_pseg_t; 146 166 147 167 148 168 /////////////////////////////// 149 typedef struct mapping_vspace_s { 150 char name[32]; // virtual space name 169 typedef struct mapping_vspace_s 170 { 171 char name[32]; // virtual space name 151 172 unsigned int start_offset; // offset of the vobj containing the start vector 152 173 unsigned int vsegs; // number of vsegs in vspace … … 160 181 161 182 ///////////////////////////// 162 typedef struct mapping_vseg_s { 163 char name[32]; // vseg name (unique in vspace) 164 unsigned int vbase; // base address in virtual space (hexa) 165 unsigned int pbase; // base address in physical space (hexa) 183 typedef struct mapping_vseg_s 184 { 185 char name[32]; // vseg name (unique in vspace) 186 unsigned int vbase; // base address in virtual space 187 paddr_t pbase; // base address in physical space 166 188 unsigned int length; // size (bytes) 167 189 unsigned int psegid; // physical segment global index … … 169 191 unsigned int ident; // identity mapping if non zero 170 192 unsigned int vobjs; // number of vobjs in vseg 171 unsigned int vobj_offset; // index of first vobj sin vseg193 unsigned int vobj_offset; // index of first vobj in vseg 172 194 } mapping_vseg_t; 173 195 174 196 175 197 ///////////////////////////// 176 typedef struct mapping_task_s { 177 char name[32]; // task name (unique in vspace) 198 typedef struct mapping_task_s 199 { 200 char name[32]; // task name (unique in vspace) 178 201 unsigned int clusterid; // physical cluster index 179 202 unsigned int proclocid; // processor local index (inside cluster) … … 181 204 unsigned int heap_vobjid; // heap vobj index in vspace 182 205 unsigned int startid; // index in start_vector 183 unsigned int use_tty; // TTY terminal required (global)206 unsigned int use_tty; // TTY channel required (global) 184 207 unsigned int use_nic; // NIC channel required (global) 185 unsigned int use_timer; // user timer required (local) 186 unsigned int use_fbdma; // DMA channel to frame buffer required (local) 208 unsigned int use_cma; // CMA channel required (global) 209 unsigned int use_ioc; // IOC channel required (global) 210 unsigned int use_tim; // user timer required (local) 211 unsigned int use_dma; // DMA channel required (local) 187 212 } mapping_task_t; 188 213 189 214 190 215 ///////////////////////////// 191 typedef struct mapping_vobj_s { 192 char name[32]; // vobj name (unique in a vspace) 193 char binpath[64]; // path for the binary code ("*.elf") 216 typedef struct mapping_vobj_s 217 { 218 char name[32]; // vobj name (unique in a vspace) 219 char binpath[64]; // path for the binary code ("*.elf") 194 220 unsigned int type; // type of vobj 195 221 unsigned int length; // size (bytes) 196 222 unsigned int align; // required alignement (logarithm of 2) 197 223 unsigned int vaddr; // virtual base addresse of the vobj 198 unsigned intpaddr; // physical base addresse of the vobj224 paddr_t paddr; // physical base addresse of the vobj 199 225 unsigned int init; // init value (used by barrier or mwmr channel) 200 226 } mapping_vobj_t; … … 202 228 203 229 ///////////////////////////// 204 typedef struct mapping_proc_s { 230 typedef struct mapping_proc_s 231 { 205 232 unsigned int irqs; // number of IRQs allocated to processor 206 233 unsigned int irq_offset; // index of first IRQ allocated to processor … … 209 236 210 237 ///////////////////////////// 211 typedef struct mapping_irq_s { 238 typedef struct mapping_irq_s 239 { 212 240 unsigned int type; // 0 => HW_IRQ / 1 => SW_IRQ 213 241 unsigned int icuid; // IRQ Index for the ICU component 214 unsigned int isr; // I nterrupt Service Routine Index215 unsigned int channel; // Channel Index (for multi-c annels peripherals)242 unsigned int isr; // ISR Index (defined in irq_handler.h) 243 unsigned int channel; // Channel Index (for multi-channels peripherals) 216 244 } mapping_irq_t; 217 245 218 246 219 247 /////////////////////////////// 220 typedef struct mapping_coproc_s { 221 char name[32]; // coprocessor name 248 typedef struct mapping_coproc_s 249 { 250 char name[32]; // coprocessor name 222 251 unsigned int psegid; // global pseg index 223 252 unsigned int ports; // number of MWMR ports used by coprocessor … … 227 256 228 257 //////////////////////////////// 229 typedef struct mapping_cp_port_s { 258 typedef struct mapping_cp_port_s 259 { 230 260 unsigned int direction; // TO_COPROC == 0 / FROM_COPROC == 1 231 261 unsigned int vspaceid; // index of the vspace containing the MWMR channel 232 unsigned int mwmr_vobjid; 262 unsigned int mwmr_vobjid; // local index of the vobj containing the MWMR channel 233 263 } mapping_cp_port_t; 234 264 235 265 236 266 /////////////////////////////// 237 typedef struct mapping_periph_s { 267 typedef struct mapping_periph_s 268 { 238 269 unsigned int type; // IOC / TTY / TIM / DMA / FBF / NIC / IOB 239 270 unsigned int psegid; // pseg index in cluster -
soft/giet_vm/xml/xml_driver.c
r232 r238 31 31 "CONST", // Constant 32 32 "MEMSPACE", // Memspace 33 "SCHED", // Scheduler 33 34 }; 34 35 … … 238 239 fprintf(fpout, " <pseg name = \"%s\" ", pseg[pseg_id].name); 239 240 fprintf(fpout, " type = \"%s\" ", pseg_type[pseg[pseg_id].type]); 240 fprintf(fpout, " base = \"0x% x\" ", pseg[pseg_id].base);241 fprintf(fpout, " length = \"0x% x\" />\n", pseg[pseg_id].length);241 fprintf(fpout, " base = \"0x%llx\" ", pseg[pseg_id].base); 242 fprintf(fpout, " length = \"0x%llx\" />\n", pseg[pseg_id].length); 242 243 } 243 244 … … 366 367 fprintf(fpout, "usetty = \"%d\" ", task[task_id].use_tty); 367 368 fprintf(fpout, "usenic = \"%d\" ", task[task_id].use_nic); 368 fprintf(fpout, "usetimer = \"%d\" ", task[task_id].use_timer); 369 fprintf(fpout, "usefbma = \"%d\" />\n", task[task_id].use_fbdma); 369 fprintf(fpout, "usedma = \"%d\" ", task[task_id].use_dma); 370 fprintf(fpout, "usecma = \"%d\" ", task[task_id].use_cma); 371 fprintf(fpout, "usetim = \"%d\" ", task[task_id].use_tim); 372 fprintf(fpout, "useioc = \"%d\" />\n", task[task_id].use_ioc); 370 373 } 371 374 fprintf(fpout, " </vspace>\n\n"); -
soft/giet_vm/xml/xml_parser.c
r232 r238 49 49 /////////////////////////////////////////////////////////////////////////////////// 50 50 51 mapping_header_t * header;52 mapping_cluster_t * cluster[MAX_CLUSTERS]; // cluster array53 mapping_pseg_t * pseg[MAX_PSEGS];// pseg array54 mapping_vspace_t * vspace[MAX_VSPACES];// vspace array55 mapping_vseg_t * vseg[MAX_VSEGS];// vseg array56 mapping_vobj_t * vobj[MAX_VOBJS];// vobj array57 mapping_task_t * task[MAX_TASKS];// task array58 mapping_proc_t * proc[MAX_PROCS];// proc array59 mapping_irq_t * irq[MAX_IRQS];// irq array60 mapping_coproc_t * coproc[MAX_COPROCS];// coproc array61 mapping_cp_port_t * cp_port[MAX_CP_PORTS]; // coproc port array62 mapping_periph_t * periph[MAX_PERIPHS];// peripheral array51 mapping_header_t * header; 52 mapping_cluster_t * cluster[MAX_CLUSTERS]; // cluster array 53 mapping_pseg_t * pseg[MAX_PSEGS]; // pseg array 54 mapping_vspace_t * vspace[MAX_VSPACES]; // vspace array 55 mapping_vseg_t * vseg[MAX_VSEGS]; // vseg array 56 mapping_vobj_t * vobj[MAX_VOBJS]; // vobj array 57 mapping_task_t * task[MAX_TASKS]; // task array 58 mapping_proc_t * proc[MAX_PROCS]; // proc array 59 mapping_irq_t * irq[MAX_IRQS]; // irq array 60 mapping_coproc_t * coproc[MAX_COPROCS]; // coproc array 61 mapping_cp_port_t * cp_port[MAX_CP_PORTS]; // coproc port array 62 mapping_periph_t * periph[MAX_PERIPHS]; // peripheral array 63 63 64 64 // Index for the various arrays … … 95 95 96 96 97 ///////////////////////// 98 // fo und peripheral99 ///////////////////////// 97 ////////////////////////////// 98 // for replicated peripheral 99 ////////////////////////////// 100 100 char found_timer = 0; 101 101 char found_icu = 0; 102 char found_xicu = 0;103 102 char found_dma = 0; 104 103 105 104 106 ////////////////////////////////// 107 //needed to generate map_config.ld 108 ////////////////////////////////// 109 unsigned int cluster_y = 0; 110 unsigned int cluster_x = 0; 111 unsigned int nb_proc_max = 0; // max number of processors per cluste 112 113 unsigned int nb_tasks_max = 0; // max number of tasks (for all vspaces) 114 unsigned int nb_timer_channel_max = 0; // max number of user timer 115 unsigned int nb_dma_channel_max = 0; 116 unsigned int nb_tty_channel = 0; 117 unsigned int nb_ioc_channel = 0; 118 unsigned int nb_nic_channel = 0; 119 unsigned int io_mmu_active = 0; 120 unsigned int use_xicu = 0xFFFFFFFF; 121 122 123 ////////////////////////////////// 124 //needed to generate giet_vseg.ld 125 ////////////////////////////////// 126 127 //kernel and boot code 128 unsigned int kernel_code_base = 0x80000000; /* kernel code */ 129 unsigned int kernel_data_base = 0x80010000; /* system cacheable data */ 130 unsigned int kernel_uncdata_base = 0x80080000; /* system uncacheable data */ 131 unsigned int kernel_init_base = 0x80090000; /* system init entry */ 132 133 unsigned int boot_code_base = 0xBFC00000; /* boot code */ 134 unsigned int boot_stack_base = 0xBFC08000; /* boot temporary stack */ 135 unsigned int boot_mapping_base = 0xBFC0C000; /* mapping_info blob */ 136 137 //periphs 138 unsigned int tim_base_offset = 0xFFFFFFFF; 139 unsigned int tty_base_offset = 0xFFFFFFFF; 140 unsigned int dma_base_offset = 0xFFFFFFFF; 141 unsigned int ioc_base_offset = 0xFFFFFFFF; 142 unsigned int nic_base_offset = 0xFFFFFFFF; 143 unsigned int fbf_base_offset = 0xFFFFFFFF; 144 unsigned int icu_base_offset = 0xFFFFFFFF; 145 unsigned int gcd_base_offset = 0xFFFFFFFF; 146 unsigned int iob_base_offset = 0xFFFFFFFF; 147 105 //////////////////////////////////////////////////////////////////// 106 // These variables are used to generate the hard_config.h file 107 //////////////////////////////////////////////////////////////////// 108 109 unsigned int cluster_y = 0; // number of clusters in a column 110 unsigned int cluster_x = 0; // number of clusters in a row 111 unsigned int nb_proc_max = 0; // max number of processors per cluster 112 unsigned int nb_tasks_max = 0; // max number of tasks (for all vspaces) 113 114 unsigned int tim_channels = 0; // max number of user timers per cluster 115 unsigned int dma_channels = 0; // max number of DMA channels per cluster 116 117 unsigned int tty_channels = 0; // total number of terminals in first TTY 118 unsigned int ioc_channels = 0; // total number of channels in first IOC 119 unsigned int nic_channels = 0; // total number of channels in first NIC 120 unsigned int cma_channels = 0; // total number of channels in first CMA 121 122 unsigned int io_mmu_active = 0; // using IOB component 123 unsigned int use_xicu = 0; // using XICU (not ICU) 124 125 126 //////////////////////////////////////////////////////////////// 127 // These variables are used to generate the giet_vseg.ld file 128 //////////////////////////////////////////////////////////////// 129 130 unsigned int periph_vbase_array[PERIPH_TYPE_MAX_VALUE] 131 = { [0 ... (PERIPH_TYPE_MAX_VALUE - 1)] = 0xFFFFFFFF }; 148 132 149 133 ////////////////////////////////////////////////////////////////////// … … 153 137 // once all the vspace have been parsed. 154 138 ///////////////////////////////////////////////////////////////////// 155 typedef struct vobj_ref_s { 139 typedef struct vobj_ref_s 140 { 156 141 char vspace_name[32]; 157 142 char vobj_name[32]; … … 162 147 163 148 ////////////////////////////////////////////////// 164 unsigned int getIntValue(xmlTextReaderPtr reader, const char * attributeName, unsigned int * ok) { 149 unsigned int getIntValue( xmlTextReaderPtr reader, 150 const char * attributeName, 151 unsigned int * ok) 152 { 165 153 unsigned int value = 0; 166 154 unsigned int i; 167 155 char c; 168 156 169 char * string = (char *) xmlTextReaderGetAttribute(reader, (const xmlChar *) attributeName); 170 171 if (string == NULL) { 157 char * string = (char *) xmlTextReaderGetAttribute(reader, 158 (const xmlChar *) attributeName); 159 160 if (string == NULL) 161 { 172 162 // missing argument 173 163 *ok = 0; 174 164 return 0; 175 165 } 176 else { 177 if ((string[0] == '0') && ((string[1] == 'x') || (string[1] == 'X'))) { 166 else 167 { 168 if ((string[0] == '0') && ((string[1] == 'x') || (string[1] == 'X'))) 169 { 178 170 // Hexa 179 for (i = 2 ; (string[i] != 0) && (i < 10) ; i++) { 171 for (i = 2 ; (string[i] != 0) && (i < 10) ; i++) 172 { 180 173 c = string[i]; 181 174 if ((c >= '0') && (c <= '9')) { value = (value << 4) + string[i] - 48; } 182 175 else if ((c >= 'a') && (c <= 'f')) { value = (value << 4) + string[i] - 87; } 183 176 else if ((c >= 'A') && (c <= 'F')) { value = (value << 4) + string[i] - 55; } 184 else { 177 else 178 { 185 179 *ok = 0; 186 180 return 0; … … 188 182 } 189 183 } 190 else { 184 else 185 { 191 186 // Decimal 192 for (i = 0; (string[i] != 0) && (i < 9); i++) { 187 for (i = 0; (string[i] != 0) && (i < 9); i++) 188 { 193 189 c = string[i]; 194 190 if ((c >= '0') && (c <= '9')) value = (value * 10) + string[i] - 48; 195 else { 191 else 192 { 196 193 *ok = 0; 197 194 return 0; … … 204 201 } // end getIntValue() 205 202 206 207 /////////////////////////////////////////////// 208 char * getStringValue(xmlTextReaderPtr reader, const char * attributeName, unsigned int * ok) { 209 char * string = (char *) xmlTextReaderGetAttribute(reader, (const xmlChar *) attributeName); 210 211 212 if (string == NULL) { 203 //////////////////////////////////////////////// 204 paddr_t getPaddrValue( xmlTextReaderPtr reader, 205 const char * attributeName, 206 unsigned int * ok) 207 { 208 paddr_t value = 0; 209 unsigned int i; 210 char c; 211 212 char * string = (char *) xmlTextReaderGetAttribute(reader, 213 (const xmlChar *) attributeName); 214 215 if (string == NULL) 216 { 217 // missing argument 218 *ok = 0; 219 return 0; 220 } 221 else 222 { 223 if ((string[0] == '0') && ((string[1] == 'x') || (string[1] == 'X'))) 224 { 225 // Hexa 226 for (i = 2 ; (string[i] != 0) && (i < 18) ; i++) 227 { 228 c = string[i]; 229 if ((c >= '0') && (c <= '9')) { value = (value << 4) + string[i] - 48; } 230 else if ((c >= 'a') && (c <= 'f')) { value = (value << 4) + string[i] - 87; } 231 else if ((c >= 'A') && (c <= 'F')) { value = (value << 4) + string[i] - 55; } 232 else 233 { 234 *ok = 0; 235 return 0; 236 } 237 } 238 } 239 else 240 { 241 // Decimal not supported for paddr_t 242 *ok = 0; 243 return 0; 244 } 245 *ok = 1; 246 return value; 247 } 248 } // end getPaddrValue() 249 250 //////////////////////////////////////////////// 251 char * getStringValue( xmlTextReaderPtr reader, 252 const char * attributeName, 253 unsigned int * ok ) 254 { 255 char * string = (char *) xmlTextReaderGetAttribute(reader, 256 (const xmlChar *) attributeName); 257 258 259 if (string == NULL) 260 { 213 261 // missing argument 214 262 *ok = 0; 215 263 return NULL; 216 264 } 217 else { 265 else 266 { 218 267 //we read only string smaller than 32 byte 219 if (strlen(string) > 32) { 268 if (strlen(string) > 32) 269 { 220 270 printf("[XML ERROR] all strings must be less than 32 bytes\n"); 221 271 exit(1); … … 227 277 } // end getStringValue() 228 278 229 230 /////////////////////////////////////// 231 int getPsegId(unsigned int cluster_id, char * pseg_name) { 279 /////////////////////////////////////////////////////// 280 void set_periph_vbase_array( unsigned int vseg_index ) 281 { 282 unsigned int vbase = vseg[vseg_index]->vbase; // peripheral vbase address 283 unsigned int psegid = vseg[vseg_index]->psegid; // pseg global index 284 unsigned int type; // peripheral type 285 unsigned int periph_id; 286 287 for ( periph_id = 0 ; periph_id < header->periphs ; periph_id++) 288 { 289 if( periph[periph_id]->psegid == psegid ) 290 { 291 type = periph[periph_id]->type; 292 if ( periph_vbase_array[type] == 0xFFFFFFFF ) 293 periph_vbase_array[type] = vbase; 294 } 295 } 296 } // end set_periph_vbase_array() 297 298 //////////////////////////////////////////////////////// 299 int getPsegId(unsigned int cluster_id, char * pseg_name) 300 { 232 301 unsigned int pseg_id; 233 302 unsigned int pseg_min = cluster[cluster_id]->pseg_offset; 234 303 unsigned int pseg_max = pseg_min + cluster[cluster_id]->psegs; 235 304 236 for (pseg_id = pseg_min; pseg_id < pseg_max; pseg_id++) { 237 if (strcmp(pseg[pseg_id]->name, pseg_name) == 0) { 305 for (pseg_id = pseg_min; pseg_id < pseg_max; pseg_id++) 306 { 307 if (strcmp(pseg[pseg_id]->name, pseg_name) == 0) 308 { 238 309 return pseg_id; 239 310 } … … 242 313 } 243 314 244 245 //////////////////////////////////////////// 246 int getVspaceId(char * vspace_name){315 /////////////////////////////////// 316 int getVspaceId(char * vspace_name) 317 { 247 318 unsigned int vspace_id; 248 319 249 for (vspace_id = 0; vspace_id < vspace_index; vspace_id++) { 250 if (!strcmp(vspace[vspace_id]->name, vspace_name)) { 320 for (vspace_id = 0; vspace_id < vspace_index; vspace_id++) 321 { 322 if (strcmp(vspace[vspace_id]->name, vspace_name) == 0) 323 { 251 324 return vspace_id; 252 325 } … … 255 328 } 256 329 257 258 //////////////////////////////////////////// 259 int getVobjLocId(unsigned int vspace_id, char * vobj_name, unsigned int vspace_max){330 /////////////////////////////////////////////////////////////////////////////////// 331 int getVobjLocId(unsigned int vspace_id, char * vobj_name, unsigned int vspace_max) 332 { 260 333 unsigned int vobj_id; 261 334 unsigned int vobj_min = vspace[vspace_id]->vobj_offset; … … 272 345 273 346 ///////////////////////////////////////// 274 void taskNode(xmlTextReaderPtr reader) { 347 void taskNode(xmlTextReaderPtr reader) 348 { 275 349 unsigned int ok; 276 350 unsigned int value; 277 351 char * str; 278 352 279 if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) { 280 return; 281 } 282 283 if (task_index >= MAX_TASKS) { 353 if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) { return; } 354 355 if (task_index >= MAX_TASKS) 356 { 284 357 printf("[XML ERROR] The number of tasks is larger than %d\n", MAX_TASKS); 285 358 } 286 359 287 360 #if XML_PARSER_DEBUG 288 361 printf(" task %d\n", task_loc_index); 289 362 #endif 290 363 … … 293 366 ////////// get name attribute 294 367 str = getStringValue(reader, "name", &ok); 295 if (ok) { 296 #if XML_PARSER_DEBUG 297 printf(" name = %s\n", str); 368 if (ok) 369 { 370 #if XML_PARSER_DEBUG 371 printf(" name = %s\n", str); 298 372 #endif 299 373 strncpy( task[task_index]->name, str, 31 ); 300 374 } 301 else { 375 else 376 { 302 377 printf("[XML ERROR] illegal or missing <name> attribute for task (%d,%d)\n", 303 378 vspace_index, task_loc_index); … … 307 382 ///////// get clusterid attribute 308 383 value = getIntValue(reader, "clusterid", &ok); 309 if (ok) { 310 #if XML_PARSER_DEBUG 311 printf(" clusterid = %x\n", value); 312 #endif 313 if (value >= header->clusters) { 384 if (ok) 385 { 386 #if XML_PARSER_DEBUG 387 printf(" clusterid = %x\n", value); 388 #endif 389 if (value >= header->clusters) 390 { 314 391 printf("[XML ERROR] <clusterid> too large for task (%d,%d)\n", 315 392 vspace_index, task_loc_index); … … 318 395 task[task_index]->clusterid = value; 319 396 } 320 else { 397 else 398 { 321 399 printf("[XML ERROR] illegal or missing <clusterid> attribute for task (%d,%d)\n", 322 400 vspace_index, task_loc_index); … … 326 404 ////////// get proclocid attribute 327 405 value = getIntValue(reader, "proclocid", &ok); 328 if (ok) { 329 #if XML_PARSER_DEBUG 330 printf(" proclocid = %x\n", value); 331 #endif 332 if (value >= cluster[task[task_index]->clusterid]->procs) { 406 if (ok) 407 { 408 #if XML_PARSER_DEBUG 409 printf(" proclocid = %x\n", value); 410 #endif 411 if (value >= cluster[task[task_index]->clusterid]->procs) 412 { 333 413 printf("[XML ERROR] <proclocid> too large for task (%d,%d)\n", 334 414 vspace_index, task_loc_index); … … 337 417 task[task_index]->proclocid = value; 338 418 } 339 else { 419 else 420 { 340 421 printf("[XML ERROR] illegal or missing <locprocid> attribute for task (%d,%d)\n", 341 422 vspace_index, task_loc_index); … … 345 426 ////////// get stackname attribute 346 427 str = getStringValue(reader, "stackname" , &ok); 347 if (ok) { 428 if (ok) 429 { 348 430 int index = getVobjLocId(vspace_index, str , vobj_loc_index); 349 if (index >= 0) { 350 #if XML_PARSER_DEBUG 351 printf(" stackname = %s\n", str); 352 printf(" stackid = %d\n", index); 431 if (index >= 0) 432 { 433 #if XML_PARSER_DEBUG 434 printf(" stackname = %s\n", str); 435 printf(" stackid = %d\n", index); 353 436 #endif 354 437 task[task_index]->stack_vobjid = index; 355 438 } 356 else { 439 else 440 { 357 441 printf("[XML ERROR] illegal or missing <stackname> for task (%d,%d)\n", 358 442 vspace_index, task_loc_index); … … 360 444 } 361 445 } 362 else { 446 else 447 { 363 448 printf("[XML ERROR] illegal or missing <stackname> for task (%d,%d)\n", 364 449 vspace_index, task_loc_index); … … 368 453 ////////// get heap attribute 369 454 str = getStringValue(reader, "heapname", &ok); 370 if (ok) { 455 if (ok) 456 { 371 457 int index = getVobjLocId(vspace_index, str, vobj_loc_index); 372 if (index >= 0) { 373 #if XML_PARSER_DEBUG 374 printf(" heapname = %s\n", str); 375 printf(" heapid = %d\n", index); 458 if (index >= 0) 459 { 460 #if XML_PARSER_DEBUG 461 printf(" heapname = %s\n", str); 462 printf(" heapid = %d\n", index); 376 463 #endif 377 464 task[task_index]->heap_vobjid = index; 378 465 } 379 else { 380 printf("[XML ERROR] illegal or missing <heapname> for task (%d,%d)\n", vspace_index, task_loc_index); 466 else 467 { 468 printf("[XML ERROR] illegal or missing <heapname> for task (%d,%d)\n", 469 vspace_index, task_loc_index); 381 470 exit(1); 382 471 } 383 472 } 384 else { 473 else 474 { 385 475 task[task_index]->heap_vobjid = -1; 386 476 } … … 389 479 ////////// get startid attribute 390 480 value = getIntValue(reader, "startid", &ok); 391 if (ok) { 392 #if XML_PARSER_DEBUG 393 printf(" startid = %x\n", value); 481 if (ok) 482 { 483 #if XML_PARSER_DEBUG 484 printf(" startid = %x\n", value); 394 485 #endif 395 486 task[task_index]->startid = value; 396 487 } 397 else { 488 else 489 { 398 490 printf("[XML ERROR] illegal or missing <startid> attribute for task (%d,%d)\n", 399 491 vspace_index, task_loc_index); … … 403 495 /////////// get usetty attribute (optionnal : 0 if missing) 404 496 value = getIntValue(reader, "usetty", &ok); 405 if (ok) { 406 #if XML_PARSER_DEBUG 407 printf(" usetty = %x\n", value); 408 #endif 409 task[task_index]->use_tty = value; 410 } 411 else { 412 task[task_index]->use_tty = 0; 413 } 497 #if XML_PARSER_DEBUG 498 printf(" usetty = %x\n", value); 499 #endif 500 task[task_index]->use_tty = (ok)? value : 0; 414 501 415 502 /////////// get usenic attribute (optionnal : 0 if missing) 416 503 value = getIntValue(reader, "usenic", &ok); 417 if (ok) { 418 #if XML_PARSER_DEBUG 419 printf(" usenic = %x\n", value); 420 #endif 421 task[task_index]->use_nic = value; 422 } 423 else { 424 task[task_index]->use_nic = 0; 425 } 426 427 /////////// get usetimer attribute (optionnal : 0 if missing) 428 value = getIntValue(reader, "usetimer", &ok); 429 if (ok) { 430 #if XML_PARSER_DEBUG 431 printf(" usetimer = %x\n", value); 432 #endif 433 task[task_index]->use_timer = value; 434 } 435 else { 436 task[task_index]->use_timer = 0; 437 } 438 439 /////////// get usefbdma attribute (optionnal : 0 if missing) 440 value = getIntValue(reader, "usefbdma", &ok); 441 if (ok) { 442 #if XML_PARSER_DEBUG 443 printf(" usefbdma = %x\n", value); 444 #endif 445 task[task_index]->use_fbdma = value; 446 } 447 else { 448 task[task_index]->use_fbdma = 0; 449 } 504 #if XML_PARSER_DEBUG 505 printf(" usenic = %x\n", value); 506 #endif 507 task[task_index]->use_nic = (ok)? value : 0; 508 509 /////////// get usetim attribute (optionnal : 0 if missing) 510 value = getIntValue(reader, "usetim", &ok); 511 #if XML_PARSER_DEBUG 512 printf(" usetim = %x\n", value); 513 #endif 514 task[task_index]->use_tim = (ok)? value : 0; 515 516 /////////// get usedma attribute (optionnal : 0 if missing) 517 value = getIntValue(reader, "usedma", &ok); 518 #if XML_PARSER_DEBUG 519 printf(" usedma = %x\n", value); 520 #endif 521 task[task_index]->use_dma = (ok)? value : 0; 522 523 /////////// get useioc attribute (optionnal : 0 if missing) 524 value = getIntValue(reader, "useioc", &ok); 525 #if XML_PARSER_DEBUG 526 printf(" useioc = %x\n", value); 527 #endif 528 task[task_index]->use_ioc = (ok)? value : 0; 529 530 /////////// get usecma attribute (optionnal : 0 if missing) 531 value = getIntValue(reader, "usecma", &ok); 532 #if XML_PARSER_DEBUG 533 printf(" usecma = %x\n", value); 534 #endif 535 task[task_index]->use_cma = (ok)? value : 0; 450 536 451 537 task_index++; … … 454 540 455 541 456 ////////////////////////////////////////// 457 void vobjNode(xmlTextReaderPtr reader) { 542 ////////////////////////////////////// 543 void vobjNode(xmlTextReaderPtr reader) 544 { 458 545 unsigned int ok; 459 546 unsigned int value; 460 547 char * str; 461 548 462 if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) { 463 return; 464 } 465 466 if (vobj_index >= MAX_VOBJS) { 467 printf("[XML ERROR] The number of vobjs is larger than %d\n", MAX_VSEGS); 468 exit(1); 469 } 470 471 #if XML_PARSER_DEBUG 472 printf(" vobj %d\n", vobj_loc_index); 549 if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) { return; } 550 551 if (vobj_index >= MAX_VOBJS) 552 { 553 printf("[XML ERROR] The number of vobjs is larger than %d\n", MAX_VOBJS); 554 exit(1); 555 } 556 557 #if XML_PARSER_DEBUG 558 printf(" vobj %d\n", vobj_loc_index); 473 559 #endif 474 560 … … 477 563 ///////// get name attribute 478 564 str = getStringValue(reader, "name", &ok); 479 if (ok) { 480 #if XML_PARSER_DEBUG 481 printf(" name = %s\n", str); 565 if (ok) 566 { 567 #if XML_PARSER_DEBUG 568 printf(" name = %s\n", str); 482 569 #endif 483 570 strncpy(vobj[vobj_index]->name, str, 31); 484 571 } 485 else { 572 else 573 { 486 574 printf("[XML ERROR] illegal or missing <name> attribute for vobj (%d,%d)\n", 487 575 vseg_index, vobj_loc_index); … … 492 580 str = getStringValue(reader, "type", &ok); 493 581 #if XML_PARSER_DEBUG 494 printf(" type = %s\n", str); 495 #endif 496 if (ok && (strcmp(str, "ELF") == 0)) { 582 printf(" type = %s\n", str); 583 #endif 584 if (ok && (strcmp(str, "ELF") == 0)) 585 { 497 586 vobj[vobj_index]->type = VOBJ_TYPE_ELF; 498 587 499 //check that this vobj is the first in vseg 500 if (vobj_count != 0) { 501 printf("[XML ERROR] an ELF vobj must be alone in a vseg (%d,%d)\n", 502 vspace_index, vobj_loc_index); 503 exit(1); 504 } 505 } 506 else if (ok && (strcmp(str, "BLOB") == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_BLOB; } 507 else if (ok && (strcmp(str, "PTAB") == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_PTAB; } 508 else if (ok && (strcmp(str, "PERI") == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_PERI; } 509 else if (ok && (strcmp(str, "MWMR") == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_MWMR; } 510 else if (ok && (strcmp(str, "LOCK") == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_LOCK; } 511 else if (ok && (strcmp(str, "BUFFER") == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_BUFFER; } 512 else if (ok && (strcmp(str, "BARRIER") == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_BARRIER; } 513 else if (ok && (strcmp(str, "CONST") == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_CONST; } 588 assert( (vobj_count == 0) && "[XML ERROR] an ELF vobj must be alone in a vseg"); 589 } 590 else if (ok && (strcmp(str, "PERI") == 0)) 591 { 592 vobj[vobj_index]->type = VOBJ_TYPE_PERI; 593 594 assert( (vobj_count == 0) && "[XML ERROR] a PERI vobj must be alone in a vseg"); 595 596 // fill the peripheral base address array 597 set_periph_vbase_array( vseg_index ); 598 } 599 else if (ok && (strcmp(str, "BLOB") == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_BLOB; } 600 else if (ok && (strcmp(str, "PTAB") == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_PTAB; } 601 else if (ok && (strcmp(str, "MWMR") == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_MWMR; } 602 else if (ok && (strcmp(str, "LOCK") == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_LOCK; } 603 else if (ok && (strcmp(str, "BUFFER") == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_BUFFER; } 604 else if (ok && (strcmp(str, "BARRIER") == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_BARRIER; } 605 else if (ok && (strcmp(str, "CONST") == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_CONST; } 514 606 else if (ok && (strcmp(str, "MEMSPACE") == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_MEMSPACE; } 515 else { 607 else if (ok && (strcmp(str, "SCHED") == 0)) { vobj[vobj_index]->type = VOBJ_TYPE_SCHED; } 608 else 609 { 516 610 printf("[XML ERROR] illegal or missing <type> attribute for vobj (%d,%d)\n", 517 611 vspace_index, vobj_loc_index); … … 523 617 if (ok) { 524 618 #if XML_PARSER_DEBUG 525 619 printf(" length = %d\n", value); 526 620 #endif 527 621 vobj[vobj_index]->length = value; … … 537 631 if (ok) { 538 632 #if XML_PARSER_DEBUG 539 633 printf(" align = %d\n", value); 540 634 #endif 541 635 vobj[vobj_index]->align = value; … … 549 643 if (ok) { 550 644 #if XML_PARSER_DEBUG 551 645 printf(" binpath = %s\n", str); 552 646 #endif 553 647 strncpy(vobj[vobj_index]->binpath, str, 63); … … 559 653 ////////// get init attribute (mandatory for mwmr and barrier) 560 654 value = getIntValue(reader, "init", &ok); 561 if (ok) { 562 #if XML_PARSER_DEBUG 563 printf(" init = %d\n", value); 655 if (ok) 656 { 657 #if XML_PARSER_DEBUG 658 printf(" init = %d\n", value); 564 659 #endif 565 660 vobj[vobj_index]->init = value; 566 661 } 567 else { 662 else 663 { 568 664 if ((vobj[vobj_index]->type == VOBJ_TYPE_MWMR) || 569 (vobj[vobj_index]->type == VOBJ_TYPE_BARRIER) || 570 (vobj[vobj_index]->type == VOBJ_TYPE_CONST)) { 665 (vobj[vobj_index]->type == VOBJ_TYPE_BARRIER) || 666 (vobj[vobj_index]->type == VOBJ_TYPE_CONST)) 667 { 571 668 printf("[XML ERROR] illegal or missing <value> attribute for vobj (%d,%d). \ 572 All MWMR or BARRIER vobj must have a init value \n",669 All MWMR or BARRIER or CONST vobj must have a init value \n", 573 670 vspace_index, vobj_loc_index); 574 671 exit(1); … … 583 680 584 681 585 ////////////////////////////////////////// 586 void vsegNode(xmlTextReaderPtr reader) { 682 ////////////////////////////////////// 683 void vsegNode(xmlTextReaderPtr reader) 684 { 587 685 unsigned int ok; 588 686 unsigned int value; … … 591 689 vobj_count = 0; 592 690 593 if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) { 594 return; 595 } 596 597 if (vseg_index >= MAX_VSEGS) { 691 if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) { return; } 692 693 if (vseg_index >= MAX_VSEGS) 694 { 598 695 printf("[XML ERROR] The number of vsegs is larger than %d\n", MAX_VSEGS); 599 696 exit(1); … … 601 698 602 699 #if XML_PARSER_DEBUG 603 700 printf(" vseg %d\n", vseg_loc_index); 604 701 #endif 605 702 … … 608 705 ////////// set vobj_offset attributes 609 706 vseg[vseg_index]->vobj_offset = vobj_index; 610 #if XML_PARSER_DEBUG 611 printf(" vobj_offset = %d\n", vobj_index); 707 708 #if XML_PARSER_DEBUG 709 printf(" vobj_offset = %d\n", vobj_index); 612 710 #endif 613 711 614 712 ///////// get name attribute 615 713 str = getStringValue(reader, "name", &ok); 616 if (ok) { 617 #if XML_PARSER_DEBUG 618 printf(" name = %s\n", str); 714 if (ok) 715 { 716 #if XML_PARSER_DEBUG 717 printf(" name = %s\n", str); 619 718 #endif 620 719 strncpy( vseg[vseg_index]->name, str, 31); 621 720 } 622 else { 721 else 722 { 623 723 printf("[XML ERROR] illegal or missing <name> attribute for vseg (%d,%d)\n", 624 724 vspace_index, vseg_loc_index); … … 628 728 ////////// get ident attribute (optional : 0 if missing) 629 729 value = getIntValue(reader, "ident", &ok); 630 if (ok) { 631 #if XML_PARSER_DEBUG 632 printf(" ident = %d\n", value); 730 if (ok) 731 { 732 #if XML_PARSER_DEBUG 733 printf(" ident = %d\n", value); 633 734 #endif 634 735 vseg[vseg_index]->ident = value; 635 736 } 636 else { 737 else 738 { 637 739 vseg[vseg_index]->ident = 0; 638 740 } … … 640 742 /////////// get vbase attribute 641 743 value = getIntValue(reader, "vbase", &ok); 642 if (ok) { 643 #if XML_PARSER_DEBUG 644 printf(" vbase = 0x%x\n", value); 744 if (ok) 745 { 746 #if XML_PARSER_DEBUG 747 printf(" vbase = 0x%x\n", value); 645 748 #endif 646 749 vseg[vseg_index]->vbase = value; 647 750 } 648 else { 751 else 752 { 649 753 printf("[XML ERROR] illegal or missing <vbase> attribute for vseg (%d,%d)\n", 650 754 vspace_index, vseg_loc_index); … … 654 758 ////////// get clusterid and psegname attributes 655 759 value = getIntValue(reader, "clusterid", &ok); 656 if (ok == 0) { 760 if (ok == 0) 761 { 657 762 printf("[XML ERROR] illegal or missing <clusterid> for vseg %d\n", 658 763 vseg_loc_index); … … 660 765 } 661 766 str = getStringValue(reader, "psegname", &ok); 662 if (ok == 0) { 767 if (ok == 0) 768 { 663 769 printf("[XML ERROR] illegal or missing <psegname> for vseg %d\n", 664 770 vseg_loc_index); … … 668 774 /////////// set psegid field 669 775 int index = getPsegId(value, str); 670 if (index >= 0) { 671 #if XML_PARSER_DEBUG 672 printf(" clusterid = %d\n", value); 673 printf(" psegname = %s\n", str); 674 printf(" psegid = %d\n", index); 776 if (index >= 0) 777 { 778 #if XML_PARSER_DEBUG 779 printf(" clusterid = %d\n", value); 780 printf(" psegname = %s\n", str); 781 printf(" psegid = %d\n", index); 675 782 #endif 676 783 vseg[vseg_index]->psegid = index; 677 784 } 678 else { 785 else 786 { 679 787 printf("[XML ERROR] pseg not found for vseg %d / clusterid = %d / psegname = %s\n", 680 788 vseg_loc_index, value, str ); … … 685 793 str = getStringValue(reader, "mode", &ok); 686 794 #if XML_PARSER_DEBUG 687 795 printf(" mode = %s\n", str); 688 796 #endif 689 797 if (ok && (strcmp(str, "CXWU") == 0)) { vseg[vseg_index]->mode = 0xF; } … … 714 822 const char * tag = (const char *) xmlTextReaderConstName(reader); 715 823 716 if (strcmp(tag, "vobj") == 0 ) { 717 vobjNode(reader); 718 } 824 if (strcmp(tag, "vobj") == 0 ) { vobjNode(reader); } 719 825 else if (strcmp(tag, "#text" ) == 0 ) { } 720 826 else if (strcmp(tag, "#comment") == 0 ) { } 721 else if (strcmp(tag, "vseg") == 0 ) { 827 else if (strcmp(tag, "vseg") == 0 ) 828 { 722 829 vseg[vseg_index]->vobjs = vobj_count; 723 830 vseg_index++; … … 756 863 757 864 #if XML_PARSER_DEBUG 758 865 printf("\n vspace %d\n", vspace_index); 759 866 #endif 760 867 … … 765 872 if (ok) { 766 873 #if XML_PARSER_DEBUG 767 874 printf(" name = %s\n", str); 768 875 #endif 769 876 strncpy(vspace[vspace_index]->name, str, 31); … … 936 1043 937 1044 938 /////////////////////////////////////////// 939 void periphNode(xmlTextReaderPtr reader) { 1045 //////////////////////////////////////// 1046 void periphNode(xmlTextReaderPtr reader) 1047 { 940 1048 char * str; 941 1049 unsigned int value; 942 1050 unsigned int ok; 943 1051 944 if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) { 945 return; 946 } 947 948 if (periph_index >= MAX_PERIPHS) { 1052 if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) { return; } 1053 1054 if (periph_index >= MAX_PERIPHS) 1055 { 949 1056 printf("[XML ERROR] The number of periphs is larger than %d\n", MAX_PERIPHS); 950 1057 } … … 955 1062 956 1063 periph[periph_index] = (mapping_periph_t *) malloc(sizeof(mapping_periph_t)); 957 958 1064 959 1065 ///////// get channels attribute (optionnal : 1 if missing) 960 1066 value = getIntValue(reader, "channels", &ok); 961 if (ok) { 1067 if (ok) 1068 { 962 1069 #if XML_PARSER_DEBUG 963 1070 printf(" channels = %d\n", value); … … 965 1072 periph[periph_index]->channels = value; 966 1073 } 967 else { 1074 else 1075 { 968 1076 periph[periph_index]->channels = 1; 969 1077 } … … 971 1079 /////////// get psegname attribute 972 1080 str = getStringValue(reader, "psegname", &ok); 973 if (ok == 0) { 1081 if (ok == 0) 1082 { 974 1083 printf("[XML ERROR] illegal or missing <psegname> for coproc %d in cluster %d\n", 975 1084 coproc_index, cluster_index); … … 979 1088 /////////// set psegid attribute 980 1089 int index = getPsegId(cluster_index, str); 981 if (index >= 0) { 1090 if (index >= 0) 1091 { 982 1092 #if XML_PARSER_DEBUG 983 1093 printf(" clusterid = %d\n", cluster_index); … … 989 1099 "peripheral psegname attribute must refer to a pseg of type PERI" ); 990 1100 } 991 else { 1101 else 1102 { 992 1103 printf("[XML ERROR] pseg not found for periph %d / clusterid = %d / psegname = %s\n", 993 1104 periph_loc_index, cluster_index, str ); … … 995 1106 } 996 1107 997 998 1108 /////////// get type attribute 999 1109 str = getStringValue(reader, "type", &ok); 1000 if (ok) { 1110 if (ok) 1111 { 1001 1112 #if XML_PARSER_DEBUG 1002 1113 printf(" type = %s\n", str); … … 1004 1115 unsigned int error = 0; 1005 1116 1006 // The TTY, IOC, NIC, FBF and IOB peripherals cannot be replicated 1007 // one per architecture 1008 if (strcmp(str, "IOC") == 0) { 1117 // The TTY, IOC, NIC, FBF, CMA and IOB peripherals are not replicated in all clusters 1118 // but can be replicated in two different clusters for fault tolerance 1119 // In case of replication, the number of channels must be the same 1120 if (strcmp(str, "IOC") == 0) 1121 { 1009 1122 periph[periph_index]->type = PERIPH_TYPE_IOC; 1010 if (header->ioc_clusterid == 0xFFFFFFFF) { 1011 header->ioc_clusterid = cluster_index; 1012 } 1013 else { 1123 if (header->ioc_cluster == 0xFFFFFFFF) 1124 { 1125 header->ioc_cluster = cluster_index; 1126 ioc_channels = periph[periph_index]->channels; 1127 } 1128 else if (header->ioc_cluster_bis == 0xFFFFFFFF) 1129 { 1130 header->ioc_cluster_bis = cluster_index; 1131 } 1132 else 1133 { 1014 1134 error = 1; 1015 1135 } 1016 1017 ioc_base_offset = pseg[periph[periph_index]->psegid]->base;1018 nb_ioc_channel = periph[periph_index]->channels;1019 1136 } 1020 else if (strcmp(str, "TTY") == 0) { 1137 else if (strcmp(str, "TTY") == 0) 1138 { 1021 1139 periph[periph_index]->type = PERIPH_TYPE_TTY; 1022 if (header->tty_clusterid == 0xFFFFFFFF) { 1023 header->tty_clusterid = cluster_index; 1024 } 1025 else { 1140 if (header->tty_cluster == 0xFFFFFFFF) 1141 { 1142 header->tty_cluster = cluster_index; 1143 tty_channels = periph[periph_index]->channels; 1144 } 1145 else if (header->tty_cluster_bis == 0xFFFFFFFF) 1146 { 1147 header->tty_cluster_bis = cluster_index; 1148 } 1149 else 1150 { 1026 1151 error = 1; 1027 1152 } 1028 1029 tty_base_offset = pseg[periph[periph_index]->psegid]->base; 1030 nb_tty_channel = periph[periph_index]->channels; 1031 } 1032 else if (strcmp(str, "FBF") == 0) { 1153 } 1154 else if (strcmp(str, "FBF") == 0) 1155 { 1033 1156 periph[periph_index]->type = PERIPH_TYPE_FBF; 1034 if (header->fbf_clusterid == 0xFFFFFFFF) { 1035 header->fbf_clusterid = cluster_index; 1036 } 1037 else { 1157 if (header->fbf_cluster == 0xFFFFFFFF) 1158 { 1159 header->fbf_cluster = cluster_index; 1160 } 1161 else if (header->fbf_cluster_bis == 0xFFFFFFFF) 1162 { 1163 header->fbf_cluster_bis = cluster_index; 1164 } 1165 else 1166 { 1038 1167 error = 1; 1039 1168 } 1040 fbf_base_offset = pseg[periph[periph_index]->psegid]->base;1041 }1042 else if (strcmp(str, "NIC") == 0){1169 } 1170 else if (strcmp(str, "NIC") == 0) 1171 { 1043 1172 periph[periph_index]->type = PERIPH_TYPE_NIC; 1044 if (header->nic_clusterid == 0xFFFFFFFF) { 1045 header->nic_clusterid = cluster_index; 1046 } 1047 else { 1173 if (header->nic_cluster == 0xFFFFFFFF) 1174 { 1175 header->nic_cluster = cluster_index; 1176 nic_channels = periph[periph_index]->channels; 1177 } 1178 else if (header->nic_cluster_bis == 0xFFFFFFFF) 1179 { 1180 header->nic_cluster_bis = cluster_index; 1181 } 1182 else 1183 { 1048 1184 error = 1; 1049 1185 } 1050 nic_base_offset = pseg[periph[periph_index]->psegid]->base; 1051 nb_nic_channel = periph[periph_index]->channels; 1052 } 1053 else if (strcmp(str, "IOB") == 0) { 1186 } 1187 else if (strcmp(str, "CMA") == 0) 1188 { 1189 periph[periph_index]->type = PERIPH_TYPE_CMA; 1190 if (header->cma_cluster == 0xFFFFFFFF) 1191 { 1192 header->cma_cluster = cluster_index; 1193 cma_channels = periph[periph_index]->channels; 1194 } 1195 else if (header->nic_cluster_bis == 0xFFFFFFFF) 1196 { 1197 header->cma_cluster_bis = cluster_index; 1198 } 1199 else 1200 { 1201 error = 1; 1202 } 1203 } 1204 else if (strcmp(str, "IOB") == 0) 1205 { 1054 1206 periph[periph_index]->type = PERIPH_TYPE_IOB; 1055 iob_base_offset = pseg[periph[periph_index]->psegid]->base; 1056 1057 if (io_mmu_active) { 1207 io_mmu_active = 1; 1208 if (header->iob_cluster == 0xFFFFFFFF) 1209 { 1210 header->iob_cluster = cluster_index; 1211 } 1212 else if (header->iob_cluster_bis == 0xFFFFFFFF) 1213 { 1214 header->iob_cluster_bis = cluster_index; 1215 } 1216 else 1217 { 1058 1218 error = 1; 1059 1219 } 1060 io_mmu_active = 1;1061 }1062 // The TIM, ICU, XICU, DMA and IOB peripherals can be replicated in several clusters1063 // one per cluster1064 else if (strcmp(str, "TIM") == 0 ){1220 } 1221 // The TIM, ICU, XICU, DMA peripherals are replicated in all clusters 1222 // but only one component per cluster 1223 else if (strcmp(str, "TIM") == 0 ) 1224 { 1065 1225 periph[periph_index]->type = PERIPH_TYPE_TIM; 1066 if (found_timer) { 1067 error = 1; 1068 } 1226 if (found_timer || use_xicu) error = 1; 1069 1227 found_timer = 1; 1070 1071 if (tim_base_offset == 0xFFFFFFFF) { 1072 tim_base_offset = pseg[ periph[periph_index]->psegid ]->base; 1073 } 1074 1075 if (nb_timer_channel_max < periph[periph_index]->channels) { 1076 nb_timer_channel_max = periph[periph_index]->channels; 1077 } 1078 } 1079 else if (strcmp(str, "ICU") == 0) { 1228 if (tim_channels < periph[periph_index]->channels) 1229 { 1230 tim_channels = periph[periph_index]->channels; 1231 } 1232 } 1233 else if (strcmp(str, "ICU") == 0) 1234 { 1080 1235 periph[periph_index]->type = PERIPH_TYPE_ICU; 1081 if (found_icu) { 1082 error = 1; 1083 } 1236 if (found_icu) error = 1; 1084 1237 found_icu = 1; 1085 1086 if (icu_base_offset == 0xFFFFFFFF) { 1087 icu_base_offset = pseg[periph[periph_index]->psegid]->base; 1088 } 1089 } 1090 else if (strcmp(str, "XICU") == 0) { 1091 periph[periph_index]->type = PERIPH_TYPE_XICU; 1092 if (found_xicu) { 1093 error = 1; 1094 } 1095 found_xicu = 1; 1096 1097 //'icu' since we can't have both xicu and icu in an arch 1098 if (icu_base_offset == 0xFFFFFFFF) { 1099 icu_base_offset = pseg[ periph[periph_index]->psegid ]->base; 1100 } 1101 1102 if (nb_timer_channel_max == 0) { 1103 nb_timer_channel_max = 32; 1104 } 1105 } 1106 else if (strcmp(str, "DMA") == 0) { 1238 } 1239 else if (strcmp(str, "XICU") == 0) 1240 { 1241 periph[periph_index]->type = PERIPH_TYPE_ICU; 1242 if (found_icu || found_timer) error = 1; 1243 found_icu = 1; 1244 if (tim_channels == 0) 1245 { 1246 tim_channels = 32; 1247 } 1248 use_xicu = 1; 1249 } 1250 else if (strcmp(str, "DMA") == 0) 1251 { 1107 1252 periph[periph_index]->type = PERIPH_TYPE_DMA; 1108 if (found_dma) { 1109 error = 1; 1110 } 1253 if (found_dma) error = 1; 1111 1254 found_dma = 1; 1112 1113 if (dma_base_offset == 0xFFFFFFFF) { 1114 dma_base_offset = pseg[periph[periph_index]->psegid]->base; 1115 } 1116 if (nb_dma_channel_max < periph[periph_index]->channels) { 1117 nb_dma_channel_max = periph[periph_index]->channels; 1118 } 1119 } 1120 else { 1255 if (dma_channels < periph[periph_index]->channels) 1256 dma_channels = periph[periph_index]->channels; 1257 } 1258 else 1259 { 1121 1260 printf("[XML ERROR] illegal <type> for peripheral %d in cluster %d\n", 1122 1261 periph_loc_index, cluster_index); … … 1124 1263 } 1125 1264 1126 if (error) { 1265 if (error) 1266 { 1127 1267 printf("[XML ERROR] illegal <type> for peripheral %d in cluster %d\n", 1128 1268 periph_loc_index, cluster_index); … … 1130 1270 } 1131 1271 } 1132 else { 1272 else 1273 { 1133 1274 printf("[XML ERROR] missing <type> for peripheral %d in cluster %d\n", 1134 1275 periph_loc_index, cluster_index); 1135 1276 exit(1); 1136 1277 } 1137 1138 1278 1139 1279 periph_index++; … … 1403 1543 void psegNode(xmlTextReaderPtr reader) { 1404 1544 unsigned int ok; 1405 unsigned intvalue;1545 paddr_t ll_value; 1406 1546 char * str; 1407 1547 … … 1450 1590 1451 1591 //////// get base attribute 1452 value = getIntValue(reader, "base", &ok);1453 #if XML_PARSER_DEBUG 1454 printf(" base = 0x% x\n",value);1592 ll_value = getPaddrValue(reader, "base", &ok); 1593 #if XML_PARSER_DEBUG 1594 printf(" base = 0x%llx\n", ll_value); 1455 1595 #endif 1456 1596 if (ok) { 1457 pseg[pseg_index]->base = value;1597 pseg[pseg_index]->base = ll_value; 1458 1598 } 1459 1599 else { … … 1464 1604 1465 1605 //////// get length attribute 1466 value = getIntValue(reader, "length", &ok);1467 #if XML_PARSER_DEBUG 1468 printf(" length = 0x% x\n",value);1606 ll_value = getPaddrValue(reader, "length", &ok); 1607 #if XML_PARSER_DEBUG 1608 printf(" length = 0x%llx\n", ll_value); 1469 1609 #endif 1470 1610 if (ok) { 1471 pseg[pseg_index]->length = value;1611 pseg[pseg_index]->length = ll_value; 1472 1612 } 1473 1613 else { … … 1485 1625 1486 1626 1487 ///////////////////////////////////////////// 1488 void clusterNode(xmlTextReaderPtr reader) { 1627 ///////////////////////////////////////// 1628 void clusterNode(xmlTextReaderPtr reader) 1629 { 1489 1630 unsigned int ok; 1490 1631 unsigned int value; … … 1510 1651 found_timer = 0; 1511 1652 found_icu = 0; 1512 found_xicu = 0;1513 1653 found_dma = 0; 1514 1654 … … 1552 1692 int status = xmlTextReaderRead(reader); 1553 1693 1554 while (status == 1) { 1694 while (status == 1) 1695 { 1555 1696 const char * tag = (const char *) xmlTextReaderConstName(reader); 1556 1697 … … 1561 1702 else if (strcmp(tag, "#text") == 0) { } 1562 1703 else if (strcmp(tag, "#comment") == 0) { } 1563 else if (strcmp(tag, "cluster") == 0) { 1564 1565 if (use_xicu == 0xFFFFFFFF) { 1566 use_xicu = found_xicu; 1567 } 1568 1569 ////////////////// peripherals checks //////////////////// 1570 if ((found_timer && use_xicu) || (!found_timer && !use_xicu)) { 1704 else if (strcmp(tag, "cluster") == 0) 1705 { 1706 1707 ////////////////// peripherals checks ///////////////////////// 1708 if ((found_timer && use_xicu) || (!found_timer && !use_xicu)) 1709 { 1571 1710 printf("[XML ERROR] illegal or missing timer peripheral in cluster %d\n", cluster_index); 1572 1711 exit(1); 1573 1712 } 1574 1713 1575 if ((found_icu && use_xicu) || (!found_icu && !use_xicu)) { 1714 if (!found_icu) 1715 { 1576 1716 printf("[XML ERROR] illegal or missing icu peripheral in cluster %d\n", cluster_index); 1577 1717 exit(1); 1578 1718 } 1579 1719 1580 if (!found_xicu && use_xicu) { 1720 if (!found_dma) 1721 { 1581 1722 printf("[XML ERROR] illegal or missing dma peripheral in cluster %d\n", cluster_index); 1582 1723 exit(1); 1583 1724 } 1584 1725 1585 if (!found_dma) { 1586 printf("[XML ERROR] illegal or missing dma peripheral in cluster %d\n", cluster_index); 1587 exit(1); 1588 } 1589 1590 1591 if (nb_proc_max < cluster[cluster_index]->procs) { 1726 1727 if (nb_proc_max < cluster[cluster_index]->procs) 1728 { 1592 1729 nb_proc_max = cluster[cluster_index]->procs; 1593 1730 } … … 1609 1746 1610 1747 ////////////////////////////////////////////// 1611 void clusterSetNode(xmlTextReaderPtr reader) { 1612 if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) { 1613 return; 1614 } 1748 void clusterSetNode(xmlTextReaderPtr reader) 1749 { 1750 if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) { return; } 1615 1751 1616 1752 #if XML_PARSER_DEBUG … … 1619 1755 1620 1756 int status = xmlTextReaderRead(reader); 1621 while (status == 1) { 1757 while (status == 1) 1758 { 1622 1759 const char * tag = (const char *) xmlTextReaderConstName(reader); 1623 1760 1624 if (strcmp(tag, "cluster") == 0) { 1625 clusterNode(reader); 1626 } 1761 if (strcmp(tag, "cluster") == 0) { clusterNode(reader); } 1627 1762 else if (strcmp(tag, "#text") == 0) { } 1628 1763 else if (strcmp(tag, "#comment") == 0) { } 1629 else if (strcmp(tag, "clusterset") == 0) { 1764 else if (strcmp(tag, "clusterset") == 0) 1765 { 1630 1766 // checking source file consistency 1631 if (cluster_index != header->clusters) { 1767 if (cluster_index != header->clusters) 1768 { 1632 1769 printf("[XML ERROR] Wrong number of clusters\n"); 1633 1770 exit(1); 1634 1771 } 1635 1772 1636 if (header->tty_clusterid == 0xFFFFFFFF) { 1773 // At least one TTY terminal for system boot 1774 if (header->tty_cluster == 0xFFFFFFFF) 1775 { 1637 1776 printf("[XML ERROR] illegal or missing tty peripheral"); 1638 1777 exit(1); … … 1647 1786 header->coprocs = coproc_index; 1648 1787 header->cp_ports = cp_port_index; 1788 header->periphs = periph_index; 1649 1789 return; 1650 1790 } … … 1669 1809 1670 1810 int status = xmlTextReaderRead(reader); 1671 while (status == 1) { 1811 while (status == 1) 1812 { 1672 1813 const char * tag = (const char *) xmlTextReaderConstName(reader); 1673 1814 1674 if (strcmp(tag, "vseg") == 0) { 1675 vsegNode(reader); 1676 } 1815 if (strcmp(tag, "vseg") == 0) { vsegNode(reader); } 1677 1816 else if (strcmp(tag, "#text") == 0) { } 1678 1817 else if (strcmp(tag, "#comment") == 0) { } … … 1736 1875 1737 1876 ////////////////////////////////////////// 1738 void headerNode(xmlTextReaderPtr reader) { 1877 void headerNode(xmlTextReaderPtr reader) 1878 { 1739 1879 char * name; 1740 1880 unsigned int value; 1741 1881 unsigned int ok; 1742 1882 1743 if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) { 1744 return; 1745 } 1883 if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_END_ELEMENT) { return; } 1746 1884 1747 1885 #if XML_PARSER_DEBUG … … 1820 1958 } 1821 1959 1822 //////// initialise non replicated peripherals cluster_id 1823 header->tty_clusterid = 0xFFFFFFFF; 1824 header->nic_clusterid = 0xFFFFFFFF; 1825 header->ioc_clusterid = 0xFFFFFFFF; 1826 header->fbf_clusterid = 0xFFFFFFFF; 1960 //////// initialise non replicated peripherals cluster index 1961 header->tty_cluster = 0xFFFFFFFF; 1962 header->nic_cluster = 0xFFFFFFFF; 1963 header->ioc_cluster = 0xFFFFFFFF; 1964 header->fbf_cluster = 0xFFFFFFFF; 1965 header->cma_cluster = 0xFFFFFFFF; 1966 header->iob_cluster = 0xFFFFFFFF; 1967 header->tty_cluster_bis = 0xFFFFFFFF; 1968 header->nic_cluster_bis = 0xFFFFFFFF; 1969 header->ioc_cluster_bis = 0xFFFFFFFF; 1970 header->fbf_cluster_bis = 0xFFFFFFFF; 1971 header->cma_cluster_bis = 0xFFFFFFFF; 1972 header->iob_cluster_bis = 0xFFFFFFFF; 1827 1973 1828 1974 ///////// set signature … … 1940 2086 // this function set the value the vobj_id fiels of all cp_ports 1941 2087 /////////////////////////////////////////////////////////////////////// 1942 void prepareBuild() { 2088 void prepareBuild() 2089 { 1943 2090 unsigned int i; 1944 2091 //asign for all cp_ports the correct vspaceid and vobjid … … 1972 2119 } 1973 2120 1974 1975 2121 ////////////////////////////////////////// 1976 void file_write(int fdout, char * towrite) { 2122 void file_write(int fdout, char * towrite) 2123 { 1977 2124 unsigned int size = strlen(towrite); 1978 if (size != write(fdout, towrite, size)) { 2125 if (size != write(fdout, towrite, size)) 2126 { 1979 2127 printf("file_write error"); 1980 2128 exit(1); … … 1982 2130 } 1983 2131 1984 1985 2132 ////////////////////////////////////////////////// 1986 void def_int_write(int fdout, char * def, int num) { 2133 void def_int_write(int fdout, char * def, int num) 2134 { 1987 2135 char buf[64]; 1988 2136 sprintf(buf, "#define\t %s %d\n", def, num); … … 1990 2138 } 1991 2139 1992 1993 ///////////////////////////////////////////////// 1994 void def_hex_write(int fdout, char * def, int num){2140 ////////////////////////////////////////////////// 2141 void def_hex_write(int fdout, char * def, int num) 2142 { 1995 2143 char buf[64]; 1996 2144 sprintf(buf, "#define\t %s 0x%x\n", def, num); … … 1998 2146 } 1999 2147 2000 2001 /////////////////////////////////////// 2002 void genHd(const char * file_path){2148 /////////////////////////////////// 2149 void genHd(const char * file_path) 2150 { 2003 2151 int fdout = open_file(file_path); 2004 2152 2005 char * prol = " /* Generated from the mapping_info file */\n\n#ifndef _HD_CONFIG_H\n#define _HD_CONFIG_H\n\n"; 2153 char * prol = "/* Generated from the mapping_info file */\n\n"; 2154 char * ifdef = "#ifndef _HD_CONFIG_H\n#define _HD_CONFIG_H\n\n"; 2155 char * epil = "\n#endif //_HD_CONFIG_H"; 2156 2006 2157 file_write(fdout, prol); 2007 2008 def_int_write(fdout, "CLUSTER_X" , cluster_x); 2009 def_int_write(fdout, "CLUSTER_Y" , cluster_y); 2010 def_int_write(fdout, "NB_CLUSTERS" , cluster_index); 2011 def_hex_write(fdout, "CLUSTER_SIZE" , (((unsigned long long) 1) << 32) / cluster_index); 2012 def_int_write(fdout, "NB_PROCS_MAX" , nb_proc_max); 2013 def_int_write(fdout, "NB_TIMERS_MAX", nb_timer_channel_max); 2014 def_int_write(fdout, "NB_DMAS_MAX" , nb_dma_channel_max); 2015 def_int_write(fdout, "NB_TTYS" , nb_tty_channel); 2016 def_int_write(fdout, "NB_IOCS" , nb_ioc_channel); 2017 def_int_write(fdout, "NB_NICS" , nb_nic_channel); 2018 def_int_write(fdout, "NB_TASKS" , nb_tasks_max); 2158 file_write(fdout, ifdef); 2159 2160 def_int_write(fdout, "CLUSTER_X ", cluster_x); 2161 def_int_write(fdout, "CLUSTER_Y ", cluster_y); 2162 def_int_write(fdout, "NB_CLUSTERS ", cluster_index); 2163 def_int_write(fdout, "NB_PROCS_MAX ", nb_proc_max); 2164 def_int_write(fdout, "NB_TASKS_MAX ", nb_tasks_max); 2019 2165 2020 2166 file_write(fdout, "\n"); 2021 def_int_write(fdout, "USE_XICU" , use_xicu); 2022 def_int_write(fdout, "IOMMU_ACTIVE ", io_mmu_active); 2023 2024 char * epil = "\n#endif //_HD_CONFIG_H"; 2167 2168 def_int_write(fdout, "NB_TIM_CHANNELS ", tim_channels); 2169 def_int_write(fdout, "NB_DMA_CHANNELS ", dma_channels); 2170 2171 file_write(fdout, "\n"); 2172 2173 def_int_write(fdout, "NB_TTY_CHANNELS ", tty_channels); 2174 def_int_write(fdout, "NB_IOC_CHANNELS ", ioc_channels); 2175 def_int_write(fdout, "NB_NIC_CHANNELS ", nic_channels); 2176 def_int_write(fdout, "NB_CMA_CHANNELS ", cma_channels); 2177 2178 file_write(fdout, "\n"); 2179 2180 def_int_write(fdout, "USE_XICU ", use_xicu); 2181 def_int_write(fdout, "IOMMU_ACTIVE ", io_mmu_active); 2182 2025 2183 file_write(fdout, epil); 2026 2184 … … 2028 2186 } 2029 2187 2030 2031 2188 //////////////////////////////////////////////////////// 2032 void ld_write(int fdout, char * seg, unsigned int addr) { 2189 void ld_write(int fdout, char * seg, unsigned int addr) 2190 { 2033 2191 char buf[64]; 2034 2192 sprintf(buf, "%s = 0x%x;\n", seg, addr); 2035 2193 file_write(fdout, buf); 2036 2037 2194 } 2038 2195 2039 2040 /////////////////////////////////////// 2041 void genLd(const char * file_path) { 2042 int fdout = open_file(file_path); 2196 ////////////////////////////////// 2197 void genLd(const char * file_path) 2198 { 2199 int fdout = open_file(file_path); 2200 unsigned int count = 0; 2201 unsigned int vseg_id; 2043 2202 2044 2203 char * prol = "/* Generated from the mapping_info file */\n\n"; 2045 2204 file_write(fdout, prol); 2046 2205 2047 //boot 2048 ld_write(fdout, "seg_boot_code_base", boot_code_base); 2049 ld_write(fdout, "seg_boot_stack_base", boot_stack_base); 2050 ld_write(fdout, "seg_mapping_base", boot_mapping_base); 2051 2052 //kernel 2053 ld_write(fdout, "\nseg_kernel_code_base", kernel_code_base); 2054 ld_write(fdout, "seg_kernel_data_base", kernel_data_base); 2055 ld_write(fdout, "seg_kernel_uncdata_base", kernel_uncdata_base); 2056 ld_write(fdout, "seg_kernel_init_base", kernel_init_base); 2057 2058 //peripherals 2059 ld_write(fdout, "\nseg_fbf_base", fbf_base_offset); 2060 ld_write(fdout, "seg_icu_base", icu_base_offset); 2061 ld_write(fdout, "seg_ioc_base", ioc_base_offset); 2062 ld_write(fdout, "seg_nic_base", nic_base_offset); 2063 ld_write(fdout, "seg_tty_base", tty_base_offset); 2064 ld_write(fdout, "seg_dma_base", dma_base_offset); 2065 ld_write(fdout, "seg_tim_base", tim_base_offset); 2066 ld_write(fdout, "seg_gcd_base", gcd_base_offset); 2067 ld_write(fdout, "seg_iob_base", iob_base_offset); 2206 // boot and kernel segments 2207 for (vseg_id = 0 ; vseg_id < header->vsegs ; vseg_id++) 2208 { 2209 if ( strcmp(vseg[vseg_id]->name, "seg_boot_code") == 0 ) 2210 { 2211 ld_write(fdout, "seg_boot_code_base ", vseg[vseg_id]->vbase); 2212 count++; 2213 } 2214 else if ( strcmp(vseg[vseg_id]->name, "seg_boot_stack") == 0 ) 2215 { 2216 ld_write(fdout, "seg_boot_stack_base ", vseg[vseg_id]->vbase); 2217 count++; 2218 } 2219 else if ( strcmp(vseg[vseg_id]->name, "seg_boot_mapping") == 0 ) 2220 { 2221 ld_write(fdout, "seg_mapping_base ", vseg[vseg_id]->vbase); 2222 count++; 2223 } 2224 else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_code") == 0 ) 2225 { 2226 ld_write(fdout, "seg_kernel_code_base ", vseg[vseg_id]->vbase); 2227 count++; 2228 } 2229 else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_data") == 0 ) 2230 { 2231 ld_write(fdout, "seg_kernel_data_base ", vseg[vseg_id]->vbase); 2232 count++; 2233 } 2234 else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_uncdata") == 0 ) 2235 { 2236 ld_write(fdout, "seg_kernel_uncdata_base ", vseg[vseg_id]->vbase); 2237 count++; 2238 } 2239 else if ( strcmp(vseg[vseg_id]->name, "seg_kernel_init") == 0 ) 2240 { 2241 ld_write(fdout, "seg_kernel_init_base ", vseg[vseg_id]->vbase); 2242 count++; 2243 } 2244 } 2245 if ( count != 7 ) 2246 { 2247 printf ("[XML ERROR] Missing Boot or Kernel vseg : only %d\n", count); 2248 printf ("Mandatory segments are :\n"); 2249 printf (" - seg_boot_code\n"); 2250 printf (" - seg_boot_stack\n"); 2251 printf (" - seg_boot_mapping\n"); 2252 printf (" - seg_kernel_code\n"); 2253 printf (" - seg_kernel_data\n"); 2254 printf (" - seg_kernel_uncdata\n"); 2255 printf (" - seg_kernel_init\n"); 2256 } 2257 2258 file_write(fdout, "\n"); 2259 2260 // non replicated peripherals 2261 ld_write(fdout, "\nseg_fbf_base ", periph_vbase_array[PERIPH_TYPE_FBF]); 2262 ld_write(fdout, "seg_ioc_base ", periph_vbase_array[PERIPH_TYPE_IOC]); 2263 ld_write(fdout, "seg_nic_base ", periph_vbase_array[PERIPH_TYPE_NIC]); 2264 ld_write(fdout, "seg_tty_base ", periph_vbase_array[PERIPH_TYPE_TTY]); 2265 ld_write(fdout, "seg_gcd_base ", periph_vbase_array[PERIPH_TYPE_GCD]); 2266 ld_write(fdout, "seg_iob_base ", periph_vbase_array[PERIPH_TYPE_IOB]); 2267 2268 file_write(fdout, "\n"); 2269 2270 // replicated peripherals 2271 ld_write(fdout, "seg_icu_base ", periph_vbase_array[PERIPH_TYPE_ICU]); 2272 ld_write(fdout, "seg_dma_base ", periph_vbase_array[PERIPH_TYPE_DMA]); 2273 ld_write(fdout, "seg_tim_base ", periph_vbase_array[PERIPH_TYPE_TIM]); 2068 2274 2069 2275 close(fdout); 2070 2276 } 2071 2277 2072 2073 char * buildPath(const char * path, const char * name) { 2278 ////////////////////////////////////////////////////// 2279 char * buildPath(const char * path, const char * name) 2280 { 2074 2281 char * res = calloc(strlen(path) + strlen(name) + 1, 1); 2075 2282 strcat(res, path); … … 2080 2287 2081 2288 2082 ///////////////////////////////////// 2083 int main(int argc, char * argv[]) { 2289 ////////////////////////////////// 2290 int main(int argc, char * argv[]) 2291 { 2084 2292 if (argc < 3) { 2085 2293 printf("Usage: xml2bin <input_file_path> <output_path>\n");
Note: See TracChangeset
for help on using the changeset viewer.