- Timestamp:
- Apr 26, 2017, 2:14:33 PM (8 years ago)
- Location:
- trunk/tools
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/tools/arch_info/arch_classes.py
r1 r6 13 13 # It handle 4 types of objects: clusters, cores, devices and irqs. 14 14 # - The number of cluster is variable (can be one). 15 # - The cluster topology can be a 2D mesh or a simpl aarray.15 # - The cluster topology can be a 2D mesh or a simple 1D array. 16 16 # - The number of cores per cluster is variable (can be zero). 17 17 # - The number of addressable devices per cluster is variable. … … 41 41 ######################################################################################### 42 42 # These arrays define the supported types of peripherals. 43 # They must be kept consistent with values defined in file arch_info.h.43 # They must be kept consistent with values defined in files arch_info.h & device.h. 44 44 ######################################################################################### 45 45 46 46 DEVICE_TYPES_STR = [ 47 'RAM', # 0 48 'DMA', # 1 49 'FBF', # 1 50 'IOB', # 3 51 'IOC_BDV', # 4 52 'IOC_HBA', # 5 53 'IOC_SDC', # 6 54 'IOC_SPI', # 7 55 'IOC_RDK', # 8 56 'MMC', # 9 57 'MWR_CPY', # 10 58 'MWR_GCD', # 11 59 'MWR_DCT', # 12 60 'NIC', # 13 61 'ROM', # 14 62 'SIM', # 15 63 'TIM', # 16 64 'TTY', # 17 65 'XCU', # 18 66 'PIC', # 19 67 'CMA', # 20 47 'RAM_SCL', # 0.0 48 'ROM_SCL', # 1.0 49 'FBF_SCL', # 2.0 50 'IOB_TSR', # 3.0 51 'IOC_BDV', # 4.0 52 'IOC_HBA', # 4.1 53 'IOC_SDC', # 4.2 54 'IOC_SPI', # 4.3 55 'IOC_RDK', # 4.4 56 'MMC_TSR', # 5.0 57 'DMA_SCL', # 6.0 58 'NIC_CBF', # 7.0 59 'TIM_SCL', # 8.0 60 'TXT_TTY', # 9.0 61 'ICU_XCU', # A.0 62 'PIC_TSR', # B.0 68 63 ] 69 64 70 65 DEVICE_TYPES_INT = [ 71 0x00000000, # 0 72 0x00010000, # 1 73 0x00020000, # 1 74 0x00030000, # 3 75 0x00040000, # 4 76 0x00040001, # 5 77 0x00040002, # 6 78 0x00040003, # 7 79 0x00040004, # 8 80 0x00050000, # 9 81 0x00060000, # 10 82 0x00060001, # 11 83 0x00060002, # 12 84 0x00070000, # 13 85 0x00080000, # 14 86 0x00090000, # 15 87 0x000A0000, # 16 88 0x000B0000, # 17 89 0x000C0000, # 18 90 0x000D0000, # 19 91 0x000E0000, # 20 66 0x00000000, # 0.0 67 0x00010000, # 1.0 68 0x00020000, # 1.0 69 0x00030000, # 3.0 70 0x00040000, # 4.0 71 0x00040001, # 4.1 72 0x00040002, # 4.2 73 0x00040003, # 4.3 74 0x00040004, # 4.4 75 0x00050000, # 5.0 76 0x00060000, # 6.0 77 0x00070000, # 7.0 78 0x00080000, # 8.0 79 0x00090000, # 9.0 80 0x000A0000, # A.0 81 0x000B0000, # B.0 92 82 ] 93 83 … … 104 94 x_width, # number of bits for x coordinate 105 95 y_width, # number of bits for y coordinate 106 irqs_per_core, # number or IRQs from XCU to one core96 irqs_per_core, # number or IRQs from ICU to one core 107 97 io_cxy, # IO cluster identifier 108 98 boot_cxy, # boot cluster identifier … … 186 176 ################################ add an input IRQ in a device 187 177 def addIrq( self, 188 dstdev, # destination device (PIC or XCU)178 dstdev, # destination device (PIC or ICU) 189 179 port, # input IRQ port index 190 180 srcdev, # source device … … 192 182 is_rx = False ): # I/O operation direction 193 183 194 assert (dstdev.ptype == ' XCU') or (dstdev.ptype == 'PIC')184 assert (dstdev.ptype == 'ICU_XCU') or (dstdev.ptype == 'PIC_TSR') 195 185 assert (port < dstdev.arg0) 196 186 … … 382 372 ram_size = 0 383 373 384 nb_cma = 0 385 cma_channels = 0 386 cma_base = 0xFFFFFFFFFFFFFFFF 387 cma_size = 0 388 389 nb_dma = 0 390 dma_channels = 0 391 dma_base = 0xFFFFFFFFFFFFFFFF 392 dma_size = 0 374 nb_rom = 0 375 rom_channels = 0 376 rom_base = 0xFFFFFFFFFFFFFFFF 377 rom_size = 0 393 378 394 379 nb_fbf = 0 … … 419 404 mmc_size = 0 420 405 421 nb_mwr = 0 422 mwr_channels = 0 423 mwr_base = 0xFFFFFFFFFFFFFFFF 424 mwr_size = 0 425 mwr_arg0 = 0 426 mwr_arg1 = 0 427 mwr_arg2 = 0 428 mwr_arg3 = 0 429 use_mwr_gcd = False 430 use_mwr_dct = False 431 use_mwr_cpy = False 406 nb_dma = 0 407 dma_channels = 0 408 dma_base = 0xFFFFFFFFFFFFFFFF 409 dma_size = 0 432 410 433 411 nb_nic = 0 … … 436 414 nic_size = 0 437 415 416 nb_sim = 0 417 sim_channels = 0 418 sim_base = 0xFFFFFFFFFFFFFFFF 419 sim_size = 0 420 421 nb_tim = 0 422 tim_channels = 0 423 tim_base = 0xFFFFFFFFFFFFFFFF 424 tim_size = 0 425 426 nb_txt = 0 427 txt_channels = 0 428 txt_base = 0xFFFFFFFFFFFFFFFF 429 txt_size = 0 430 431 nb_icu = 0 432 icu_channels = 0 433 icu_base = 0xFFFFFFFFFFFFFFFF 434 icu_size = 0 435 icu_arg0 = 0 436 438 437 nb_pic = 0 439 438 pic_channels = 0 … … 441 440 pic_size = 0 442 441 443 nb_rom = 0 444 rom_channels = 0 445 rom_base = 0xFFFFFFFFFFFFFFFF 446 rom_size = 0 447 448 nb_sim = 0 449 sim_channels = 0 450 sim_base = 0xFFFFFFFFFFFFFFFF 451 sim_size = 0 452 453 nb_tim = 0 454 tim_channels = 0 455 tim_base = 0xFFFFFFFFFFFFFFFF 456 tim_size = 0 457 458 nb_tty = 0 459 tty_channels = 0 460 tty_base = 0xFFFFFFFFFFFFFFFF 461 tty_size = 0 462 463 nb_xcu = 0 464 xcu_channels = 0 465 xcu_base = 0xFFFFFFFFFFFFFFFF 466 xcu_size = 0 467 xcu_arg0 = 0 468 469 nb_drom = 0 470 drom_channels = 0 471 drom_base = 0xFFFFFFFFFFFFFFFF 472 drom_size = 0 442 nb_rom = 0 443 rom_channels = 0 444 rom_base = 0xFFFFFFFFFFFFFFFF 445 rom_size = 0 473 446 474 447 # get devices attributes … … 476 449 for device in cluster.devices: 477 450 478 if ( device.ptype == 'RAM ' ):451 if ( device.ptype == 'RAM_SCL' ): 479 452 ram_base = device.base 480 453 ram_size = device.size … … 482 455 nb_ram +=1 483 456 484 elif ( device.ptype == 'CMA' ): 485 cma_base = device.base 486 cma_size = device.size 487 cma_channels = device.channels 488 nb_cma +=1 489 490 elif ( device.ptype == 'DMA' ): 491 dma_base = device.base 492 dma_size = device.size 493 dma_channels = device.channels 494 nb_dma +=1 495 496 elif ( device.ptype == 'FBF' ): 457 elif ( device.ptype == 'ROM_SCL' ): 458 rom_base = device.base 459 rom_size = device.size 460 rom_channels = device.channels 461 nb_rom +=1 462 463 elif ( device.ptype == 'FBF_SCL' ): 497 464 fbf_base = device.base 498 465 fbf_size = device.size … … 502 469 nb_fbf +=1 503 470 504 elif ( device.ptype == 'IOB ' ):471 elif ( device.ptype == 'IOB_TSR' ): 505 472 iob_base = device.base 506 473 iob_size = device.size … … 532 499 use_ioc_spi = True 533 500 nb_ioc += 1 534 535 501 elif ( device.ptype == 'IOC_RDK' ): 536 502 ioc_base = device.base … … 540 506 nb_ioc += 1 541 507 542 elif ( device.ptype == 'MMC ' ):508 elif ( device.ptype == 'MMC_TSR' ): 543 509 mmc_base = device.base 544 510 mmc_size = device.size … … 546 512 nb_mmc +=1 547 513 548 elif ( device.ptype == 'MWR_GCD' ): 549 mwr_base = device.base 550 mwr_size = device.size 551 mwr_channels = device.channels 552 mwr_arg0 = device.arg0 553 mwr_arg1 = device.arg1 554 mwr_arg2 = device.arg2 555 mwr_arg3 = device.arg3 556 use_mwr_gcd = True 557 nb_mwr +=1 558 elif ( device.ptype == 'MWR_DCT' ): 559 mwr_base = device.base 560 mwr_size = device.size 561 mwr_channels = device.channels 562 mwr_arg0 = device.arg0 563 mwr_arg1 = device.arg1 564 mwr_arg2 = device.arg2 565 mwr_arg3 = device.arg3 566 use_mwr_dct = True 567 nb_mwr +=1 568 elif ( device.ptype == 'MWR_CPY' ): 569 mwr_base = device.base 570 mwr_size = device.size 571 mwr_channels = device.channels 572 mwr_arg0 = device.arg0 573 mwr_arg1 = device.arg1 574 mwr_arg2 = device.arg2 575 mwr_arg3 = device.arg3 576 use_mwr_cpy = True 577 nb_mwr +=1 578 579 elif ( device.ptype == 'ROM' ): 580 rom_base = device.base 581 rom_size = device.size 582 rom_channels = device.channels 583 nb_rom +=1 584 585 elif ( device.ptype == 'DROM' ): 586 drom_base = device.base 587 drom_size = device.size 588 drom_channels = device.channels 589 nb_drom +=1 590 591 elif ( device.ptype == 'SIM' ): 592 sim_base = device.base 593 sim_size = device.size 594 sim_channels = device.channels 595 nb_sim +=1 596 597 elif ( device.ptype == 'NIC' ): 514 elif ( device.ptype == 'DMA_SCL' ): 515 dma_base = device.base 516 dma_size = device.size 517 dma_channels = device.channels 518 nb_dma +=1 519 520 elif ( device.ptype == 'NIC_CBF' ): 598 521 nic_base = device.base 599 522 nic_size = device.size … … 601 524 nb_nic +=1 602 525 603 elif ( device.ptype == 'PIC' ): 526 elif ( device.ptype == 'TIM_SCL' ): 527 tim_base = device.pseg.base 528 tim_size = device.pseg.size 529 tim_channels = device.channels 530 nb_tim +=1 531 532 elif ( device.ptype == 'TXT_TTY' ): 533 txt_base = device.base 534 txt_size = device.size 535 txt_channels = device.channels 536 nb_txt +=1 537 538 elif ( device.ptype == 'ICU_XCU' ): 539 icu_base = device.base 540 icu_size = device.size 541 icu_channels = device.channels 542 icu_arg0 = device.arg0 543 icu_arg1 = device.arg1 544 icu_arg2 = device.arg2 545 icu_arg3 = device.arg3 546 nb_icu +=1 547 548 elif ( device.ptype == 'PIC_TSR' ): 604 549 pic_base = device.base 605 550 pic_size = device.size 606 551 pic_channels = device.channels 607 552 nb_pic +=1 608 609 elif ( device.ptype == 'TIM' ):610 tim_base = device.pseg.base611 tim_size = device.pseg.size612 tim_channels = device.channels613 nb_tim +=1614 615 elif ( device.ptype == 'TTY' ):616 tty_base = device.base617 tty_size = device.size618 tty_channels = device.channels619 nb_tty +=1620 621 elif ( device.ptype == 'XCU' ):622 xcu_base = device.base623 xcu_size = device.size624 xcu_channels = device.channels625 xcu_arg0 = device.arg0626 xcu_arg1 = device.arg1627 xcu_arg2 = device.arg2628 nb_xcu +=1629 630 # no more than two access to external devices631 assert ( nb_fbf <= 2 )632 assert ( nb_cma <= 2 )633 assert ( nb_ioc <= 2 )634 assert ( nb_nic <= 2 )635 assert ( nb_tim <= 2 )636 assert ( nb_tty <= 2 )637 assert ( nb_pic <= 2 )638 553 639 554 # one and only one IOC controller … … 647 562 rdk_base = 0 648 563 rdk_size = 0 649 650 # only one type of MWR controller651 nb_mwr_types = 0652 if use_mwr_gcd: nb_mwr_types += 1653 if use_mwr_dct: nb_mwr_types += 1654 if use_mwr_cpy: nb_mwr_types += 1655 if ( nb_mwr > 0 ) : assert ( nb_mwr_types == 1 )656 564 657 565 # Compute total number of cores, devices and irqs … … 697 605 s += '/* Peripherals */\n' 698 606 s += '\n' 699 s += '#define NB_T TY_CHANNELS %d\n' % tty_channels607 s += '#define NB_TXT_CHANNELS %d\n' % txt_channels 700 608 s += '#define NB_IOC_CHANNELS %d\n' % ioc_channels 701 609 s += '#define NB_NIC_CHANNELS %d\n' % nic_channels 702 s += '#define NB_CMA_CHANNELS %d\n' % cma_channels703 610 s += '#define NB_TIM_CHANNELS %d\n' % tim_channels 704 s += '#define NB_DMA_CHANNELS %d\n' % dma_channels 705 s += '\n' 706 s += '#define USE_XCU %d\n' % ( nb_xcu != 0 ) 707 s += '#define USE_DMA %d\n' % ( nb_dma != 0 ) 708 s += '\n' 611 s += '\n' 612 s += '#define USE_ICU %d\n' % ( nb_icu != 0 ) 709 613 s += '#define USE_IOB %d\n' % ( nb_iob != 0 ) 710 614 s += '#define USE_PIC %d\n' % ( nb_pic != 0 ) 711 615 s += '#define USE_FBF %d\n' % ( nb_fbf != 0 ) 712 616 s += '#define USE_NIC %d\n' % ( nb_nic != 0 ) 617 s += '#define USE_DMA %d\n' % ( nb_dma != 0 ) 713 618 s += '\n' 714 619 s += '#define USE_IOC_BDV %d\n' % use_ioc_bdv … … 718 623 s += '#define USE_IOC_RDK %d\n' % use_ioc_rdk 719 624 s += '\n' 720 s += '#define USE_MWR_GCD %d\n' % use_mwr_gcd721 s += '#define USE_MWR_DCT %d\n' % use_mwr_dct722 s += '#define USE_MWR_CPY %d\n' % use_mwr_cpy723 s += '\n'724 625 s += '#define FBUF_X_SIZE %d\n' % fbf_arg0 725 626 s += '#define FBUF_Y_SIZE %d\n' % fbf_arg1 726 627 s += '\n' 727 s += '#define XCU_NB_HWI %d\n' % xcu_arg0 728 s += '#define XCU_NB_PTI %d\n' % xcu_arg1 729 s += '#define XCU_NB_WTI %d\n' % xcu_arg2 730 s += '#define XCU_NB_OUT %d\n' % xcu_channels 731 s += '\n' 732 s += '#define MWR_TO_COPROC %d\n' % mwr_arg0 733 s += '#define MWR_FROM_COPROC %d\n' % mwr_arg1 734 s += '#define MWR_CONFIG %d\n' % mwr_arg2 735 s += '#define MWR_STATUS %d\n' % mwr_arg3 628 s += '#define ICU_NB_HWI %d\n' % icu_arg0 629 s += '#define ICU_NB_PTI %d\n' % icu_arg1 630 s += '#define ICU_NB_WTI %d\n' % icu_arg2 631 s += '#define ICU_NB_OUT %d\n' % icu_arg3 736 632 s += '\n' 737 633 … … 741 637 s += '#define SEG_RAM_SIZE 0x%x\n' % ram_size 742 638 s += '\n' 743 s += '#define SEG_CMA_BASE 0x%x\n' % (cma_base & local_physical_mask) 744 s += '#define SEG_CMA_SIZE 0x%x\n' % cma_size 639 s += '#define SEG_FBF_BASE 0x%x\n' % (fbf_base & local_physical_mask) 640 s += '#define SEG_FBF_SIZE 0x%x\n' % fbf_size 641 s += '\n' 642 s += '#define SEG_IOB_BASE 0x%x\n' % (iob_base & local_physical_mask) 643 s += '#define SEG_IOB_SIZE 0x%x\n' % iob_size 644 s += '\n' 645 s += '#define SEG_IOC_BASE 0x%x\n' % (ioc_base & local_physical_mask) 646 s += '#define SEG_IOC_SIZE 0x%x\n' % ioc_size 647 s += '\n' 648 s += '#define SEG_MMC_BASE 0x%x\n' % (mmc_base & local_physical_mask) 649 s += '#define SEG_MMC_SIZE 0x%x\n' % mmc_size 745 650 s += '\n' 746 651 s += '#define SEG_DMA_BASE 0x%x\n' % (dma_base & local_physical_mask) 747 652 s += '#define SEG_DMA_SIZE 0x%x\n' % dma_size 748 653 s += '\n' 749 s += '#define SEG_FBF_BASE 0x%x\n' % (fbf_base & local_physical_mask)750 s += '#define SEG_FBF_SIZE 0x%x\n' % fbf_size751 s += '\n'752 s += '#define SEG_IOB_BASE 0x%x\n' % (iob_base & local_physical_mask)753 s += '#define SEG_IOB_SIZE 0x%x\n' % iob_size754 s += '\n'755 s += '#define SEG_IOC_BASE 0x%x\n' % (ioc_base & local_physical_mask)756 s += '#define SEG_IOC_SIZE 0x%x\n' % ioc_size757 s += '\n'758 s += '#define SEG_MMC_BASE 0x%x\n' % (mmc_base & local_physical_mask)759 s += '#define SEG_MMC_SIZE 0x%x\n' % mmc_size760 s += '\n'761 s += '#define SEG_MWR_BASE 0x%x\n' % (mwr_base & local_physical_mask)762 s += '#define SEG_MWR_SIZE 0x%x\n' % mwr_size763 s += '\n'764 654 s += '#define SEG_ROM_BASE 0x%x\n' % (rom_base & local_physical_mask) 765 655 s += '#define SEG_ROM_SIZE 0x%x\n' % rom_size … … 777 667 s += '#define SEG_TIM_SIZE 0x%x\n' % tim_size 778 668 s += '\n' 779 s += '#define SEG_T TY_BASE 0x%x\n' % (tty_base & local_physical_mask)780 s += '#define SEG_T TY_SIZE 0x%x\n' % tty_size781 s += '\n' 782 s += '#define SEG_ XCU_BASE 0x%x\n' % (xcu_base & local_physical_mask)783 s += '#define SEG_ XCU_SIZE 0x%x\n' % xcu_size669 s += '#define SEG_TXT_BASE 0x%x\n' % (txt_base & local_physical_mask) 670 s += '#define SEG_TXT_SIZE 0x%x\n' % txt_size 671 s += '\n' 672 s += '#define SEG_ICU_BASE 0x%x\n' % (icu_base & local_physical_mask) 673 s += '#define SEG_ICU_SIZE 0x%x\n' % icu_size 784 674 s += '\n' 785 675 s += '#define SEG_RDK_BASE 0x%x\n' % (rdk_base & local_physical_mask) 786 676 s += '#define SEG_RDK_SIZE 0x%x\n' % rdk_size 787 s += '\n'788 s += '#define SEG_DROM_BASE 0x%x\n' % (drom_base & local_physical_mask)789 s += '#define SEG_DROM_SIZE 0x%x\n' % drom_size790 677 s += '\n' 791 678 s += '#endif\n' … … 931 818 self.arg2 = arg2 # optional (semantic depends on ptype) 932 819 self.arg3 = arg3 # optional (semantic depends on ptype) 933 self.irqs = [] # set of input IRQs (for PIC and XCU only)820 self.irqs = [] # set of input IRQs (for PIC and ICU only) 934 821 self.irq_ctrl = None # interrupt controller for this device 935 822 return … … 946 833 s += ' arg2="%d"' % self.arg2 947 834 s += ' arg3="%d"' % self.arg3 948 if ( (self.ptype == 'PIC ') or (self.ptype == 'XCU') ):835 if ( (self.ptype == 'PIC_TSR') or (self.ptype == 'ICU_XCU') ): 949 836 s += ' >\n' 950 837 for irq in self.irqs: s += irq.xml() … … 958 845 959 846 if ( verbose ): 960 print '*** cbin for device[%d] / type %s' \961 % (self.index , self.ptype )847 print '*** cbin for device[%d] / type = %s / base = %x' \ 848 % (self.index , self.ptype , self.base) 962 849 963 850 # check index … … 985 872 986 873 byte_stream = bytearray() 987 byte_stream += mapping.int2bytes(4,ptype_id) # device type988 874 byte_stream += mapping.int2bytes(8,self.base) # segment base address 989 875 byte_stream += mapping.int2bytes(8,self.size) # segment size 876 byte_stream += mapping.int2bytes(4,ptype_id) # device type 990 877 byte_stream += mapping.int2bytes(4,self.channels) # number of channels 991 878 byte_stream += mapping.int2bytes(4,self.arg0) # optionnal arg0 … … 997 884 998 885 if ( verbose ): 999 print 'ptype = %d' % ptype_id1000 886 print 'base = %x' % self.base 1001 887 print 'size = %x' % self.size … … 1034 920 1035 921 if ( verbose ): 1036 print '*** cbin for irq[%d] / type= %s' \1037 % (self. index , self.isrtype)922 print '*** cbin for irq[%d] / src_dev = %s' \ 923 % (self.port , self.dev.ptype) 1038 924 1039 925 # check index … … 1041 927 print '[genarch error] in Irq.cbin()' 1042 928 print ' irq global index = %d / expected = %d' \ 1043 % (self.index ,expected)929 % (self.index , expected) 1044 930 sys.exit(1) 1045 931 -
trunk/tools/arch_info/arch_info.h
r1 r6 63 63 * The 16 MSB bits define the functionnal type. 64 64 * The 16 LSB bits define the implementation type. 65 * It must be consistent with values defined in file arch_class.py65 * It must be consistent with values defined in files arch_class.py, and device.* 66 66 ***************************************************************************************/ 67 67 68 68 enum deviceTypes 69 69 { 70 DEV_TYPE_RAM 71 DEV_TYPE_ DMA= 0x00010000,72 DEV_TYPE_FBF 73 DEV_TYPE_IOB 70 DEV_TYPE_RAM_SCL = 0x00000000, 71 DEV_TYPE_ROM_SCL = 0x00010000, 72 DEV_TYPE_FBF_SCL = 0x00020000, 73 DEV_TYPE_IOB_TSR = 0x00030000, 74 74 DEV_TYPE_IOC_BDV = 0x00040000, 75 75 DEV_TYPE_IOC_HBA = 0x00040001, … … 77 77 DEV_TYPE_IOC_SPI = 0x00040003, 78 78 DEV_TYPE_IOC_RDK = 0x00040004, 79 DEV_TYPE_MMC = 0x00050000, 80 DEV_TYPE_MWR_CPY = 0x00060000, 81 DEV_TYPE_MWR_GCD = 0x00060001, 82 DEV_TYPE_MWR_DCT = 0x00060002, 83 DEV_TYPE_NIC = 0x00070000, 84 DEV_TYPE_ROM = 0x00080000, 85 DEV_TYPE_SIM = 0x00090000, 86 DEV_TYPE_TIM = 0x000A0000, 87 DEV_TYPE_TTY = 0x000B0000, 88 DEV_TYPE_XCU = 0x000C0000, 89 DEV_TYPE_PIC = 0x000D0000, 90 DEV_TYPE_CMA = 0x000E0000, 79 DEV_TYPE_MMC_TSR = 0x00050000, 80 DEV_TYPE_DMA_SCL = 0x00060000, 81 DEV_TYPE_NIC_CBF = 0x00070000, 82 DEV_TYPE_TIM_SCL = 0x00080000, 83 DEV_TYPE_TXT_TTY = 0x00090000, 84 DEV_TYPE_ICU_XCU = 0x000A0000, 85 DEV_TYPE_PIC_TSR = 0x000B0000, 91 86 }; 92 87 … … 143 138 { 144 139 uint32_t gid; // core hardware identifier 140 uint16_t cxy; // cluster identifier 145 141 uint16_t lid; // core local index in cluster 146 uint16_t cxy; // cluster identifier147 142 } 148 143 archinfo_core_t; … … 154 149 typedef struct __attribute__((packed)) archinfo_device_s 155 150 { 151 uint64_t base; // base address in physical space 152 uint64_t size; // channel size (bytes) 156 153 uint32_t type; // supported values defined above 157 uint64_t base; // base address in physical space158 uint64_t size; // size (bytes)159 154 uint32_t channels; // number of channels 160 155 uint32_t arg0; // semantic depends on device type … … 162 157 uint32_t arg2; // semantic depends on device type 163 158 uint32_t arg3; // semantic depends on device type 164 uint32_t irqs; // number of input IRQs (for XCU or PIC)159 uint32_t irqs; // number of input IRQs (for ICU or PIC) 165 160 uint32_t irq_offset; // global index of first IRQ 166 161 } -
trunk/tools/arch_info/boot_info.h
r1 r6 32 32 ********************************************************************************************/ 33 33 34 #define BOOT_INFO_SIGNATURE 0x BABEF00D34 #define BOOT_INFO_SIGNATURE 0x12344321 35 35 36 36 /********************************************************************************************* … … 69 69 typedef struct boot_device_s 70 70 { 71 uint64_t base; /*! segment physical base address */ 72 uint64_t size; /*! channel size (bytes) */ 71 73 uint32_t type; /*! peripheral type (func | impl) */ 72 xptr_t base; /*! segment global base address */73 uint64_t size; /*! channel size (bytes) */74 74 uint32_t channels; /*! number of channels */ 75 75 uint32_t param0; /*! semantic depends on peripherat type */ … … 90 90 typedef struct boot_info_s 91 91 { 92 uint32_t signature; /*! boot info signature*/92 uint32_t signature; /*! boot info signature */ 93 93 94 94 // global platform parameters 95 95 96 uint32_t paddr_width; /*! number of bits in physical address*/97 uint32_t x_width; /*! number of bits to code X coordinate*/98 uint32_t y_width; /*! number of bits to code Y coordinate*/99 uint32_t x_size; /*! number of cluster in a row*/100 uint32_t y_size; /*! number of cluster in a column*/101 uint32_t io_cxy; /*! IO cluster identifier*/96 uint32_t paddr_width; /*! number of bits in physical address */ 97 uint32_t x_width; /*! number of bits to code X coordinate */ 98 uint32_t y_width; /*! number of bits to code Y coordinate */ 99 uint32_t x_size; /*! number of cluster in a row */ 100 uint32_t y_size; /*! number of cluster in a column */ 101 uint32_t io_cxy; /*! IO cluster identifier */ 102 102 103 // s pecific cluster parameters103 // shared resources 104 104 105 uint32_t cxy; /*! current cluster identifier */ 106 uint32_t cores_nr; /*! number of cores in current cluster */ 107 boot_core_t core[CONFIG_MAX_CORES_PER_CLUSTER]; /* array of core descriptors */ 108 uint32_t devices_nr; /*! number of peripherals in current cluster */ 109 boot_device_t dev[CONFIG_MAX_DEVICES_PER_CLUSTER]; /* array of device descriptors */ 110 uint32_t pages_nr; /*! total number of 4 Kbytes pages in cluster */ 111 uint32_t pages_offset; /*! number of pages already allocated for kernel */ 105 uint32_t ext_dev_nr; /*! number of external peripherals */ 106 boot_device_t ext_dev[CONFIG_MAX_EXT_DEV]; /*! array of external peripherals */ 107 108 // private resources (per cluster) 109 110 uint32_t cxy; /*! cluster identifier */ 111 uint32_t cores_nr; /*! number of local cores in */ 112 boot_core_t core[CONFIG_MAX_LOCAL_CORES]; /*! array of core descriptors */ 113 uint32_t int_dev_nr; /*! number of local peripherals */ 114 boot_device_t int_dev[CONFIG_MAX_INT_DEV]; /*! array of internal peripherals */ 115 uint32_t pages_nr; /*! number of 4 Kbytes pages */ 116 uint32_t pages_offset; /*! number of pages allocated for kernel */ 112 117 113 118 // kernel segments 114 119 115 intptr_t kernel_code_start; /*! kernel code base address*/116 intptr_t kernel_code_end; /*! kernel code last address (excluded)*/117 intptr_t kernel_data_start; /*! kernel data base address*/118 intptr_t kernel_data_end; /*! kernel data last address (excluded)*/120 intptr_t kernel_code_start; /*! kernel code base address */ 121 intptr_t kernel_code_end; /*! kernel code last address (excluded) */ 122 intptr_t kernel_data_start; /*! kernel data base address */ 123 intptr_t kernel_data_end; /*! kernel data last address (excluded) */ 119 124 } 120 125 boot_info_t; -
trunk/tools/arch_info/genarch.py
r1 r6 23 23 # --nb_ttys=int : number of TTY channels 24 24 # --nb_nics=int : number of NIC channels 25 # --nb_cmas=int : number of CMA channels26 25 # --fbf_size=int : frame buffer width & heigth 27 26 # --ioc_type=string : can be IOC_BDV , IOC_HBA , IOC_SDC , IOC_SPI 28 # --mwr_type=string : can be MWR_GCD , MWR_DCT , MWR_CPY29 27 # --io_cxy=int : IO cluster identifier 30 28 # --boot_cxy=int : boot cluster identifier … … 76 74 help = 'define number ot NIC channels' ) 77 75 78 parser.add_option( '--nb_cmas', type = 'int', dest = 'nb_cmas',79 default = 2,80 help = 'define number ot CMA channels' )81 82 76 parser.add_option( '--fbf_size', type = 'int', dest = 'fbf_size', 83 77 default = 128, … … 87 81 default = 'IOC_BDV', 88 82 help = 'define type of IOC: BDV / HBA / SDC / RDK / SPI' ) 89 90 parser.add_option( '--mwr_type', type = 'string', dest = 'mwr_type',91 default = 'MWR_CPY',92 help = 'define type of COPROC: CPY / DCT / GCD' )93 83 94 84 parser.add_option( '--io_cxy', type = 'int', dest = 'io_cxy', … … 129 119 fbf_size = options.fbf_size # frame buffer width & heigth 130 120 nb_nics = options.nb_nics # number of NIC channels 131 nb_cmas = options.nb_cmas # number of CMA channels132 121 ioc_type = options.ioc_type # ioc controller type 133 mwr_type = options.mwr_type # hardware coprocessor type134 122 io_cxy = options.io_cxy # IO cluster identifier 135 123 boot_cxy = options.boot_cxy # boot cluster identifier … … 163 151 nb_ttys, 164 152 nb_nics, 165 nb_cmas,166 153 fbf_size, 167 154 ioc_type, 168 mwr_type,169 155 io_cxy, 170 156 boot_cxy, -
trunk/tools/bootloader_tsar/boot.c
r1 r6 1 /* 2 * boot.c - TSAR bootloader implementation. 3 * 4 * Authors : Alain Greiner / Vu Son (2016) 5 * 6 * Copyright (c) UPMC Sorbonne Universites 7 * 8 * This file is part of ALMOS-MKH. 9 * 10 * ALMOS-MKH is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; version 2.0 of the License. 13 * 14 * ALMOS-MKH is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with ALMOS-MKH; if not, write to the Free Software Foundation, 21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 */ 23 1 24 /**************************************************************************** 2 * This file contains the ALMOS-MKH. boot-loader for the TSAR architecture. 25 * This file contains the ALMOS-MKH. boot-loader for the TSAR architecture. * 3 26 * * 4 27 * It supports clusterised shared memory multi-processor architectures, * … … 47 70 48 71 #include <elf-types.h> 72 #include <hal_types.h> 49 73 50 74 #include <almos_config.h> … … 53 77 #include <arch_info.h> 54 78 #include <boot_info.h> 55 56 #include <hal_types.h>57 79 58 80 #include <boot_utils.h> … … 62 84 #include <boot_tty_driver.h> 63 85 64 /**************************************************************************** 65 * Macros. *86 /***************************************************************************** 87 * Macros. 66 88 ****************************************************************************/ 67 89 … … 70 92 (~(PPM_PAGE_SIZE-1))) 71 93 72 /**************************************************************************** 73 * Global variables. *94 /***************************************************************************** 95 * Global variables. 74 96 ****************************************************************************/ 75 97 76 98 // synchronization variables. 77 volatile boot_barrier_t global_barrier; /* Used by bscpu to synchronize 78 with other CP0s cores. */ 79 80 volatile uint32_t global_count; /* Number of cores expected in 81 global barrier. */ 82 83 volatile uint32_t local_barrier; /* Used by CP0 to synchronize 84 with local CPi. */ 85 86 volatile uint32_t boot_cluster_ready; /* Modified by bscpu to report 87 that the boot cluster is 88 ready. */ 89 90 // kernel image memory layout. 91 uint32_t ktext_base; /* ktext segment base address. */ 92 uint32_t ktext_end; /* ktext segment end address. */ 93 uint32_t kdata_base; /* kdata segment base address. */ 94 uint32_t kdata_end; /* kdata segment end address. */ 95 96 uint32_t kernel_entry; /* Kernel entry point. */ 97 98 // Extern variables. 99 extern void boot_entry(); /* boot_loader() function */ 100 101 /**************************************************************************** 102 * Internal functions. * 103 ****************************************************************************/ 104 99 100 volatile boot_remote_spinlock_t tty0_lock; // protect TTY0 access 101 volatile boot_remote_barrier_t global_barrier; // synchronize CP0 cores 102 volatile boot_remote_barrier_t local_barrier; // synchronize cores in one cluster 103 uint32_t active_cp0s_nr; // number of expected CP0s 104 105 // kernel segments layout variables 106 107 uint32_t seg_kcode_base; // kcode segment base address 108 uint32_t seg_kcode_size; // kcode segment size (bytes) 109 uint32_t seg_kdata_base; // kdata segment base address 110 uint32_t seg_kdata_size; // kdata segment size (bytes) 111 uint32_t kernel_entry; // kernel entry point 112 113 // address used by the WTI to activate remote CP0s 114 115 extern void boot_entry(); // boot_loader entry point 116 117 /********************************************************************************* 118 * This function returns the printable string for each device type 119 ********************************************************************************/ 105 120 char * device_type_str( uint32_t dev_type ) 106 121 { 107 if ( dev_type == DEV_TYPE_RAM ) return "RAM";108 else if( dev_type == DEV_TYPE_ DMA ) return "DMA";109 else if( dev_type == DEV_TYPE_FBF ) return "FBF";110 else if( dev_type == DEV_TYPE_IOB ) return "IOB";122 if ( dev_type == DEV_TYPE_RAM_SCL ) return "RAM_SCL"; 123 else if( dev_type == DEV_TYPE_ROM_SCL ) return "ROM_SCL"; 124 else if( dev_type == DEV_TYPE_FBF_SCL ) return "FBF_SCL"; 125 else if( dev_type == DEV_TYPE_IOB_TSR ) return "IOB_TSR"; 111 126 else if( dev_type == DEV_TYPE_IOC_BDV ) return "IOC_BDV"; 112 127 else if( dev_type == DEV_TYPE_IOC_HBA ) return "IOC_HBA"; … … 114 129 else if( dev_type == DEV_TYPE_IOC_SPI ) return "IOC_SPI"; 115 130 else if( dev_type == DEV_TYPE_IOC_RDK ) return "IOC_RDK"; 116 else if( dev_type == DEV_TYPE_MMC ) return "MMC"; 117 else if( dev_type == DEV_TYPE_MWR_CPY ) return "MWR_CPY"; 118 else if( dev_type == DEV_TYPE_MWR_GCD ) return "MWR_GCD"; 119 else if( dev_type == DEV_TYPE_MWR_DCT ) return "MWR_DCT"; 120 else if( dev_type == DEV_TYPE_NIC ) return "NIC"; 121 else if( dev_type == DEV_TYPE_ROM ) return "ROM"; 122 else if( dev_type == DEV_TYPE_SIM ) return "SIM"; 123 else if( dev_type == DEV_TYPE_TIM ) return "TIM"; 124 else if( dev_type == DEV_TYPE_TTY ) return "TTY"; 125 else if( dev_type == DEV_TYPE_XCU ) return "XCU"; 126 else if( dev_type == DEV_TYPE_PIC ) return "PIC"; 127 else if( dev_type == DEV_TYPE_CMA ) return "CMA"; 128 else return "UNDEFINED"; 131 else if( dev_type == DEV_TYPE_MMC_TSR ) return "MMC_TSR"; 132 else if( dev_type == DEV_TYPE_DMA_SCL ) return "DMA_SCL"; 133 else if( dev_type == DEV_TYPE_NIC_CBF ) return "NIC_CBF"; 134 else if( dev_type == DEV_TYPE_TIM_SCL ) return "TIM_SCL"; 135 else if( dev_type == DEV_TYPE_TXT_TTY ) return "TXT_TTY"; 136 else if( dev_type == DEV_TYPE_ICU_XCU ) return "ICU_XCU"; 137 else if( dev_type == DEV_TYPE_PIC_TSR ) return "PIC_TSR"; 138 else return "undefined"; 129 139 } 130 140 131 /**************************************************************************** 141 /************************************************************************************ 132 142 * This function loads the arch_info.bin file into the boot cluster memory. 133 **************************************************************************** /143 ***********************************************************************************/ 134 144 static void boot_archinfo_load() 135 145 { … … 154 164 155 165 #if DEBUG_BOOT_INFO 156 boot_printf("\n[BOOT ] file %s loaded at %l\n",157 ARCHINFO_PATHNAME , ARCHINFO_BASE );166 boot_printf("\n[BOOT INFO] in %s : file %s loaded at address = %x\n", 167 __FUNCTION__ , ARCHINFO_PATHNAME , ARCHINFO_BASE ); 158 168 #endif 159 169 160 170 } // boot_archinfo_load() 161 171 162 /**************************************************************************** 163 * This function loads the 'kernel.elf' file into the boot cluster memory * 164 * bank, analyzes it then places the kernel image at the temporary physical * 165 * memory address KERN_IMG_TMP_BASE since other processors are still * 166 * executing the preloader code (which means that the kernel image cannot * 167 * be placed now at its final memory location starting at address 0x0. * 168 ****************************************************************************/ 172 /************************************************************************************** 173 * This function loads the 'kernel.elf' file into the boot cluster memory buffer, 174 * analyzes it, and places the the two seg_kcode & seg_kdata segments at their final 175 * physical adresses (just after the preloader zone). 176 * It set the global variables defining the kernel layout. 177 *************************************************************************************/ 169 178 static void boot_kernel_load() 170 179 { 171 Elf32_Ehdr* elf_header; /* Pointer on 'kernel.elf' header. */ 172 Elf32_Phdr* program_header; /* Pointer on 'kernel.elf' program 173 header. */ 174 uint32_t phdr_offset; /* Program header offset in 175 'kernel.elf' file. */ 176 uint32_t segments_nb; /* Total number of segments in 177 'kernel.elf' file. */ 178 179 uint32_t seg_src_addr; /* Segment address in 'kernel.elf' 180 file (source). */ 181 uint32_t seg_paddr; /* Physical address at which the 182 first byte of the segment resides 183 in memory. */ 184 uint32_t seg_offset; /* Offset from the beginning of 185 'kernel.elf' file to the segment's 186 first byte. */ 187 uint32_t seg_filesz; /* Segment's number of bytes in 188 'kernel.elf' file. */ 189 uint32_t seg_memsz; /* Segment's number of bytes in the 190 memory image. */ 191 192 uint32_t seg_id; /* Iterator for program header scanning 193 loop. */ 194 195 /* Loading file into memory. */ 196 if (boot_fat32_load(KERNEL_PATHNAME, KERN_BASE, KERN_MAX_SIZE)) 197 { 198 boot_printf("\n[BOOT ERROR]: boot_kernel_load(): " 199 "<%s> file not found\n", 180 Elf32_Ehdr * elf_header; // pointer on kernel.elf header. 181 Elf32_Phdr * program_header; // pointer on kernel.elf program header. 182 uint32_t phdr_offset; // program header offset in kernel.elf file. 183 uint32_t segments_nb; // number of segments in kernel.elf file. 184 uint32_t seg_src_addr; // segment address in kernel.elf file (source). 185 uint32_t seg_paddr; // segment local physical address of segment 186 uint32_t seg_offset; // segment offset in kernel.elf file 187 uint32_t seg_filesz; // segment size (bytes) in kernel.elf file 188 uint32_t seg_memsz; // segment size (bytes) in memory image. 189 bool_t kcode_found; // kcode segment found. 190 bool_t kdata_found; // kdata segment found. 191 uint32_t seg_id; // iterator for segments loop. 192 193 #if DEBUG_BOOT_ELF 194 boot_printf("\n[BOOT INFO] %s enters for file %s at cycle %d\n", 195 __FUNCTION__ , KERNEL_PATHNAME , boot_get_proctime() ); 196 #endif 197 198 // Load kernel.elf file into memory buffer 199 if ( boot_fat32_load(KERNEL_PATHNAME, KERN_BASE, KERN_MAX_SIZE) ) 200 { 201 boot_printf("\n[BOOT ERROR] in %s : <%s> file not found\n", 200 202 KERNEL_PATHNAME); 201 203 boot_exit(); 202 204 } 203 205 204 /* 205 * Initializing pointer to header which is the first element of the 206 * .elf file. 207 */ 206 // get pointer to kernel.elf header 208 207 elf_header = (Elf32_Ehdr*)KERN_BASE; 209 208 210 / * Signature problem, abort program !!! */209 // check signature 211 210 if ((elf_header->e_ident[EI_MAG0] != ELFMAG0) || 212 211 (elf_header->e_ident[EI_MAG1] != ELFMAG1) || … … 220 219 } 221 220 222 / * Getting the program header table offset and the number of segments. */221 // Get program header table offset and number of segments 223 222 phdr_offset = elf_header->e_phoff; 224 223 segments_nb = elf_header->e_phnum; 225 224 226 / * Getting the program header table pointer. */225 // Get program header table pointer 227 226 program_header = (Elf32_Phdr*)(KERN_BASE + phdr_offset); 228 227 229 /* Looking for loadable segments. */ 228 // loop on segments 229 kcode_found = false; 230 kdata_found = false; 230 231 for (seg_id = 0; seg_id < segments_nb; seg_id++) 231 232 { 232 // Found one: 233 if (program_header[seg_id].p_type == PT_LOAD) 233 if (program_header[seg_id].p_type == PT_LOAD) // Found one loadable segment 234 234 { 235 // Get ting itsattributes.235 // Get segment attributes. 236 236 seg_paddr = program_header[seg_id].p_paddr; 237 237 seg_offset = program_header[seg_id].p_offset; … … 239 239 seg_memsz = program_header[seg_id].p_memsz; 240 240 241 // Load it to its appropriate physical memory address.241 // get segment base address in buffer 242 242 seg_src_addr = (uint32_t)KERN_BASE + seg_offset; 243 boot_memcpy((void*)(KERN_IMG_TMP_BASE + seg_paddr), 244 (void*)seg_src_addr, 245 seg_filesz); 243 244 // Load segment to its final physical memory address 245 boot_memcpy( (void*)seg_paddr, 246 (void*)seg_src_addr, 247 seg_filesz ); 248 249 #if DEBUG_BOOT_ELF 250 boot_printf("\n[BOOT INFO] in %s for file %s : found loadable segment\n" 251 " base = %x / size = %x\n", 252 __FUNCTION__ , KERNEL_PATHNAME , seg_paddr , seg_memsz ); 253 #endif 246 254 247 255 // Fill remaining memory with zero if (filesz < memsz). 248 boot_memset((void*)(KERN_IMG_TMP_BASE + seg_paddr + seg_filesz), 249 0, 250 seg_memsz - seg_filesz); 251 252 /* 253 * Note: we suppose that the 'kernel.elf' file contains only 2 254 * loadable segments ktext + kdata and that the main 255 * difference between these two is the WRITE permission: ktext 256 * contains read-only instructions and read_only data, 257 * while kdata contains writable data. 258 */ 259 260 // Get ktext segment base and end addresses. 261 if ((program_header[seg_id].p_flags & PF_W) == 0) 262 { 263 ktext_base = seg_paddr; 264 ktext_end = seg_paddr + seg_memsz; 265 } 266 267 // Get kdata segment base and end addresses. 268 else 269 { 270 kdata_base = seg_paddr; 271 kdata_end = seg_paddr + seg_memsz; 256 if( seg_memsz < seg_filesz ) 257 { 258 boot_memset( (void*)(seg_paddr + seg_filesz), 0, seg_memsz - seg_filesz); 259 } 260 261 // Note: we suppose that the 'kernel.elf' file contains only 2 262 // loadable segments ktext & kdata and that the main 263 // difference between these two is the WRITE permission: ktext 264 // contains read-only instructions and read_only data, 265 // while kdata contains writable data. 266 267 if ((program_header[seg_id].p_flags & PF_W) == 0) // kcode segment 268 { 269 if( kcode_found ) 270 { 271 boot_printf("\n[BOOT_ERROR] in %s for file %s :\n" 272 " two loadable kcode segments found\n", 273 __FUNCTION__ , KERNEL_PATHNAME ); 274 boot_exit(); 275 } 276 277 kcode_found = true; 278 seg_kcode_base = seg_paddr; 279 seg_kcode_size = seg_memsz; 280 } 281 else // kdata segment 282 { 283 if( kdata_found ) 284 { 285 boot_printf("\n[BOOT_ERROR] in %s for file %s :\n" 286 " two loadable kdata segments found\n", 287 __FUNCTION__ , KERNEL_PATHNAME ); 288 boot_exit(); 289 } 290 291 kdata_found = true; 292 seg_kdata_base = seg_paddr; 293 seg_kdata_size = seg_memsz; 272 294 } 273 295 } 274 296 } 275 297 276 // Get the entry point for kernel code. 298 // check kcode & kdata segments found 299 if( kcode_found == false ) 300 { 301 boot_printf("\n[BOOT_ERROR] in %s for file %s :\n" 302 " kcode segment not found\n", 303 __FUNCTION__ , KERNEL_PATHNAME ); 304 boot_exit(); 305 } 306 if( kdata_found == false ) 307 { 308 boot_printf("\n[BOOT_ERROR] in %s for file %s :\n" 309 " kdata segment not found\n", 310 __FUNCTION__ , KERNEL_PATHNAME ); 311 boot_exit(); 312 } 313 314 // set entry point 277 315 kernel_entry = (uint32_t)elf_header->e_entry; 278 316 317 #if DEBUG_BOOT_ELF 318 boot_printf("\n[BOOT INFO] %s successfully completed for file %s at cycle %d\n", 319 __FUNCTION__ , KERNEL_PATHNAME , boot_get_proctime() ); 320 #endif 321 279 322 } // boot_kernel_load() 280 323 281 /**************************************************************************** 282 * This function initializes the local 'boot_info_t' structure. *283 * @ boot_info : pointer to local boot_info_t structure *284 * @ cxy : cluster identifier *285 **************************************************************************** /324 /************************************************************************************* 325 * This function initializes the boot_info_t structure for a given cluster. 326 * @ boot_info : pointer to local boot_info_t structure 327 * @ cxy : cluster identifier 328 ************************************************************************************/ 286 329 static void boot_info_init( boot_info_t * boot_info, 287 330 cxy_t cxy ) 288 331 { 289 archinfo_header_t * header; 332 archinfo_header_t * header; 290 333 archinfo_core_t * core_base; 291 334 archinfo_cluster_t * cluster_base; … … 294 337 295 338 archinfo_cluster_t * cluster; 339 archinfo_cluster_t * my_cluster = NULL; // target cluster 340 archinfo_cluster_t * io_cluster = NULL; // cluster containing ext. peripherals 341 296 342 archinfo_core_t * core; 297 343 uint32_t core_id; … … 303 349 boot_device_t * boot_dev; 304 350 305 // get pointer on ARCHINFO header 306 header = (archinfo_header_t*)ARCHINFO_BASE; 351 #if DEBUG_BOOT_INFO 352 boot_printf("\n[BOOT INFO] %s : enter for cluster %x at cycle %d\n", 353 __FUNCTION__ , cxy , boot_get_proctime() ); 354 #endif 355 356 // get pointer on ARCHINFO header and on the four arch_info arrays 357 header = (archinfo_header_t*)ARCHINFO_BASE; 358 core_base = archinfo_get_core_base (header); 359 cluster_base = archinfo_get_cluster_base(header); 360 device_base = archinfo_get_device_base (header); 361 irq_base = archinfo_get_irq_base (header); 307 362 308 363 // Initialize global platform parameters … … 315 370 316 371 // Initialize kernel segments 317 boot_info->kernel_code_start = ktext_base; 318 boot_info->kernel_code_end = ktext_end; 319 boot_info->kernel_data_start = kdata_base; 320 boot_info->kernel_data_end = kdata_end; 321 322 // Initialize specific cluster parameter 323 core_base = archinfo_get_core_base (header); 324 cluster_base = archinfo_get_cluster_base(header); 325 device_base = archinfo_get_device_base (header); 326 irq_base = archinfo_get_irq_base (header); 327 328 // lopp on the clusters to find local cluster descriptor 372 boot_info->kernel_code_start = seg_kcode_base; 373 boot_info->kernel_code_end = seg_kcode_base + seg_kcode_size; 374 boot_info->kernel_data_start = seg_kdata_base; 375 boot_info->kernel_data_end = seg_kdata_base + seg_kdata_size; 376 377 // loop on arch_info clusters to get relevant pointers 329 378 for (cluster = cluster_base; 330 379 cluster < &cluster_base[header->x_size * header->y_size]; 331 380 cluster++) 332 381 { 333 if (cluster->cxy != cxy) continue; 334 335 boot_info->cxy = cluster->cxy; 336 boot_info->cores_nr = cluster->cores; 337 boot_info->devices_nr = cluster->devices; 338 339 #if DEBUG_BOOT_INFO 340 boot_printf("\n[BOOT] build boot_info for cluster %x : %d cores / %d devices\n", 341 cluster->cxy , cluster->cores , cluster->devices ); 342 #endif 343 // Initialize array of core descriptors 344 for (core = &core_base[cluster->core_offset], core_id = 0; 345 core < &core_base[cluster->core_offset + cluster->cores]; 346 core++, core_id++) 382 if( cluster->cxy == cxy ) my_cluster = cluster; 383 if( cluster->cxy == header->io_cxy ) io_cluster = cluster; 384 } 385 386 if( my_cluster == NULL ) 387 { 388 boot_printf("\n[ERROR] in %s : cannot found cluster %x in arch_info\n", 389 __FUNCTION__ , cxy ); 390 boot_exit(); 391 } 392 393 if( io_cluster == NULL ) 394 { 395 boot_printf("\n[ERROR] in %s : cannot found io_cluster %x in arch_info\n", 396 __FUNCTION__ , header->io_cxy ); 397 boot_exit(); 398 } 399 400 // loop on all arch-info peripherals in IO_cluster, 401 // to initialize the boot_info array of external peripherals 402 403 #if DEBUG_BOOT_INFO 404 boot_printf("\n[BOOT INFO] %s : External peripherals\n", __FUNCTION__ ); 405 #endif 406 407 device_id = 0; 408 for (device = &device_base[io_cluster->device_offset]; 409 device < &device_base[io_cluster->device_offset + io_cluster->devices]; 410 device++ ) 411 { 412 // initialise one entry for each external peripheral 413 if( (device->type != DEV_TYPE_RAM_SCL) && 414 (device->type != DEV_TYPE_ICU_XCU) && 415 (device->type != DEV_TYPE_MMC_TSR) && 416 (device->type != DEV_TYPE_DMA_SCL) ) 347 417 { 348 boot_info->core[core_id].gid = (gid_t)core->gid; 349 boot_info->core[core_id].lid = (lid_t)core->lid; 350 boot_info->core[core_id].cxy = (cxy_t)core->cxy; 351 352 #if DEBUG_BOOT_INFO 353 boot_printf(" - core %x : cxy = %x / lid = %d\n", 354 core->gid , core->cxy , core->lid ); 355 #endif 356 418 boot_dev = &boot_info->ext_dev[device_id]; 419 420 boot_dev->type = device->type; 421 boot_dev->base = device->base; 422 boot_dev->size = device->size; 423 boot_dev->channels = device->channels; 424 boot_dev->param0 = device->arg0; 425 boot_dev->param1 = device->arg1; 426 boot_dev->param2 = device->arg2; 427 boot_dev->param3 = device->arg3; 428 boot_dev->irqs = device->irqs; 429 430 device_id++; 357 431 } 358 432 359 // Initialize array of device descriptors 360 for (device = &device_base[cluster->device_offset], device_id = 0; 361 device < &device_base[cluster->device_offset + cluster->devices]; 362 device++, device_id++) 363 { 364 boot_dev = &boot_info->dev[device_id]; 365 366 boot_dev->type = device->type; 367 boot_dev->base = (xptr_t)device->base; 368 boot_dev->size = device->size; 369 boot_dev->channels = device->channels; 370 boot_dev->param0 = device->arg0; 371 boot_dev->param1 = device->arg1; 372 boot_dev->param2 = device->arg2; 373 boot_dev->param3 = device->arg3; 374 boot_dev->irqs = device->irqs; 375 376 #if DEBUG_BOOT_INFO 377 boot_printf(" - device %s : base = %l / size = %d / channels = %d / irqs = %d\n", 433 #if DEBUG_BOOT_INFO 434 boot_printf(" - %s : base = %l / size = %l / channels = %d / irqs = %d\n", 378 435 device_type_str( device->type ) , device->base , device->size , 379 436 device->channels , device->irqs ); 380 437 #endif 381 382 // Initialize information about physical memory in cluster 383 if (device->type == DEV_TYPE_RAM) 384 { 385 // Compute total number of physical memory pages in cluster 386 boot_info->pages_nr = device->size >> CONFIG_PPM_PAGE_SHIFT; 387 388 // Get the last address allocated for the kernel segments 389 uint32_t end = (ktext_end < kdata_end) ? kdata_end : ktext_end; 390 391 // Computing the number of pages allocated for the kernel. 392 if( (end & CONFIG_PPM_PAGE_MASK) == 0 ) 393 { 394 boot_info->pages_offset = end >> CONFIG_PPM_PAGE_SHIFT; 395 } 396 else 397 { 398 boot_info->pages_offset = (end >> CONFIG_PPM_PAGE_SHIFT) + 1; 399 } 400 } 401 402 // Initialize array of irq descriptors for XCU 403 if (device->type == DEV_TYPE_XCU) 404 { 405 for (irq_id = 0; irq_id < CONFIG_MAX_HWIS_PER_ICU; irq_id++) 406 { 407 boot_dev->irq[irq_id].valid = 0; 408 } 409 410 for (irq = &irq_base[device->irq_offset]; 411 irq < &irq_base[device->irq_offset + device->irqs]; 412 irq++) 413 { 414 boot_dev->irq[irq->port].valid = 1; 415 boot_dev->irq[irq->port].dev_type = irq->dev_type; 416 boot_dev->irq[irq->port].channel = irq->channel; 417 boot_dev->irq[irq->port].is_rx = irq->is_rx; 438 439 // Initialize array of irq descriptors for PIC 440 if (device->type == DEV_TYPE_PIC_TSR) 441 { 442 for (irq_id = 0; irq_id < CONFIG_MAX_IRQS_PER_PIC; irq_id++) 443 { 444 boot_dev->irq[irq_id].valid = 0; 445 } 446 447 for (irq = &irq_base[device->irq_offset]; 448 irq < &irq_base[device->irq_offset + device->irqs]; 449 irq++) 450 { 451 boot_dev->irq[irq->port].valid = 1; 452 boot_dev->irq[irq->port].dev_type = irq->dev_type; 453 boot_dev->irq[irq->port].channel = irq->channel; 454 boot_dev->irq[irq->port].is_rx = irq->is_rx; 418 455 419 456 #if DEBUG_BOOT_INFO … … 421 458 irq->port , device_type_str( irq->dev_type ) , irq->channel , irq->is_rx ); 422 459 #endif 423 424 } 425 } 426 427 // Initialize array of irq descriptors for PIC 428 if (device->type == DEV_TYPE_PIC) 429 { 430 for (irq_id = 0; irq_id < CONFIG_MAX_IRQS_PER_PIC; irq_id++) 431 { 432 boot_dev->irq[irq_id].valid = 0; 433 } 434 435 for (irq = &irq_base[device->irq_offset]; 436 irq < &irq_base[device->irq_offset + device->irqs]; 437 irq++) 438 { 439 boot_dev->irq[irq->port].valid = 1; 440 boot_dev->irq[irq->port].dev_type = irq->dev_type; 441 boot_dev->irq[irq->port].channel = irq->channel; 442 boot_dev->irq[irq->port].is_rx = irq->is_rx; 460 } 461 } 462 } 463 464 // initialize number of external peripherals 465 boot_info->ext_dev_nr = device_id; 466 467 // Initialize cluster specific resources 468 boot_info->cxy = my_cluster->cxy; 469 470 #if DEBUG_BOOT_INFO 471 boot_printf("\n[BOOT INFO] %s : cores in cluster %x\n", __FUNCTION__ ); 472 #endif 473 474 // Initialize array of core descriptors 475 core_id = 0; 476 for (core = &core_base[my_cluster->core_offset]; 477 core < &core_base[my_cluster->core_offset + my_cluster->cores]; 478 core++ ) 479 { 480 boot_info->core[core_id].gid = (gid_t)core->gid; 481 boot_info->core[core_id].lid = (lid_t)core->lid; 482 boot_info->core[core_id].cxy = (cxy_t)core->cxy; 483 484 #if DEBUG_BOOT_INFO 485 boot_printf(" - core_gid = %x : cxy = %x / lid = %d\n", 486 core->gid , core->cxy , core->lid ); 487 #endif 488 core_id++; 489 } 490 491 // Initialize number of cores in my_cluster 492 boot_info->cores_nr = core_id; 493 494 // loop on all peripherals in my_cluster to initialise 495 // boot_info array of internal peripherals in my_cluster 496 497 #if DEBUG_BOOT_INFO 498 boot_printf("\n[BOOT INFO] %s : internal peripherals in cluster %x\n", __FUNCTION__ ); 499 #endif 500 501 device_id = 0; 502 for (device = &device_base[my_cluster->device_offset]; 503 device < &device_base[my_cluster->device_offset + my_cluster->devices]; 504 device++ ) 505 { 506 // initialise one entry for each internal peripheral 507 if( (device->type == DEV_TYPE_RAM_SCL) || 508 (device->type == DEV_TYPE_ICU_XCU) || 509 (device->type == DEV_TYPE_MMC_TSR) || 510 (device->type == DEV_TYPE_DMA_SCL) ) 511 { 512 boot_dev = &boot_info->int_dev[device_id]; 513 514 boot_dev->type = device->type; 515 boot_dev->base = device->base; 516 boot_dev->size = device->size; 517 boot_dev->channels = device->channels; 518 boot_dev->param0 = device->arg0; 519 boot_dev->param1 = device->arg1; 520 boot_dev->param2 = device->arg2; 521 boot_dev->param3 = device->arg3; 522 boot_dev->irqs = device->irqs; 523 524 device_id++; 525 } 526 527 #if DEBUG_BOOT_INFO 528 boot_printf(" - %s : base = %l / size = %l / channels = %d / irqs = %d\n", 529 device_type_str( device->type ) , device->base , device->size , 530 device->channels , device->irqs ); 531 #endif 532 533 // Initialize information about physical memory in cluster 534 if (device->type == DEV_TYPE_RAM_SCL) 535 { 536 // Compute total number of physical memory pages in cluster 537 boot_info->pages_nr = device->size >> CONFIG_PPM_PAGE_SHIFT; 538 539 // Get the last address allocated for the kernel segments 540 uint32_t end; 541 if( boot_info->kernel_code_end > boot_info->kernel_data_end ) 542 { 543 end = boot_info->kernel_code_end; 544 } 545 else 546 { 547 end = boot_info->kernel_data_end; 548 } 549 550 // Compute the number of pages allocated for the kernel. 551 if( (end & CONFIG_PPM_PAGE_MASK) == 0 ) 552 { 553 boot_info->pages_offset = end >> CONFIG_PPM_PAGE_SHIFT; 554 } 555 else 556 { 557 boot_info->pages_offset = (end >> CONFIG_PPM_PAGE_SHIFT) + 1; 558 } 559 560 #if DEBUG_BOOT_INFO 561 boot_printf(" . physical memory : %x pages / first free page = %x\n", 562 boot_info->pages_nr , boot_info->pages_offset ); 563 #endif 564 } 565 566 // Initialize array of irq descriptors for XCU 567 if (device->type == DEV_TYPE_ICU_XCU) 568 { 569 for (irq_id = 0; irq_id < CONFIG_MAX_HWIS_PER_ICU; irq_id++) 570 { 571 boot_dev->irq[irq_id].valid = 0; 572 } 573 574 for (irq = &irq_base[device->irq_offset]; 575 irq < &irq_base[device->irq_offset + device->irqs]; 576 irq++) 577 { 578 boot_dev->irq[irq->port].valid = 1; 579 boot_dev->irq[irq->port].dev_type = irq->dev_type; 580 boot_dev->irq[irq->port].channel = irq->channel; 581 boot_dev->irq[irq->port].is_rx = irq->is_rx; 443 582 444 583 #if DEBUG_BOOT_INFO … … 447 586 #endif 448 587 449 }450 588 } 451 589 } 452 453 #if DEBUG_BOOT_INFO 454 boot_printf(" - ram : number of pages = %x / first free page = %x\n", 455 boot_info->pages_nr , boot_info->pages_offset ); 456 #endif 457 458 } 590 } 591 592 // initialize number of internal peripherals in my_cluster 593 boot_info->int_dev_nr = device_id; 594 595 // set boot_info signature 596 boot_info->signature = BOOT_INFO_SIGNATURE; 597 459 598 } // boot_info_init() 460 599 461 /**************************************************************************** 462 * This function is executed by all cores in order to check their * 463 * local boot_info_t structure. * 464 * @ boot_info : pointer to local 'boot_info_t' structure to be checked. * 465 * @ lid : core local identifier, index the core descriptor table. * 466 ****************************************************************************/ 600 /*********************************************************************************** 601 * This function check the local boot_info_t structure for a given core. 602 * @ boot_info : pointer to local 'boot_info_t' structure to be checked. 603 * @ lid : core local identifier, index the core descriptor table. 604 **********************************************************************************/ 467 605 static void boot_check_core( boot_info_t * boot_info, 468 606 lid_t lid) … … 490 628 } // boot_check_core() 491 629 492 /**************************************************************************** 493 * This function is called by the bscpu to activate all other CP0s. *630 /********************************************************************************* 631 * This function is called by CP0 in cluster(0,0) to activate all other CP0s. 494 632 * It returns the number of CP0s actually activated. 495 **************************************************************************** /496 static uint32_t boot_wake_ cp0()633 ********************************************************************************/ 634 static uint32_t boot_wake_all_cp0s() 497 635 { 498 archinfo_header_t* header; /* Pointer on ARCHINFO header. */ 499 archinfo_cluster_t* cluster_base; /* Pointer on ARCHINFO cluster 500 base. */ 501 archinfo_cluster_t* cluster; /* Iterator for waking CP0 loop. */ 502 archinfo_device_t* device_base; /* Pointer on ARCHINFO peripheral 503 device base. */ 504 archinfo_device_t* device; /* Iterator for finding XICU device 505 loop. */ 506 507 uint32_t cp0_nb = 0; /* Number of CP0 woken up. */ 636 archinfo_header_t* header; // Pointer on ARCHINFO header 637 archinfo_cluster_t* cluster_base; // Pointer on ARCHINFO clusters base 638 archinfo_cluster_t* cluster; // Iterator for loop on clusters 639 archinfo_device_t* device_base; // Pointer on ARCHINFO devices base 640 archinfo_device_t* device; // Iterator for loop on devices 641 uint32_t cp0_nb = 0; // CP0s counter 508 642 509 643 header = (archinfo_header_t*)ARCHINFO_BASE; … … 528 662 continue; 529 663 530 // Look for the XICU device associated to the CP0 of this cluster 531 // then send an WTI to it in order to wake it up. 664 // search XICU device associated to CP0, and send a WTI to activate it 532 665 for (device = &device_base[cluster->device_offset]; 533 666 device < &device_base[cluster->device_offset + cluster->devices]; 534 667 device++) 535 668 { 536 if (device->type == DEV_TYPE_XCU) 537 { 669 if (device->type == DEV_TYPE_ICU_XCU) 670 { 671 672 #if DEBUG_BOOT_WAKUP 673 boot_printf("\n[BOOT] core[%x][0] activated at cycle %d\n", 674 cluster->cxy , boot_get_proctime ); 675 #endif 676 538 677 boot_remote_sw((xptr_t)device->base, (uint32_t)boot_entry); 539 678 cp0_nb++; … … 545 684 } // boot_wake_cp0() 546 685 547 /**************************************************************************** 548 * This function is called by all CP0 to activate all local CPi cores. *549 * @ boot_info : pointer to local 'boot_info_t' structure, used to find *550 * the XICU device associated with local CPi base addresses. *551 **************************************************************************** /552 static void boot_wake_local_cores(boot_info_t * boot_info)686 /********************************************************************************* 687 * This function is called by all CP0 to activate all local CPi cores. 688 * @ boot_info : pointer to local 'boot_info_t' structure, used to find 689 * the XICU device associated with local CPi base addresses. 690 *********************************************************************************/ 691 static void boot_wake_local_cores(boot_info_t * boot_info) 553 692 { 554 boot_device_t * device; // Iterator on devices555 unsigned int core_id; // Iterator on cores693 boot_device_t * device; // Iterator on devices 694 unsigned int core_id; // Iterator on cores 556 695 557 696 // loop on devices to find XCU 558 for (device = &boot_info-> dev[0];559 device < &boot_info-> dev[boot_info->devices_nr];697 for (device = &boot_info->int_dev[0]; 698 device < &boot_info->int_dev[boot_info->int_dev_nr]; 560 699 device++) 561 700 { 562 if (device->type == DEV_TYPE_ XCU)701 if (device->type == DEV_TYPE_ICU_XCU) 563 702 { 564 703 // loop on cores 565 704 for (core_id = 1; core_id < boot_info->cores_nr; core_id++) 705 { 706 707 #if DEBUG_BOOT_WAKUP 708 boot_printf("\n[BOOT] core[%x][%d] activated at cycle %d\n", 709 boot_info->cxy , core_id , boot_get_proctime() ); 710 #endif 566 711 boot_remote_sw((xptr_t) (device->base + (core_id << 2)), 567 712 (uint32_t)boot_entry); 713 } 568 714 } 569 715 } 570 716 } // boot_wake_local_cores() 571 717 572 /**************************************************************************** 573 * API functions. * 574 ****************************************************************************/ 575 576 /**************************************************************************** 718 719 /********************************************************************************* 577 720 * This main function of the boot-loader is called by the boot_entry() 578 721 * function, and executed by all cores. 579 722 * The arguments values are computed by the boot_entry code. 580 * @ lid : core local identifier in its cluster,723 * @ lid : core local identifier, 581 724 * @ cxy : cluster identifier, 582 **************************************************************************** /725 *********************************************************************************/ 583 726 void boot_loader( lid_t lid, 584 727 cxy_t cxy ) 585 728 { 586 boot_info_t * boot_info; // Pointer on local boot_info_t structure 587 uint32_t local_count; // Number of cores expected in local barrier */ 729 boot_info_t * boot_info; // pointer on local boot_info_t structure 588 730 589 731 if (lid == 0) 590 732 { 591 /************************************** 592 * PHASE ONE: only bscpu executes it. *593 ************************************** /733 /**************************************************** 734 * PHASE A : only CP0 in boot cluster executes it 735 ***************************************************/ 594 736 if (cxy == BOOT_CORE_CXY) 595 737 { 596 boot_printf("\n[BOOT] Starting on core[%d] in cluster %xat cycle %d\n",597 lid, cxy, boot_get_proctime());738 boot_printf("\n[BOOT] core[%x][%d] enters at cycle %d\n", 739 cxy , lid , boot_get_proctime() ); 598 740 599 741 // Initialize IOC driver 600 742 if (USE_IOC_BDV) boot_bdv_init(); 601 743 else if (USE_IOC_HBA) boot_hba_init(); 602 /* 603 else if (USE_IOC_SDC) boot_sdc_init(); 604 else if (USE_IOC_SPI) boot_spi_init(); 605 */ 744 // else if (USE_IOC_SDC) boot_sdc_init(); 745 // else if (USE_IOC_SPI) boot_spi_init(); 606 746 else if (!USE_IOC_RDK) 607 747 { 608 boot_printf("\n[BOOT ERROR] boot_loader(): " 609 "No IOC driver\n" 610 ); 748 boot_printf("\n[BOOT ERROR] in %s : no IOC driver\n"); 611 749 boot_exit(); 612 750 } 613 751 614 // Initialize simplified version ofFAT32.752 // Initialize FAT32. 615 753 boot_fat32_init(); 754 755 // Load the 'kernel.elf' file into memory from IOC, and set 756 // the global variables defining the kernel layout 757 boot_kernel_load(); 758 759 boot_printf("\n[BOOT] core[%x][%d] loaded kernel at cycle %d\n", 760 cxy , lid , boot_get_proctime() ); 616 761 617 762 // Load the arch_info.bin file into memory. 618 763 boot_archinfo_load(); 619 764 620 // Load the 'kernel.elf' file into memory. 621 boot_kernel_load(); 622 623 // Get local 'boot_info_t' structure base address. 765 // Get local boot_info_t structure base address. 624 766 // It is the first structure in the .kdata segment. 625 boot_info = (boot_info_t*)(KERN_IMG_TMP_BASE + kdata_base); 626 627 // Signature problem, abort program !!! 767 boot_info = (boot_info_t *)seg_kdata_base; 768 769 // Initialize local boot_info_t structure. 770 boot_info_init( boot_info , cxy ); 771 772 // check boot_info signature 628 773 if (boot_info->signature != BOOT_INFO_SIGNATURE) 629 774 { 630 boot_printf("\n[BOOT ] boot_loader():"631 " boot_info signatureshould be %x\n",632 BOOT_INFO_SIGNATURE);775 boot_printf("\n[BOOT ERROR] in %s reported by core[%x][%d]\n" 776 " illegal boot_info signature / should be %x\n", 777 __FUNCTION__ , cxy , lid , BOOT_INFO_SIGNATURE ); 633 778 boot_exit(); 634 779 } 635 780 636 // Initialize local 'boot_info_t' structure. 637 boot_printf("\n[BOOT] boot_loader(): " 638 "Initializing the local boot_info_t structure " 639 "at cycle %d\n", 640 boot_get_proctime()); 641 642 boot_info_init(boot_info, cxy); 781 boot_printf("\n[BOOT] core[%x][%d] loaded boot_info at cycle %d\n", 782 cxy , lid , boot_get_proctime() ); 643 783 644 784 // Check core information. 645 785 boot_check_core(boot_info, lid); 646 786 647 // Set the barrier. 648 boot_cluster_ready = 0; 649 650 // Activate other CP0s 651 boot_printf("\n[BOOT] boot_loader(): " 652 "Waking other CP0 up at cycle %d\n", 653 boot_get_proctime()); 654 655 global_count = boot_wake_cp0(); 656 657 // Wait until all CP0s ready to enter kernel. 658 boot_printf("\n[BOOT] boot_loader(): " 659 "Waiting for other %d CP0 at cycle %d\n", 660 global_count, boot_get_proctime()); 661 662 boot_barrier(XPTR(BOOT_CORE_CXY, &global_barrier), 663 global_count); 664 665 // activate other local cores of the boot cluster. 666 local_barrier = 0; 667 boot_printf("\n[BOOT] boot_loader(): " 668 "Waking other CPi up at cycle %d\n", 669 boot_get_proctime()); 670 671 boot_wake_local_cores(boot_info); 672 673 // Wait until all other local cores are ready 674 boot_printf("\n[BOOT] boot_loader(): " 675 "Waiting for other %d CPi at cycle %d\n", 676 boot_info->cores_nr - 1, boot_get_proctime()); 677 678 local_count = boot_info->cores_nr - 1; 679 while (local_barrier != local_count); 680 681 // Move the local kernel image at address 0x0 (erase preloader code). 682 boot_printf("\n[BOOT] boot_loader(): " 683 "Moving the kernel image and erasing the preloader" 684 "at cycle %d\n", 685 boot_get_proctime()); 686 687 // ktext segment. 688 boot_memcpy((void*)ktext_base, 689 (void*)(KERN_IMG_TMP_BASE + ktext_base), 690 ktext_end - ktext_base); 691 692 // kdata segment. 693 boot_memcpy((void*)kdata_base, 694 (void*)(KERN_IMG_TMP_BASE + kdata_base), 695 kdata_end - kdata_base); 696 697 // activate other local cores. 698 boot_cluster_ready = 1; 699 boot_printf("\n[BOOT] boot_loader(): " 700 "Everything is set, jumping to the kernel " 701 "at cycle %d\n", 702 boot_get_proctime()); 787 // Activate other CP0s / get number of active CP0s 788 active_cp0s_nr = boot_wake_all_cp0s() + 1; 789 790 // Wait until all clusters (i.e all CP0s) ready to enter kernel. 791 boot_remote_barrier( XPTR( BOOT_CORE_CXY , &global_barrier ) , 792 active_cp0s_nr ); 793 794 // activate other local cores 795 boot_wake_local_cores( boot_info ); 796 797 // Wait until all local cores in cluster ready 798 boot_remote_barrier( XPTR( cxy , &local_barrier ) , 799 boot_info->cores_nr ); 703 800 } 704 /**************************************************** 705 * PHASE TWO: all CP0s other than bscpu execute it. *706 **************************************************** /801 /****************************************************************** 802 * PHASE B : all CP0s other than CP0 in boot cluster execute it 803 *****************************************************************/ 707 804 else 708 805 { 709 /* 710 * Note: at this point, we cannot access the global variables of 711 * this boot code since all the address extension registers for 712 * DATA are pointing to their local cluster in order to have 713 * access to the local stack and execute this C code. 714 * However, all the address extension registers for INSTRUCTIONS 715 * are still pointing to the boot cluster, thus we can access 716 * and call functions defined in the boot code, for example 717 * boot_remote_memcpy(). 718 */ 719 720 // Copy the boot-loader binary code 'boot.elf' into the local memory 721 boot_remote_memcpy(XPTR(cxy, BOOT_BASE), 722 XPTR(BOOT_CORE_CXY, BOOT_BASE), 723 (unsigned int)BOOT_MAX_SIZE); 724 725 /* 726 * Note: from now on, it is safe to refer to the boot code global variables 727 * such as the base address and size of the kernel segments. 728 */ 729 730 // switch to the INSTRUCTION local memory space, 731 // to avoid contention at the boot cluster. 806 // at this point, all INSTRUCTION address extension registers 807 // point on cluster(0,0), but the DATA extension registers point 808 // already on the local cluster to use the local stack. 809 // To access the bootloader global variables we must first copy 810 // the boot code (data and instructions) in the local cluster. 811 boot_remote_memcpy( XPTR( cxy , BOOT_BASE ), 812 XPTR( BOOT_CORE_CXY , BOOT_BASE ), 813 BOOT_MAX_SIZE ); 814 815 // from now, it is safe to refer to the boot code global variables 816 boot_printf("\n[BOOT] core[%x][%d] replicated boot code at cycle %d\n", 817 cxy , lid , boot_get_proctime() ); 818 819 // switch to the INSTRUCTION local memory space, to avoid contention. 732 820 asm volatile("mtc2 %0, $25" :: "r"(cxy)); 733 821 734 // Copy the 'arch_info.bin'file into the local memory.822 // Copy the arch_info.bin file into the local memory. 735 823 boot_remote_memcpy(XPTR(cxy, ARCHINFO_BASE), 736 824 XPTR(BOOT_CORE_CXY, ARCHINFO_BASE), 737 (unsigned int)ARCHINFO_MAX_SIZE); 738 739 // Copy the kernel image into local memory at address 0x0. 740 // ktext segment. 741 boot_remote_memcpy(XPTR(cxy, ktext_base), 742 XPTR(BOOT_CORE_CXY, KERN_IMG_TMP_BASE + ktext_base), 743 ktext_end - ktext_base); 744 // kdata segment. 745 boot_remote_memcpy(XPTR(cxy, kdata_base), 746 XPTR(BOOT_CORE_CXY, KERN_IMG_TMP_BASE + kdata_base), 747 kdata_end - kdata_base); 748 749 // Get local 'boot_info_t' structure base address. 750 // This is the first structure in the kdata segment. 751 boot_info = (boot_info_t*)kdata_base; 825 ARCHINFO_MAX_SIZE ); 826 827 boot_printf("\n[BOOT] core[%x][%d] replicated arch_info at cycle %d\n", 828 cxy , lid , boot_get_proctime() ); 829 830 // Copy the kcode segment into local memory 831 boot_remote_memcpy( XPTR( cxy , seg_kcode_base ), 832 XPTR( BOOT_CORE_CXY , seg_kcode_base ), 833 seg_kcode_size ); 834 835 // Copy the kdata segment into local memory 836 boot_remote_memcpy( XPTR( cxy , seg_kdata_base ), 837 XPTR( BOOT_CORE_CXY , seg_kdata_base ), 838 seg_kdata_size ); 839 840 boot_printf("\n[BOOT] core[%x][%d] replicated kernel code at cycle %d\n", 841 cxy , lid , boot_get_proctime() ); 842 843 // Get local boot_info_t structure base address. 844 boot_info = (boot_info_t*)seg_kdata_base; 752 845 753 846 // Initialize local boot_info_t structure. 754 boot_info_init( boot_info, cxy);847 boot_info_init( boot_info , cxy ); 755 848 756 849 // Check core information. 757 boot_check_core(boot_info, lid); 758 759 // Activateall other local CPi cores in this cluster. 760 local_barrier = 0; 761 boot_wake_local_cores(boot_info); 762 763 // Waiting until all other local cores ready 764 local_count = boot_info->cores_nr - 1; 765 while (local_barrier != local_count); 766 767 // All cores in this cluster are ready to enter kernel. 768 boot_barrier(XPTR(BOOT_CORE_CXY, &global_barrier), 769 global_count); 850 boot_check_core( boot_info , lid ); 851 852 // get number of active clusters from BOOT_CORE cluster 853 uint32_t count = boot_remote_lw( XPTR( BOOT_CORE_CXY , &active_cp0s_nr ) ); 854 855 // Wait until all clusters (i.e all CP0s) ready to enter kernel 856 boot_remote_barrier( XPTR( BOOT_CORE_CXY , &global_barrier ) , count ); 857 858 // activate other local cores 859 boot_wake_local_cores( boot_info ); 860 861 // Wait until all local cores in cluster ready 862 boot_remote_barrier( XPTR( cxy , &local_barrier ) , 863 boot_info->cores_nr ); 770 864 } 771 865 } … … 773 867 { 774 868 /*************************************************************** 775 * PHASE THREE: all non CP0 cores in all clusters execute it. *869 * PHASE C: all non CP0 cores in all clusters execute it 776 870 **************************************************************/ 777 871 778 if (cxy == BOOT_CORE_CXY) // boot cluster only 779 { 780 // Report to the local CP0 that CPi is ready 781 boot_atomic_add((int32_t*)&local_barrier, 1); 782 783 // wait completion of kernel image move in boot cluster 784 while (boot_cluster_ready != 1); 785 786 // Check core information 787 boot_info = (boot_info_t*)kdata_base; 788 boot_check_core(boot_info, lid); 789 } 790 else // other clusters 791 { 792 // Switch to the INSTRUCTIONS local memory space 793 // to avoid contention at the boot cluster. 794 asm volatile("mtc2 %0, $25" :: "r"(cxy)); 795 796 // Report to the local CP0 that CPi is ready 797 boot_atomic_add((int32_t*)&local_barrier, 1); 798 799 // Check core information 800 boot_info = (boot_info_t*)kdata_base; 801 boot_check_core(boot_info, lid); 802 } 803 } 804 805 // Jump to the kernel code. 806 asm volatile("jr %0" :: "r"(kernel_entry)); 872 // Switch to the INSTRUCTIONS local memory space 873 // to avoid contention at the boot cluster. 874 asm volatile("mtc2 %0, $25" :: "r"(cxy)); 875 876 // Get local boot_info_t structure base address. 877 boot_info = (boot_info_t *)seg_kdata_base; 878 879 // Check core information 880 boot_check_core(boot_info, lid); 881 882 // Wait until all local cores in cluster ready 883 boot_remote_barrier( XPTR( cxy , &local_barrier ) , boot_info->cores_nr ); 884 } 885 886 // Each core compute address of a temporary kernel stack 887 // in the upper part of the local cluster memory... 888 uint32_t stack_ptr = ((boot_info->pages_nr - lid) << 12) - 16; 889 890 // All cores initialise stack pointer, 891 // reset the BEV bit in status register, 892 // register "boot_info" argument in a0, 893 // and jump to kernel_entry. 894 asm volatile( "mfc0 $27, $12 \n" 895 "lui $26, 0xFFBF \n" 896 "ori $26, $26, 0xFFFF \n" 897 "and $27, $27, $26 \n" 898 "mtc0 $27, $12 \n" 899 "move $4, %0 \n" 900 "move $29, %1 \n" 901 "jr %2 \n" 902 :: "r"(boot_info) , "r"(stack_ptr) , "r"(kernel_entry) ); 807 903 808 904 } // boot_loader() -
trunk/tools/bootloader_tsar/boot_bdv_driver.c
r1 r6 12 12 13 13 #ifndef SEG_IOC_BASE 14 # error "The SEG_IOC_BASE value should be defined in the ' boot_config.h' file"14 # error "The SEG_IOC_BASE value should be defined in the 'hard_config.h' file" 15 15 #endif 16 16 17 #ifndef IO_CXY 18 # error "The IO_CXY value should be defined in the 'boot_config.h' file" 17 #ifndef X_IO 18 # error "The X_IO value should be defined in the 'hard_config.h' file" 19 #endif 20 21 #ifndef Y_IO 22 # error "The Y_IO value should be defined in the 'hard_config.h' file" 23 #endif 24 25 #ifndef Y_WIDTH 26 # error "The Y_WIDTH value should be defined in the 'hard_config.h' file" 19 27 #endif 20 28 … … 31 39 static uint32_t boot_bdv_get_register( uint32_t reg ) 32 40 { 33 cxy_t cxy = IO_CXY;41 cxy_t cxy = (X_IO << Y_WIDTH) + Y_IO; 34 42 uint32_t * ptr = (uint32_t *)SEG_IOC_BASE + reg; 35 43 … … 46 54 uint32_t val ) 47 55 { 48 cxy_t cxy = IO_CXY;56 cxy_t cxy = (X_IO << Y_WIDTH) + Y_IO; 49 57 uint32_t * ptr = (uint32_t *)SEG_IOC_BASE + reg; 50 58 -
trunk/tools/bootloader_tsar/boot_config.h
r1 r6 1 /**************************************************************************** 2 * This file defines various hardware and configuration parameters for the * 3 * ALMOS-MKH boot-loader. * 4 ****************************************************************************/ 1 /********************************************************************************* 2 * This file defines various configuration parameters for ALMOS-MKH boot-loader. 3 ********************************************************************************/ 5 4 6 5 #ifndef _BOOT_CONFIG_H … … 8 7 9 8 // Debug options 10 #define DEBUG_BOOT_INFO 111 #define DEBUG_BOOT_ELF 19 #define DEBUG_BOOT_INFO 0 10 #define DEBUG_BOOT_ELF 0 12 11 #define DEBUG_BOOT_IOC 0 13 #define DEBUG_BOOT_ FAT32114 #define USE_FIXED_FORMAT012 #define DEBUG_BOOT_WAKUP 1 13 #define DEBUG_BOOT_FAT32 0 15 14 16 // io_cluster identifier17 #define IO_CXY 015 // Core identifier format 16 #define USE_FIXED_FORMAT 1 18 17 19 // Peripheral base addresses (in io_cluster) 20 #define SEG_IOC_BASE 0xb3000000 21 #define SEG_TTY_BASE 0xb4000000 22 #define SEG_MMC_BASE 0xb2000000 18 // cache line 19 #define CACHE_LINE_SIZE 64 20 21 // Preloader temporary segment 22 #define PRELOADER_BASE 0x0 /* Preloader base address. */ 23 #define PRELOADER_MAX_SIZE 0x4000 /* Preloader max size. */ 23 24 24 25 // boot code temporary segment 25 26 #define BOOT_BASE 0x100000 /* 'boot.elf' base address. */ 26 #define BOOT_MAX_SIZE 0x 100000 /* 'boot.elf' max size. */27 #define BOOT_MAX_SIZE 0x010000 /* 'boot.elf' max size. */ 27 28 28 29 // arch_info temporary segment 29 #define ARCHINFO_BASE 0x200000 /* 'arch_info.bin' base address */30 #define ARCHINFO_MAX_SIZE 0x 200000 /* 'arch_info.bin'max size. */30 #define ARCHINFO_BASE 0x200000 /* 'arch_info.bin' file base address */ 31 #define ARCHINFO_MAX_SIZE 0x010000 /* 'arch_info.bin' file max size. */ 31 32 32 33 // kernel code temporary segment 33 #define KERN_BASE 0x400000 /* 'kernel.elf' base address */ 34 #define KERN_MAX_SIZE 0x100000 /* 'kernel.elf' max size. */ 35 36 // Preloader temporary segment 37 #define PRELOADER_BASE 0x0 /* Preloader base address. */ 38 #define PRELOADER_MAX_SIZE 0x100000 /* Preloader max size. */ 34 #define KERN_BASE 0x400000 /* 'kernel.elf' file base address */ 35 #define KERN_MAX_SIZE 0x100000 /* 'kernel.elf' file max size. */ 39 36 40 37 // Temporary stacks segments 41 38 #define BOOT_STACK_BASE 0x504000 /* Boot stack base address. */ 42 #define BOOT_STACK_SIZE 0x1000 /* Boot stack size (4Kb) */ 43 44 // Pas clair du tout TODO [AG] 45 #define KERN_IMG_TMP_BASE 0X600000 39 #define BOOT_STACK_SIZE 0x4000 /* Boot stack size (16Kb) */ 46 40 47 41 #endif // _BOOT_CONFIG_H -
trunk/tools/bootloader_tsar/boot_entry.S
r1 r6 1 /* 2 * boot_entry.S - TSAR bootloader entry point. 3 * 4 * Authors : Alain Greiner / Vu Son (2016) 5 * 6 * Copyright (c) UPMC Sorbonne Universites 7 * 8 * This file is part of ALMOS-MKH. 9 * 10 * ALMOS-MKH is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; version 2.0 of the License. 13 * 14 * ALMOS-MKH is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with ALMOS-MKH; if not, write to the Free Software Foundation, 21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 */ 23 1 24 /************************************************************************************************* 2 25 * This file contains the entry point of the ALMOS-MK boot-loader for TSAR architecture. * … … 61 84 mfc0 k0, CP0_PROCID 62 85 andi k0, k0, 0xFFF /* k0 <= gid */ 63 andi t1, k0, ((1 << P ADDR_WIDTH) - 1)/* t1 <= lid */64 srl t2, k0, P ADDR_WIDTH/* t2 <= cxy */86 andi t1, k0, ((1 << P_WIDTH) - 1) /* t1 <= lid */ 87 srl t2, k0, P_WIDTH /* t2 <= cxy */ 65 88 66 /* 67 * Initializing stack pointer from previously retrieved lid value. 68 */ 89 /* Initialize stack pointer from previously retrieved lid value */ 69 90 70 91 la t0, BOOT_STACK_BASE /* t0 <= BOOT_STACK_BASE */ 71 92 li k1, BOOT_STACK_SIZE /* k1 <= BOOT_STACK_SIZE */ 72 93 multu k1, t1 73 mflo k0 ,/* k0 <= BOOT_STACK_SIZE * lid */94 mflo k0 /* k0 <= BOOT_STACK_SIZE * lid */ 74 95 subu sp, t0, k0 /* P[cxy,lid] stack top initialized */ 75 96 76 /* 77 * Switching to local DSPACE by changing the value of the address extension registers. 78 */ 97 /* Switch to local DSPACE by changing the value of the address extension registers */ 79 98 80 99 mtc2 t2, CP2_DATA_PADDR_EXT 81 100 82 /* 83 * Jumping to boot_loader() function after passing 2 arguments in the registers. 84 */ 101 /* Jump to boot_loader() function after passing 2 arguments in the registers */ 85 102 86 103 or a0, zero, t1 /* a0 <= lid */ … … 96 113 *************/ 97 114 98 /* 99 * Testing if this is bscpu. 100 */ 115 /* Test if this is bscpu */ 101 116 102 117 mfc0 k0, CP0_PROCID … … 108 123 li t4, BOOT_CORE_CXY /* t4 <= bscpu cxy */ 109 124 110 /* 111 * Getting base address of the core descriptor table in 'arch_info.bin' file. 112 */ 125 /* Get base address of the core descriptor table in 'arch_info.bin' file */ 113 126 114 127 la t0, ARCHINFO_BASE /* t0 <= ARCHINFO_BASE */ … … 116 129 addu t2, t0, t1 /* t2 <= ARCHINFO_CORE_BASE */ 117 130 118 /* 119 * Scanning the core descriptor table if this is not bscpu. TODO If not found? 120 */ 131 /* scan the core descriptor table if this is not bscpu. TODO If not found? */ 121 132 122 133 li t3, 0x8 /* t3 <= ARCHINFO_CORE_SIZE */ … … 127 138 addu t2, t2, t3 /* t2 <= @ next archinfo_core */ 128 139 129 /* 130 * Getting (cxy, lid) values from the found core descriptor. 131 */ 140 /* Get (cxy, lid) values from the found core descriptor */ 132 141 133 142 lw t3, -8(t2) /* t3 <= lid */ 134 143 lw t4, -4(t2) /* t4 <= cxy */ 135 144 136 /* 137 * Initializing stack pointer from previously retrieved lid value. 138 */ 145 /* Initialize stack pointer from previously retrieved lid value */ 139 146 140 147 bscpu_exit: … … 145 152 subu sp, t0, k0 /* P[cxy,lid] stack top initialized */ 146 153 147 /* 148 * Switching to local DSPACE by changing the value of the address extension registers. 149 */ 154 /* Switch to local DSPACE by changing the value of the address extension registers */ 150 155 151 156 mtc2 t4, CP2_DATA_PADDR_EXT 152 157 153 /* 154 * Jumping to boot_loader() function after passing 2 arguments in the registers. 155 */ 158 /* Jumping to boot_loader() function after passing 2 arguments in registers */ 156 159 157 160 or a0, zero, t3 /* a0 <= lid */ -
trunk/tools/bootloader_tsar/boot_fat32.c
r1 r6 148 148 { 149 149 #if DEBUG_BOOT_FAT32 150 boot_printf("\n[BOOT ] %s: Enters at cycle %d\n",150 boot_printf("\n[BOOT INFO] %s enters at cycle %d\n", 151 151 __FUNCTION__ , boot_get_proctime() ); 152 152 #endif … … 163 163 164 164 #if DEBUG_BOOT_FAT32 165 boot_printf("\n[BOOT ] %s: FSI Sector loaded at cycle %d\n",165 boot_printf("\n[BOOT INFO] %s : FSI Sector loaded at cycle %d\n", 166 166 __FUNCTION__ , boot_get_proctime() ); 167 167 #endif … … 197 197 198 198 #if DEBUG_BOOT_FAT32 199 boot_printf("\n[BOOT ] %s: free_clusters_nr = %x / free_cluster_hint = %x\n",199 boot_printf("\n[BOOT INFO] %s : free_clusters_nr = %x / free_cluster_hint = %x\n", 200 200 __FUNCTION__ , boot_fat.free_clusters_nr , boot_fat.free_cluster_hint ); 201 201 #endif … … 430 430 431 431 #if DEBUG_BOOT_FAT32 432 boot_printf("\n[BOOT ] %s: returns <%s> from <%s> at cycle %d\n",432 boot_printf("\n[BOOT INFO] %s : returns <%s> from <%s> at cycle %d\n", 433 433 __FUNCTION__ , path_component , pathname , boot_get_proctime() ); 434 434 #endif … … 592 592 593 593 #if DEBUG_BOOT_FAT32 594 boot_printf("\n[BOOT ] %s: Enters for <%s> file at cycle %d\n",594 boot_printf("\n[BOOT INFO] %s enters for <%s> file at cycle %d\n", 595 595 __FUNCTION__ , pathname, boot_get_proctime()); 596 596 #endif … … 615 615 while ( found == 0 ) 616 616 { 617 618 boot_printf("\n!!! enter second while for <%s> path_comp\n", path_comp );619 620 617 cluster_lba = cluster_to_lba( parent_cluster ); 621 618 … … 646 643 if (ord == LAST_ENTRY) // no more entry in this directory 647 644 { 648 649 boot_printf("\n@@@ for <%s> component / offset = %d : last entry\n", path_comp , offset );650 651 645 found = 2; 652 646 } … … 654 648 else if (ord == FREE_ENTRY) // unused, check the next entry 655 649 { 656 657 boot_printf("\n@@@ for <%s> component / offset = %d : free entry\n", path_comp , offset );658 659 650 continue; 660 651 } … … 672 663 get_name_from_long(entry, buffer_lfn); 673 664 674 boot_printf("\n@@@ for <%s> component / offset = %d : LFN entry = %s\n",675 path_comp , offset , buffer_lfn );676 677 665 // Append this portion of the name to the full name buffer 678 666 boot_strcpy(name + 13 * (lfn_seq_order-1) , buffer_lfn); … … 685 673 { 686 674 if (lfn_seq_elem_nr == 0) get_name_from_short(entry, name); 687 688 boot_printf("\n@@@ for <%s> component / offset = %d : SFN entry = %s\n",689 path_comp , offset , name );690 675 691 676 // check if the full name is what we are looking for. … … 725 710 } // end second while for one component in pathname 726 711 727 boot_printf("\n### exit hwile fpr component <%s>\n", path_comp );728 729 712 // Check the result of this path component search. 730 713 if (found == 2) … … 755 738 756 739 #if DEBUG_BOOT_FAT32 757 boot_printf("\n[BOOT ] fat_file_search():"758 " <%s> file of size %x found at cluster %x at cycle %d\n",759 pathname, *file_size, *first_cluster, boot_get_proctime());740 boot_printf("\n[BOOT INFO] %s : <%s> file found at cycle %d\n" 741 " fat_cluster = %x / size = %x\n", 742 __FUNCTION__ , pathname , boot_get_proctime() , *first_cluster , *file_size ); 760 743 #endif 761 744 … … 771 754 int boot_fat32_init() 772 755 { 773 774 boot_printf("@@@ BEFORE_VALUE = %x\n", FAT_MAGIC_VALUE);775 776 756 // FAT32 initialization should be done only once 777 757 if (boot_fat.initialized == FAT_MAGIC_VALUE) … … 783 763 784 764 #if DEBUG_BOOT_FAT32 785 boot_printf("\n[BOOT ] %s: Enters at cycle %d\n",765 boot_printf("\n[BOOT INFO] %s: Enters at cycle %d\n", 786 766 __FUNCTION__ , boot_get_proctime() ); 787 767 #endif … … 799 779 800 780 #if DEBUG_BOOT_FAT32 801 boot_printf("\n[BOOT ] %s: Boot Sector loaded at cycle %d\n",781 boot_printf("\n[BOOT INFO] %s: Boot Sector loaded at cycle %d\n", 802 782 __FUNCTION__ , boot_get_proctime() ); 803 // unsigned char * data = boot_fat.block_buffer;804 // uint32_t byte;805 // for( byte = 0 ; byte < 16 ; byte++ ) boot_printf("%d : %x\n", byte , data[byte] );806 783 #endif 807 784 … … 865 842 boot_fat.initialized = FAT_MAGIC_VALUE; 866 843 867 boot_printf("@@@ AFTER_VALUE = %x\n", FAT_MAGIC_VALUE);868 869 fat32_desc_display();870 871 844 // Set information from FS Information Sector 872 845 if (set_fsi()) return -1; … … 878 851 #if DEBUG_BOOT_FAT32 879 852 fat32_desc_display(); 880 boot_printf("\n[BOOT ] boot_fat32_init(): FAT32 File System initialized at cycle %d\n",881 boot_get_proctime());853 boot_printf("\n[BOOT INFO] %s : FAT32 File System initialized at cycle %d\n", 854 __FUNCTION__ , boot_get_proctime() ); 882 855 #endif 883 856 … … 907 880 908 881 #if DEBUG_BOOT_FAT32 909 boot_printf("\n[BOOT ] %s: Enters for file <%s> at cycle %d\n",882 boot_printf("\n[BOOT INFO] %s enters for file <%s> at cycle %d\n", 910 883 __FUNCTION__ , pathname, boot_get_proctime() ); 911 884 #endif … … 973 946 974 947 #if DEBUG_BOOT_FAT32 975 boot_printf("\n[BOOT ] boot_fat32_load():"976 " File <%s> of size %x loaded at address %x at cycle %d\n",977 pathname, size, buff_addr, boot_get_proctime());948 boot_printf("\n[BOOT INFO] %s : file <%s> loaded at cycle %d\n" 949 " address = %x , size = %x\n", 950 __FUNCTION__ , pathname , boot_get_proctime() , buff_addr , size ); 978 951 #endif 979 952 -
trunk/tools/bootloader_tsar/boot_hba_driver.c
r1 r6 7 7 8 8 #include <boot_config.h> 9 #include <hard_config.h> 9 10 #include <boot_hba_driver.h> 10 11 #include <boot_mmc_driver.h> … … 15 16 #endif 16 17 17 #ifndef IO_CXY 18 # error "The IO_CXY value should be defined in the 'boot_config.h' file" 18 #ifndef Y_IO 19 # error "The Y_IO value should be defined in the 'hard_config.h' file" 20 #endif 21 22 #ifndef X_IO 23 # error "The X_IO value should be defined in the 'hard_config.h' file" 24 #endif 25 26 #ifndef Y_WIDTH 27 # error "The Y_WIDTH value should be defined in the 'hard_config.h' file" 19 28 #endif 20 29 … … 47 56 static uint32_t boot_hba_get_register(uint32_t reg) 48 57 { 49 cxy_t cxy = IO_CXY;58 cxy_t cxy = (X_IO << Y_WIDTH) + Y_IO; 50 59 uint32_t * ptr = (uint32_t *)SEG_IOC_BASE + reg; 51 60 … … 61 70 void boot_hba_set_register(uint32_t reg, uint32_t val) 62 71 { 63 cxy_t cxy = IO_CXY;72 cxy_t cxy = (X_IO << Y_WIDTH) + Y_IO; 64 73 uint32_t * ptr = (uint32_t *)SEG_IOC_BASE + reg; 65 74 -
trunk/tools/bootloader_tsar/boot_tty_driver.c
r1 r6 1 /////////////////////////////////////////////////////////////////////////////////// 2 // File : boot_tty_driver.c 3 // Date : 18/01/2017 4 // Author : Alain Greiner / Vu Son 5 // Copyright (c) UPMC-LIP6 6 /////////////////////////////////////////////////////////////////////////////////// 1 /* 2 * boot_tty_driver.c - TSAR bootloader TTY driver implementation. 3 * 4 * Authors : Alain Greiner / Vu Son (2016) 5 * 6 * Copyright (c) UPMC Sorbonne Universites 7 * 8 * This file is part of ALMOS-MKH. 9 * 10 * ALMOS-MKH is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; version 2.0 of the License. 13 * 14 * ALMOS-MKH is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with ALMOS-MKH; if not, write to the Free Software Foundation, 21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 */ 7 23 8 24 #include <boot_config.h> … … 11 27 #include <boot_utils.h> 12 28 13 #ifndef SEG_T TY_BASE14 # error "The SEG_T TY_BASE value should be defined in the 'boot_config.h' file"29 #ifndef SEG_TXT_BASE 30 # error "The SEG_TXT_BASE value should be defined in the 'hard_config.h' file" 15 31 #endif 16 32 17 #ifndef IO_CXY 18 # error "The IO_CXY value should be defined in the 'boot_config.h' file" 33 #ifndef X_IO 34 # error "The X_IO value should be defined in the 'hard_config.h' file" 35 #endif 36 37 #ifndef Y_IO 38 # error "The Y_IO value should be defined in the 'hard_config.h' file" 39 #endif 40 41 #ifndef Y_WIDTH 42 # error "The Y_WIDTH value should be defined in the 'hard_config.h' file" 19 43 #endif 20 44 21 45 22 /**************************************************************************** 23 * Internal functions. * 24 ****************************************************************************/ 25 26 /**************************************************************************** 27 * This function returns the value of the a TTY register. * 28 * @ reg : TTY register to be read. * 29 * @ returns the value stored in 'reg'. * 30 ****************************************************************************/ 46 ///////////////////////////////////////////////////////////////////////////// 47 // This function returns the value contained in a TTY0 register. 48 // @ reg : register to be read. 49 // @ returns the value stored in 'reg'. 50 ///////////////////////////////////////////////////////////////////////////// 31 51 static uint32_t boot_tty_get_register( uint32_t reg ) 32 52 { 33 cxy_t cxy = IO_CXY;34 uint32_t * ptr = (uint32_t *)SEG_T TY_BASE + reg;53 cxy_t cxy = (X_IO << Y_WIDTH) + Y_IO; 54 uint32_t * ptr = (uint32_t *)SEG_TXT_BASE + reg; 35 55 36 56 return boot_remote_lw( XPTR( cxy , ptr ) ); … … 38 58 } // boot_tty_get_register() 39 59 40 / ****************************************************************************41 * This function sets a new value to a TTY register. * 42 * @ reg : TTY register to be configured. * 43 * @ val : new value to be written to 'reg'. * 44 ****************************************************************************/60 ///////////////////////////////////////////////////////////////////////////// 61 // This function sets a new value to a TTY0 register. 62 // @ reg : register to be configured. 63 // @ val : new value to be written to 'reg'. 64 ///////////////////////////////////////////////////////////////////////////// 45 65 static void boot_tty_set_register( uint32_t reg, 46 66 uint32_t val ) 47 67 { 48 cxy_t cxy = IO_CXY;49 uint32_t * ptr = (uint32_t *)SEG_T TY_BASE + reg;68 cxy_t cxy = (X_IO << Y_WIDTH) + Y_IO; 69 uint32_t * ptr = (uint32_t *)SEG_TXT_BASE + reg; 50 70 51 71 boot_remote_sw( XPTR( cxy , ptr ) , val ); … … 53 73 } // boot_tty_set_register() 54 74 55 /**************************************************************************** 56 * Driver API functions. * 57 ****************************************************************************/ 58 75 ////////////////////////////////// 59 76 int boot_tty_write( char * buf, 60 77 uint32_t nbytes ) 61 78 { 62 uint32_t nb_printed; /* Iterator for printing loop. */63 uint32_t nb_test; /* Iterator for retry loop. */64 uint32_t error; /* Used to detect if an error occurs. */79 uint32_t nb_printed; 80 uint32_t nb_test; 81 uint32_t error; 65 82 66 / * Printing to the boot TTY terminal. */83 // Print nbytes to TTY0 terminal 67 84 for (nb_printed = 0; nb_printed < nbytes; nb_printed++) 68 85 { 69 // Poll ing the TTY driverstatus.70 if ((boot_tty_get_register(TTY_STATUS ) & TTY_WRITE_BUSY))86 // Poll the TTY0 status. 87 if ((boot_tty_get_register(TTY_STATUS_REG) & TTY_STATUS_TX_FULL)) 71 88 { 72 // TTY_WRITE_BUSY bit of TTY_STATUS register is set, keeps polling.73 89 error = 1; 74 90 for (nb_test = 0; nb_test < 10000; nb_test++) 75 if ((boot_tty_get_register(TTY_STATUS) & TTY_WRITE_BUSY) == 0) 91 { 92 if ((boot_tty_get_register(TTY_STATUS_REG) & TTY_STATUS_TX_FULL) == 0) 76 93 { 77 94 error = 0; 78 95 break; 79 96 } 97 } 80 98 81 // Reporting an error if the TTY_WRITE_BUSY bit is still set after 82 // 10000 retries. 83 if (error) 84 return -1; 99 // Report error after 10000 retries. 100 if (error) return -1; 85 101 } 86 102 87 // Writ ing a character to the boot TTYterminal.103 // Write one character to TTY0 terminal. 88 104 // Special treatment for a newline: Carriage Return before Line Feed. 89 if (buf[nb_printed] == '\n') 90 boot_tty_set_register(TTY_WRITE, (uint32_t)'\r'); 91 boot_tty_set_register(TTY_WRITE, (uint32_t)buf[nb_printed]); 105 if (buf[nb_printed] == '\n') boot_tty_set_register(TTY_WRITE_REG , (uint32_t)'\r'); 106 boot_tty_set_register(TTY_WRITE_REG , (uint32_t)buf[nb_printed]); 92 107 } 93 108 -
trunk/tools/bootloader_tsar/boot_tty_driver.h
r1 r6 1 /* 2 * boot_tty_driver.h - TSAR bootloader TTY driver definition. 3 * 4 * Authors : Alain Greiner / Vu Son (2016) 5 * 6 * Copyright (c) UPMC Sorbonne Universites 7 * 8 * This file is part of ALMOS-MKH. 9 * 10 * ALMOS-MKH is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; version 2.0 of the License. 13 * 14 * ALMOS-MKH is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with ALMOS-MKH; if not, write to the Free Software Foundation, 21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 */ 23 1 24 /**************************************************************************** 2 * This file defines a nano-driver for SocLib vci_multi_tty component, used * 3 * by the ALMOS-MKH boot-loader. * 4 * * 5 * The SEG_TTY_BASE address must be defined in the 'hard_config.h' file. * 6 * * 7 * All accesses to the device registers are performed via 2 low-level * 8 * functions 'boot_tty_get_register()' and 'boot_tty_set_register()'. * 25 * This file defines a nano-driver for SocLib vci_multi_tty component, 26 * used by the ALMOS-MKH boot-loader. 27 * The SEG_TTY_BASE address must be defined in the 'hard_config.h' file. 28 * All accesses to the device registers are performed via 2 low-level 29 * functions 'boot_tty_get_register()' and 'boot_tty_set_register()'. 9 30 ****************************************************************************/ 10 31 … … 20 41 enum TTY_registers 21 42 { 22 TTY_WRITE = 0, /* character to be displayed on screen*/23 TTY_STATUS = 1, /* read and write buffer status*/24 TTY_READ = 2, /* character in the keyboard*/25 TTY_CONFIG = 3, /* unused*/43 TTY_WRITE_REG = 0, /* character to be displayed on screen */ 44 TTY_STATUS_REG = 1, /* read and write buffer status */ 45 TTY_READ_REG = 2, /* character in the keyboard */ 46 TTY_CONFIG_REG = 3, /* unused */ 26 47 27 48 TTY_SPAN = 4, /* segment size for one channel ( words ) */ … … 34 55 enum TTY_status 35 56 { 36 TTY_ READ_BUSY = 1,/* Set if TTY_READ register contains a data. */37 TTY_ WRITE_BUSY = 2,/* Set if TTY_WRITE register contains a data. */57 TTY_STATUS_RX_FULL = 1, /* Set if TTY_READ register contains a data. */ 58 TTY_STATUS_TX_FULL = 2, /* Set if TTY_WRITE register contains a data. */ 38 59 }; 39 60 40 61 /**************************************************************************** 41 * Driver API functions. * 42 ****************************************************************************/ 43 44 /**************************************************************************** 45 * This function writes a character string from the 'buf' buffer to the * 46 * boot TTY terminal. It tests the TTY_STATUS register before writing each * 47 * character of the string to the TTY_WRITE register. If TTY_WRITE_BUSY * 48 * bit is set, it keeps testing the TTY_STATUS register. If after 10000 * 49 * retries the bit is still set, the function reports an error and returns. * 50 * @ buf : buffer containing the string to be printed * 51 * @ nbytes : number of characters to be printed * 52 * @ returns 0 on success, -1 on error. * 62 * This function writes a character string from the 'buf' buffer to the 63 * boot TTY terminal. It tests the TTY_STATUS register before writing each 64 * character of the string to the TTY_WRITE register. If TTY_WRITE_BUSY 65 * bit is set, it keeps testing the TTY_STATUS register. If after 10000 66 * retries the bit is still set, the function reports an error and returns. 67 **************************************************************************** 68 * @ buf : buffer containing the string to be printed. 69 * @ nbytes : number of characters to be printed. 70 * @ returns 0 on success, -1 on error. 53 71 ****************************************************************************/ 54 72 int boot_tty_write( char * buf, -
trunk/tools/bootloader_tsar/boot_utils.c
r1 r6 1 /* 2 * boot_utils.c - TSAR bootloader utilities implementation. 3 * 4 * Authors : Alain Greiner / Vu Son (2016) 5 * 6 * Copyright (c) UPMC Sorbonne Universites 7 * 8 * This file is part of ALMOS-MKH. 9 * 10 * ALMOS-MKH is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; version 2.0 of the License. 13 * 14 * ALMOS-MKH is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with ALMOS-MKH; if not, write to the Free Software Foundation, 21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 */ 23 1 24 #include <stdarg.h> 2 25 … … 5 28 #include <boot_utils.h> 6 29 30 31 /**************************************************************************** 32 * Global variables * 33 ****************************************************************************/ 34 35 extern boot_remote_spinlock_t tty0_lock; // allocated in boot.c 36 7 37 /**************************************************************************** 8 38 * Remote accesses. * 9 39 ****************************************************************************/ 10 40 41 ////////////////////////////////// 11 42 uint32_t boot_remote_lw(xptr_t xp) 12 43 { 13 uint32_t res; /* Value to be read, stored at the remote address. */ 14 uint32_t ptr; /* Classic pointer to the distant memory location. */ 15 uint32_t cxy; /* Identifier of the cluster containing the distant 16 memory location. */ 17 18 /* Extracting information from the extended pointer. */ 44 uint32_t res; 45 uint32_t ptr; 46 uint32_t cxy; 47 48 // Extracting information from the extended pointer 19 49 ptr = (uint32_t)GET_PTR(xp); 20 50 cxy = (uint32_t)GET_CXY(xp); 21 51 22 / * Assembly instructions to get the work done. */52 // Assembly instructions to get the work done. 23 53 asm volatile("mfc2 $15, $24\n" /* $15 <= CP2_DATA_PADDR_EXT */ 24 54 "mtc2 %2, $24\n" /* CP2_DATA_PADDR_EXT <= cxy */ … … 37 67 } // boot_remote_lw() 38 68 39 /****************************************************************************/ 40 69 ///////////////////////////////////////////// 41 70 void boot_remote_sw(xptr_t xp, uint32_t data) 42 71 { … … 62 91 } // boot_remote_sw() 63 92 64 /****************************************************************************/ 65 93 ////////////////////////////////////////////////////// 66 94 int32_t boot_remote_atomic_add(xptr_t xp, int32_t val) 67 95 { … … 98 126 } // boot_remote_atomic_add() 99 127 100 /****************************************************************************/ 101 102 void boot_remote_memcpy(xptr_t dest, xptr_t src, unsigned int size) 128 /////////////////////////////////////////////////////////////// 129 void boot_remote_memcpy(xptr_t dest, xptr_t src, uint32_t size) 103 130 { 104 131 uint32_t words_nr; /* Number of 32-bit words to be copied. */ … … 194 221 ****************************************************************************/ 195 222 196 void boot_memcpy(void* dest, void* src, unsigned int size) 197 { 198 /* Word-by-word copy if both addresses are word-aligned. */ 199 if ((((unsigned int)dest & 0x3) == 0) && 200 (((unsigned int)src & 0x3) == 0)) 201 { 202 // 'size' might not be a multiple of 4 bytes, we have to copy a few 203 // bytes left (at most 3) byte-by-byte later. 223 /////////////////////////////////////////////////////// 224 void boot_memcpy(void * dst, void * src, uint32_t size) 225 { 226 uint32_t * wdst = dst; 227 uint32_t * wsrc = src; 228 229 // word-by-word copy if both addresses are word-aligned 230 if ( (((uint32_t)dst & 0x3) == 0) && (((uint32_t)src & 0x3) == 0) ) 231 { 204 232 while (size > 3) 205 233 { 206 * (unsigned int*)dest++ = *(unsigned int*)src++;234 *wdst++ = *wsrc++; 207 235 size -= 4; 208 236 } 209 237 } 210 238 211 /* 212 * Byte-by-byte copy if: 213 * - At least 1 of the 2 addresses is not word-aligned, 214 * - 'size' value is not a multiple of 4 bytes. 215 */ 239 unsigned char * cdst = (unsigned char *)wdst; 240 unsigned char * csrc = (unsigned char *)wsrc; 241 242 // byte-by-byte copy if: 243 // - At least 1 of the 2 addresses is not word-aligned, 244 // - 'size' value is not a multiple of 4 bytes. 216 245 while (size) 217 *(unsigned char*)dest++ = *(unsigned char*)src++; 218 246 { 247 *cdst++ = *csrc++; 248 } 219 249 } // boot_memcpy() 220 250 221 /****************************************************************************/ 222 223 void boot_memset(void* base, int val, unsigned int size) 224 { 225 unsigned int wval; /* Word-sized value to word-by-word filling. */ 226 227 /* Word-by-word filling if the base address is word-aligned. */ 228 // Extracting the first 2 bytes of 'val'. 251 //////////////////////////////////////////////////// 252 void boot_memset(void * dst, int val, uint32_t size) 253 { 229 254 val &= 0xFF; 230 // Making it word-sized. 231 wval = (val << 24) | (val << 16) | (val << 8) | val; 232 233 if (((unsigned int)base & 0x3) == 0) 234 { 235 // 'size' might not be a multiple of 4 bytes, we have to fill a 236 // few bytes left (at most 3) byte-by-byte later. 255 256 // build a word-sized value 257 uint32_t wval = (val << 24) | (val << 16) | (val << 8) | val; 258 uint32_t * wdst = (uint32_t *)dst; 259 260 // word per word if address aligned 261 if (((uint32_t)dst & 0x3) == 0) 262 { 237 263 while (size > 3) 238 264 { 239 * (unsigned int*)base++ = wval;265 *wdst++ = wval; 240 266 size -= 4; 241 267 } 242 268 } 243 269 244 /* 245 * Byte-by-byte filling if: 246 * - The base address is not word-aligned, 247 * - 'size' value is not a multiple of 4 bytes. 248 */ 270 char * cdst = (char *)wdst; 271 272 // byte per byte 249 273 while (size--) 250 *(unsigned char*)base++ = val; 251 274 { 275 *cdst++ = (char)val; 276 } 252 277 } // boot_memset() 253 278 … … 256 281 ****************************************************************************/ 257 282 283 /////////////////////////////////////// 258 284 void boot_strcpy(char* dest, char* src) 259 285 { … … 267 293 } // boot_strcpy() 268 294 269 /****************************************************************************/ 270 271 unsigned int boot_strlen(char* s) 272 { 273 unsigned int res = 0; /* Length of the string (in bytes). */ 295 ///////////////////////////// 296 uint32_t boot_strlen(char* s) 297 { 298 uint32_t res = 0; /* Length of the string (in bytes). */ 274 299 275 300 if (s != NULL) … … 283 308 } // boot_strlen() 284 309 285 /****************************************************************************/ 286 310 /////////////////////////////////// 287 311 int boot_strcmp(char* s1, char* s2) 288 312 { … … 308 332 ****************************************************************************/ 309 333 334 ///////////////////////// 310 335 void boot_puts(char* str) 311 336 { … … 314 339 } // boot_puts() 315 340 316 /****************************************************************************/ 317 318 void boot_printf(char* format, ...) 319 { 320 va_list arg; /* Used to iterate arguments list. */ 321 char buf[16]; /* Buffer for argument conversion. */ 322 char* print_pt; /* String pointer for argument printing. */ 323 int arg_val; /* Raw value of the argument. */ 324 unsigned int arg_len; /* Length of a argument (in bytes). */ 325 unsigned int nb_printed; /* Iterator for text printing loop. */ 326 unsigned int conv_index; /* Index for argument conversion loop. */ 327 328 const char conv_tab[] = "0123456789ABCDEF"; 329 330 /* Starting the arguments iterating process with a va_list. */ 331 va_start(arg, format); 332 333 print_text: 334 335 while (*format) 336 { 337 /* Counting the number of ordinary characters. */ 338 for (nb_printed = 0; 339 (format[nb_printed] != '\0') && (format[nb_printed] != '%'); 340 nb_printed++); 341 342 /* Copying them unchanged to the boot TTY terminal. */ 343 if (nb_printed > 0) 341 /////////////////////////////////////// 342 void boot_printf( char * format , ... ) 343 { 344 va_list args; 345 va_start( args , format ); 346 347 // take the lock protecting TTY0 348 boot_remote_lock( XPTR( 0 , &tty0_lock ) ); 349 350 printf_text: 351 352 while ( *format ) 353 { 354 uint32_t i; 355 for (i = 0 ; format[i] && (format[i] != '%') ; i++); 356 if (i) 344 357 { 345 if (boot_tty_write(format, nb_printed)) 346 goto error; 347 format += nb_printed; 358 boot_tty_write( format , i ); 359 format += i; 348 360 } 349 350 /* Skipping the '%' character. */ 351 if (*format == '%') 361 if (*format == '%') 352 362 { 353 363 format++; 354 goto print _argument;364 goto printf_arguments; 355 365 } 356 366 } 357 367 358 /* Freeing the va_list. */ 359 va_end(arg); 360 368 // release the lock 369 boot_remote_unlock( XPTR( 0 , &tty0_lock ) ); 370 371 va_end( args ); 361 372 return; 362 373 363 print_argument: 364 365 /* Analyzing the conversion specifier. */ 366 switch (*format++) 367 { 368 // A character. 369 case ('c'): 374 printf_arguments: 375 376 { 377 char buf[20]; 378 char * pbuf = NULL; 379 uint32_t len = 0; 380 static const char HexaTab[] = "0123456789ABCDEF"; 381 uint32_t i; 382 383 switch (*format++) 370 384 { 371 // Retrieving the argument. 372 arg_val = va_arg(arg, int); 373 374 // Preparing for the printing. 375 arg_len = 1; 376 buf[0] = arg_val; 377 print_pt = &buf[0]; 378 break; 385 case ('c'): /* char conversion */ 386 { 387 int val = va_arg( args , int ); 388 len = 1; 389 buf[0] = val; 390 pbuf = &buf[0]; 391 break; 392 } 393 case ('d'): /* 32 bits decimal signed */ 394 { 395 int val = va_arg( args , int ); 396 if (val < 0) 397 { 398 val = -val; 399 boot_tty_write( "-" , 1 ); 400 } 401 for(i = 0; i < 10; i++) 402 { 403 buf[9 - i] = HexaTab[val % 10]; 404 if (!(val /= 10)) break; 405 } 406 len = i + 1; 407 pbuf = &buf[9 - i]; 408 break; 409 } 410 case ('u'): /* 32 bits decimal unsigned */ 411 { 412 uint32_t val = va_arg( args , uint32_t ); 413 for(i = 0; i < 10; i++) 414 { 415 buf[9 - i] = HexaTab[val % 10]; 416 if (!(val /= 10)) break; 417 } 418 len = i + 1; 419 pbuf = &buf[9 - i]; 420 break; 421 } 422 case ('x'): /* 32 bits hexadecimal unsigned */ 423 { 424 uint32_t val = va_arg( args , uint32_t ); 425 boot_tty_write( "0x" , 2 ); 426 for(i = 0; i < 8; i++) 427 { 428 buf[7 - i] = HexaTab[val & 0xF]; 429 if (!(val = (val>>4))) break; 430 } 431 len = i + 1; 432 pbuf = &buf[7 - i]; 433 break; 434 } 435 case ('X'): /* 32 bits hexadecimal unsigned on 10 char */ 436 { 437 uint32_t val = va_arg( args , uint32_t ); 438 boot_tty_write( "0x" , 2 ); 439 for(i = 0; i < 8; i++) 440 { 441 buf[7 - i] = HexaTab[val & 0xF]; 442 val = (val>>4); 443 } 444 len = 8; 445 pbuf = buf; 446 break; 447 } 448 case ('l'): /* 64 bits hexadecimal unsigned */ 449 { 450 uint64_t val = va_arg( args , uint64_t ); 451 boot_tty_write( "0x" , 2 ); 452 for(i = 0; i < 16; i++) 453 { 454 buf[15 - i] = HexaTab[val & 0xF]; 455 if (!(val = (val>>4))) break; 456 } 457 len = i + 1; 458 pbuf = &buf[15 - i]; 459 break; 460 } 461 case ('L'): /* 64 bits hexadecimal unsigned on 18 char */ 462 { 463 uint64_t val = va_arg( args , uint64_t ); 464 boot_tty_write( "0x" , 2 ); 465 for(i = 0; i < 16; i++) 466 { 467 buf[15 - i] = HexaTab[val & 0xF]; 468 val = (val>>4); 469 } 470 len = 16; 471 pbuf = buf; 472 break; 473 } 474 case ('s'): /* string */ 475 { 476 char* str = va_arg( args , char* ); 477 while (str[len]) 478 { 479 len++; 480 } 481 pbuf = str; 482 break; 483 } 484 default: 485 { 486 boot_tty_write( "\n[PANIC] in boot_printf() : illegal format\n", 43 ); 487 } 379 488 } 380 489 381 // A 32-bit signed decimal notation of an integer. 382 case ('d'): 383 { 384 // Retrieving the argument. 385 arg_val = va_arg(arg, int); 386 387 // Printing the minus sign if needed. 388 if (arg_val < 0) 389 { 390 arg_val = -arg_val; 391 if (boot_tty_write("-", 1)) 392 goto error; 393 } 394 395 // Converting the argument raw value to a character string. 396 // Note that the maximum value for this type is 2.147.483.647 397 // (2^31 - 1), a 10-digit number. 398 for (conv_index = 0; conv_index < 10; conv_index++) 399 { 400 // Writing to the buffer, starting from the least significant 401 // digit. 402 buf[9 - conv_index] = conv_tab[arg_val % 10]; 403 404 // Getting to the next digit, stop when no more digit. 405 if ((arg_val /= 10) == 0) 406 break; 407 } 408 409 // Preparing for the printing. 410 arg_len = conv_index + 1; 411 print_pt = &buf[9 - conv_index]; 412 break; 413 } 414 415 // A 32-bit unsigned decimal notation of an integer. 416 case ('u'): 417 { 418 // Retrieving the argument. 419 arg_val = va_arg(arg, unsigned int); 420 421 // Converting the argument raw value to a character string. 422 // Note that the maximum value for this type is 4.294.967.295 423 // (2^32 - 1), also a 10-digit number. 424 for (conv_index = 0; conv_index < 10; conv_index++) 425 { 426 // Writing to the buffer, starting from the least significant 427 // digit. 428 buf[9 - conv_index] = conv_tab[arg_val % 10]; 429 430 // Getting to the next digit, stop when no more digit. 431 if ((arg_val /= 10) == 0) 432 break; 433 } 434 435 // Preparing for the printing. 436 arg_len = conv_index + 1; 437 print_pt = &buf[9 - conv_index]; 438 break; 439 } 440 441 // A 32-bit unsigned hexadecimal notation of an integer. 442 case ('x'): 443 { 444 // Retrieving the argument. 445 arg_val = va_arg(arg, unsigned int); 446 447 // Printing the hexadecimal prefix. 448 if (boot_tty_write("0x", 2)) 449 goto error; 450 451 // Converting the argument raw value to a character string. 452 // Note that the maximum value for this type is 0xFFFFFFFF 453 // (2^32 - 1), a 8-digit hexadecimal number. 454 for (conv_index = 0; conv_index < 8; conv_index++) 455 { 456 // Writing to the buffer, starting from the least significant 457 // digit. 458 buf[7 - conv_index] = conv_tab[arg_val % 16]; 459 460 // Getting to the next digit, stop when no more digit. 461 if ((arg_val >>= 4) == 0) 462 break; 463 } 464 465 // Preparing for the printing. 466 arg_len = conv_index + 1; 467 print_pt = &buf[7 - conv_index]; 468 break; 469 } 470 471 // A 64-bit unsigned hexadecimal notation of an integer. 472 case ('l'): 473 { 474 // Retrieving the argument. 475 arg_val = va_arg(arg, unsigned long long); 476 477 // Printing the hexadecimal prefix. 478 if (boot_tty_write("0x", 2)) 479 goto error; 480 481 // Converting the argument raw value to a character string. 482 // Note that the maximum value for this type is 0xFFFFFFFFFFFFFFFF 483 // (2^64 - 1), a 16-digit hexadecimal number. 484 for (conv_index = 0; conv_index < 16; conv_index++) 485 { 486 // Writing to the buffer, starting from the least significant 487 // digit. 488 buf[15 - conv_index] = conv_tab[arg_val % 16]; 489 490 // Getting to the next digit, stop when no more digit. 491 if ((arg_val >>= 4) == 0) 492 break; 493 } 494 495 // Preparing for the printing. 496 arg_len = conv_index + 1; 497 print_pt = &buf[15 - conv_index]; 498 break; 499 } 500 501 // A NUL terminated string. 502 case ('s'): 503 { 504 // Retrieving the argument. 505 print_pt = va_arg(arg, char*); 506 507 // Preparing for the printing. 508 arg_len = boot_strlen(print_pt); 509 break; 510 } 511 512 default: 513 goto error; 514 515 } 516 517 /* Printing the converted argument. */ 518 if (boot_tty_write(print_pt, arg_len)) 519 goto error; 520 521 goto print_text; 522 523 error: 524 525 /* Trying to print an error message then exit. */ 526 boot_puts("\n[BOOT ERROR] boot_printf(): " 527 "Cannot print the whole message\n" 528 ); 529 530 boot_exit(); 531 532 } // boot_printf() 490 if( pbuf != NULL ) boot_tty_write( pbuf, len ); 491 492 goto printf_text; 493 } 494 } // boot_printf() 495 496 497 498 499 533 500 534 501 /**************************************************************************** … … 536 503 ****************************************************************************/ 537 504 505 //////////////// 538 506 void boot_exit() 539 507 { 540 boot_printf("\n[BOOT PANIC] Suiciding at cycle %d...\n", 541 boot_get_proctime() 542 ); 543 544 while (1) 545 asm volatile ("nop"); 508 boot_printf("\n[BOOT PANIC] core %x suicide at cycle %d...\n", 509 boot_get_procid() , boot_get_proctime() ); 510 511 while (1) asm volatile ("nop"); 546 512 547 513 } // boot_exit() 548 514 549 /****************************************************************************/ 550 551 unsigned int boot_get_proctime() 552 { 553 unsigned int res; /* Value stored in the CP0_COUNT register. */ 515 //////////////////////////// 516 uint32_t boot_get_proctime() 517 { 518 uint32_t res; /* Value stored in the CP0_COUNT register. */ 554 519 555 520 asm volatile("mfc0 %0, $9" : "=r"(res)); … … 559 524 } // boot_get_proctime() 560 525 561 /****************************************************************************/ 562 563 u nsigned int boot_get_procid()564 { 565 u nsigned int res; /* Value stored in the CP0_PROCID register. */526 527 ////////////////////////// 528 uint32_t boot_get_procid() 529 { 530 uint32_t res; /* Value stored in the CP0_PROCID register. */ 566 531 567 532 asm volatile("mfc0 %0, $15, 1" : "=r"(res)); … … 571 536 } // boot_get_procid() 572 537 573 /****************************************************************************/ 574 575 void boot_barrier(xptr_t xp_barrier, uint32_t count) 576 { 577 boot_barrier_t* ptr; /* Classic pointer to the toggling 578 barrier. */ 579 uint32_t cxy; /* Identifier of the cluster containing 580 the toggling barrier. */ 581 uint32_t expected; /* Expected barrier state after reset. */ 582 uint32_t current; /* Number of processors reached the 583 barrier. */ 584 585 /* Extracting information from the extended pointer. */ 586 ptr = (boot_barrier_t*)GET_PTR(xp_barrier); 587 cxy = (uint32_t) GET_CXY(xp_barrier); 588 589 /* 590 * Explicitly testing the barrier sense value because no initialization 591 * has been previously done. 592 */ 593 if (boot_remote_lw(XPTR(cxy, &ptr->sense)) == 0) 594 expected = 1; 595 else 596 expected = 0; 538 539 //////////////////////////////////////////////// 540 void boot_remote_barrier( xptr_t xp_barrier, 541 uint32_t count) 542 { 543 boot_remote_barrier_t * ptr; 544 uint32_t cxy; 545 uint32_t expected; 546 uint32_t current; 547 548 // Extract information from the extended pointer 549 ptr = (boot_remote_barrier_t*)GET_PTR(xp_barrier); 550 cxy = (uint32_t) GET_CXY(xp_barrier); 551 552 // Explicitly test the barrier sense value because no initialization 553 if (boot_remote_lw(XPTR(cxy, &ptr->sense)) == 0) expected = 1; 554 else expected = 0; 597 555 598 / * Incrementing the counter. */556 // Atomically increment counter 599 557 current = boot_remote_atomic_add(XPTR(cxy, &ptr->current), 1); 600 558 601 / * The processor arrived last resets the barrier and toggles its sense. */559 // The processor arrived last resets the barrier and toggles its sense 602 560 if (current == (count - 1)) 603 561 { … … 605 563 boot_remote_sw(XPTR(cxy, &ptr->sense), expected); 606 564 } 607 / * Other processors poll the sense. */565 // Other processors poll the sense 608 566 else 609 567 { … … 613 571 } // boot_barrier() 614 572 573 //////////////////////////////////////// 574 void boot_remote_lock( xptr_t lock_xp ) 575 576 { 577 // Extract information from the extended pointer 578 boot_remote_spinlock_t * ptr = (boot_remote_spinlock_t *)GET_PTR( lock_xp ); 579 uint32_t cxy = GET_CXY( lock_xp ); 580 581 // get next free ticket 582 uint32_t ticket = boot_remote_atomic_add( XPTR( cxy , &ptr->ticket ) , 1 ); 583 584 // poll the current slot index 585 while ( boot_remote_lw( XPTR( cxy , &ptr->current ) ) != ticket ) 586 { 587 asm volatile ("nop"); 588 } 589 590 } // boot_remote_lock() 591 592 ///////////////////////////////////////// 593 void boot_remote_unlock( xptr_t lock_xp ) 594 { 595 asm volatile ( "sync" ); // for consistency 596 597 // Extract information from the extended pointer 598 boot_remote_spinlock_t * ptr = (boot_remote_spinlock_t *)GET_PTR( lock_xp ); 599 uint32_t cxy = GET_CXY( lock_xp ); 600 xptr_t current_xp = XPTR( cxy , &ptr->current ); 601 602 // get current index value 603 uint32_t current = boot_remote_lw( current_xp ); 604 605 // increment current index 606 boot_remote_sw( current_xp , current + 1 ); 607 608 } // boot_remote_unlock() 609 610 -
trunk/tools/bootloader_tsar/boot_utils.h
r1 r6 1 /* 2 * boot_utils.h - TSAR bootloader utilities definition. 3 * 4 * Authors : Alain Greiner / Vu Son (2016) 5 * 6 * Copyright (c) UPMC Sorbonne Universites 7 * 8 * This file is part of ALMOS-MKH. 9 * 10 * ALMOS-MKH is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; version 2.0 of the License. 13 * 14 * ALMOS-MKH is distributed in the hope that it will be useful, but 15 * WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with ALMOS-MKH; if not, write to the Free Software Foundation, 21 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 */ 23 1 24 /**************************************************************************** 2 25 * This file defines various utility functions for the boot code. * … … 26 49 27 50 /**************************************************************************** 28 * This function reads an aligned 32-bit word from another memory address * 29 * space. * 30 * @ xp : extended pointer to the distant memory location to be read * 31 * from. * 32 * * 33 * @ returns the value read. * 51 * This function reads an aligned 32-bit word from a remote cluster. 52 * @ xp : extended pointer to the distant memory location. 53 * @ returns the value read. 34 54 ****************************************************************************/ 35 55 uint32_t boot_remote_lw(xptr_t xp); 36 56 37 57 /**************************************************************************** 38 * This function writes an aligned 32-bit word in another memory address * 39 * space. * 40 * @ xp : extended pointer to the distant memory location to be written * 41 * to. * 42 * @ data : data value to be written to the distant memory location. * 58 * This function writes an aligned 32-bit word to a remote cluster. 59 * @ xp : extended pointer to the distant memory location. 60 * @ data : data value to be written. 43 61 ****************************************************************************/ 44 62 void boot_remote_sw(xptr_t xp, uint32_t data); 45 63 46 64 /**************************************************************************** 47 * This function atomically adds an value 'val' to the current value stored * 48 * at a distant memory location pointed to by the extended pointer 'xp'. * 49 * @ xp : extended pointer to the distant memory location whose value * 50 * is to be modified. * 51 * @ val : signed value to be added. * 52 * * 53 * @ returns the value stored at the distant memory location BEFORE the * 54 * atomic operation. * 65 * This function atomically adds a value 'val' to the current value stored 66 * in a remote cluster. 67 * @ xp : extended pointer to the distant memory location. 68 * @ val : signed value to be added. 69 * @ returns the value stored BEFORE the atomic operation. 55 70 ****************************************************************************/ 56 71 int32_t boot_remote_atomic_add(xptr_t xp, int32_t val); 57 72 58 73 /**************************************************************************** 59 * This function copies 'size' bytes from the buffer pointed to by 'src' *60 * to the buffer pointed to by 'dest'. These 2 addresses may be in any *61 * different memory address spaces. *62 * @ dest : extended pointer to the destination buffer. *63 * @ src : extended pointer to the source buffer. *64 * @ size : size of memory block to be copied (in bytes). *65 ****************************************************************************/ 66 void boot_remote_memcpy(xptr_t dest, xptr_t src, u nsigned int size);74 * This function copies 'size' bytes from the buffer pointed to by 'src' 75 * to the buffer pointed to by 'dest'. These 2 addresses may be in any 76 * different memory address spaces. 77 * @ dest : extended pointer to the destination buffer. 78 * @ src : extended pointer to the source buffer. 79 * @ size : size of memory block to be copied (in bytes). 80 ****************************************************************************/ 81 void boot_remote_memcpy(xptr_t dest, xptr_t src, uint32_t size); 67 82 68 83 /**************************************************************************** … … 71 86 72 87 /**************************************************************************** 73 * This function atomically adds an value 'val' to the current variable * 74 * pointed to by 'ptr'. It only returns when the atomic operation is * 75 * successful. * 76 * @ ptr : pointer to the variable to be modified. * 77 * @ val : signed value to be added. * 78 * * 79 * @ returns the value of the variable BEFORE the atomic operation. * 88 * This function atomically adds an value 'val' to the current variable 89 * pointed to by 'ptr'. It only returns when the atomic operation is 90 * successful. 91 * @ ptr : pointer to the variable to be modified. 92 * @ val : signed value to be added. 93 * @ returns the value of the variable BEFORE the atomic operation. 80 94 ****************************************************************************/ 81 95 int32_t boot_atomic_add(int32_t* ptr, int32_t val); … … 86 100 87 101 /**************************************************************************** 88 * This function performs a local memory copy (destination and source *89 * addresses are in the same memory space) of 'size' bytes from 'src' *90 * address to 'dest' address. *91 * @ dest : destination physical address, *92 * @ src : source physical address, *93 * @ size : size of memory block to be copied in bytes. *94 ****************************************************************************/ 95 void boot_memcpy(void* dest, void* src, u nsigned int size);96 97 /**************************************************************************** 98 * This function fills the first 'size' bytes of the local memory area, *99 * pointed to by 'base' with a constant value 'val'. *100 * @ base : base address of the memory area to be initialized, *101 * @ val : value of the constant byte to initialize the area, *102 * @ size : size of memory block to be filled in bytes. *103 ****************************************************************************/ 104 void boot_memset(void* base, int val, u nsigned int size);102 * This function performs a local memory copy (destination and source 103 * addresses are in the same memory space) of 'size' bytes from 'src' 104 * address to 'dest' address. 105 * @ dest : destination physical address, 106 * @ src : source physical address, 107 * @ size : size of memory block to be copied in bytes. 108 ****************************************************************************/ 109 void boot_memcpy(void* dest, void* src, uint32_t size); 110 111 /**************************************************************************** 112 * This function fills the first 'size' bytes of the local memory area, 113 * pointed to by 'base' with a constant value 'val'. 114 * @ base : base address of the memory area to be initialized, 115 * @ val : value of the constant byte to initialize the area, 116 * @ size : size of memory block to be filled in bytes. 117 ****************************************************************************/ 118 void boot_memset(void* base, int val, uint32_t size); 105 119 106 120 /**************************************************************************** … … 109 123 110 124 /**************************************************************************** 111 * This function converts the letter 'c' to lower case, if possible. * 112 * @ c : letter to be converted. * 113 * * 114 * @ returns the converted letter, or 'c' if the conversion was not * 115 * possible. * 125 * This function converts the letter 'c' to lower case, if possible. 126 * @ c : letter to be converted. 127 * @ returns the converted letter, or 'c' if conversion not possible. 116 128 ****************************************************************************/ 117 129 static inline unsigned char boot_to_lower(unsigned char c) … … 122 134 123 135 /**************************************************************************** 124 * This function converts the letter 'c' to upper case, if possible. * 125 * @ c : letter to be converted. * 126 * * 127 * @ returns the converted letter, or 'c' if the conversion was not * 128 * possible. * 136 * This function converts the letter 'c' to upper case, if possible. 137 * @ c : letter to be converted. 138 * @ returns the converted letter, or 'c' if conversion not possible. 129 139 ****************************************************************************/ 130 140 static inline unsigned char boot_to_upper(unsigned char c) … … 135 145 136 146 /**************************************************************************** 137 * This function copies the string pointed to by 'src' (the terminating *138 * null byte '\0' NOT included) to the buffer pointed to by 'dest'. *139 * @ src : pointer to the string to be copied. *140 * @ dest : pointer to the destination string. *147 * This function copies the string pointed to by 'src' (the terminating 148 * null byte '\0' NOT included) to the buffer pointed to by 'dest'. 149 * @ src : pointer to the string to be copied. 150 * @ dest : pointer to the destination string. 141 151 ****************************************************************************/ 142 152 void boot_strcpy(char* dest, char* src); 143 153 144 154 /**************************************************************************** 145 * This function calculates the length of the string pointed to by 's', * 146 * excluding the terminating null byte '\0'. * 147 * @ s : pointer to the string whose length is to be computed. * 148 * * 149 * @ returns the number of bytes in the string. * 150 ****************************************************************************/ 151 unsigned int boot_strlen(char* s); 152 153 /**************************************************************************** 154 * This function compares the 2 strings pointed to by 's1' and 's2'. * 155 * @ s1 : pointer to the first string to be compared. * 156 * @ s2 : pointer to the second string to be compared. * 157 * * 158 * @ returns 0 if these 2 strings match, 1 otherwise. * 155 * This function calculates the length of the string pointed to by 's', 156 * excluding the terminating null byte '\0'. 157 * @ s : pointer to the string whose length is to be computed. 158 * @ returns the number of bytes in the string. 159 ****************************************************************************/ 160 uint32_t boot_strlen(char* s); 161 162 /**************************************************************************** 163 * This function compares the 2 strings pointed to by 's1' and 's2'. 164 * @ s1 : pointer to the first string to be compared. 165 * @ s2 : pointer to the second string to be compared. 166 * @ returns 0 if these 2 strings match, 1 otherwise. 159 167 ****************************************************************************/ 160 168 int boot_strcmp(char* s1, char* s2); … … 165 173 166 174 /**************************************************************************** 167 * This function writes the NUL terminated string pointed to by 'str' to *168 * t he boot TTY terminal. *169 * @ str : pointer to the string to be printed on the boot TTY terminal. *175 * This function writes the NUL terminated string pointed to by 'str' 176 * to the boot TTY terminal. 177 * @ str : pointer to the string to be printed on the boot TTY terminal. 170 178 ****************************************************************************/ 171 179 void boot_puts(char* str); 172 180 173 181 /**************************************************************************** 174 * This function produces output, according to the 'format' format, to the *175 * boot TTY terminal. *176 * @ format : the string defining the format of the output. It is composed *177 * of 0 or more directives: *178 * - ordinary characters (not %), which are copied unchanged to *179 * the boot TTY terminal. *180 * - conversion specifications (introduced by the character %, *181 * ended by a conversion specifier), each of which results in *182 * fetching 0 or more subsequent arguments. The arguments must *183 * correspond properly (after type promotion) with the *184 * conversion specifier. *185 * *186 * Conversion specifiers: *187 * - %d : 32-bit signed decimal notation of an integer, *188 * - %u : 32-bit unsigned decimal notation of an integer, *189 * - %x : 32-bit unsigned hexadecimal notation of an integer, *190 * - %l : 64-bit unsigned hexadecimal notation of an integer, *191 * - %c : character, *192 * - %s : NUL terminated string. *182 * This function produces output, according to the 'format' format, to the 183 * boot TTY terminal. 184 * @ format : the string defining the format of the output. It is composed 185 * of 0 or more directives: 186 * - ordinary characters (not %), which are copied unchanged to 187 * the boot TTY terminal. 188 * - conversion specifications (introduced by the character %, 189 * ended by a conversion specifier), each of which results in 190 * fetching 0 or more subsequent arguments. The arguments must 191 * correspond properly (after type promotion) with the 192 * conversion specifier. 193 * 194 * Conversion specifiers: 195 * - %d : 32-bit signed decimal notation of an integer, 196 * - %u : 32-bit unsigned decimal notation of an integer, 197 * - %x : 32-bit unsigned hexadecimal notation of an integer, 198 * - %l : 64-bit unsigned hexadecimal notation of an integer, 199 * - %c : character, 200 * - %s : NUL terminated string. 193 201 ****************************************************************************/ 194 202 void boot_printf(char* format, ...); … … 199 207 200 208 /**************************************************************************** 201 * This function causes a termination during the boot procedure once the *202 * boot code detects an error. *209 * This function causes a termination during the boot procedure once the 210 * boot code detects an error. 203 211 ****************************************************************************/ 204 212 void boot_exit() __attribute__((noreturn)); 205 213 206 214 /**************************************************************************** 207 * This function returns the cycle count stored in the CP0_COUNT register * 208 * of the currently running processor. * 209 * * 210 * @ returns the processor cycle count. * 211 ****************************************************************************/ 212 unsigned int boot_get_proctime(); 213 214 /**************************************************************************** 215 * This function returns the global hardware identifier gid stored in the * 216 * CP0_PROCID register of the currently running processor. * 217 * * 218 * @ returns the processor gid. * 219 ****************************************************************************/ 220 unsigned int boot_get_procid(); 221 222 /**************************************************************************** 223 * This structure defines a toggling barrier, that can be used to * 224 * synchronize a group of cores, whether or not they are in a same cluster, * 225 * without any specific initialization. * 226 ****************************************************************************/ 227 typedef struct boot_barrier_s 215 * This function returns the cycle count stored in the CP0_COUNT register 216 * of the currently running processor. 217 * @ returns the processor cycle count. 218 ****************************************************************************/ 219 uint32_t boot_get_proctime(); 220 221 /**************************************************************************** 222 * This function returns the global hardware identifier gid stored in the 223 * CP0_PROCID register of the currently running processor. 224 * @ returns the processor gid 225 ****************************************************************************/ 226 uint32_t boot_get_procid(); 227 228 /**************************************************************************** 229 * This structure defines a toggling barrier, that can be used to 230 * synchronize a group of cores, whether or not they are in a same cluster, 231 * without any specific initialization. 232 ****************************************************************************/ 233 typedef struct boot_remote_barrier_s 228 234 { 229 235 uint32_t current; // Number of arrived cores … … 231 237 uint32_t pad[(CACHE_LINE_SIZE>>2)-2]; // Padding 232 238 } 233 boot_barrier_t; 234 235 /**************************************************************************** 236 * This function blocks all processors arriving at the barrier pointed to * 237 * by the extend pointer 'xp_barrier' and only returns when all 'count' * 238 * expected processors reach the barrier. * 239 * @ xp_barrier : extended pointer to a toggling barrier. * 240 * @ count : number of expected processors. * 241 ****************************************************************************/ 242 void boot_barrier( xptr_t xp_barrier, 243 uint32_t count ); 239 boot_remote_barrier_t; 240 241 /**************************************************************************** 242 * This function blocks all processors arriving at the barrier pointed to 243 * by the extend pointer 'xp_barrier' and only returns when all 'count' 244 * expected processors reach the barrier. 245 * @ xp_barrier : extended pointer to a toggling barrier. 246 * @ count : number of expected processors. 247 ****************************************************************************/ 248 void boot_remote_barrier( xptr_t xp_barrier, 249 uint32_t count ); 250 251 /**************************************************************************** 252 * This structure defines a remote queuing spinlock, that can be used to 253 * synchronize a group of cores, whether or not they are in a same cluster, 254 * without any specific initialization. 255 ****************************************************************************/ 256 typedef struct boot_remote_spinlock_s 257 { 258 uint32_t ticket; // next free ticket index 259 uint32_t current; // current owner index 260 uint32_t pad[(CACHE_LINE_SIZE>>2)-2]; // Padding 261 } 262 boot_remote_spinlock_t; 263 264 /**************************************************************************** 265 * This blocking function returns only when the lock is successfully taken. 266 * @ lock_xp : extended pointer on lock. 267 ****************************************************************************/ 268 void boot_remote_lock( xptr_t lock_xp ); 269 270 /**************************************************************************** 271 * This function release the lock. 272 * @ lock_xp : extended pointer on lock. 273 ****************************************************************************/ 274 void boot_remote_unlock( xptr_t lock_xp ); 244 275 245 276
Note: See TracChangeset
for help on using the changeset viewer.