Ignore:
Timestamp:
Nov 7, 2017, 3:08:12 PM (5 years ago)
Author:
alain
Message:

First implementation of fork/exec.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/hal/tsar_mips32/core/hal_gpt.c

    r406 r407  
    135135    uint32_t   attr;
    136136
    137     gpt_dmsg("\n[DMSG] %s : core[%x,%d] enter\n",
    138     __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid );
     137gpt_dmsg("\n[DBG] %s : core[%x,%d] enter\n",
     138__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid );
    139139
    140140    // check page size
     
    157157    // initialize generic page table descriptor
    158158    page_xp   = XPTR( local_cxy , page );
    159 
    160159        gpt->ptr  = GET_PTR( ppm_page2base( page_xp ) );
    161160        gpt->ppn  = ppm_page2ppn( page_xp );
    162         gpt->page = GET_PTR( page_xp );
    163161
    164162    // identity map the kentry_vseg (must exist for all processes)
     
    167165         vpn < (CONFIG_VMM_KENTRY_BASE + CONFIG_VMM_KENTRY_SIZE); vpn++ )
    168166    {
    169         gpt_dmsg("\n[DMSG] %s : identity map vpn %d\n", __FUNCTION__ , vpn );
     167
     168gpt_dmsg("\n[DBG] %s : identity map vpn %d\n", __FUNCTION__ , vpn );
    170169
    171170        error = hal_gpt_set_pte( gpt,
     
    181180    }
    182181
    183     gpt_dmsg("\n[DMSG] %s : core[%x,%d] exit\n",
    184     __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid );
     182gpt_dmsg("\n[DBG] %s : core[%x,%d] exit\n",
     183__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid );
    185184
    186185        return 0;
     
    271270} // end hal_gpt_destroy()
    272271
    273 ////////////////////////////////
    274 void hal_gpt_print( gpt_t * gpt,
    275                     pid_t   pid )
    276 {
     272///////////////////////////////////////////
     273void hal_gpt_display( process_t * process )
     274{
     275    gpt_t    * gpt;
    277276        uint32_t   ix1;
    278277        uint32_t   ix2;
     
    285284    vpn_t      vpn;
    286285
    287 
     286    assert( (process != NULL) , __FUNCTION__ , "NULL process pointer\n");
     287
     288    // get pointer on gpt
     289    gpt = &(process->vmm.gpt);
     290
     291    // get pointer on PT1
    288292    pt1 = (uint32_t *)gpt->ptr;
    289293
    290294    printk("\n***** Generic Page Table for process %x : &gpt = %x / &pt1 = %x\n\n",
    291     pid , gpt , pt1 );
     295    process->pid , gpt , pt1 );
    292296
    293297    // scan the PT1
     
    324328        }
    325329        }
    326 } // end hal_gpt_print()
     330} // end hal_gpt_display()
    327331
    328332
     
    351355    uint32_t            tsar_attr;           // PTE attributes for TSAR MMU
    352356
    353     gpt_dmsg("\n[DMSG] %s : core[%x,%d] enter for vpn = %x / ppn = %x / gpt_attr = %x\n",
     357    gpt_dmsg("\n[DBG] %s : core[%x,%d] enter for vpn = %x / ppn = %x / gpt_attr = %x\n",
    354358    __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn , ppn , attr );
    355359 
     
    364368    tsar_attr = gpt2tsar( attr );
    365369
    366     gpt_dmsg("\n[DMSG] %s : core[%x,%d] / vpn = %x / &pt1 = %x / tsar_attr = %x\n",
     370    gpt_dmsg("\n[DBG] %s : core[%x,%d] / vpn = %x / &pt1 = %x / tsar_attr = %x\n",
    367371    __FUNCTION__, local_cxy , CURRENT_THREAD->core->lid , vpn , pt1 , tsar_attr );
    368372
     
    396400        pte1 = *pte1_ptr;
    397401       
    398         gpt_dmsg("\n[DMSG] %s : core[%x,%d] / vpn = %x / current_pte1 = %x\n",
     402        gpt_dmsg("\n[DBG] %s : core[%x,%d] / vpn = %x / current_pte1 = %x\n",
    399403        __FUNCTION__, local_cxy , CURRENT_THREAD->core->lid , vpn , pte1 );
    400404       
     
    438442            pt2     = (uint32_t *)GET_PTR( ppm_ppn2base( pt2_ppn ) );
    439443
    440         gpt_dmsg("\n[DMSG] %s : core[%x,%d] / vpn = %x / pte1 = %x / &pt2 = %x\n",
     444        gpt_dmsg("\n[DBG] %s : core[%x,%d] / vpn = %x / pte1 = %x / &pt2 = %x\n",
    441445        __FUNCTION__, local_cxy , CURRENT_THREAD->core->lid , vpn , pte1 , pt2 );
    442446       
     
    450454        hal_fence();
    451455
    452     gpt_dmsg("\n[DMSG] %s : core[%x,%d] exit / vpn = %x / pte2_attr = %x / pte2_ppn = %x\n",
     456    gpt_dmsg("\n[DBG] %s : core[%x,%d] exit / vpn = %x / pte2_attr = %x / pte2_ppn = %x\n",
    453457    __FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid , vpn ,
    454458    pt2[2 * ix2] , pt2[2 * ix2 + 1] );
     
    727731error_t hal_gpt_copy( gpt_t  * dst_gpt,
    728732                      gpt_t  * src_gpt,
     733                      vpn_t    vpn_base,
     734                      vpn_t    vpn_size,
    729735                      bool_t   cow )
    730736{
     737    vpn_t        vpn;       // current vpn
     738
    731739    uint32_t     ix1;       // index in PT1
    732740    uint32_t     ix2;       // index in PT2
     
    737745    uint32_t   * src_pt2;   // local pointer on PT2 for SRC_GPT
    738746
    739     uint32_t     pte1;
     747        kmem_req_t   req;       // for dynamic PT2 allocation
     748
     749    uint32_t     src_pte1;
     750    uint32_t     dst_pte1;
     751
    740752    uint32_t     pte2_attr;
    741753    uint32_t     pte2_ppn;
    742     uint32_t     pte2_writable;
    743754
    744755    page_t     * page;
     
    748759    ppn_t        dst_pt2_ppn;
    749760
    750     // get pointers on PT1 for src_gpt & dst_gpt
     761gpt_dmsg("\n[DBG] %s : core[%x,%d] enter\n",
     762__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid );
     763
     764    // check page size
     765    assert( (CONFIG_PPM_PAGE_SIZE == 4096) , __FUNCTION__ ,
     766    "for TSAR, the page must be 4 Kbytes\n" );
     767
     768    // check SRC_PT1 and DST_PT1 existence
     769    assert( (src_gpt->ptr != NULL) , __FUNCTION__ , "SRC_PT1 does not exist\n");
     770    assert( (dst_gpt->ptr != NULL) , __FUNCTION__ , "DST_PT1 does not exist\n");
     771
     772    // get pointers on SRC_PT1 and DST_PT1
    751773    src_pt1 = (uint32_t *)src_gpt->ptr;
    752774    dst_pt1 = (uint32_t *)dst_gpt->ptr;
    753775
     776    // scan pages in vseg
     777    for( vpn = vpn_base ; vpn < (vpn_base + vpn_size) ; vpn++ )
     778    {
     779        ix1 = TSAR_MMU_IX1_FROM_VPN( vpn );
     780        ix2 = TSAR_MMU_IX2_FROM_VPN( vpn );
     781
     782        // get SRC_PT1 entry
     783        src_pte1 = src_pt1[ix1];
     784
     785        // do nothing if SRC_PTE1 unmapped
     786                if( (src_pte1 & TSAR_MMU_MAPPED) != 0 )   // SRC_PTE1 is mapped
     787        {
     788            assert( (src_pte1 & TSAR_MMU_SMALL) , __FUNCTION__ ,
     789            "no BIG page for user process in TSAR architecture\n" );
     790
     791            // get DST_PT1 entry
     792            dst_pte1 = dst_pt1[ix1];
     793
     794            // map dst_pte1 if required
     795            if( (dst_pte1 & TSAR_MMU_MAPPED) == 0 )
     796            {
     797                // allocate one physical page for a new DST_PT2
     798                    req.type  = KMEM_PAGE;
     799                    req.size  = 0;                     // 1 small page
     800                    req.flags = AF_KERNEL | AF_ZERO;
     801                    page = (page_t *)kmem_alloc( &req );
     802
     803                if( page == NULL )
     804                {
     805                                printk("\n[ERROR] in %s : cannot allocate PT2\n", __FUNCTION__ );
     806                    return ENOMEM;
     807                }
     808
     809                // build extended pointer on page descriptor
     810                page_xp = XPTR( local_cxy , page );
     811
     812                // get PPN for this new DST_PT2
     813                dst_pt2_ppn    = (ppn_t)ppm_page2ppn( page_xp );
     814
     815                // build the new dst_pte1
     816                dst_pte1 = TSAR_MMU_MAPPED | TSAR_MMU_SMALL | dst_pt2_ppn;
     817
     818                // register it in DST_GPT
     819                dst_pt1[ix1] = dst_pte1;
     820            }
     821
     822            // get PPN and pointer on SRC_PT2
     823            src_pt2_ppn = (ppn_t)TSAR_MMU_PTBA_FROM_PTE1( src_pte1 );
     824            src_pt2     = (uint32_t *)GET_PTR( ppm_ppn2base( src_pt2_ppn ) );
     825
     826            // get PPN and pointer on DST_PT2
     827            dst_pt2_ppn = (ppn_t)TSAR_MMU_PTBA_FROM_PTE1( dst_pte1 );
     828            dst_pt2     = (uint32_t *)GET_PTR( ppm_ppn2base( dst_pt2_ppn ) );
     829
     830            // get attr and ppn from SRC_PT2
     831            pte2_attr = TSAR_MMU_ATTR_FROM_PTE2( src_pt2[2 * ix2] );
     832            pte2_ppn  = TSAR_MMU_PPN_FROM_PTE2(  src_pt2[2 * ix2 + 1] );
     833
     834            // no copy if SRC_PTE2 unmapped
     835            if( (pte2_attr & TSAR_MMU_MAPPED) != 0 )  // valid PTE2 in SRC_GPT
     836            {
     837                // set a new PTE2 in DST_PT2
     838                dst_pt2[2*ix2]     = pte2_attr;
     839                dst_pt2[2*ix2 + 1] = pte2_ppn;
     840                       
     841                // FIXME increment page descriptor refcount for the referenced page
     842
     843                // handle Copy-On-Write
     844                if( cow && (pte2_attr & TSAR_MMU_WRITABLE) )
     845                {
     846                    // reset WRITABLE flag in DST_GPT
     847                    hal_atomic_and( &dst_pt2[2*ix2] , ~TSAR_MMU_WRITABLE );
     848
     849                    // set COW flag in DST_GPT
     850                    hal_atomic_or( &dst_pt2[2*ix2] , TSAR_MMU_COW );
     851                }
     852            }
     853        }   // end if PTE1 mapped
     854    }   // end loop on vpn
     855
     856    hal_fence();
     857
     858gpt_dmsg("\n[DBG] %s : core[%x,%d] exit\n",
     859__FUNCTION__ , local_cxy , CURRENT_THREAD->core->lid );
     860
     861    return 0;
     862
     863}  // end hal_gpt_copy()
     864
     865///////////////////////////////////////
     866bool_t hal_gpt_pte_is_cow( gpt_t * gpt,
     867                           vpn_t   vpn )
     868{
     869    uint32_t * pt1;
     870    uint32_t   pte1;
     871
     872    uint32_t * pt2;
     873    ppn_t      pt2_ppn;
     874
     875    uint32_t   ix1 = TSAR_MMU_IX1_FROM_VPN( vpn );
     876    uint32_t   ix2 = TSAR_MMU_IX2_FROM_VPN( vpn );
     877
     878    // get PTE1 value
     879        pt1  = gpt->ptr;
     880    pte1 = pt1[ix1];
     881
     882        if( (pte1 & TSAR_MMU_MAPPED) == 0 )    // PT1 entry not mapped
     883        {
     884                return false;
     885        }
     886
     887        if( (pte1 & TSAR_MMU_SMALL) == 0 )     // it's a PTE1
     888        {
     889                return false;
     890        }
     891    else                                   // it's a PTD1
     892    {
     893        // compute PT2 base address
     894        pt2_ppn = TSAR_MMU_PTBA_FROM_PTE1( pte1 );
     895        pt2     = (uint32_t*)GET_PTR( ppm_ppn2base( pt2_ppn ) );
     896
     897        if( pt2[2*ix2] & TSAR_MMU_COW ) return true;
     898        else                            return false;
     899    }
     900}   // end hal_gpt_pte_is_cow()
     901
     902
     903
     904
     905
     906
     907
     908
     909
     910
     911
     912
     913/* deprecated : old hal_gpt_copy [AG]
     914 
    754915    // scan the SRC_PT1
    755916        for( ix1 = 0 ; ix1 < 2048 ; ix1++ )
     
    834995}  // end hal_gpt_copy()
    835996
     997*/
Note: See TracChangeset for help on using the changeset viewer.