Changeset 6


Ignore:
Timestamp:
Apr 26, 2017, 2:14:33 PM (4 years ago)
Author:
alain
Message:

Modify the boot_info_t struct to describe external peripherals in all clusters.

Location:
trunk/tools
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/arch_info/arch_classes.py

    r1 r6  
    1313#  It handle 4 types of objects: clusters, cores, devices and irqs.
    1414#  - The number of cluster is variable (can be one).
    15 #  - The cluster topology can be a 2D mesh or a simpla array.
     15#  - The cluster topology can be a 2D mesh or a simple 1D array.
    1616#  - The number of cores per cluster is variable (can be zero).
    1717#  - The number of addressable devices per cluster is variable.
     
    4141#########################################################################################
    4242# 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.
    4444#########################################################################################
    4545
    4646DEVICE_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
    6863    ]
    6964   
    7065DEVICE_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
    9282    ]
    9383
     
    10494                  x_width,           # number of bits for x coordinate
    10595                  y_width,           # number of bits for y coordinate
    106                   irqs_per_core,     # number or IRQs from XCU to one core
     96                  irqs_per_core,     # number or IRQs from ICU to one core
    10797                  io_cxy,            # IO cluster identifier
    10898                  boot_cxy,          # boot cluster identifier
     
    186176    ################################   add an input IRQ in a device
    187177    def addIrq( self,
    188                 dstdev,                # destination device (PIC or XCU)
     178                dstdev,                # destination device (PIC or ICU)
    189179                port,                  # input IRQ port index
    190180                srcdev,                # source device
     
    192182                is_rx = False ):       # I/O operation direction
    193183
    194         assert (dstdev.ptype == 'XCU') or (dstdev.ptype == 'PIC')
     184        assert (dstdev.ptype == 'ICU_XCU') or (dstdev.ptype == 'PIC_TSR')
    195185        assert (port < dstdev.arg0)
    196186
     
    382372        ram_size     = 0
    383373
    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
    393378
    394379        nb_fbf       = 0
     
    419404        mmc_size     = 0
    420405
    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
    432410
    433411        nb_nic       = 0
     
    436414        nic_size     = 0
    437415
     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
    438437        nb_pic       = 0
    439438        pic_channels = 0
     
    441440        pic_size     = 0
    442441
    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
    473446
    474447        # get devices attributes
     
    476449            for device in cluster.devices:
    477450
    478                 if ( device.ptype == 'RAM' ):
     451                if ( device.ptype == 'RAM_SCL' ):
    479452                    ram_base     = device.base
    480453                    ram_size     = device.size
     
    482455                    nb_ram +=1
    483456               
    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' ):
    497464                    fbf_base     = device.base
    498465                    fbf_size     = device.size
     
    502469                    nb_fbf +=1
    503470
    504                 elif ( device.ptype == 'IOB' ):
     471                elif ( device.ptype == 'IOB_TSR' ):
    505472                    iob_base     = device.base
    506473                    iob_size     = device.size
     
    532499                    use_ioc_spi  = True
    533500                    nb_ioc += 1
    534 
    535501                elif ( device.ptype == 'IOC_RDK' ):
    536502                    ioc_base     = device.base
     
    540506                    nb_ioc += 1
    541507
    542                 elif ( device.ptype == 'MMC' ):
     508                elif ( device.ptype == 'MMC_TSR' ):
    543509                    mmc_base     = device.base
    544510                    mmc_size     = device.size
     
    546512                    nb_mmc +=1
    547513
    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' ):
    598521                    nic_base     = device.base
    599522                    nic_size     = device.size
     
    601524                    nb_nic +=1
    602525
    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' ):
    604549                    pic_base     = device.base
    605550                    pic_size     = device.size
    606551                    pic_channels = device.channels
    607552                    nb_pic +=1
    608 
    609                 elif ( device.ptype == 'TIM' ):
    610                     tim_base     = device.pseg.base
    611                     tim_size     = device.pseg.size
    612                     tim_channels = device.channels
    613                     nb_tim +=1
    614 
    615                 elif ( device.ptype == 'TTY' ):
    616                     tty_base     = device.base
    617                     tty_size     = device.size
    618                     tty_channels = device.channels
    619                     nb_tty +=1
    620 
    621                 elif ( device.ptype == 'XCU' ):
    622                     xcu_base     = device.base
    623                     xcu_size     = device.size
    624                     xcu_channels = device.channels
    625                     xcu_arg0     = device.arg0
    626                     xcu_arg1     = device.arg1
    627                     xcu_arg2     = device.arg2
    628                     nb_xcu +=1
    629 
    630         # no more than two access to external devices
    631         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 )
    638553
    639554        # one and only one IOC controller
     
    647562            rdk_base = 0
    648563            rdk_size = 0
    649 
    650         # only one type of MWR controller
    651         nb_mwr_types = 0
    652         if use_mwr_gcd:       nb_mwr_types += 1
    653         if use_mwr_dct:       nb_mwr_types += 1
    654         if use_mwr_cpy:       nb_mwr_types += 1
    655         if ( nb_mwr > 0 ) : assert ( nb_mwr_types == 1 )
    656564
    657565        # Compute total number of cores, devices and irqs
     
    697605        s += '/* Peripherals */\n'
    698606        s += '\n'
    699         s += '#define NB_TTY_CHANNELS        %d\n'    % tty_channels
     607        s += '#define NB_TXT_CHANNELS        %d\n'    % txt_channels
    700608        s += '#define NB_IOC_CHANNELS        %d\n'    % ioc_channels
    701609        s += '#define NB_NIC_CHANNELS        %d\n'    % nic_channels
    702         s += '#define NB_CMA_CHANNELS        %d\n'    % cma_channels
    703610        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 )
    709613        s += '#define USE_IOB                %d\n'    % ( nb_iob != 0 )
    710614        s += '#define USE_PIC                %d\n'    % ( nb_pic != 0 )
    711615        s += '#define USE_FBF                %d\n'    % ( nb_fbf != 0 )
    712616        s += '#define USE_NIC                %d\n'    % ( nb_nic != 0 )
     617        s += '#define USE_DMA                %d\n'    % ( nb_dma != 0 )
    713618        s += '\n'
    714619        s += '#define USE_IOC_BDV            %d\n'    % use_ioc_bdv
     
    718623        s += '#define USE_IOC_RDK            %d\n'    % use_ioc_rdk
    719624        s += '\n'
    720         s += '#define USE_MWR_GCD            %d\n'    % use_mwr_gcd
    721         s += '#define USE_MWR_DCT            %d\n'    % use_mwr_dct
    722         s += '#define USE_MWR_CPY            %d\n'    % use_mwr_cpy
    723         s += '\n'
    724625        s += '#define FBUF_X_SIZE            %d\n'    % fbf_arg0
    725626        s += '#define FBUF_Y_SIZE            %d\n'    % fbf_arg1
    726627        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
    736632        s += '\n'
    737633
     
    741637        s += '#define SEG_RAM_SIZE           0x%x\n'  % ram_size
    742638        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
    745650        s += '\n'
    746651        s += '#define SEG_DMA_BASE           0x%x\n'  % (dma_base & local_physical_mask)
    747652        s += '#define SEG_DMA_SIZE           0x%x\n'  % dma_size
    748653        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_size
    751         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_size
    754         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_size
    757         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_size
    760         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_size
    763         s += '\n'
    764654        s += '#define SEG_ROM_BASE           0x%x\n'  % (rom_base & local_physical_mask)
    765655        s += '#define SEG_ROM_SIZE           0x%x\n'  % rom_size
     
    777667        s += '#define SEG_TIM_SIZE           0x%x\n'  % tim_size
    778668        s += '\n'
    779         s += '#define SEG_TTY_BASE           0x%x\n'  % (tty_base & local_physical_mask)
    780         s += '#define SEG_TTY_SIZE           0x%x\n'  % tty_size
    781         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_size
     669        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
    784674        s += '\n'
    785675        s += '#define SEG_RDK_BASE           0x%x\n'  % (rdk_base & local_physical_mask)
    786676        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_size
    790677        s += '\n'
    791678        s += '#endif\n'
     
    931818        self.arg2     = arg2          # optional (semantic depends on ptype)
    932819        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)
    934821        self.irq_ctrl = None          # interrupt controller for this device
    935822        return
     
    946833        s += ' arg2="%d"'                    % self.arg2
    947834        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') ):
    949836            s += ' >\n'
    950837            for irq in self.irqs: s += irq.xml()
     
    958845
    959846        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)
    962849
    963850        # check index
     
    985872
    986873        byte_stream = bytearray()
    987         byte_stream += mapping.int2bytes(4,ptype_id)       # device type
    988874        byte_stream += mapping.int2bytes(8,self.base)      # segment base address
    989875        byte_stream += mapping.int2bytes(8,self.size)      # segment size
     876        byte_stream += mapping.int2bytes(4,ptype_id)       # device type
    990877        byte_stream += mapping.int2bytes(4,self.channels)  # number of channels
    991878        byte_stream += mapping.int2bytes(4,self.arg0)      # optionnal arg0
     
    997884
    998885        if ( verbose ):
    999             print 'ptype      = %d' %  ptype_id
    1000886            print 'base       = %x' %  self.base
    1001887            print 'size       = %x' %  self.size
     
    1034920
    1035921        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)
    1038924
    1039925        # check index
     
    1041927            print '[genarch error] in Irq.cbin()'
    1042928            print '    irq global index = %d / expected = %d' \
    1043                        % (self.index,expected)
     929                       % (self.index , expected)
    1044930            sys.exit(1)
    1045931
  • trunk/tools/arch_info/arch_info.h

    r1 r6  
    6363 * The 16 MSB bits define the functionnal type.
    6464 * The 16 LSB bits define the implementation type.
    65  * It must be consistent with values defined in file arch_class.py
     65 * It must be consistent with values defined in files arch_class.py, and device.*
    6666 ***************************************************************************************/
    6767
    6868enum deviceTypes
    6969{
    70     DEV_TYPE_RAM       = 0x00000000,
    71     DEV_TYPE_DMA       = 0x00010000,
    72     DEV_TYPE_FBF       = 0x00020000,
    73     DEV_TYPE_IOB       = 0x00030000,
     70    DEV_TYPE_RAM_SCL   = 0x00000000,
     71    DEV_TYPE_ROM_SCL   = 0x00010000,
     72    DEV_TYPE_FBF_SCL   = 0x00020000,
     73    DEV_TYPE_IOB_TSR   = 0x00030000,
    7474    DEV_TYPE_IOC_BDV   = 0x00040000,
    7575    DEV_TYPE_IOC_HBA   = 0x00040001,
     
    7777    DEV_TYPE_IOC_SPI   = 0x00040003,
    7878    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,
    9186};
    9287
     
    143138{
    144139    uint32_t    gid;             // core hardware identifier
     140    uint16_t    cxy;             // cluster identifier         
    145141    uint16_t    lid;             // core local index in cluster
    146     uint16_t    cxy;             // cluster identifier         
    147142}
    148143archinfo_core_t;
     
    154149typedef struct __attribute__((packed))  archinfo_device_s
    155150{
     151    uint64_t    base;            // base address in physical space
     152    uint64_t    size;            // channel size (bytes)
    156153    uint32_t    type;            // supported values defined above
    157     uint64_t    base;            // base address in physical space
    158     uint64_t    size;            // size (bytes)
    159154    uint32_t    channels;        // number of channels
    160155    uint32_t    arg0;            // semantic depends on device type
     
    162157    uint32_t    arg2;            // semantic depends on device type
    163158    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)
    165160    uint32_t    irq_offset;      // global index of first IRQ
    166161}
  • trunk/tools/arch_info/boot_info.h

    r1 r6  
    3232 ********************************************************************************************/
    3333
    34 #define BOOT_INFO_SIGNATURE    0xBABEF00D
     34#define BOOT_INFO_SIGNATURE    0x12344321
    3535
    3636/*********************************************************************************************
     
    6969typedef struct boot_device_s
    7070{
     71    uint64_t    base;                 /*! segment physical base address                     */
     72    uint64_t    size;                 /*! channel size (bytes)                              */
    7173    uint32_t    type;                 /*! peripheral type (func | impl)                     */
    72     xptr_t      base;                 /*! segment global base address                       */
    73     uint64_t    size;                 /*! channel size (bytes)                              */
    7474    uint32_t    channels;             /*! number of channels                                */
    7575    uint32_t    param0;               /*! semantic depends on peripherat type               */
     
    9090typedef struct boot_info_s
    9191{
    92     uint32_t      signature;         /*! boot info signature                                */
     92    uint32_t      signature;                     /*! boot info signature                    */
    9393
    9494    // global platform parameters
    9595
    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                  */
    102102
    103     // specific cluster parameters
     103    // shared resources
    104104
    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   */
    112117
    113118    // kernel segments
    114119
    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)    */
    119124}
    120125boot_info_t;
  • trunk/tools/arch_info/genarch.py

    r1 r6  
    2323#  --nb_ttys=int     : number of TTY channels
    2424#  --nb_nics=int     : number of NIC channels
    25 #  --nb_cmas=int     : number of CMA channels
    2625#  --fbf_size=int    : frame buffer width & heigth
    2726#  --ioc_type=string : can be IOC_BDV , IOC_HBA , IOC_SDC , IOC_SPI
    28 #  --mwr_type=string : can be MWR_GCD , MWR_DCT , MWR_CPY
    2927#  --io_cxy=int      : IO cluster identifier
    3028#  --boot_cxy=int    : boot cluster identifier
     
    7674                   help = 'define number ot NIC channels' )
    7775
    78 parser.add_option( '--nb_cmas', type = 'int', dest = 'nb_cmas',
    79                    default = 2,
    80                    help = 'define number ot CMA channels' )
    81 
    8276parser.add_option( '--fbf_size', type = 'int', dest = 'fbf_size',
    8377                   default = 128,
     
    8781                   default = 'IOC_BDV',
    8882                   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' )
    9383
    9484parser.add_option( '--io_cxy', type = 'int', dest = 'io_cxy',
     
    129119fbf_size       = options.fbf_size    # frame buffer width & heigth
    130120nb_nics        = options.nb_nics     # number of NIC channels           
    131 nb_cmas        = options.nb_cmas     # number of CMA channels           
    132121ioc_type       = options.ioc_type    # ioc controller type
    133 mwr_type       = options.mwr_type    # hardware coprocessor type
    134122io_cxy         = options.io_cxy      # IO cluster identifier
    135123boot_cxy       = options.boot_cxy    # boot cluster identifier
     
    163151                        nb_ttys,
    164152                        nb_nics,
    165                         nb_cmas,
    166153                        fbf_size,
    167154                        ioc_type,
    168                         mwr_type,
    169155                        io_cxy,
    170156                        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
    124/****************************************************************************
    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. *
    326 *                                                                          *
    427 * It supports clusterised shared memory multi-processor architectures,     *
     
    4770
    4871#include <elf-types.h>
     72#include <hal_types.h>
    4973
    5074#include <almos_config.h>
     
    5377#include <arch_info.h>
    5478#include <boot_info.h>
    55 
    56 #include <hal_types.h>
    5779
    5880#include <boot_utils.h>
     
    6284#include <boot_tty_driver.h>
    6385
    64 /****************************************************************************
    65  *                                 Macros.                                  *
     86/*****************************************************************************
     87 *                                 Macros.                             
    6688 ****************************************************************************/
    6789
     
    7092                            (~(PPM_PAGE_SIZE-1)))
    7193
    72 /****************************************************************************
    73  *                             Global variables.                            *
     94/*****************************************************************************
     95 *                             Global variables.                           
    7496 ****************************************************************************/
    7597
    7698// 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
     100volatile boot_remote_spinlock_t tty0_lock;       // protect TTY0 access
     101volatile boot_remote_barrier_t  global_barrier;  // synchronize CP0 cores
     102volatile boot_remote_barrier_t  local_barrier;   // synchronize cores in one cluster
     103uint32_t                        active_cp0s_nr;  // number of expected CP0s
     104 
     105// kernel segments layout variables
     106
     107uint32_t                        seg_kcode_base;  // kcode segment base address
     108uint32_t                        seg_kcode_size;  // kcode segment size (bytes)
     109uint32_t                        seg_kdata_base;  // kdata segment base address
     110uint32_t                        seg_kdata_size;  // kdata segment size (bytes)
     111uint32_t                        kernel_entry;    // kernel entry point
     112
     113// address used by the WTI to activate remote CP0s
     114
     115extern void                     boot_entry();    // boot_loader entry point
     116
     117/*********************************************************************************
     118 * This function returns the printable string for each device type
     119 ********************************************************************************/
    105120char * device_type_str( uint32_t dev_type )
    106121{
    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";
    111126    else if( dev_type == DEV_TYPE_IOC_BDV ) return "IOC_BDV";
    112127    else if( dev_type == DEV_TYPE_IOC_HBA ) return "IOC_HBA";
     
    114129    else if( dev_type == DEV_TYPE_IOC_SPI ) return "IOC_SPI";
    115130    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";
    129139}
    130140
    131 /****************************************************************************
     141/************************************************************************************
    132142 * This function loads the arch_info.bin file into the boot cluster memory.
    133  ****************************************************************************/
     143 ***********************************************************************************/
    134144static void boot_archinfo_load()
    135145{
     
    154164
    155165#if DEBUG_BOOT_INFO
    156 boot_printf("\n[BOOT] file %s loaded at %l\n",
    157             ARCHINFO_PATHNAME , ARCHINFO_BASE );
     166boot_printf("\n[BOOT INFO] in %s : file %s loaded at address = %x\n",
     167            __FUNCTION__ , ARCHINFO_PATHNAME , ARCHINFO_BASE );
    158168#endif
    159169
    160170} // boot_archinfo_load()
    161171
    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 *************************************************************************************/
    169178static void boot_kernel_load()
    170179{
    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
     194boot_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",
    200202                    KERNEL_PATHNAME);
    201203        boot_exit();
    202204    }
    203205
    204     /*
    205      * Initializing pointer to header which is the first element of the
    206      * .elf file.
    207      */
     206    // get pointer to kernel.elf header 
    208207    elf_header = (Elf32_Ehdr*)KERN_BASE;
    209208
    210     /* Signature problem, abort program !!! */
     209    // check signature
    211210    if ((elf_header->e_ident[EI_MAG0] != ELFMAG0)   ||
    212211        (elf_header->e_ident[EI_MAG1] != ELFMAG1)   ||
     
    220219    }
    221220
    222     /* Getting the program header table offset and the number of segments. */
     221    // Get program header table offset and number of segments
    223222    phdr_offset     = elf_header->e_phoff;
    224223    segments_nb     = elf_header->e_phnum;
    225224
    226     /* Getting the program header table pointer. */
     225    // Get program header table pointer
    227226    program_header  = (Elf32_Phdr*)(KERN_BASE + phdr_offset);
    228227
    229     /* Looking for loadable segments. */
     228    // loop on segments
     229    kcode_found = false;
     230    kdata_found = false;
    230231    for (seg_id = 0; seg_id < segments_nb; seg_id++)
    231232    {
    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
    234234        {
    235             // Getting its attributes.
     235            // Get segment attributes.
    236236            seg_paddr    = program_header[seg_id].p_paddr;   
    237237            seg_offset   = program_header[seg_id].p_offset;
     
    239239            seg_memsz    = program_header[seg_id].p_memsz;
    240240
    241             // Load it to its appropriate physical memory address.
     241            // get segment base address in buffer
    242242            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
     250boot_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
    246254
    247255            // 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;
    272294            }
    273295        }
    274296    }
    275297
    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
    277315    kernel_entry = (uint32_t)elf_header->e_entry;
    278316
     317#if DEBUG_BOOT_ELF
     318boot_printf("\n[BOOT INFO] %s successfully completed for file %s at cycle %d\n",
     319            __FUNCTION__ , KERNEL_PATHNAME , boot_get_proctime() );
     320#endif
     321
    279322} // boot_kernel_load()
    280323
    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 ************************************************************************************/
    286329static void boot_info_init( boot_info_t * boot_info,
    287330                            cxy_t         cxy )
    288331{
    289     archinfo_header_t  * header;       
     332    archinfo_header_t  * header;
    290333    archinfo_core_t    * core_base;     
    291334    archinfo_cluster_t * cluster_base;
     
    294337
    295338    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
    296342    archinfo_core_t    * core;
    297343    uint32_t             core_id;
     
    303349    boot_device_t      * boot_dev;
    304350
    305     // get pointer on ARCHINFO header
    306     header = (archinfo_header_t*)ARCHINFO_BASE;
     351#if DEBUG_BOOT_INFO
     352boot_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);
    307362
    308363    // Initialize global platform parameters
     
    315370
    316371    // 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
    329378    for (cluster =  cluster_base;
    330379         cluster < &cluster_base[header->x_size * header->y_size];
    331380         cluster++)
    332381    {
    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
     404boot_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) )
    347417        {
    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++;
    357431        }
    358432
    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
     434boot_printf("  - %s : base = %l / size = %l / channels = %d / irqs = %d\n",
    378435            device_type_str( device->type ) , device->base , device->size ,
    379436            device->channels , device->irqs );   
    380437#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;
    418455
    419456#if DEBUG_BOOT_INFO
     
    421458            irq->port , device_type_str( irq->dev_type ) , irq->channel , irq->is_rx );
    422459#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
     471boot_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
     485boot_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
     498boot_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
     528boot_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
     561boot_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;
    443582
    444583#if DEBUG_BOOT_INFO
     
    447586#endif
    448587
    449                 }
    450588            }
    451589        }
    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
    459598} // boot_info_init()
    460599
    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 **********************************************************************************/
    467605static void boot_check_core( boot_info_t * boot_info,
    468606                             lid_t         lid)
     
    490628} // boot_check_core()
    491629
    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.
    494632 * It returns the number of CP0s actually activated.
    495  ****************************************************************************/
    496 static uint32_t boot_wake_cp0()
     633 ********************************************************************************/
     634static uint32_t boot_wake_all_cp0s()
    497635{
    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
    508642
    509643    header       = (archinfo_header_t*)ARCHINFO_BASE;
     
    528662            continue;
    529663
    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
    532665        for (device = &device_base[cluster->device_offset];
    533666             device < &device_base[cluster->device_offset + cluster->devices];
    534667             device++)
    535668        {
    536             if (device->type == DEV_TYPE_XCU)
    537             {
     669            if (device->type == DEV_TYPE_ICU_XCU)
     670            {
     671
     672#if DEBUG_BOOT_WAKUP
     673boot_printf("\n[BOOT] core[%x][0] activated at cycle %d\n",
     674            cluster->cxy , boot_get_proctime );
     675#endif
     676
    538677                boot_remote_sw((xptr_t)device->base, (uint32_t)boot_entry);
    539678                cp0_nb++;
     
    545684} // boot_wake_cp0()
    546685
    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 *********************************************************************************/
     691static void boot_wake_local_cores(boot_info_t * boot_info)
    553692{
    554     boot_device_t*  device;         // Iterator on devices
    555     unsigned int    core_id;        // Iterator on cores
     693    boot_device_t *  device;         // Iterator on devices
     694    unsigned int     core_id;        // Iterator on cores
    556695
    557696    // 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];
    560699         device++)
    561700    {
    562         if (device->type == DEV_TYPE_XCU)
     701        if (device->type == DEV_TYPE_ICU_XCU)
    563702        {
    564703            // loop on cores
    565704            for (core_id = 1; core_id < boot_info->cores_nr; core_id++)
     705            {
     706
     707#if DEBUG_BOOT_WAKUP
     708boot_printf("\n[BOOT] core[%x][%d] activated at cycle %d\n",
     709             boot_info->cxy , core_id , boot_get_proctime() );
     710#endif
    566711                boot_remote_sw((xptr_t) (device->base + (core_id << 2)),
    567712                               (uint32_t)boot_entry);
     713            }
    568714        }
    569715    }
    570716} // boot_wake_local_cores()
    571717
    572 /****************************************************************************
    573  *                               API functions.                             *
    574  ****************************************************************************/
    575 
    576 /****************************************************************************
     718
     719/*********************************************************************************
    577720 * This main function of the boot-loader is called by the  boot_entry() 
    578721 * function, and executed by all cores.
    579722 * The arguments values are computed by the boot_entry code.
    580  * @ lid    : core local identifier in its cluster,
     723 * @ lid    : core local identifier,
    581724 * @ cxy    : cluster identifier,
    582  ****************************************************************************/
     725 *********************************************************************************/
    583726void boot_loader( lid_t lid,
    584727                  cxy_t cxy )
    585728{
    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
    588730
    589731    if (lid == 0)
    590732    {
    591         /**************************************
    592          * PHASE ONE: only bscpu executes it. *
    593          **************************************/
     733        /****************************************************
     734         * PHASE A : only CP0 in boot cluster executes it
     735         ***************************************************/
    594736        if (cxy == BOOT_CORE_CXY)
    595737        {
    596             boot_printf("\n[BOOT] Starting on core[%d] in cluster %x at 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() );
    598740
    599741            // Initialize IOC driver
    600742            if      (USE_IOC_BDV) boot_bdv_init();
    601743            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();
    606746            else if (!USE_IOC_RDK)
    607747            {
    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");
    611749                boot_exit();
    612750            }
    613751
    614             // Initialize simplified version of FAT32.
     752            // Initialize FAT32.
    615753            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() );
    616761
    617762            // Load the arch_info.bin file into memory.
    618763            boot_archinfo_load();
    619764
    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.
    624766            // 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
    628773            if (boot_info->signature != BOOT_INFO_SIGNATURE)
    629774            {
    630                 boot_printf("\n[BOOT] boot_loader(): "
    631                             "boot_info signature should 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 );
    633778                boot_exit();
    634779            }
    635780
    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() );
    643783
    644784            // Check core information.
    645785            boot_check_core(boot_info, lid);
    646786
    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 );
    703800        }
    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         *****************************************************************/
    707804        else
    708805        {
    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.
    732820            asm volatile("mtc2  %0, $25" :: "r"(cxy));
    733821
    734             // Copy the 'arch_info.bin' file into the local memory.
     822            // Copy the arch_info.bin file into the local memory.
    735823            boot_remote_memcpy(XPTR(cxy,           ARCHINFO_BASE),
    736824                               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;
    752845
    753846            // Initialize local boot_info_t structure.
    754             boot_info_init(boot_info, cxy);
     847            boot_info_init( boot_info , cxy );
    755848
    756849            // 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 );
    770864        }
    771865    }
     
    773867    {
    774868        /***************************************************************
    775          * PHASE THREE: all non CP0 cores in all clusters execute it.  *
     869         * PHASE C: all non CP0 cores in all clusters execute it
    776870         **************************************************************/
    777871
    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) );
    807903
    808904} // boot_loader()
  • trunk/tools/bootloader_tsar/boot_bdv_driver.c

    r1 r6  
    1212
    1313#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"
    1515#endif
    1616
    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"
    1927#endif
    2028
     
    3139static uint32_t boot_bdv_get_register( uint32_t reg )
    3240{
    33     cxy_t      cxy = IO_CXY;
     41    cxy_t      cxy = (X_IO << Y_WIDTH) + Y_IO;
    3442    uint32_t * ptr = (uint32_t *)SEG_IOC_BASE + reg;
    3543   
     
    4654                                   uint32_t val )
    4755{
    48     cxy_t      cxy = IO_CXY;
     56    cxy_t      cxy = (X_IO << Y_WIDTH) + Y_IO;
    4957    uint32_t * ptr = (uint32_t *)SEG_IOC_BASE + reg;
    5058
  • 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 ********************************************************************************/
    54
    65#ifndef _BOOT_CONFIG_H
     
    87
    98// Debug options
    10 #define DEBUG_BOOT_INFO     1
    11 #define DEBUG_BOOT_ELF      1
     9#define DEBUG_BOOT_INFO     0
     10#define DEBUG_BOOT_ELF      0
    1211#define DEBUG_BOOT_IOC      0
    13 #define DEBUG_BOOT_FAT32    1
    14 #define USE_FIXED_FORMAT    0
     12#define DEBUG_BOOT_WAKUP    1
     13#define DEBUG_BOOT_FAT32    0
    1514
    16 // io_cluster identifier
    17 #define IO_CXY              0
     15// Core identifier format
     16#define USE_FIXED_FORMAT    1
    1817
    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.          */
    2324
    2425// boot code temporary segment
    2526#define BOOT_BASE           0x100000        /* 'boot.elf' base address.     */
    26 #define BOOT_MAX_SIZE       0x100000        /* 'boot.elf' max size.         */
     27#define BOOT_MAX_SIZE       0x010000        /* 'boot.elf' max size.         */
    2728
    2829// arch_info temporary segment
    29 #define ARCHINFO_BASE       0x200000        /* 'arch_info.bin' base address */
    30 #define ARCHINFO_MAX_SIZE   0x200000        /* '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.    */
    3132
    3233// 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.       */
    3936
    4037// Temporary stacks segments
    4138#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)       */
    4640
    4741#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
    124/*************************************************************************************************
    225 * This file contains the entry point of the ALMOS-MK boot-loader for TSAR architecture.         *
     
    6184    mfc0    k0,     CP0_PROCID         
    6285    andi    k0,     k0,     0xFFF                       /* k0 <= gid                        */
    63     andi    t1,     k0,     ((1 << PADDR_WIDTH) - 1)    /* t1 <= lid                        */
    64     srl     t2,     k0,     PADDR_WIDTH                 /* t2 <= cxy                        */
     86    andi    t1,     k0,     ((1 << P_WIDTH) - 1)        /* t1 <= lid                        */
     87    srl     t2,     k0,     P_WIDTH                     /* t2 <= cxy                        */
    6588   
    66     /*
    67      * Initializing stack pointer from previously retrieved lid value.
    68      */
     89    /* Initialize stack pointer from previously retrieved lid value  */
    6990   
    7091    la      t0,     BOOT_STACK_BASE                     /* t0 <= BOOT_STACK_BASE            */
    7192    li      k1,     BOOT_STACK_SIZE                     /* k1 <= BOOT_STACK_SIZE            */
    7293    multu   k1,     t1
    73     mflo    k0,                                         /* k0 <= BOOT_STACK_SIZE * lid      */
     94    mflo    k0                                          /* k0 <= BOOT_STACK_SIZE * lid      */
    7495    subu    sp,     t0,     k0                          /* P[cxy,lid] stack top initialized */
    7596
    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  */
    7998
    8099    mtc2    t2,     CP2_DATA_PADDR_EXT
    81100
    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  */
    85102
    86103    or      a0,     zero,   t1                          /* a0 <= lid                        */     
     
    96113 *************/
    97114
    98     /*
    99      * Testing if this is bscpu.
    100      */
     115    /* Test if this is bscpu  */
    101116
    102117    mfc0    k0,     CP0_PROCID         
     
    108123    li      t4,     BOOT_CORE_CXY                       /* t4 <= bscpu cxy                  */
    109124
    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 */
    113126
    114127    la      t0,     ARCHINFO_BASE                       /* t0 <= ARCHINFO_BASE              */
     
    116129    addu    t2,     t0,     t1                          /* t2 <= ARCHINFO_CORE_BASE         */
    117130
    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?  */
    121132
    122133    li      t3,     0x8                                 /* t3 <= ARCHINFO_CORE_SIZE         */
     
    127138    addu    t2,     t2,     t3                          /* t2 <= @ next archinfo_core       */
    128139
    129     /*
    130      * Getting (cxy, lid) values from the found core descriptor.
    131      */
     140    /* Get (cxy, lid) values from the found core descriptor  */
    132141   
    133142    lw      t3,     -8(t2)                              /* t3 <= lid                        */
    134143    lw      t4,     -4(t2)                              /* t4 <= cxy                        */
    135144
    136     /*
    137      * Initializing stack pointer from previously retrieved lid value.
    138      */
     145    /* Initialize stack pointer from previously retrieved lid value  */
    139146
    140147bscpu_exit:   
     
    145152    subu    sp,     t0,     k0                          /* P[cxy,lid] stack top initialized */
    146153
    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  */
    150155
    151156    mtc2    t4,     CP2_DATA_PADDR_EXT
    152157
    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 */
    156159
    157160    or      a0,     zero,   t3                          /* a0 <= lid                        */     
  • trunk/tools/bootloader_tsar/boot_fat32.c

    r1 r6  
    148148{
    149149#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",
    151151                __FUNCTION__ , boot_get_proctime() );
    152152#endif
     
    163163
    164164#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",
    166166                __FUNCTION__ , boot_get_proctime() );
    167167#endif
     
    197197
    198198#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",
    200200                __FUNCTION__ , boot_fat.free_clusters_nr , boot_fat.free_cluster_hint );
    201201#endif
     
    430430
    431431#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",
    433433                __FUNCTION__ , path_component , pathname , boot_get_proctime() );
    434434#endif
     
    592592
    593593#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",
    595595                __FUNCTION__ , pathname, boot_get_proctime());
    596596#endif
     
    615615        while ( found == 0 )
    616616        {
    617 
    618 boot_printf("\n!!! enter second while for <%s> path_comp\n", path_comp );
    619 
    620617            cluster_lba = cluster_to_lba( parent_cluster );
    621618           
     
    646643                if (ord == LAST_ENTRY)             // no more entry in this directory
    647644                {
    648 
    649 boot_printf("\n@@@ for <%s> component / offset = %d : last entry\n", path_comp , offset );
    650 
    651645                    found = 2;
    652646                }
     
    654648                else if (ord == FREE_ENTRY)        // unused, check the next entry
    655649                {
    656 
    657 boot_printf("\n@@@ for <%s> component / offset = %d : free entry\n", path_comp , offset );
    658 
    659650                    continue;
    660651                }
     
    672663                    get_name_from_long(entry, buffer_lfn);
    673664
    674 boot_printf("\n@@@ for <%s> component / offset = %d : LFN entry = %s\n",
    675             path_comp , offset , buffer_lfn );
    676 
    677665                    // Append this portion of the name to the full name buffer
    678666                    boot_strcpy(name + 13 * (lfn_seq_order-1) , buffer_lfn);
     
    685673                {
    686674                    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 );
    690675
    691676                    // check if the full name is what we are looking for.
     
    725710        } // end second while for one component in pathname
    726711       
    727 boot_printf("\n### exit hwile fpr component <%s>\n", path_comp );
    728 
    729712        // Check the result of this path component search.
    730713        if (found == 2)
     
    755738
    756739#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 );
    760743#endif
    761744
     
    771754int boot_fat32_init()
    772755{
    773 
    774 boot_printf("@@@ BEFORE_VALUE = %x\n", FAT_MAGIC_VALUE);
    775 
    776756    // FAT32 initialization should be done only once
    777757    if (boot_fat.initialized == FAT_MAGIC_VALUE)
     
    783763
    784764#if DEBUG_BOOT_FAT32   
    785 boot_printf("\n[BOOT] %s: Enters at cycle %d\n",
     765boot_printf("\n[BOOT INFO] %s: Enters at cycle %d\n",
    786766            __FUNCTION__ , boot_get_proctime() );
    787767#endif
     
    799779
    800780#if DEBUG_BOOT_FAT32   
    801 boot_printf("\n[BOOT] %s: Boot Sector loaded at cycle %d\n",
     781boot_printf("\n[BOOT INFO] %s: Boot Sector loaded at cycle %d\n",
    802782            __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] );
    806783#endif
    807784
     
    865842    boot_fat.initialized    = FAT_MAGIC_VALUE;
    866843
    867 boot_printf("@@@ AFTER_VALUE = %x\n", FAT_MAGIC_VALUE);
    868 
    869 fat32_desc_display();
    870    
    871844    // Set information from FS Information Sector
    872845    if (set_fsi()) return -1;
     
    878851#if DEBUG_BOOT_FAT32   
    879852    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() );
    882855#endif
    883856
     
    907880
    908881#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",
    910883                __FUNCTION__ , pathname, boot_get_proctime() );
    911884#endif
     
    973946
    974947#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 );
    978951#endif
    979952
  • trunk/tools/bootloader_tsar/boot_hba_driver.c

    r1 r6  
    77
    88#include <boot_config.h>
     9#include <hard_config.h>
    910#include <boot_hba_driver.h>
    1011#include <boot_mmc_driver.h>
     
    1516#endif
    1617
    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"
    1928#endif
    2029
     
    4756static uint32_t boot_hba_get_register(uint32_t reg)
    4857{
    49     cxy_t      cxy = IO_CXY;
     58    cxy_t      cxy = (X_IO << Y_WIDTH) + Y_IO;
    5059    uint32_t * ptr = (uint32_t *)SEG_IOC_BASE + reg;
    5160   
     
    6170void boot_hba_set_register(uint32_t reg, uint32_t val)
    6271{
    63     cxy_t      cxy = IO_CXY;
     72    cxy_t      cxy = (X_IO << Y_WIDTH) + Y_IO;
    6473    uint32_t * ptr = (uint32_t *)SEG_IOC_BASE + reg;
    6574
  • 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 */
    723
    824#include <boot_config.h>
     
    1127#include <boot_utils.h>
    1228
    13 #ifndef SEG_TTY_BASE
    14 # error "The SEG_TTY_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"
    1531#endif
    1632
    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"
    1943#endif
    2044
    2145
    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/////////////////////////////////////////////////////////////////////////////
    3151static uint32_t boot_tty_get_register( uint32_t reg )
    3252{
    33     cxy_t      cxy = IO_CXY;
    34     uint32_t * ptr = (uint32_t *)SEG_TTY_BASE + reg;
     53    cxy_t      cxy = (X_IO << Y_WIDTH) + Y_IO;
     54    uint32_t * ptr = (uint32_t *)SEG_TXT_BASE + reg;
    3555   
    3656    return boot_remote_lw( XPTR( cxy , ptr ) );
     
    3858} // boot_tty_get_register()
    3959
    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/////////////////////////////////////////////////////////////////////////////
    4565static void boot_tty_set_register( uint32_t reg,
    4666                                   uint32_t val )
    4767{
    48     cxy_t      cxy = IO_CXY;
    49     uint32_t * ptr = (uint32_t *)SEG_TTY_BASE + reg;
     68    cxy_t      cxy = (X_IO << Y_WIDTH) + Y_IO;
     69    uint32_t * ptr = (uint32_t *)SEG_TXT_BASE + reg;
    5070
    5171    boot_remote_sw( XPTR( cxy , ptr ) , val );
     
    5373} // boot_tty_set_register()
    5474
    55 /****************************************************************************
    56  *                           Driver API functions.                          *
    57  ****************************************************************************/
    58 
     75//////////////////////////////////
    5976int boot_tty_write( char    * buf,
    6077                    uint32_t  nbytes )
    6178{
    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;
    6582
    66     /* Printing to the boot TTY terminal. */
     83    // Print nbytes to TTY0 terminal
    6784    for (nb_printed = 0; nb_printed < nbytes; nb_printed++)
    6885    {
    69         // Polling the TTY driver status.
    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))
    7188        {
    72             // TTY_WRITE_BUSY bit of TTY_STATUS register is set, keeps polling.
    7389            error = 1;
    7490            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)
    7693                {
    7794                    error = 0;
    7895                    break;
    7996                }
     97            }
    8098
    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;
    85101        }
    86102
    87         // Writing a character to the boot TTY terminal.
     103        // Write one character to TTY0 terminal.
    88104        // 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]);
    92107    }
    93108
  • 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
    124/****************************************************************************
    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()'.
    930 ****************************************************************************/
    1031
     
    2041enum TTY_registers
    2142{
    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                                       */
    2647   
    2748    TTY_SPAN    = 4,    /* segment size for one channel ( words )           */
     
    3455enum TTY_status
    3556{
    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.   */
    3859};
    3960
    4061/****************************************************************************
    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.     
    5371 ****************************************************************************/
    5472int 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
    124#include <stdarg.h>
    225
     
    528#include <boot_utils.h>
    629
     30
     31/****************************************************************************
     32 *                        Global variables                                  *
     33 ****************************************************************************/
     34
     35extern boot_remote_spinlock_t  tty0_lock;   // allocated in boot.c
     36
    737/****************************************************************************
    838 *                              Remote accesses.                            *
    939 ****************************************************************************/
    1040
     41//////////////////////////////////
    1142uint32_t boot_remote_lw(xptr_t xp)
    1243{
    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
    1949    ptr = (uint32_t)GET_PTR(xp);
    2050    cxy = (uint32_t)GET_CXY(xp);
    2151
    22     /* Assembly instructions to get the work done. */
     52    // Assembly instructions to get the work done.
    2353    asm volatile("mfc2  $15,    $24\n"  /* $15 <= CP2_DATA_PADDR_EXT        */
    2454                 "mtc2  %2,     $24\n"  /* CP2_DATA_PADDR_EXT <= cxy        */
     
    3767} // boot_remote_lw()
    3868
    39 /****************************************************************************/
    40 
     69/////////////////////////////////////////////
    4170void boot_remote_sw(xptr_t xp, uint32_t data)
    4271{
     
    6291} // boot_remote_sw()
    6392
    64 /****************************************************************************/
    65 
     93//////////////////////////////////////////////////////
    6694int32_t boot_remote_atomic_add(xptr_t xp, int32_t val)
    6795{
     
    98126} // boot_remote_atomic_add()
    99127
    100 /****************************************************************************/
    101 
    102 void boot_remote_memcpy(xptr_t dest, xptr_t src, unsigned int size)
     128///////////////////////////////////////////////////////////////
     129void boot_remote_memcpy(xptr_t dest, xptr_t src, uint32_t size)
    103130{
    104131    uint32_t words_nr;  /* Number of 32-bit words to be copied.             */
     
    194221 ****************************************************************************/
    195222
    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///////////////////////////////////////////////////////
     224void 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    {
    204232        while (size > 3)
    205233        {
    206             *(unsigned int*)dest++ = *(unsigned int*)src++;
     234            *wdst++ = *wsrc++;
    207235            size -= 4;
    208236        }
    209237    }
    210238
    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.
    216245    while (size)
    217         *(unsigned char*)dest++ = *(unsigned char*)src++;
    218 
     246    {
     247        *cdst++ = *csrc++;
     248    }
    219249} // boot_memcpy()
    220250
    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////////////////////////////////////////////////////
     252void boot_memset(void * dst, int val, uint32_t size)
     253{
    229254    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    {
    237263        while (size > 3)
    238264        {
    239             *(unsigned int*)base++ = wval;
     265            *wdst++ = wval;
    240266            size -= 4;
    241267        }
    242268    }
    243269   
    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
    249273    while (size--)
    250         *(unsigned char*)base++ = val;
    251 
     274    {
     275        *cdst++ = (char)val;
     276    }
    252277} // boot_memset()
    253278
     
    256281 ****************************************************************************/
    257282
     283///////////////////////////////////////
    258284void boot_strcpy(char* dest, char* src)
    259285{
     
    267293} // boot_strcpy()
    268294
    269 /****************************************************************************/
    270 
    271 unsigned int boot_strlen(char* s)
    272 {
    273     unsigned int res = 0;   /* Length of the string (in bytes).             */
     295/////////////////////////////
     296uint32_t boot_strlen(char* s)
     297{
     298    uint32_t res = 0;   /* Length of the string (in bytes).             */
    274299
    275300    if (s != NULL)
     
    283308} // boot_strlen()
    284309
    285 /****************************************************************************/
    286 
     310///////////////////////////////////
    287311int boot_strcmp(char* s1, char* s2)
    288312{
     
    308332 ****************************************************************************/
    309333
     334/////////////////////////
    310335void boot_puts(char* str)
    311336{
     
    314339} // boot_puts()
    315340   
    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///////////////////////////////////////
     342void 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
     350printf_text:
     351
     352    while ( *format )
     353    {
     354        uint32_t i;
     355        for (i = 0 ; format[i] && (format[i] != '%') ; i++);
     356        if (i)
    344357        {
    345             if (boot_tty_write(format, nb_printed))
    346                 goto error;
    347             format += nb_printed;
     358            boot_tty_write( format , i );
     359            format += i;
    348360        }
    349 
    350         /* Skipping the '%' character. */
    351         if (*format == '%')
     361        if (*format == '%')
    352362        {
    353363            format++;
    354             goto print_argument;
     364            goto printf_arguments;
    355365        }
    356366    }
    357367
    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 );
    361372    return;
    362373
    363 print_argument:
    364 
    365     /* Analyzing the conversion specifier. */
    366     switch (*format++)
    367     {
    368         // A character.
    369         case ('c'):
     374printf_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++)
    370384        {
    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            }
    379488        }
    380489
    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
    533500
    534501/****************************************************************************
     
    536503 ****************************************************************************/
    537504
     505////////////////
    538506void boot_exit()
    539507{
    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");
    546512
    547513} // boot_exit()
    548514
    549 /****************************************************************************/
    550 
    551 unsigned int boot_get_proctime()
    552 {
    553     unsigned int res;       /* Value stored in the CP0_COUNT register.      */
     515////////////////////////////
     516uint32_t boot_get_proctime()
     517{
     518    uint32_t res;       /* Value stored in the CP0_COUNT register.      */
    554519
    555520    asm volatile("mfc0 %0, $9" : "=r"(res));
     
    559524} // boot_get_proctime()
    560525
    561 /****************************************************************************/
    562 
    563 unsigned int boot_get_procid()
    564 {
    565     unsigned int res;       /* Value stored in the CP0_PROCID register.     */
     526
     527//////////////////////////
     528uint32_t boot_get_procid()
     529{
     530    uint32_t res;       /* Value stored in the CP0_PROCID register.     */
    566531
    567532    asm volatile("mfc0 %0, $15, 1" : "=r"(res));
     
    571536} // boot_get_procid()
    572537
    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////////////////////////////////////////////////
     540void 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;
    597555   
    598     /* Incrementing the counter. */
     556    // Atomically increment counter
    599557    current = boot_remote_atomic_add(XPTR(cxy, &ptr->current), 1);
    600558   
    601     /* The processor arrived last resets the barrier and toggles its sense. */
     559    // The processor arrived last resets the barrier and toggles its sense
    602560    if (current == (count - 1))
    603561    {
     
    605563        boot_remote_sw(XPTR(cxy, &ptr->sense), expected);
    606564    }
    607     /* Other processors poll the sense. */
     565    // Other processors poll the sense
    608566    else
    609567    {
     
    613571} // boot_barrier()
    614572
     573////////////////////////////////////////
     574void 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/////////////////////////////////////////
     593void 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
    124/****************************************************************************
    225 * This file defines various utility functions for the boot code.           *
     
    2649
    2750/****************************************************************************
    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.     
    3454 ****************************************************************************/
    3555uint32_t boot_remote_lw(xptr_t xp);
    3656
    3757/****************************************************************************
    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.
    4361 ****************************************************************************/
    4462void boot_remote_sw(xptr_t xp, uint32_t data);
    4563
    4664/****************************************************************************
    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.
    5570 ****************************************************************************/
    5671int32_t boot_remote_atomic_add(xptr_t xp, int32_t val);
    5772
    5873/****************************************************************************
    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, unsigned 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 ****************************************************************************/
     81void boot_remote_memcpy(xptr_t dest, xptr_t src, uint32_t size);
    6782
    6883/****************************************************************************
     
    7186
    7287/****************************************************************************
    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. 
    8094 ****************************************************************************/
    8195int32_t boot_atomic_add(int32_t* ptr, int32_t val);
     
    86100
    87101/****************************************************************************
    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, unsigned 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,   unsigned 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 ****************************************************************************/
     109void 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 ****************************************************************************/
     118void boot_memset(void* base, int val,   uint32_t size);
    105119
    106120/****************************************************************************
     
    109123
    110124/****************************************************************************
    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.
    116128 ****************************************************************************/
    117129static inline unsigned char boot_to_lower(unsigned char c)
     
    122134
    123135/****************************************************************************
    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.
    129139 ****************************************************************************/
    130140static inline unsigned char boot_to_upper(unsigned char c)
     
    135145
    136146/****************************************************************************
    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.
    141151 ****************************************************************************/
    142152void boot_strcpy(char* dest, char* src);
    143153
    144154/****************************************************************************
    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 ****************************************************************************/
     160uint32_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.
    159167 ****************************************************************************/
    160168int boot_strcmp(char* s1, char* s2);
     
    165173
    166174/****************************************************************************
    167  * This function writes the NUL terminated string pointed to by 'str' to    *
    168  * the 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.
    170178 ****************************************************************************/
    171179void boot_puts(char* str);
    172180
    173181/****************************************************************************
    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. 
    193201 ****************************************************************************/
    194202void boot_printf(char* format, ...);
     
    199207
    200208/****************************************************************************
    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.
    203211 ****************************************************************************/
    204212void boot_exit() __attribute__((noreturn));
    205213
    206214/****************************************************************************
    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 ****************************************************************************/
     219uint32_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 ****************************************************************************/
     226uint32_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 ****************************************************************************/
     233typedef struct boot_remote_barrier_s
    228234{
    229235    uint32_t current;                      // Number of arrived cores
     
    231237    uint32_t pad[(CACHE_LINE_SIZE>>2)-2];  // Padding
    232238}
    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 );
     239boot_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 ****************************************************************************/
     248void 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 ****************************************************************************/
     256typedef 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}
     262boot_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 ****************************************************************************/
     268void boot_remote_lock( xptr_t  lock_xp );
     269
     270/****************************************************************************
     271 * This function release the lock.
     272 * @ lock_xp    : extended pointer on lock.
     273 ****************************************************************************/
     274void boot_remote_unlock( xptr_t  lock_xp );
    244275
    245276
Note: See TracChangeset for help on using the changeset viewer.