Changeset 732 for soft


Ignore:
Timestamp:
Dec 3, 2015, 4:27:38 PM (8 years ago)
Author:
alain
Message:

Introduce a new rule to simplify the memory mapping:
A big physical page cannot contain more than one vseg.
(Only the 4 identity mapping vsegs used by the boot code
can be packed in one single vseg)

File:
1 edited

Legend:

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

    r726 r732  
    3131//    - the various "application.elf" files.
    3232//
    33 // 2) The GIET-VM uses the paged virtual memory to provides two services:
     33// 2) The GIET-VM uses the paged virtual memory to provide two services:
    3434//    - classical memory protection, when several independant applications compiled
    3535//      in different virtual spaces are executing on the same hardware platform.
     
    198198// As each vseg is mapped by a different processor, the PT1 entry cannot
    199199// be concurrently accessed, and we don't need to take any lock.
     200//
     201// Implementation note:
     202// This function checks that the PT1 entry is not already mapped,
     203// to enforce the rule: only one vseg in a given BPP.
     204// The 4 vsegs used by the boot code being packed in one single BPP,
     205// this verif is not done for all identity mapping vsegs.
    200206//////////////////////////////////////////////////////////////////////////////
    201207void boot_add_pte1( unsigned int vspace_id,
     
    204210                    unsigned int vpn,        // 20 bits right-justified
    205211                    unsigned int flags,      // 10 bits left-justified
    206                     unsigned int ppn )       // 28 bits right-justified
     212                    unsigned int ppn,        // 28 bits right-justified
     213                    unsigned int ident )     // identity mapping if non zero
    207214{
     215    unsigned int   pte1;     // PTE1 value
     216    paddr_t        paddr;    // PTE1 physical address
     217
    208218    // compute index in PT1
    209219    unsigned int    ix1 = vpn >> 9;         // 11 bits for ix1
    210220
    211     // get page table physical base address
    212     paddr_t  pt1_pbase = _ptabs_paddr[vspace_id][x][y];
    213 
    214     if ( pt1_pbase == 0 )
     221    // get PT1 physical base address
     222    paddr_t  pt1_base = _ptabs_paddr[vspace_id][x][y];
     223
     224    if ( pt1_base == 0 )
    215225    {
    216226        _printf("\n[BOOT ERROR] in boot_add_pte1() : no PTAB in cluster[%d,%d]"
     
    219229    }
    220230
     231    // compute pte1 physical address
     232    paddr = pt1_base + 4*ix1;
     233
     234    // check PTE1 not already mapped
     235    if ( ident == 0 )
     236    {
     237        if ( _physical_read( paddr ) & PTE_V )
     238        {
     239            _printf("\n[BOOT ERROR] in boot_add_pte1() : vpn %x already mapped "
     240                    "in PTAB[%d,%d] for vspace %d\n", vpn , x , y , vspace_id );
     241            _exit();
     242        }
     243    }
     244
    221245    // compute pte1 : 2 bits V T / 8 bits flags / 3 bits RSVD / 19 bits bppi
    222     unsigned int    pte1 = PTE_V |
    223                            (flags & 0x3FC00000) |
    224                            ((ppn>>9) & 0x0007FFFF);
     246    pte1 = PTE_V | (flags & 0x3FC00000) | ((ppn>>9) & 0x0007FFFF);
    225247
    226248    // write pte1 in PT1
    227     _physical_write( pt1_pbase + 4*ix1, pte1 );
     249    _physical_write( paddr , pte1 );
    228250
    229251    asm volatile ("sync");
     
    238260// allocation), this function checks a possible overflow of the PT2 array.
    239261// As a given entry in PT1 can be shared by several vsegs, mapped by
    240 // different processors, we need to take the lock protecting PTAB[v][x]y].
     262// different processors, we need to take the lock protecting PTAB[v][x][y].
    241263//////////////////////////////////////////////////////////////////////////////
    242264void boot_add_pte2( unsigned int vspace_id,
     
    245267                    unsigned int vpn,        // 20 bits right-justified
    246268                    unsigned int flags,      // 10 bits left-justified
    247                     unsigned int ppn )       // 28 bits right-justified
     269                    unsigned int ppn,        // 28 bits right-justified
     270                    unsigned int ident )     // identity mapping if non zero
    248271{
    249272    unsigned int ix1;
     
    331354//
    332355// A given vseg can be mapped in a Big Physical Pages (BPP: 2 Mbytes) or in a
    333 // Small Physical Pages (SPP: 4 Kbytes), depending on the "big" attribute of vseg,
    334 // with the following rules:
    335 // - SPP : There is only one vseg in a small physical page, but a single vseg
    336 //   can cover several contiguous small physical pages.
    337 // - BPP : It can exist several vsegs in a single big physical page, and a single
    338 //   vseg can cover several contiguous big physical pages.
     356// Small Physical Pages (SPP: 4 Kbytes), depending on the "big" attribute of vseg.
     357//
     358// All boot vsegs are packed in a single BPP (2 Mbytes). For all other vsegs,
     359// there is only one vseg in a given page (BPP or SPP), but a single vseg can
     360// cover several contiguous physical pages.
     361// Only the vsegs used by the boot code can be identity mapping.
    339362//
    340363// 1) First step: it computes various vseg attributes and checks
     
    343366// 2) Second step: it allocates the required number of contiguous physical pages,
    344367//    computes the physical base address (if the vseg is not identity mapping),
    345 //    and register it in the vseg pbase field.
    346 //    Only the vsegs used by the boot code and the peripheral vsegs
    347 //    can be identity mapping. The first big physical page in cluster[0,0]
    348 //    is reserved for the boot vsegs.
     368//    register it in the vseg pbase field, and update the page table(s).
    349369//
    350 // 3) Third step (only for vseg that have the VSEG_TYPE_PTAB): the M page tables
    351 //    associated to the M vspaces must be packed in the same vseg.
     370// 3) Third step (only for vseg that have the VSEG_TYPE_PTAB): for a given cluster,
     371//    the M page tables associated to the M vspaces are packed in the same vseg.
    352372//    We divide this vseg in M sub-segments, and compute the vbase and pbase
    353373//    addresses for M page tables, and register these addresses in the _ptabs_paddr
    354374//    and _ptabs_vaddr arrays.
    355 // 
    356375/////////////////////////////////////////////////////////////////////////////////////
    357376void boot_vseg_map( mapping_vseg_t* vseg,
     
    414433
    415434    // compute ppn
    416     if ( vseg->ident )           // identity mapping
     435    if ( vseg->ident )           // identity mapping : no memory allocation required
    417436    {
    418437        ppn = vpn;
     
    425444            pmem_alloc_t*     palloc = &boot_pmem_alloc[x_dest][y_dest];
    426445
    427             if ( big == 0 )             // SPP : small physical pages
     446            if ( big == 0 )      // allocate contiguous SPPs
    428447            {
    429                 // allocate contiguous small physical pages
    430448                ppn = _get_small_ppn( palloc, npages );
    431449            }
    432             else                            // BPP : big physical pages
     450            else                 // allocate contiguous BPPs
    433451            {
    434  
    435                 // one big page can be shared by several vsegs
    436                 // we must chek if BPP already allocated
    437                 if ( is_ptab )   // It cannot be mapped
    438                 {
    439                     ppn = _get_big_ppn( palloc, npages );
    440                 }
    441                 else             // It can be mapped
    442                 {
    443                     unsigned int ix1   = vpn >> 9;   // 11 bits
    444                     paddr_t      paddr = _ptabs_paddr[vsid][x_dest][y_dest] + (ix1<<2);
    445                     unsigned int pte1  = _physical_read( paddr );
    446 
    447                     if ( (pte1 & PTE_V) == 0 )     // BPP not allocated yet
    448                     {
    449                         // allocate contiguous big physical pages
    450                         ppn = _get_big_ppn( palloc, npages );
    451                     }
    452                     else                           // BPP already allocated
    453                     {
    454                         // test if new vseg has the same mode bits than
    455                         // the other vsegs in the same big page
    456                         unsigned int pte1_mode = 0;
    457                         if (pte1 & PTE_C) pte1_mode |= C_MODE_MASK;
    458                         if (pte1 & PTE_X) pte1_mode |= X_MODE_MASK;
    459                         if (pte1 & PTE_W) pte1_mode |= W_MODE_MASK;
    460                         if (pte1 & PTE_U) pte1_mode |= U_MODE_MASK;
    461                         if (vseg->mode != pte1_mode)
    462                         {
    463                             _printf("\n[BOOT ERROR] in boot_vseg_map() : "
    464                                     "vseg %s has different flags than another vseg "
    465                                     "in the same BPP\n", vseg->name );
    466                             _exit();
    467                         }
    468                         ppn = ((pte1 << 9) & 0x0FFFFE00);
    469                     }
    470                 }
    471                 ppn = ppn | (vpn & 0x1FF);
     452                ppn = _get_big_ppn( palloc, npages );
    472453            }
    473454        }
     
    478459    }
    479460
    480     // update vseg.pbase field and update vsegs chaining
     461    // update vseg.pbase field and register vseg mapped
    481462    vseg->pbase     = ((paddr_t)ppn) << 12;
    482463    vseg->mapped    = 1;
    483 
    484464
    485465    //////////// Third step : (only if the vseg is a page table)
     
    611591                               vpn + (p<<9),
    612592                               flags,
    613                                ppn + (p<<9) );
     593                               ppn + (p<<9),
     594                               vseg->ident );
    614595            }
    615596            else         // small pages => PTE2s
     
    620601                               vpn + p,     
    621602                               flags,
    622                                ppn + p );
     603                               ppn + p,
     604                               vseg->ident );
    623605            }
    624606        }
     
    638620                                           vpn + (p<<9),
    639621                                           flags,
    640                                            ppn + (p<<9) );
     622                                           ppn + (p<<9),
     623                                           vseg->ident );
    641624                        }
    642625                        else         // small pages => PTE2s
     
    647630                                           vpn + p,
    648631                                           flags,
    649                                            ppn + p );
     632                                           ppn + p,
     633                                           vseg->ident );
    650634                        }
    651635                    }
     
    664648                                   vpn + (p<<9),
    665649                                   flags,
    666                                    ppn + (p<<9) );
     650                                   ppn + (p<<9),
     651                                   vseg->ident );
    667652                }
    668653                else         // small pages = PTE2s
     
    673658                                   vpn + p,
    674659                                   flags,
    675                                    ppn + p );
     660                                   ppn + p,
     661                                   vseg->ident );
    676662                }
    677663            }
     
    694680                                               vpn + (p<<9),
    695681                                               flags,
    696                                                ppn + (p<<9) );
     682                                               ppn + (p<<9),
     683                                               vseg->ident );
    697684                            }
    698685                            else        // small pages -> PTE2s
     
    703690                                               vpn + p,
    704691                                               flags,
    705                                                ppn + p );
     692                                               ppn + p,
     693                                               vseg->ident );
    706694                            }
    707695                        }
     
    13371325        psched->context[ltid].slot[CTX_VSID_ID],
    13381326        psched->context[ltid].slot[CTX_NORUN_ID],
    1339         psched->context[ltid].slot[CTX_SIG_ID] );
     1327        psched->context[ltid].slot[CTX_SIGS_ID] );
    13401328#endif
    13411329                } // end if FIT
     
    18971885            boot_ptab_extend();
    18981886
    1899             _printf("\n[BOOT] Physical memory allocators and page tables"
     1887            _printf("\n[BOOT] Page tables"
    19001888                    " initialized at cycle %d\n", _get_proctime() );
    19011889        }
Note: See TracChangeset for help on using the changeset viewer.