Ignore:
Timestamp:
Jan 2, 2016, 4:57:40 PM (9 years ago)
Author:
alain
Message:

Introduce the _v2p_add_pte1(), _v2p_add_pte2(), _v2p_del_pte1(), _v2p_del_pte2() functions
to support dynamic mapping / unmapping associated to the giet_fat_mmap() and giet_fat_munmap() system calls.

Location:
soft/giet_vm/giet_common
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/giet_common/vmem.c

    r534 r751  
    1010#include <vmem.h>
    1111#include <ctx_handler.h>
     12#include <kernel_locks.h>
    1213#include <giet_config.h>
     14
     15//////////////////////////////////////////////////////////////////////////////////
     16// Extern global variables (allocated in boot.c or kernel_init.c)
     17//////////////////////////////////////////////////////////////////////////////////
     18
     19extern  spin_lock_t         _ptabs_spin_lock[GIET_NB_VSPACE_MAX][X_SIZE][Y_SIZE];
     20extern  unsigned long long  _ptabs_paddr[GIET_NB_VSPACE_MAX][X_SIZE][Y_SIZE];
     21extern  unsigned int        _ptabs_next_pt2[GIET_NB_VSPACE_MAX][X_SIZE][Y_SIZE];
     22extern  unsigned int        _ptabs_max_pt2;
    1323
    1424///////////////////////////////////////////////////////
     
    104114
    105115
     116////////////////////////////////////////////
     117void _v2p_add_pte1( unsigned int vspace_id,
     118                    unsigned int x,
     119                    unsigned int y,
     120                    unsigned int vpn,        // 20 bits right-justified
     121                    unsigned int flags,      // 10 bits left-justified
     122                    unsigned int ppn,        // 28 bits right-justified
     123                    unsigned int ident )     // identity mapping if non zero
     124{
     125    unsigned int   pte1;     // PTE1 value
     126    paddr_t        paddr;    // PTE1 physical address
     127
     128    // compute index in PT1
     129    unsigned int    ix1 = vpn >> 9;         // 11 bits for ix1
     130
     131    // get PT1 physical base address
     132    paddr_t  pt1_base = _ptabs_paddr[vspace_id][x][y];
     133
     134    if ( pt1_base == 0 )
     135    {
     136        _printf("\n[GIET ERROR] in _v2p_add_pte1() : no PTAB in cluster[%d,%d]"
     137                    " containing processors\n", x , y );
     138        _exit();
     139    }
     140
     141    // get lock protecting PTAB[vspace_id][x][y]
     142    _spin_lock_acquire( &_ptabs_spin_lock[vspace_id][x][y] );
     143
     144    // compute pte1 physical address
     145    paddr = pt1_base + 4*ix1;
     146
     147    // check PTE1 not already mapped
     148    if ( ident == 0 )
     149    {
     150        if ( _physical_read( paddr ) & PTE_V )
     151        {
     152            _printf("\n[GIET ERROR] in _v2p_add_pte1() : vpn %x already mapped "
     153                    "in PTAB[%d,%d] for vspace %d\n", vpn , x , y , vspace_id );
     154            _spin_lock_release( &_ptabs_spin_lock[vspace_id][x][y] );
     155            _exit();
     156        }
     157    }
     158
     159    // compute pte1 : 2 bits V T / 8 bits flags / 3 bits RSVD / 19 bits bppi
     160    pte1 = PTE_V | (flags & 0x3FC00000) | ((ppn>>9) & 0x0007FFFF);
     161
     162    // write pte1 in PT1
     163    _physical_write( paddr , pte1 );
     164
     165    // release lock protecting PTAB[vspace_id][x][y]
     166    _spin_lock_release( &_ptabs_spin_lock[vspace_id][x][y] );
     167
     168    asm volatile ("sync");
     169
     170}   // end _v2p_add_pte1()
     171
     172
     173
     174///////////////////////////////////////////
     175void _v2p_add_pte2( unsigned int vspace_id,
     176                    unsigned int x,
     177                    unsigned int y,
     178                    unsigned int vpn,        // 20 bits right-justified
     179                    unsigned int flags,      // 10 bits left-justified
     180                    unsigned int ppn,        // 28 bits right-justified
     181                    unsigned int ident )     // identity mapping if non zero
     182{
     183    unsigned int ix1;
     184    unsigned int ix2;
     185    paddr_t      pt2_pbase;     // PT2 physical base address
     186    paddr_t      pte2_paddr;    // PTE2 physical address
     187    unsigned int pt2_id;        // PT2 index
     188    unsigned int ptd;           // PTD : entry in PT1
     189
     190    ix1 = vpn >> 9;             // 11 bits for ix1
     191    ix2 = vpn & 0x1FF;          //  9 bits for ix2
     192
     193    // get page table physical base address
     194    paddr_t      pt1_pbase = _ptabs_paddr[vspace_id][x][y];
     195
     196    if ( pt1_pbase == 0 )
     197    {
     198        _printf("\n[GIET ERROR] in _v2p_add_pte2() : no PTAB for vspace %d "
     199                "in cluster[%d,%d]\n", vspace_id , x , y );
     200        _exit();
     201    }
     202
     203    // get lock protecting PTAB[vspace_id][x][y]
     204    _spin_lock_acquire( &_ptabs_spin_lock[vspace_id][x][y] );
     205
     206    // get ptd in PT1
     207    ptd = _physical_read( pt1_pbase + 4 * ix1 );
     208
     209    if ((ptd & PTE_V) == 0)    // undefined PTD: compute PT2 base address,
     210                               // and set a new PTD in PT1
     211    {
     212        // get a new pt2_id
     213        pt2_id = _ptabs_next_pt2[vspace_id][x][y];
     214        _ptabs_next_pt2[vspace_id][x][y] = pt2_id + 1;
     215
     216        // check overflow
     217        if (pt2_id == _ptabs_max_pt2)
     218        {
     219            _printf("\n[GIET ERROR] in _v2p_add_pte2() : PTAB[%d,%d,%d]"
     220                    " contains not enough PT2s\n", vspace_id, x, y );
     221            _spin_lock_release( &_ptabs_spin_lock[vspace_id][x][y] );
     222            _exit();
     223        }
     224
     225        pt2_pbase = pt1_pbase + PT1_SIZE + PT2_SIZE * pt2_id;
     226        ptd = PTE_V | PTE_T | (unsigned int) (pt2_pbase >> 12);
     227
     228        // set PTD into PT1
     229        _physical_write( pt1_pbase + 4*ix1, ptd);
     230    }
     231    else                       // valid PTD: compute PT2 base address
     232    {
     233        pt2_pbase = ((paddr_t)(ptd & 0x0FFFFFFF)) << 12;
     234    }
     235
     236    // set PTE in PT2 : flags & PPN in two 32 bits words
     237    pte2_paddr  = pt2_pbase + 8 * ix2;
     238    _physical_write(pte2_paddr     , (PTE_V | flags) );
     239    _physical_write(pte2_paddr + 4 , ppn );
     240
     241    // release lock protecting PTAB[vspace_id][x][y]
     242    _spin_lock_release( &_ptabs_spin_lock[vspace_id][x][y] );
     243
     244    asm volatile ("sync");
     245
     246}   // end _v2p_add_pte2()
     247
     248////////////////////////////////////////////
     249void _v2p_del_pte1( unsigned int vspace_id,
     250                    unsigned int x,
     251                    unsigned int y,
     252                    unsigned int vpn )       // 20 bits right-justified
     253{
     254    unsigned int ix1 = vpn >> 9;             // 11 bits for ix1
     255
     256    // get page table physical base address
     257    paddr_t pt1_pbase = _ptabs_paddr[vspace_id][x][y];
     258
     259    // check PTAB defined
     260    if ( pt1_pbase == 0 )
     261    {
     262        _printf("\n[GIET ERROR] in _v2p_del_pte1() : no PTAB for vspace %d "
     263                "in cluster[%d,%d]\n", vspace_id , x , y );
     264        _exit();
     265    }
     266
     267    // get ptd in PT1
     268    paddr_t ptd_paddr = pt2_pbase + 4 * ix1;
     269    unsigned int ptd = _physical_read( ptd_paddr );
     270
     271    // check ptd valid
     272    if ((ptd & PTE_V) == 0)   
     273    {
     274        _printf("\n[GIET ERROR] in _v2p_del_pte1() : vpn %x not mapped in PT1"
     275                "for vspace %d in cluster[%d,%d]\n", vpn , vspace_id , x , y );
     276        _exit();
     277    }
     278
     279    // invalidate PTD in PT1
     280    _physical_write( ptd_paddr , 0 );
     281
     282}   // end _v2p_del_pte1()
     283 
     284////////////////////////////////////////////
     285void _v2p_del_pte2( unsigned int vspace_id,
     286                    unsigned int x,
     287                    unsigned int y,
     288                    unsigned int vpn )       // 20 bits right-justified
     289{
     290    unsigned int ix1 = vpn >> 9;             // 11 bits for ix1
     291    unsigned int ix2 = vpn & 0x1FF;          //  9 bits for ix2
     292
     293    // get page table physical base address
     294    paddr_t pt1_pbase = _ptabs_paddr[vspace_id][x][y];
     295
     296    // check PTAB defined
     297    if ( pt1_pbase == 0 )
     298    {
     299        _printf("\n[GIET ERROR] in _v2p_del_pte2() : no PTAB for vspace %d "
     300                "in cluster[%d,%d]\n", vspace_id , x , y );
     301        _exit();
     302    }
     303
     304    // get ptd in PT1
     305    unsigned int ptd = _physical_read( pt1_pbase + 4 * ix1 );
     306
     307    // check ptd valid
     308    if ((ptd & PTE_V) == 0)   
     309    {
     310        _printf("\n[GIET ERROR] in _v2p_del_pte2() : vpn %x not mapped in PT1"
     311                "for vspace %d in cluster[%d,%d]\n", vpn , vspace_id , x , y );
     312        _exit();
     313    }
     314
     315    // get PT2 physical base address
     316    paddr_t  pt2_pbase = ((paddr_t)(ptd & 0x0FFFFFFF)) << 12;
     317
     318    // invalidate PTE in PT2
     319    paddr_t pte2_paddr  = pt2_pbase + 8 * ix2;
     320    _physical_write( pte2_paddr , 0 );
     321
     322    asm volatile ("sync");
     323
     324}  // end _v2p_del_pte2()
     325
     326
    106327
    107328// Local Variables:
  • soft/giet_vm/giet_common/vmem.h

    r534 r751  
    8585                                   unsigned int* flags );
    8686
     87//////////////////////////////////////////////////////////////////////////////
     88// This function registers a new PTE1 in the page table defined
     89// by the <vspace_id> argument, and the <x,y> coordinates.
     90// It updates only the first level PT1.
     91// This function checks that the PT1 entry is not already mapped,
     92// to enforce the rule: only one vseg in a given BPP.
     93// The 4 vsegs used by the boot code being packed in one single BPP,
     94// this verif is not done for all identity mapping vsegs.
     95//////////////////////////////////////////////////////////////////////////////
     96void _v2p_add_pte1( unsigned int vspace_id,   // vspace index
     97                    unsigned int x,           // cluster X coordinate
     98                    unsigned int y,           // cluster Y coordinate
     99                    unsigned int vpn,         // 20 bits right-justified
     100                    unsigned int flags,       // 10 bits left-justified
     101                    unsigned int ppn,         // 28 bits right-justified
     102                    unsigned int ident );     // identity mapping if non zero
     103
     104//////////////////////////////////////////////////////////////////////////////
     105// This function registers a new PTE2 in the page table defined
     106// by the <vspace_id> argument, and the (x,y) coordinates.
     107// It updates both the first level PT1 and the second level PT2.
     108// As the set of PT2s is implemented as a fixed size array (no dynamic
     109// allocation), this function checks a possible overflow of the PT2 array.
     110// As a given entry in PT1 can be shared by several vsegs, mapped by
     111// different processors, we need to take the lock protecting PTAB[v][x][y].
     112//////////////////////////////////////////////////////////////////////////////
     113void _v2p_add_pte2( unsigned int vspace_id,   // vspace index
     114                    unsigned int x,           // cluster X coordinate
     115                    unsigned int y,           // cluster Y coordinate
     116                    unsigned int vpn,         // 20 bits right-justified
     117                    unsigned int flags,       // 10 bits left-justified
     118                    unsigned int ppn,         // 28 bits right-justified
     119                    unsigned int ident );     // identity mapping if non zero
     120
     121//////////////////////////////////////////////////////////////////////////////
     122// This function invalidate a PTE1 entry in the page table identified by the
     123// <vspace_id> argument and the <x,y> coordinates. The PTE1 entry is
     124// defined by the <vpn> virtual page number.
     125//////////////////////////////////////////////////////////////////////////////
     126void _v2p_del_pte1( unsigned int vspace_id,   // vspace index
     127                    unsigned int x,           // cluster X coordinate
     128                    unsigned int y,           // cluster Y coordinate
     129                    unsigned int vpn );       // 20 bits right-justified
     130
     131//////////////////////////////////////////////////////////////////////////////
     132// This function invalidate a PTE2 entry in the page table identified by the
     133// <vspace_id> argument and the <x,y> coordinates. The PTE2 entry is
     134// defined by the <vpn> virtual page number. The PT1 used to access the PTE2
     135// juis not modified.
     136//////////////////////////////////////////////////////////////////////////////
     137void _v2p_del_pte2( unsigned int vspace_id,   // vspace index
     138                    unsigned int x,           // cluster X coordinate
     139                    unsigned int y,           // cluster Y coordinate
     140                    unsigned int vpn );       // 20 bits right-justified
     141
     142
    87143#endif
    88144
Note: See TracChangeset for help on using the changeset viewer.