Ignore:
Timestamp:
Aug 17, 2017, 3:02:18 PM (7 years ago)
Author:
alain
Message:

Few bugs in VMM

File:
1 edited

Legend:

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

    r391 r401  
    3535
    3636////////////////////////////////////////////////////////////////////////////////////////
    37 // This define the masks for the TSAR MMU PTE attributes. (from TSAR MMU specification)
     37// This define the masks for the TSAR MMU PTE attributes (from TSAR MMU specification)
    3838////////////////////////////////////////////////////////////////////////////////////////
    3939
    40 #define TSAR_MMU_PRESENT        0x80000000
    41 #define TSAR_MMU_PTD1           0x40000000
     40#define TSAR_MMU_MAPPED         0x80000000
     41#define TSAR_MMU_SMALL          0x40000000
    4242#define TSAR_MMU_LOCAL          0x20000000
    4343#define TSAR_MMU_REMOTE         0x10000000
     
    4949#define TSAR_MMU_DIRTY          0x00400000
    5050
    51 #define TSAR_MMU_COW            0x00000001
    52 #define TSAR_MMU_SWAP           0x00000004
    53 #define TSAR_MMU_LOCKED         0x00000008
     51#define TSAR_MMU_COW            0x00000001       // only for small pages
     52#define TSAR_MMU_SWAP           0x00000004       // only for small pages
     53#define TSAR_MMU_LOCKED         0x00000008       // only for small pages
    5454
    5555////////////////////////////////////////////////////////////////////////////////////////
     
    6464#define TSAR_MMU_PPN_WIDTH                 28
    6565
     66#define TSAR_MMU_PTE1_ATTR_MASK            0xFFC00000
     67#define TSAR_MMU_PTE1_PPN_MASK             0x0007FFFF
     68
    6669#define TSAR_MMU_IX1_FROM_VPN( vpn )       ((vpn >> 9) & 0x7FF)
    6770#define TSAR_MMU_IX2_FROM_VPN( vpn )       (vpn & 0x1FF)
     
    7376#define TSAR_MMU_PPN_FROM_PTE2( pte2 )     (pte2 & 0x0FFFFFFF)
    7477#define TSAR_MMU_ATTR_FROM_PTE2( pte2 )    (pte2 & 0xFFC000FF)
     78
     79
     80///////////////////////////////////////////////////////////////////////////////////////
     81// This static function translates the GPT attributes to the TSAR attributes
     82///////////////////////////////////////////////////////////////////////////////////////
     83static inline uint32_t gpt2tsar( uint32_t gpt_attr )
     84{
     85    uint32_t tsar_attr = 0;
     86
     87    if( gpt_attr & GPT_MAPPED     ) tsar_attr |= TSAR_MMU_MAPPED;
     88    if( gpt_attr & GPT_SMALL      ) tsar_attr |= TSAR_MMU_SMALL;
     89    if( gpt_attr & GPT_WRITABLE   ) tsar_attr |= TSAR_MMU_WRITABLE;
     90    if( gpt_attr & GPT_EXECUTABLE ) tsar_attr |= TSAR_MMU_EXECUTABLE;
     91    if( gpt_attr & GPT_CACHABLE   ) tsar_attr |= TSAR_MMU_CACHABLE;
     92    if( gpt_attr & GPT_USER       ) tsar_attr |= TSAR_MMU_USER;
     93    if( gpt_attr & GPT_DIRTY      ) tsar_attr |= TSAR_MMU_DIRTY;
     94    if( gpt_attr & GPT_ACCESSED   ) tsar_attr |= TSAR_MMU_LOCAL;
     95    if( gpt_attr & GPT_GLOBAL     ) tsar_attr |= TSAR_MMU_GLOBAL;
     96    if( gpt_attr & GPT_COW        ) tsar_attr |= TSAR_MMU_COW;
     97    if( gpt_attr & GPT_SWAP       ) tsar_attr |= TSAR_MMU_SWAP;
     98    if( gpt_attr & GPT_LOCKED     ) tsar_attr |= TSAR_MMU_LOCKED;
     99
     100    return tsar_attr;
     101}
     102
     103///////////////////////////////////////////////////////////////////////////////////////
     104// This static function translates the TSAR attributes to the GPT attributes
     105///////////////////////////////////////////////////////////////////////////////////////
     106static inline uint32_t tsar2gpt( uint32_t tsar_attr )
     107{
     108    uint32_t gpt_attr = 0;
     109
     110    if( tsar_attr & TSAR_MMU_MAPPED     ) gpt_attr |= GPT_MAPPED;
     111    if( tsar_attr & TSAR_MMU_MAPPED     ) gpt_attr |= GPT_READABLE;
     112    if( tsar_attr & TSAR_MMU_SMALL      ) gpt_attr |= GPT_SMALL;
     113    if( tsar_attr & TSAR_MMU_WRITABLE   ) gpt_attr |= GPT_WRITABLE;
     114    if( tsar_attr & TSAR_MMU_EXECUTABLE ) gpt_attr |= GPT_EXECUTABLE;
     115    if( tsar_attr & TSAR_MMU_CACHABLE   ) gpt_attr |= GPT_CACHABLE;
     116    if( tsar_attr & TSAR_MMU_USER       ) gpt_attr |= GPT_USER;
     117    if( tsar_attr & TSAR_MMU_DIRTY      ) gpt_attr |= GPT_DIRTY;
     118    if( tsar_attr & TSAR_MMU_LOCAL      ) gpt_attr |= GPT_ACCESSED;
     119    if( tsar_attr & TSAR_MMU_REMOTE     ) gpt_attr |= GPT_ACCESSED;
     120    if( tsar_attr & TSAR_MMU_GLOBAL     ) gpt_attr |= GPT_GLOBAL;
     121    if( tsar_attr & TSAR_MMU_COW        ) gpt_attr |= GPT_COW;
     122    if( tsar_attr & TSAR_MMU_SWAP       ) gpt_attr |= GPT_SWAP;
     123    if( tsar_attr & TSAR_MMU_LOCKED     ) gpt_attr |= GPT_LOCKED;
     124
     125    return gpt_attr;
     126}
    75127
    76128/////////////////////////////////////
     
    107159        gpt->page = GET_PTR( page_xp );
    108160
    109 /*
    110     // initialize PTE entries attributes masks
    111     GPT_MAPPED     = TSAR_MMU_PRESENT;
    112     GPT_SMALL      = TSAR_MMU_PTD1;
    113     GPT_READABLE   = TSAR_MMU_PRESENT;
    114     GPT_WRITABLE   = TSAR_MMU_WRITABLE;
    115     GPT_EXECUTABLE = TSAR_MMU_EXECUTABLE;
    116     GPT_CACHABLE   = TSAR_MMU_CACHABLE;
    117     GPT_USER       = TSAR_MMU_USER;     
    118     GPT_DIRTY      = TSAR_MMU_DIRTY;   
    119     GPT_ACCESSED   = TSAR_MMU_LOCAL | TSAR_MMU_REMOTE;
    120     GPT_GLOBAL     = TSAR_MMU_GLOBAL;
    121     GPT_COW        = TSAR_MMU_COW;
    122     GPT_SWAP       = TSAR_MMU_SWAP;
    123     GPT_LOCKED     = TSAR_MMU_LOCKED;
    124 */
    125161        return 0;
    126162} // end hal_gpt_create()
     
    154190        {
    155191        pte1 = pt1[ix1];
    156                 if( (pte1 & TSAR_MMU_PRESENT) != 0 )  // PTE1 valid
     192                if( (pte1 & TSAR_MMU_MAPPED) != 0 )  // PTE1 valid
    157193        {
    158             if( (pte1 & TSAR_MMU_PTD1) == 0 )   // BIG page
     194            if( (pte1 & TSAR_MMU_SMALL) == 0 )   // BIG page
    159195            {
    160196                if( (pte1 & TSAR_MMU_USER) != 0 )
     
    185221                    {
    186222                        attr = TSAR_MMU_ATTR_FROM_PTE2( pt2[2 * ix2] );
    187                                 if( ((attr & TSAR_MMU_PRESENT) != 0 ) && ((attr & TSAR_MMU_USER) != 0) ) 
     223                                if( ((attr & TSAR_MMU_MAPPED) != 0 ) && ((attr & TSAR_MMU_USER) != 0) ) 
    188224                        {
    189225                            // release the physical page
     
    230266        {
    231267        pte1 = pt1[ix1];
    232                 if( (pte1 & TSAR_MMU_PRESENT) != 0 )
     268                if( (pte1 & TSAR_MMU_MAPPED) != 0 )
    233269        {
    234             if( (pte1 & TSAR_MMU_PTD1) == 0 )  // BIG page
     270            if( (pte1 & TSAR_MMU_SMALL) == 0 )  // BIG page
    235271            {
    236272                printk(" - BIG   : pt1[%d] = %x\n", ix1 , pte1 );
     
    247283                    pte2_attr = TSAR_MMU_ATTR_FROM_PTE2( pt2[2 * ix2] );
    248284                    pte2_ppn  = TSAR_MMU_PPN_FROM_PTE2( pt2[2 * ix2 + 1] );
    249                             if( (pte2_attr & TSAR_MMU_PRESENT) != 0 )
     285                            if( (pte2_attr & TSAR_MMU_MAPPED) != 0 )
    250286                    {
    251287                        printk(" - SMALL   : pt1[%d] = %x / pt2[%d] / pt2[%d]\n",
     
    263299                         vpn_t     vpn,
    264300                         ppn_t     ppn,
    265                          uint32_t  attr )
    266 {
    267     uint32_t          * pt1;         // virtual base addres of PT1
    268         volatile uint32_t * pte1_ptr;    // pointer on PT1 entry
    269         uint32_t            pte1;        // PT1 entry value
    270 
    271         ppn_t               pt2_ppn;     // PPN of PT2
    272         uint32_t          * pt2;         // virtual base address of PT2
    273 
    274         uint32_t            small;       // requested PTE is for a small page
     301                         uint32_t  attr )    // generic GPT attributes
     302{
     303    uint32_t          * pt1;                 // virtual base addres of PT1
     304        volatile uint32_t * pte1_ptr;            // pointer on PT1 entry
     305        uint32_t            pte1;                // PT1 entry value
     306
     307        ppn_t               pt2_ppn;             // PPN of PT2
     308        uint32_t          * pt2;                 // virtual base address of PT2
     309
     310        uint32_t            small;               // requested PTE is for a small page
    275311        bool_t              atomic;
    276312
    277         page_t            * page;        // pointer on new physical page descriptor
    278     xptr_t              page_xp;     // extended pointer on new page descriptor
    279 
    280     uint32_t            ix1;         // index in PT1
    281     uint32_t            ix2;         // index in PT2
     313        page_t            * page;                // pointer on new physical page descriptor
     314    xptr_t              page_xp;             // extended pointer on new page descriptor
     315
     316    uint32_t            ix1;                 // index in PT1
     317    uint32_t            ix2;                 // index in PT2
     318
     319    uint32_t            tsar_attr;           // PTE attributes for TSAR MMU
    282320
    283321    // compute indexes in PT1 and PT2
     
    286324
    287325    pt1   = gpt->ptr;
    288         small = (attr & TSAR_MMU_PTD1);
     326        small = attr & GPT_SMALL;
     327
     328    // compute tsar_attr from generic attributes
     329    tsar_attr = gpt2tsar( attr );
    289330
    290331    // get PT1 entry value
     
    294335    // Big pages (PTE1) are only set for the kernel vsegs, in the kernel init phase.
    295336    // There is no risk of concurrent access.
    296         if( small == 0 )
    297         {
    298                 if( (pte1 != 0) || (attr & GPT_COW) )
     337        if( small == 0 ) 
     338    {
     339        if( pte1 != 0 )
    299340                {
    300                         printk("\n[ERROR] in %s : set a big page in a mapped PT1 entry / PT1[%d] = %x\n",
     341                        panic("\n[PANIC] in %s : set a big page in a mapped PT1 entry / PT1[%d] = %x\n",
    301342                   __FUNCTION__ , ix1 , pte1 );
    302                         return EINVAL;
    303343                }
    304344     
    305345        // set the PTE1
    306                 *pte1_ptr = attr | (ppn >> 9);
     346                *pte1_ptr = (tsar_attr  & TSAR_MMU_PTE1_ATTR_MASK) |
     347                    ((ppn >> 9) & TSAR_MMU_PTE1_PPN_MASK);
    307348                hal_fence();
    308349                return 0;
     
    311352    // From this point, the requested PTE is a PTE2 (small page)
    312353
    313         if( (pte1 & TSAR_MMU_PRESENT) == 0 )      // the PT1 entry is not valid
     354        if( (pte1 & TSAR_MMU_MAPPED) == 0 )      // the PT1 entry is not valid
    314355        {
    315356        // allocate one physical page for the PT2
     
    334375                {
    335376                    atomic = hal_atomic_cas( (void*)pte1, 0 ,
    336                                       TSAR_MMU_PRESENT | TSAR_MMU_PTD1 | pt2_ppn );
     377                                      TSAR_MMU_MAPPED | TSAR_MMU_SMALL | pt2_ppn );
    337378        }
    338379        while( (atomic == false) && (*pte1_ptr == 0) );
     
    356397        {
    357398        // This valid entry must be a PTD1
    358         if( (pte1 & TSAR_MMU_PTD1) == 0 )
     399        if( (pte1 & TSAR_MMU_SMALL) == 0 )
    359400        {
    360401                        printk("\n[ERROR] in %s : set a small page in a big PT1 entry / PT1[%d] = %x\n",
     
    373414        pt2[2 * ix2 + 1] = ppn;
    374415        hal_fence();
    375         pt2[2 * ix2]     = attr;
     416        pt2[2 * ix2]     = tsar_attr;
    376417        hal_fence();
    377418
    378419        return 0;
     420
    379421} // end of hal_gpt_set_pte()
    380422
     
    398440    pte1 = pt1[ix1];
    399441
    400         if( (pte1 & TSAR_MMU_PRESENT) == 0 )   // PT1 entry not present
     442        if( (pte1 & TSAR_MMU_MAPPED) == 0 )   // PT1 entry not present
    401443        {
    402444                *attr = 0;
     
    404446        }
    405447
    406         if( (pte1 & TSAR_MMU_PTD1) == 0 )     // it's a PTE1
    407         {
    408                 *attr = TSAR_MMU_ATTR_FROM_PTE1( pte1 );
     448        if( (pte1 & TSAR_MMU_SMALL) == 0 )     // it's a PTE1
     449        {
     450                *attr = tsar2gpt( TSAR_MMU_ATTR_FROM_PTE1( pte1 ) );
    409451        *ppn  = TSAR_MMU_PPN_FROM_PTE1( pte1 ) | (vpn & ((1<<TSAR_MMU_IX2_WIDTH)-1));
    410452        }
     
    416458
    417459            *ppn  = pt2[2*ix2+1] & ((1<<TSAR_MMU_PPN_WIDTH)-1);
    418             *attr = pt2[2*ix2];
     460            *attr = tsar2gpt( pt2[2*ix2] );
    419461    }
    420462} // end hal_gpt_get_pte()
     
    432474    ppn_t      ppn;         // PPN of page to be released
    433475
    434     kmem_req_t req;
    435 
    436476    // get ix1 & ix2 indexes
    437477    uint32_t   ix1 = TSAR_MMU_IX1_FROM_VPN( vpn );
    438478    uint32_t   ix2 = TSAR_MMU_IX2_FROM_VPN( vpn );
    439479
    440     // get pointer on calling process
    441     process_t  * process = CURRENT_THREAD->process;
    442 
    443     // compute is_ref
    444     bool_t is_ref = ( GET_CXY( process->ref_xp ) == local_cxy );
    445 
    446480    // get PTE1 value
    447481        pt1      = gpt->ptr;
    448482    pte1     = pt1[ix1];
    449483
    450         if( (pte1 & TSAR_MMU_PRESENT) == 0 )   // PT1 entry not present
     484        if( (pte1 & TSAR_MMU_MAPPED) == 0 )   // PT1 entry not present
    451485        {
    452486                return;
    453487        }
    454488
    455         if( (pte1 & TSAR_MMU_PTD1) == 0 )      // it's a PTE1
     489        if( (pte1 & TSAR_MMU_SMALL) == 0 )      // it's a PTE1
    456490        {
    457491        // get PPN
     
    461495        pt1[ix1] = 0;
    462496            hal_fence();
    463 
    464         // releases the physical page if local
    465         // req.type  = KMEM_PAGE;
    466             // req.size  = 9;
    467         // req.ptr   = (void*)(ppn << CONFIG_PPM_PAGE_SHIFT);
    468             // kmem_free( &req );
    469497
    470498        return;
     
    483511            hal_fence();       
    484512
    485         // releases the small page
    486         // req.type  = KMEM_PAGE;
    487             // req.size  = 0;
    488         // req.ptr   = (void*)(ppn << CONFIG_PPM_PAGE_SHIFT);
    489             // kmem_free( &req );
    490 
    491513        return;
    492514    }
     
    519541
    520542    // If present, the page must be small
    521         if( ((pte1 & TSAR_MMU_PRESENT) != 0) && ((pte1 & TSAR_MMU_PTD1) == 0) )
     543        if( ((pte1 & TSAR_MMU_MAPPED) != 0) && ((pte1 & TSAR_MMU_SMALL) == 0) )
    522544    {
    523545        printk("\n[ERROR] in %s : try to lock a big page / PT1[%d] = %x\n",
     
    526548    }
    527549
    528         if( (pte1 & TSAR_MMU_PRESENT) == 0 )  // missing PT1 entry   
     550        if( (pte1 & TSAR_MMU_MAPPED) == 0 )  // missing PT1 entry   
    529551        {
    530552        // allocate one physical page for PT2
     
    550572                {
    551573                        atomic = hal_atomic_cas( (void*)pte1_ptr , 0 ,
    552                                      TSAR_MMU_PRESENT | TSAR_MMU_PTD1 | pt2_ppn );
     574                                     TSAR_MMU_MAPPED | TSAR_MMU_SMALL | pt2_ppn );
    553575                }
    554576        while( (atomic == false) && (*pte1_ptr == 0) );
     
    570592    {
    571593        // This valid entry must be a PTD1
    572         if( (pte1 & TSAR_MMU_PTD1) == 0 )
     594        if( (pte1 & TSAR_MMU_SMALL) == 0 )
    573595        {
    574596                        printk("\n[ERROR] in %s : set a small page in a big PT1 entry / PT1[%d] = %x\n",
     
    592614        do
    593615    {
    594         // busy waiting until GPT_LOCK == 0
     616        // busy waiting until TSAR_MMU_LOCK == 0
    595617        do
    596618                {
     
    598620                        hal_rdbar();
    599621                }
    600         while( (attr & GPT_LOCKED) != 0 );
    601 
    602         // try to set the GPT_LOCK wit a CAS
    603                 atomic = hal_atomic_cas( (void*)pte2_ptr, attr , (attr | GPT_LOCKED) );
     622        while( (attr & TSAR_MMU_LOCKED) != 0 );
     623
     624                atomic = hal_atomic_cas( (void*)pte2_ptr, attr , (attr | TSAR_MMU_LOCKED) );
    604625        }
    605626    while( atomic == 0 );
    606627
    607628        return 0;
     629
    608630}  // end hal_gpt_lock_pte()
    609631
     
    632654
    633655    // check PTE1 present and small page
    634     if( ((pte1 & TSAR_MMU_PRESENT) == 0) || ((pte1 & TSAR_MMU_PTD1) == 0) )
     656    if( ((pte1 & TSAR_MMU_MAPPED) == 0) || ((pte1 & TSAR_MMU_SMALL) == 0) )
    635657    {
    636658        printk("\n[ERROR] in %s : try to unlock a big or undefined page / PT1[%d] = %x\n",
     
    650672
    651673    // check PTE2 present and locked
    652     if( ((attr & TSAR_MMU_PRESENT) == 0) || ((attr & GPT_LOCKED) == 0) );
    653     {
    654         printk("\n[ERROR] in %s : try to unlock an undefined page / PT1[%d] = %x\n",
     674    if( ((attr & TSAR_MMU_MAPPED) == 0) || ((attr & TSAR_MMU_LOCKED) == 0) );
     675    {
     676        printk("\n[ERROR] in %s : unlock an unlocked/unmapped page / PT1[%d] = %x\n",
    655677                 __FUNCTION__ , ix1 , pte1 );
    656678        return EINVAL;
     
    658680
    659681    // reset GPT_LOCK
    660         *pte2_ptr = attr & !GPT_LOCKED;
     682        *pte2_ptr = attr & ~TSAR_MMU_LOCKED;
    661683
    662684        return 0;
     685
    663686}  // end hal_gpt_unlock_pte()
    664687
     
    695718        {
    696719        pte1 = src_pt1[ix1];
    697                 if( (pte1 & TSAR_MMU_PRESENT) != 0 )
     720                if( (pte1 & TSAR_MMU_MAPPED) != 0 )
    698721        {
    699             if( (pte1 & TSAR_MMU_PTD1) == 0 )  // PTE1 => big kernel page
     722            if( (pte1 & TSAR_MMU_SMALL) == 0 )  // PTE1 => big kernel page
    700723            {
    701724                // big kernel pages are shared by all processes => copy it
     
    727750                // set a new PTD1 in DST_GPT
    728751                dst_pt2_ppn  = (ppn_t)ppm_page2ppn( page_xp );
    729                 dst_pt1[ix1] = TSAR_MMU_PRESENT | TSAR_MMU_PTD1 | dst_pt2_ppn;
     752                dst_pt1[ix1] = TSAR_MMU_MAPPED | TSAR_MMU_SMALL | dst_pt2_ppn;
    730753
    731754                // get pointer on PT2 in SRC_GPT
     
    739762                    pte2_attr = TSAR_MMU_ATTR_FROM_PTE2( src_pt2[2 * ix2] );
    740763
    741                             if( (pte2_attr & TSAR_MMU_PRESENT) != 0 )  // valid PTE2 in SRC_GPT
     764                            if( (pte2_attr & TSAR_MMU_MAPPED) != 0 )  // valid PTE2 in SRC_GPT
    742765                    {
    743766                        // get GPT_WRITABLE & PPN
Note: See TracChangeset for help on using the changeset viewer.