Changeset 490


Ignore:
Timestamp:
Jan 16, 2015, 1:24:18 PM (9 years ago)
Author:
haoliu
Message:

Implemented a new way to construct the ptabs in boot. In the map.bin file,
each physical segment in cluster[x][y] is handled by the processor[x][y][0]. So
the constrcuting of page table is done in parrallel by all the
processor[x][y][0] at the same time.

This way spents less time than the constructing sequential by one processor(
the processor[0][0][0])

Location:
soft/giet_vm
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/giet_boot/boot.c

    r477 r490  
    166166unsigned int           _ptabs_max_pt2;
    167167
     168__attribute__((section (".bootdata")))
     169//volatile struct _boot_init_ok {
     170//    unsigned int value;
     171//}__attribute__((aligned(64)));
     172//struct _boot_init_ok boot_init_ok = {0};
     173volatile unsigned int boot_init_ok = 0;
     174
     175__attribute__((section (".bootdata")))
     176volatile _giet_lock_t lock_tty;
     177
     178__attribute__((section (".bootdata")))
     179volatile _giet_barrier_t barrier_boot;
     180
     181__attribute__((section (".bootdata")))
     182volatile _giet_lock_t lock_next_pt2[GIET_NB_VSPACE_MAX][X_SIZE][Y_SIZE];
     183
    168184// Global variables for TTY
    169185__attribute__((section (".bootdata")))
     
    191207__attribute__((section (".bootdata")))
    192208unsigned int           _tty_rx_buf[NB_TTY_CHANNELS];
    193 
    194 
    195 
    196209
    197210//////////////////////////////////////////////////////////////////////////////
     
    209222
    210223#if (BOOT_DEBUG_PT > 1)
     224_get_lock(&lock_tty);
    211225_puts(" - PTE1 in PTAB[");
    212226_putd( vspace_id );
     
    217231_puts("] : vpn = ");
    218232_putx( vpn );
    219 #endif
     233_puts(" / ppn = ");
     234_putx( ppn );
     235_puts(" / flags = ");
     236_putx( flags );
     237_puts("\n");
     238_release_lock(&lock_tty);
     239#endif
     240
     241    unsigned int procid     = _get_procid();
     242    unsigned int x_cluster  = (procid >> (Y_WIDTH + P_WIDTH)) & ((1<<X_WIDTH)-1);
     243    unsigned int y_cluster  = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
    220244
    221245    // compute index in PT1
     
    228252    if ( pt1_pbase == 0 )
    229253    {
     254        _get_lock(&lock_tty);
    230255        _puts("\n[BOOT ERROR] in boot_add_pte1() : illegal pbase address for PTAB[");
    231256        _putd( vspace_id );
     
    234259        _puts(",");
    235260        _putd( y );
     261        _puts("]");
     262        _puts(" in cluster[");
     263        _putd(x_cluster);
     264        _puts(",");
     265        _putd(y_cluster);
    236266        _puts("]\n");
     267        _release_lock(&lock_tty);
    237268        _exit();
    238269    }
     
    246277    _physical_write( pt1_pbase + 4*ix1, pte1 );
    247278
    248 #if (BOOT_DEBUG_PT > 1)
    249 _puts(" / ppn = ");
    250 _putx( ppn );
    251 _puts(" / flags = ");
    252 _putx( flags );
     279#if (BOOT_DEBUG_PT > 1 )
     280_get_lock(&lock_tty);
     281_puts(" - Write pte1 ");
     282_putx( pte1 );
     283_puts(" in paddr ");
     284_putl( pt1_pbase + 4*ix1 );
     285_puts(" in cluster[");
     286_putd(x_cluster);
     287_puts(",");
     288_putd(y_cluster);
     289_puts("]\n");
    253290_puts("\n");
     291_release_lock(&lock_tty);
    254292#endif
    255293
     
    272310
    273311#if (BOOT_DEBUG_PT > 1)
     312_get_lock(&lock_tty);
    274313_puts(" - PTE2 in PTAB[");
    275314_putd( vspace_id );
     
    280319_puts("] : vpn = ");
    281320_putx( vpn );
     321_puts(" / ppn = ");
     322_putx( ppn );
     323_puts(" / flags = ");
     324_putx( flags );
     325_puts("\n");
     326_release_lock(&lock_tty);
    282327#endif
    283328
     
    298343    if ( pt1_pbase == 0 )
    299344    {
     345        _get_lock(&lock_tty);
    300346        _puts("\n[BOOT ERROR] in boot_add_pte2() : PTAB[");
    301347        _putd( vspace_id );
     
    305351        _putd( y );
    306352        _puts("] undefined\n");
     353        _release_lock(&lock_tty);
    307354        _exit();
    308355    }
    309356
    310357    // get ptd in PT1
     358    _get_lock(&lock_next_pt2[vspace_id][x][y]);
    311359    ptd = _physical_read(pt1_pbase + 4 * ix1);
    312360
     
    337385    }
    338386
     387    _release_lock(&lock_next_pt2[vspace_id][x][y]);
    339388    // set PTE in PT2 : flags & PPN in two 32 bits words
    340389    pte2_paddr  = pt2_pbase + 8 * ix2;
    341390    _physical_write(pte2_paddr     , (PTE_V |flags) );
    342391    _physical_write(pte2_paddr + 4 , ppn);
    343 
    344 #if (BOOT_DEBUG_PT > 1)
    345 _puts(" / ppn = ");
    346 _putx( ppn );
    347 _puts(" / flags = ");
    348 _putx( flags );
    349 _puts("\n");
    350 #endif
    351392
    352393}   // end boot_add_pte2()
     
    498539                    paddr_t      paddr = _ptabs_paddr[vsid][x_dest][y_dest] + (ix1<<2);
    499540                    unsigned int pte1  = _physical_read( paddr );
     541#if (BOOT_DEBUG_PT > 1)
     542_get_lock(&lock_tty);
     543_puts("[BOOT DEBUG] ");
     544_puts( vseg->name );
     545_puts(" in cluster[");
     546_putd( x_dest );
     547_puts(",");
     548_putd( y_dest );
     549_puts("] : vbase = ");
     550_putx( vseg->vbase );
     551_puts(" / paddr = ");
     552_putl( paddr );
     553_puts(" / pte1 = ");
     554_putx( pte1 );
     555_puts(" by processor ");
     556_putd(_get_procid());
     557_puts("\n");
     558_release_lock(&lock_tty);
     559#endif
    500560                    if ( (pte1 & PTE_V) == 0 )     // BPP not allocated yet
    501561                    {
     
    578638
    579639#if BOOT_DEBUG_PT
     640_get_lock(&lock_tty);
    580641_puts("[BOOT DEBUG] ");
    581642_puts( vseg->name );
     
    594655_putl( vseg->pbase );
    595656_puts("\n");
     657_release_lock(&lock_tty);
    596658#endif
    597659
     
    779841// In each cluster all page tables for the different vspaces must be
    780842// packed in one vseg occupying one single BPP (Big Physical Page).
     843//
     844// This fonction is executed by the processor[x][y][0], the vsegs mapped in the
     845// cluster[x][y] in map.bin file are handled by the processor[x][y][0]
    781846//
    782847// For each vseg, the mapping is done in two steps:
     
    803868    mapping_vseg_t*     vseg   = _get_vseg_base(header);
    804869    mapping_vobj_t*     vobj   = _get_vobj_base(header);
     870    mapping_cluster_t*  cluster ;
     871    mapping_pseg_t*     pseg    ;
    805872
    806873    unsigned int vspace_id;
    807874    unsigned int vseg_id;
     875
     876    unsigned int procid     = _get_procid();
     877    unsigned int x_cluster  = (procid >> (Y_WIDTH + P_WIDTH)) & ((1<<X_WIDTH)-1);
     878    unsigned int y_cluster  = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
     879    unsigned int lpid       = procid & ((1<<P_WIDTH)-1);
     880
     881    if(lpid)
     882    {
     883        _puts("[BOOT ERROR] boot_ptabs_init() : error local processor id\n");
     884        _exit();
     885    }
    808886
    809887    if (header->vspaces == 0 )
     
    818896
    819897#if BOOT_DEBUG_PT
    820 _puts("\n[BOOT DEBUG] map PTAB global vsegs\n");
     898_get_lock(&lock_tty);
     899_puts("\n[BOOT DEBUG] map PTAB global vsegs in cluster[");
     900_putd(x_cluster);
     901_puts(",");
     902_putd(y_cluster);
     903_puts("]");
     904_puts("\n");
     905_release_lock(&lock_tty);
    821906#endif
    822907
     
    824909    {
    825910        unsigned int vobj_id = vseg[vseg_id].vobj_offset;
    826         if ( (vobj[vobj_id].type == VOBJ_TYPE_PTAB) )
     911        pseg    = _get_pseg_base(header) + vseg[vseg_id].psegid;
     912        cluster = _get_cluster_base(header) + pseg->clusterid;
     913        if ( (vobj[vobj_id].type == VOBJ_TYPE_PTAB) &&
     914             (cluster->x == x_cluster) &&
     915             (cluster->y == y_cluster))
    827916        {
    828917            boot_vseg_map( &vseg[vseg_id], 0xFFFFFFFF );
     
    831920    }
    832921
     922    _barrier_wait(&barrier_boot);
     923
    833924    for (vseg_id = 0; vseg_id < header->globals; vseg_id++)
    834925    {
    835926        unsigned int vobj_id = vseg[vseg_id].vobj_offset;
    836         if ( (vobj[vobj_id].type == VOBJ_TYPE_PTAB) )
     927        pseg    = _get_pseg_base(header) + vseg[vseg_id].psegid;
     928        cluster = _get_cluster_base(header) + pseg->clusterid;
     929        if ( (vobj[vobj_id].type == VOBJ_TYPE_PTAB) &&
     930             (cluster->x == x_cluster) &&
     931             (cluster->y == y_cluster))
    837932        {
    838933            boot_vseg_pte( &vseg[vseg_id], 0xFFFFFFFF );
     
    841936    }
    842937
     938    _barrier_wait(&barrier_boot);
     939
    843940    ///////// Phase 2 : global vsegs occupying more than one BPP (one loop)
    844941
    845942#if BOOT_DEBUG_PT
    846 _puts("\n[BOOT DEBUG] map all multi-BPP global vsegs\n");
    847 #endif
     943_get_lock(&lock_tty);
     944_puts("\n[BOOT DEBUG] map all multi-BPP global vseg in cluster[");
     945_putd(x_cluster);
     946_puts(",");
     947_putd(y_cluster);
     948_puts("]");
     949_puts("\n");
     950_release_lock(&lock_tty);
     951#endif   
    848952
    849953    for (vseg_id = 0; vseg_id < header->globals; vseg_id++)
    850954    {
    851955        unsigned int vobj_id = vseg[vseg_id].vobj_offset;
     956        pseg    = _get_pseg_base(header) + vseg[vseg_id].psegid;
     957        cluster = _get_cluster_base(header) + pseg->clusterid;
    852958        if ( (vobj[vobj_id].length > 0x200000) &&
    853              (vseg[vseg_id].mapped == 0) )
     959             (vseg[vseg_id].mapped == 0) &&
     960             (cluster->x == x_cluster) &&
     961             (cluster->y == y_cluster))
    854962        {
    855963            boot_vseg_map( &vseg[vseg_id], 0xFFFFFFFF );
     
    862970
    863971#if BOOT_DEBUG_PT
    864 _puts("\n[BOOT DEBUG] map all others global vsegs\n");
     972_get_lock(&lock_tty);
     973_puts("\n[BOOT DEBUG] map all others global in cluster[ ");
     974_putd(x_cluster);
     975_puts(",");
     976_putd(y_cluster);
     977_puts("]");
     978_puts("\n");
     979_release_lock(&lock_tty);
    865980#endif
    866981
    867982    for (vseg_id = 0; vseg_id < header->globals; vseg_id++)
    868983    {
    869         if ( vseg[vseg_id].mapped == 0 )
     984        unsigned int vobj_id = vseg[vseg_id].vobj_offset;
     985        pseg    = _get_pseg_base(header) + vseg[vseg_id].psegid;
     986        cluster = _get_cluster_base(header) + pseg->clusterid;
     987        if ( (vobj[vobj_id].length <= 0x200000) &&
     988             (vseg[vseg_id].mapped == 0) &&
     989             (cluster->x == x_cluster) &&
     990             (cluster->y == y_cluster))
    870991        {
    871992            boot_vseg_map( &vseg[vseg_id], 0xFFFFFFFF );
     
    8811002
    8821003#if BOOT_DEBUG_PT
     1004_get_lock(&lock_tty);
    8831005_puts("\n[BOOT DEBUG] map private vsegs for vspace ");
    8841006_puts( vspace[vspace_id].name );
     1007_puts(" in cluster[ ");
     1008_putd(x_cluster);
     1009_puts(",");
     1010_putd(y_cluster);
     1011_puts("]");
    8851012_puts("\n");
     1013_release_lock(&lock_tty);
    8861014#endif
    8871015
     
    8901018             vseg_id++)
    8911019        {
    892             boot_vseg_map( &vseg[vseg_id], vspace_id );
    893             vseg[vseg_id].mapped = 1;
    894             boot_vseg_pte( &vseg[vseg_id], vspace_id );
    895         }
    896     }
    897 
    898 #if (BOOT_DEBUG_PT > 1)
     1020            pseg    = _get_pseg_base(header) + vseg[vseg_id].psegid;
     1021            cluster = _get_cluster_base(header) + pseg->clusterid;
     1022            if((vseg[vseg_id].mapped == 0) &&
     1023               (cluster->x == x_cluster) &&
     1024               (cluster->y == y_cluster))
     1025            {
     1026                boot_vseg_map( &vseg[vseg_id], vspace_id );
     1027                vseg[vseg_id].mapped = 1;
     1028                boot_vseg_pte( &vseg[vseg_id], vspace_id );
     1029            }
     1030        }
     1031    }
     1032
     1033#if (BOOT_DEBUG_PT > 2)
     1034_get_lock(&lock_tty);
    8991035mapping_vseg_t*    curr;
    9001036mapping_pseg_t*    pseg    = _get_pseg_base(header);
     
    9261062    } 
    9271063}
     1064_release_lock(&lock_tty);
    9281065#endif
    9291066
     
    14011538
    14021539            // ctx_sr : value required before an eret instruction
    1403             unsigned int ctx_sr = 0x0000FF13;
     1540            unsigned int ctx_sr = 0x2000FF13;
    14041541
    14051542            // ctx_ptpr : page table physical base address (shifted by 13 bit)
     
    21212258// This function initialises the physical memory allocators in each
    21222259// cluster containing a RAM pseg.
     2260// it is handled by the processor[x][y][0]
    21232261/////////////////////////////////////////////////////////////////////////
    21242262void boot_pmem_init()
     
    21302268    unsigned int cluster_id;
    21312269    unsigned int pseg_id;
    2132 
    2133     // scan all clusters
    2134     for ( cluster_id = 0 ; cluster_id < X_SIZE*Y_SIZE ; cluster_id++ )
    2135     {
    2136         // scan the psegs in cluster to find first pseg of type RAM
    2137         unsigned int pseg_min = cluster[cluster_id].pseg_offset;
    2138         unsigned int pseg_max = pseg_min + cluster[cluster_id].psegs;
    2139         for ( pseg_id = pseg_min ; pseg_id < pseg_max ; pseg_id++ )
    2140         {
    2141             if ( pseg[pseg_id].type == PSEG_TYPE_RAM )
    2142             {
    2143                 unsigned int x    = cluster[cluster_id].x;
    2144                 unsigned int y    = cluster[cluster_id].y;
    2145                 unsigned int base = (unsigned int)pseg[pseg_id].base;
    2146                 unsigned int size = (unsigned int)pseg[pseg_id].length;
    2147                 _pmem_alloc_init( x, y, base, size );
     2270    unsigned int procid     = _get_procid();
     2271    unsigned int x_cluster  = (procid >> (Y_WIDTH + P_WIDTH)) & ((1<<X_WIDTH)-1);
     2272    unsigned int y_cluster  = (procid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
     2273    unsigned int lpid       = procid & ((1<<P_WIDTH)-1);
     2274    if(lpid)
     2275    {
     2276        _puts("[BOOT ERROR] boot_pmem_init() : error local processor id\n");
     2277        _exit();
     2278    }      // scan all clusters
     2279
     2280    cluster_id = x_cluster * Y_SIZE + y_cluster;
     2281    // scan the psegs in cluster to find first pseg of type RAM
     2282    unsigned int pseg_min = cluster[cluster_id].pseg_offset;
     2283    unsigned int pseg_max = pseg_min + cluster[cluster_id].psegs;
     2284    for ( pseg_id = pseg_min ; pseg_id < pseg_max ; pseg_id++ )
     2285    {
     2286        if ( pseg[pseg_id].type == PSEG_TYPE_RAM )
     2287        {
     2288            unsigned int x    = cluster[cluster_id].x;
     2289            unsigned int y    = cluster[cluster_id].y;
     2290            if(x != x_cluster || y != y_cluster)
     2291            {
     2292                _puts("[BOOT ERROR] boot_pmem_init() : error cluster id \n");
     2293                _exit();
     2294            } 
     2295            unsigned int base = (unsigned int)pseg[pseg_id].base;
     2296            unsigned int size = (unsigned int)pseg[pseg_id].length;
     2297            _pmem_alloc_init( x, y, base, size );
    21482298
    21492299#if BOOT_DEBUG_PT
     2300_get_lock(&lock_tty);
    21502301_puts("\n[BOOT DEBUG] pmem allocator initialised in cluster[");
    21512302_putd( x );
     
    21572308_putx( size );
    21582309_puts("\n");
    2159 #endif
    2160                break;
    2161             }
     2310_release_lock(&lock_tty);
     2311#endif
     2312            break;
    21622313        }
    21632314    }
     
    21732324    mapping_cluster_t* cluster    = _get_cluster_base(header);
    21742325    unsigned int       gpid       = _get_procid();
    2175  
     2326    unsigned int       clusterid, p;
     2327
    21762328    if ( gpid == 0 )    // only Processor 0 does it
    21772329    {
     
    21862338        _putd(_get_proctime());
    21872339        _puts("\n");
    2188 
    21892340        // Load the map.bin file into memory and check it
    21902341        boot_mapping_init();
     
    21962347        _puts("\n");
    21972348
     2349        _barrier_init(&barrier_boot, X_SIZE*Y_SIZE);
     2350
     2351        for ( clusterid = 1 ; clusterid < X_SIZE*Y_SIZE ; clusterid++ )
     2352        {
     2353            unsigned int x          = cluster[clusterid].x;
     2354            unsigned int y          = cluster[clusterid].y;
     2355            unsigned int cluster_xy = (x<<Y_WIDTH) + y;
     2356
     2357            _xcu_send_wti_paddr( cluster_xy, 0, (unsigned int)boot_entry );
     2358        }
     2359    }
     2360    //Parallel phase to construct the ptab by each processor[x][y][0]
     2361    if( (gpid & ((1 << P_WIDTH) -1)) == 0)
     2362    {
    21982363        // Initializes the physical memory allocators
    21992364        boot_pmem_init();
    2200 
    2201         _puts("\n[BOOT] Physical memory allocators initialised at cycle ");
    2202         _putd(_get_proctime());
    2203         _puts("\n");
    2204 
    2205         // Build page tables
     2365        // Build ge tables
    22062366        boot_ptabs_init();
    2207 
    2208         _puts("\n[BOOT] Page tables initialised at cycle ");
     2367        //wait for all processors finished the work
     2368        _barrier_wait(&barrier_boot);
     2369
     2370        if( gpid ) while( boot_init_ok == 0);
     2371    }
     2372
     2373    if ( gpid == 0 )    // only Processor 0 does it
     2374    {
     2375        _puts("\n[BOOT] Physical memory allocators and Page table initialized at cycle ");
    22092376        _putd(_get_proctime());
    22102377        _puts("\n");
     
    22452412        boot_elf_load();
    22462413
    2247         // P0 starts all other processors
    2248         unsigned int clusterid, p;
     2414        // wake up the processors which has constructed the ptab before
     2415        boot_init_ok = 1;
    22492416
    22502417        for ( clusterid = 0 ; clusterid < X_SIZE*Y_SIZE ; clusterid++ )
     
    22552422            unsigned int cluster_xy = (x<<Y_WIDTH) + y;
    22562423
    2257             for ( p = 0 ; p < nprocs; p++ )
    2258             {
    2259                 if ( (nprocs > 0) && ((clusterid != 0) || (p != 0)) )
    2260                 {
    2261                     _xcu_send_wti( cluster_xy, p, (unsigned int)boot_entry );
    2262                 }
     2424            for ( p = 1 ; p < nprocs; p++ )
     2425            {
     2426                _xcu_send_wti( cluster_xy, p, (unsigned int)boot_entry );
    22632427            }
    22642428        }
    2265  
    22662429    }  // end monoprocessor boot
    22672430
  • soft/giet_vm/giet_boot/boot_entry.S

    r427 r490  
    22 * file   : boot.S
    33 * date   : 01/17/2014
    4  * author : Cesar Fuguet & Alain Greiner
     4 * author : Cesar Fuguet & Alain Greiner & Hao Liu
    55 *
    66 * This file contains the boot_entry() function that is the entry
     
    1919 * to the boot_init() fuction defined in the boot.c file.
    2020 *
    21  * - Processor 0 uses a larger stack:         64 Kbytes.
     21 * - each processor[x][y][0] uses a larger stack: 1,25 Kbytes.
    2222 * - Other processors use a smaller stack:    256 bytes.
    23  *     => the SEG_BOOT_STACK_SIZE cannot be smaller 320 Kytes.
    24  *         (64K + 1024 * 256 = 320 Kbytes = 0x50000)
     23 *     => the SEG_BOOT_STACK_SIZE cannot be smaller 512 Kytes.
     24 *         (256*(1024+256) + (1024 - 256) * 256 = 512 Kbytes = 0x80000)
    2525 */
    2626
     
    4545    /* (proc_id is a "continuous" index, while proc_xyl is a "fixed format" index */
    4646
     47
    4748    mfc0   k0,      CP0_PROCID
    4849    andi   k0,      k0,     0xFFF             /* k0 <= proc_xyl                   */
     
    5556    mflo   t5
    5657    addu   t5,      t5,     t4                /* t5 <= cluster_id                 */
    57     li     t7,      NB_PROCS_MAX
    58     multu  t5,      t7
    59     mflo   t0
    60     addu   t0,      t0,     t1                /* t0 <= proc_id                    */
    61    
     58    li     t6,      0x100 * (NB_PROCS_MAX - 1) + 0x500  /* stack size per cluster */
     59    multu  t6,      t5
     60    mflo   t7
    6261
    6362    /* All processors initializes stack pointer, depending on proc_id             */
    6463
    6564   la      k0,      SEG_BOOT_STACK_BASE
    66    li      k1,      0x10000         /* k1 <= P0 stack size == 64 Kbytes           */
    67    addu    sp,      k0,     k1      /* P0 stack from base to (base + 64K)         */
     65   addu    k0,      k0,     t7
     66   li      k1,      0x500           /* k1 <= local P0 stack size == 1,25 Kbytes            */
     67   addu    sp,      k0,     k1      /* P0 stack from base to (base + stack size * cluster_id + 1,25K )         */
    6868
    69    li      k1,      0x100           /* k1 <= Pi stack size == 256 bytes           */
    70    multu   k1,      t0             
     69   li      k1,      0x100           /* k1 <= Pi stack size == 256 bytes            */
     70   multu   k1,      t1             
    7171   mflo    k0                       /* k0 <= 256 * proc_id                        */
    72    addu    sp,      sp,     k1
    73    addu    sp,      sp,     k0      /* Pi stacks from base + 64K + proc_id*256    */
     72   addu    sp,      sp,     k0      /* Pi stacks from base + stack size * cluster_id + 1,25K + proc_id*256    */
    7473
    7574
    7675    /* All processors jump to the boot_init function                              */
    7776
    78     la      k0,     boot_init
    79     jr      k0
     77    la     k0,     boot_init
     78    jr     k0
    8079    nop
    8180
  • soft/giet_vm/giet_common/utils.c

    r466 r490  
    409409}
    410410
    411 
     411///////////////////////////////////////////////////////////////////////////////////
     412//                      barrier functions
     413///////////////////////////////////////////////////////////////////////////////////
     414void _barrier_init( _giet_barrier_t* barrier,
     415                   unsigned int    ntasks )
     416{
     417    barrier->ntasks = ntasks;
     418    barrier->count  = ntasks;
     419    barrier->sense  = 0;
     420
     421    asm volatile ("sync" ::: "memory");
     422}
     423
     424////////////////////////////////////////////
     425void _barrier_wait( _giet_barrier_t* barrier )
     426{
     427
     428    // compute expected sense value
     429    unsigned int expected;
     430    if ( barrier->sense == 0 ) expected = 1;
     431    else                       expected = 0;
     432
     433    // parallel decrement barrier counter using atomic instructions LL/SC
     434    // - input : pointer on the barrier counter (pcount)
     435    // - output : counter value (count)
     436    volatile unsigned int* pcount  = (unsigned int *)&barrier->count;
     437    volatile unsigned int  count    = 0;  // avoid a warning
     438
     439    asm volatile( "addu   $2,     %1,        $0      \n"
     440                  "barrier_llsc:                     \n"
     441                  "ll     $8,     0($2)              \n"
     442                  "addi   $9,     $8,        -1      \n"
     443                  "sc     $9,     0($2)              \n"
     444                  "beqz   $9,     barrier_llsc       \n"
     445                  "addu   %0,     $8,        $0      \n"
     446                  : "=r" (count)
     447                  : "r" (pcount)
     448                  : "$2", "$8", "$9", "memory" );
     449
     450    // the last task re-initializes count and toggle sense,
     451    // waking up all other waiting tasks
     452    if (count == 1)   // last task
     453    {
     454        barrier->count = barrier->ntasks;
     455        barrier->sense = expected;
     456    }
     457    else              // other tasks busy waiting the sense flag
     458    {
     459        // polling sense flag
     460        // input: pointer on the sens flag (psense)
     461        // input: expected sense value (expected)
     462        volatile unsigned int* psense  = (unsigned int *)&barrier->sense;
     463        asm volatile ( "barrier_sense:                   \n"
     464                       "lw    $3,   0(%0)                \n"
     465                       "bne   $3,   %1,    barrier_sense \n"
     466                       :
     467                       : "r"(psense), "r"(expected)
     468                       : "$3" );
     469    }
     470
     471    asm volatile ("sync" ::: "memory");
     472}
     473
     474///////////////////////////////////////////////////////////////////////////////////
     475//                      Locks access functions
     476///////////////////////////////////////////////////////////////////////////////////
     477
     478///////////////////////////////////
     479void _get_lock( _giet_lock_t* lock )
     480{
     481    register unsigned int* plock = &(lock->value);
     482
     483#if NO_HARD_CC
     484
     485    register unsigned int delay  = (_get_proctime() ^ _get_procid() << 4) & 0xFF;
     486    if (delay == 0) delay = 0x80;
     487
     488    asm volatile (
     489            "_lock_llsc:             \n"
     490            "    ll   $2,    0(%0)       \n" /* $2 <= lock current value         */
     491            "    bnez $2,    _lock_delay \n" /* delay if lock already taken      */
     492            "    li   $3,    1           \n" /* $3 <= argument for sc            */
     493            "    sc   $3,    0(%0)       \n" /* try to set lock                  */
     494            "    bnez $3,    _lock_ok    \n" /* exit if atomic                   */
     495            "    _lock_delay:            \n"
     496            "    move $4,    %1          \n" /* $4 <= delay                      */
     497            "    _lock_loop:             \n"
     498            "    addi $4,    $4,    -1   \n" /* $4 <= $4 - 1                     */
     499            "    bnez $4,    _lock_loop  \n" /* test end delay                   */
     500            "    nop                     \n"
     501            "    j           _lock_llsc  \n" /* retry                            */
     502            "    nop                     \n"
     503            "    _lock_ok:               \n"
     504            :
     505            :"r"(plock), "r"(delay)
     506            :"$2", "$3", "$4", "memory");
     507#else
     508
     509    asm volatile (
     510            "_lock_llsc:                 \n"
     511            "    lw   $2,    0(%0)       \n" /* $2 <= lock current value         */
     512            "    bnez $2,    _lock_llsc  \n" /* retry if lock already taken      */
     513            "    nop                     \n"
     514            "    ll   $2,    0(%0)       \n" /* ll_buffer <= lock current value  */
     515            "    bnez $2,    _lock_llsc  \n" /* retry if lock already taken      */
     516            "    li   $3,    1           \n" /* $3 <= argument for sc            */
     517            "    sc   $3,    0(%0)       \n" /* try to set lock                  */
     518            "    beqz $3,    _lock_llsc  \n" /* retry if sc failure              */
     519            "    nop                     \n"
     520            :
     521            :"r"(plock)
     522            :"$2", "$3", "memory");
     523#endif
     524
     525}
     526
     527///////////////////////////////////////
     528void _release_lock( _giet_lock_t* lock )
     529{
     530    asm volatile ( "sync\n" ::: "memory" );
     531    // sync is necessary because of the TSAR consistency model
     532    lock->value = 0;
     533}
    412534
    413535////////////////////////////////////////////////////////////////////////////////////
  • soft/giet_vm/giet_common/utils.h

    r455 r490  
    3535extern _ld_symbol_t kernel_init_vbase;
    3636
     37
     38
     39///////////////////////////////////////////////////////////////////////////////////
     40//      Locks access functions
     41///////////////////////////////////////////////////////////////////////////////////
     42volatile typedef struct _giet_barrier_s
     43{
     44    char         name[32];   // barrier name
     45    unsigned int sense;      // barrier state (toggle)
     46    unsigned int ntasks;     // total number of expected tasks
     47    unsigned int count;      // number of not arrived tasks
     48} _giet_barrier_t;
     49
     50extern void _barrier_init( _giet_barrier_t* barrier,
     51                           unsigned int    ntasks );   
     52
     53extern void _barrier_wait( _giet_barrier_t* barrier );
     54
     55
     56///////////////////////////////////////////////////////////////////////////////////
     57//      Locks access functions
     58///////////////////////////////////////////////////////////////////////////////////
     59volatile typedef struct _giet_lock_s { unsigned int value;
     60                                       unsigned int padding[15]; } _giet_lock_t;
     61
     62
     63extern void _get_lock(_giet_lock_t* lock);
     64
     65extern void _release_lock(_giet_lock_t* lock);
    3766///////////////////////////////////////////////////////////////////////////////////
    3867//     CP0 registers access functions
  • soft/giet_vm/giet_drivers/xcu_driver.c

    r456 r490  
    181181}
    182182
     183////////////////////////////////////////////
     184void _xcu_send_wti_paddr( unsigned int cluster_xy,
     185                          unsigned int wti_index,
     186                          unsigned int wdata )
     187{
     188#if USE_XCU
     189    // parameters checking
     190    unsigned int x = cluster_xy >> Y_WIDTH;
     191    unsigned int y = cluster_xy & ((1<<Y_WIDTH)-1);
     192    if (x >= X_SIZE)               _exit();
     193    if (y >= Y_SIZE)               _exit();
     194    if (wti_index >= 32)           _exit();
     195
     196    paddr_t paddr =
     197         SEG_XCU_BASE + ((paddr_t)cluster_xy << 32) +
     198        (XCU_REG(XCU_WTI_REG, wti_index) << 2);
     199
     200    _physical_write(paddr, wdata);
     201
     202#else
     203    _puts("[GIET ERROR] _xcu_send_wti() should not be used if USE_XCU is not set\n");
     204    _exit();
     205#endif
     206}
    183207///////////////////////////////////////////////////
    184208void _xcu_get_wti_value( unsigned int   cluster_xy,
  • soft/giet_vm/giet_drivers/xcu_driver.h

    r437 r490  
    9393                           unsigned int wdata );
    9494
     95///////////////////////////////////////////////////////////////////////////////
     96// This function writes the "wdata" by physical xcu address value in the mailbox
     97// defined by the "cluster_xy" and "wti_index" arguments.
     98////////////////////////////////////////////////////////////////////////////////
     99void _xcu_send_wti_paddr( unsigned int cluster_xy,
     100                          unsigned int wti_index,
     101                          unsigned int wdata );
    95102////////////////////////////////////////////////////////////////////////////////
    96103// This function returns the value contained in a WTI mailbox defined by
Note: See TracChangeset for help on using the changeset viewer.