Ignore:
Timestamp:
Oct 9, 2013, 9:32:41 AM (11 years ago)
Author:
meunier
Message:
  • Added a syscall and some user functions to manipulate the Simulation Helper
  • Changed the the way the Vseg -> Pseg mapping is made during the boot to better utilize the address space (+ adaptation of the algorithm in memo)
  • Fixed a bug in boot_init (vobj_init): the vobj initialization could only be made for the first application (ptpr was not changed)
File:
1 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/memo/src/pseg.cpp

    r238 r255  
    3535#include <iomanip>
    3636
     37#include <cstdio>
     38
    3739#include "pseg.h"
    3840#include "exception.h"
     41
     42
     43#define max(x, y) (((x) > (y)) ? (x) : (y))
    3944
    4045
     
    4449
    4550//////////////////////////////////////
    46 const std::string & VSeg::name() const
    47 {
     51const std::string & VSeg::name() const {
    4852        return m_name;
    4953}
    5054
    5155//////////////////////////////////////
    52 const std::string & VSeg::file() const
    53 {
     56const std::string & VSeg::file() const {
    5457        return m_file;
    5558}
    5659
    5760///////////////////////////
    58 uintptr_t VSeg::vma() const
    59 {
     61uintptr_t VSeg::vma() const {
    6062        return m_vma;
    6163}
    6264
    6365/////////////////////////
    64 paddr_t VSeg::lma() const
    65 {
     66paddr_t VSeg::lma() const {
    6667        return m_lma;
    6768}
    6869
    6970///////////////////////////
    70 size_t VSeg::length() const
    71 {
     71size_t VSeg::length() const {
    7272        return m_length;
    7373}
    7474
    7575/////////////////////////
    76 size_t VSeg::type() const
    77 {
     76size_t VSeg::type() const {
    7877        return m_type;
    7978}
    8079
    8180/////////////////////////////////////////
    82 void VSeg::print( std::ostream &o ) const
     81void VSeg::print(std::ostream &o) const
    8382{
    8483        o << std::hex << std::noshowbase
     
    8988      << m_lma << ", size: 0x"
    9089      << std::setw (8) << std::setfill('0')
    91       << m_length  << ",ident: "
    92       << (m_ident ? "yes" : "no") << ", in(file): "
    93       << m_file << ", name: " << m_name << ">";
     90          << m_length  << ",ident: "
     91          << (m_ident ? "yes" : "no") << ", in(file): "
     92          << m_file << ", name: " << m_name << ">";
    9493}
    9594
    9695/////////////
    97 VSeg::~VSeg()
    98 {
    99 }
     96VSeg::~VSeg() {}
    10097
    10198/////////////////////////////////////////
    102 VSeg & VSeg::operator=( const VSeg &ref )
    103 {
    104     if ( &ref == this )
     99VSeg & VSeg::operator=(const VSeg & ref)
     100{
     101    if (&ref == this)
    105102        return *this;
    106103
    107     m_name = ref.m_name,
     104    m_name = ref.m_name;
    108105    m_file = ref.m_file;
    109106    m_vma = ref.m_vma;
     
    111108    m_length = ref.m_length;
    112109    m_ident = ref.m_ident;
    113         return *this;
     110    return *this;
    114111}
    115112
     
    117114VSeg::VSeg()
    118115    : m_name("No Name"),
    119       m_file("Empty section"),
    120       m_vma(0),
    121       m_length(0),
    122       m_loadable(false),
    123       m_ident(0)
     116    m_file("Empty section"),
     117    m_vma(0),
     118    m_length(0),
     119    m_loadable(false),
     120    m_ident(0)
    124121{
    125122}
     
    127124////////////////////////////////////
    128125VSeg::VSeg(std::string&  binaryName,
    129            std::string&  name,
    130            uintptr_t     vma,
    131            size_t        length,
    132            bool          loadable,
    133            bool          ident)
    134     : m_name(name),
    135       m_file(binaryName),
    136       m_vma(vma),
    137       m_length(length),
    138       m_loadable(loadable),
    139       m_ident(ident)
     126        std::string&  name,
     127        uintptr_t     vma,
     128        size_t        length,
     129        bool          loadable,
     130        bool          ident)
     131: m_name(name),
     132    m_file(binaryName),
     133    m_vma(vma),
     134    m_length(length),
     135    m_loadable(loadable),
     136    m_ident(ident)
    140137{
    141138}
    142139
    143140/////////////////////////////
    144 VSeg::VSeg( const VSeg &ref )
    145     : m_name("To be copied"),
    146       m_file("Empty"),
    147       m_vma(0),
    148       m_length(0),
    149       m_loadable(false),
    150       m_ident(0)
     141VSeg::VSeg(const VSeg &ref):
     142    m_name(ref.m_name),
     143    m_file(ref.m_file),
     144    m_vma(ref.m_vma),
     145    m_length(ref.m_length),
     146    m_loadable(ref.m_loadable),
     147    m_ident(ref.m_ident)
    151148{
    152149    (*this) = ref;
     
    159156
    160157/////////////////////////
    161 paddr_t PSeg::lma() const
    162 {
    163         return m_lma;
     158paddr_t PSeg::lma() const {
     159    return m_lma;
    164160}
    165161
    166162///////////////////////////
    167 paddr_t PSeg::limit() const
    168 {
    169         return m_limit;
    170 }
    171 
    172 /////////////////////////////
    173 paddr_t PSeg::length() const
    174 {
    175         return m_length;
     163paddr_t PSeg::length() const {
     164    return m_length;
    176165}
    177166
    178167/////////////////////////
    179 size_t PSeg::type() const
    180 {
    181         return m_type;
    182 }
    183 
    184 /////////////////////////////
    185 paddr_t PSeg::nextLma() const
    186 {
    187         return m_nextLma;
     168size_t PSeg::type() const {
     169    return m_type;
    188170}
    189171
    190172//////////////////////////////////////
    191 const std::string & PSeg::name() const
    192 {
    193         return m_name;
     173const std::string & PSeg::name() const {
     174    return m_name;
    194175}
    195176
     
    198179{
    199180
    200     if(this->m_type == PSEG_TYPE_PERI)
     181    if (this->m_type == PSEG_TYPE_PERI)
    201182        return;
    202183
     
    204185    size_t    size = m_vsegs.size();
    205186    paddr_t   used[size][2];          // lma, lma+length
    206     size_t    i,j,error=0;
    207    
    208     for(it = m_vsegs.begin(), i= 0 ; it < m_vsegs.end() ; it++, i++)
     187    size_t    i, j, error = 0;
     188
     189    for (it = m_vsegs.begin(), i = 0; it < m_vsegs.end(); it++, i++)
    209190    {
    210191        paddr_t it_limit = (*it).lma() + (*it).length();
    211         for(j=0; j< i; j++)
     192        for(j = 0; j < i; j++)
    212193        {
    213             if( used[j][0] == (*it).lma() ) //not the same lma ,
    214             {
    215                 error = 1;
    216                 std::cout << "ok \n";
    217             }
    218             if( used[j][1] == it_limit )  // and not the same limit
     194            if (used[j][0] == (*it).lma()) //not the same lma ,
     195                {
     196                    error = 1;
     197                }
     198            if (used[j][1] == it_limit)  // and not the same limit
    219199            {
    220200                error = 2;
    221201            }
    222             if( (used[j][0] < (*it).lma()) and ((*it).lma() < used[j][1]) ) // lma  within
     202            if ((used[j][0] < (*it).lma()) and ((*it).lma() < used[j][1])) // lma  within
    223203            {
    224204                error = 3;
    225205            }
    226             if(  ((used[j][0] < it_limit) and (it_limit < used[j][1] )) ) // limit no within
     206            if (((used[j][0] < it_limit) and (it_limit < used[j][1]))) // limit no within
    227207            {
    228208                error = 4;
     
    232212                std::cout << "used[j][1]: " << std::hex << used[j][1] << std::endl;
    233213            }
    234             if(error)
     214            if (error)
    235215            {
    236216                std::ostringstream err;
    237                 err << " Error" << error << " ,ovelapping Buffers:" << std::endl
     217                err << " Error" << error << ", ovelapping Buffers:" << std::endl
    238218                    << *it << std::endl << m_vsegs[j] << std::endl;
    239219                throw exception::RunTimeError( err.str().c_str() );
     
    246226}
    247227
    248 //////////////////////////////////////
    249 void PSeg::setName(std::string& name )
    250 {
    251     m_name = name;
    252 }
    253228
    254229/////////////////////////////////////////////////////////
    255 paddr_t PSeg::align( paddr_t toAlign, unsigned alignPow2)
    256 {
     230paddr_t PSeg::align(paddr_t toAlign, unsigned alignPow2) {
    257231    return ((toAlign + (1 << alignPow2) - 1 ) >> alignPow2) << alignPow2;
    258232}
    259233
    260234//////////////////////////////////////////
    261 paddr_t PSeg::pageAlign( paddr_t toAlign )
    262 {
     235paddr_t PSeg::pageAlign(paddr_t toAlign) {
    263236    size_t pgs = pageSize();
    264237    size_t pageSizePow2 = __builtin_ctz(pgs);
    265    
     238
    266239    return align(toAlign, pageSizePow2);
    267240}
    268241
    269 ////////////////////////////////
    270 void PSeg::setLma( paddr_t lma )
    271 {
    272     m_lma = lma;
    273    
    274     m_nextLma = pageAlign(lma);
    275 
    276     m_pageLimit = pageAlign(m_lma+m_length);
    277 
    278     m_limit = (m_lma + m_length);
    279 }
    280 
    281 /////////////////////////////////////
    282 void PSeg::setLength( paddr_t length )
    283 {
    284     m_length = length;
    285 
    286     m_pageLimit = pageAlign(m_lma+m_length);
    287 
    288     m_limit = (m_lma + m_length);
    289 }
     242
    290243
    291244////////////////////////////
    292 void PSeg::add( VSeg& vseg )
    293 {
    294     vseg.m_lma = m_nextLma;
    295 //    incNextLma(vseg.length());   //for the next vseg
     245void PSeg::add(VSeg& vseg) {
     246    std::vector<VSeg>::iterator it;
     247    int nb_elems = m_vsegs.size();
     248    int i = 0;
     249    bool mapped = false;
     250    paddr_t prev_base = m_lma;
     251    paddr_t prev_length = 0x0;
     252    paddr_t curr_base = 0x0;
     253    paddr_t curr_length = 0x0;
     254    paddr_t next_base = 0x0;
     255    paddr_t next_length = 0x0;
     256
     257    const int alignment = max(vseg.m_align, __builtin_ctz(pageSize())); // 12
     258
     259    if (vseg.length() == 0) {
     260        std::cout << "*** Error: Adding a vseg of size 0 (base " << vseg.vma() << ")" << std::endl;
     261        exit(1);
     262    }
     263
     264    if (nb_elems == 0) {
     265        if (vseg.length() <= m_length) {
     266            vseg.m_lma = m_lma;
     267            m_vsegs.push_back(vseg);
     268            return;
     269        }
     270        else {
     271            std::cout << "*** Error: Not enough space to map first VSeg (base = "
     272                      << std::hex << vseg.vma() << " - Size = " << vseg.length() << ")" << std::endl;
     273            std::cout << "    PSeg too small! (base = " << m_lma << " - size = "
     274                      << m_length << ")" << std::endl;
     275            exit(1);
     276        }
     277    }
     278
     279    curr_base = m_vsegs[0].lma(); // Initialisation avant recherche du min
     280    curr_length = m_vsegs[0].length();
     281    for (it = m_vsegs.begin(); it != m_vsegs.end(); it++) {
     282        if ((*it).lma() < curr_base) {
     283            curr_base = (*it).lma();
     284            curr_length = (*it).length();
     285        }
     286    }
     287
     288    while (i < nb_elems) {
     289        if (align(prev_base + prev_length, alignment) + vseg.length() <= curr_base) {
     290            vseg.m_lma = align(prev_base + prev_length, alignment);
     291            mapped = true;
     292            break;
     293        }
     294        else if (i < nb_elems - 1) {
     295            // Searching for the vseg already mapped with lowest paddr > curr_base
     296            next_base = 0;
     297            bool found = false;
     298            for (it = m_vsegs.begin(); it != m_vsegs.end(); it++) {
     299                if ((!found || (*it).lma() < next_base) && (*it).lma() > curr_base) {
     300                    found = true;
     301                    next_base = (*it).lma();
     302                    next_length = (*it).length();
     303                }
     304            }
     305            assert(found);
     306
     307            prev_base = curr_base;
     308            prev_length = curr_length;
     309
     310            curr_base = next_base;
     311            curr_length = next_length;
     312        }
     313        else {
     314            if (align(curr_base + curr_length, alignment) + vseg.length() <= m_lma + m_length) {
     315                vseg.m_lma = align(curr_base + curr_length, alignment);
     316                mapped = true;
     317            }
     318        }
     319        i++;
     320    }
     321
     322    if (!mapped) {
     323        std::cout << "*** Error: Not enough space to map VSeg (base = " << std::hex << vseg.vma() << " - Size = " << vseg.length() << ")" << std::endl;
     324        exit(1);
     325    }
     326
    296327    m_vsegs.push_back(vseg);
    297328}
    298329
     330
    299331/////////////////////////////////
    300 void PSeg::addIdent( VSeg& vseg )
    301 {
     332void PSeg::addIdent(VSeg& vseg) {
     333    std::vector<VSeg>::iterator it;
     334
     335    for (it = m_vsegs.begin(); it != m_vsegs.end(); it++) {
     336        if ((vseg.vma() == (*it).lma()) ||
     337            ((vseg.vma() < (*it).lma()) && (vseg.vma() + vseg.length() > (*it).lma())) ||
     338            ((vseg.vma() > (*it).lma()) && ((*it).lma() + (*it).length() > vseg.vma()))) {
     339            std::cout << "*** Error: Identity VSeg overlaps another segment:" << std::endl
     340                      << "Added Segment Base : " << std::hex << vseg.vma()
     341                      << " - Size : " << vseg.length() << std::endl;
     342            std::cout << "Existing Segment Base : " << (*it).lma()
     343                      << " - size : " << (*it).length() << std::endl;
     344            exit(1);
     345        }
     346    }
     347
    302348    vseg.m_lma = vseg.m_vma;
    303349    m_vsegs.push_back(vseg);
    304350}
    305351
     352
    306353/////////////////////////////////////////
    307 void PSeg::setNextLma( paddr_t nextLma)
    308 {
    309     m_nextLma = nextLma;
    310     confNextLma();
    311 }
    312 
    313 //////////////////////////////////
    314 void PSeg::incNextLma( size_t inc)
    315 {
    316     m_nextLma += inc;
    317     confNextLma();
    318 }
    319 
    320 ////////////////////////
    321 void PSeg::confNextLma()
    322 {
    323     if(m_nextLma > m_limit)
    324     {
    325         std::cerr << "Erreur pseg overflow... nextLma: "
    326                   << std::hex << m_nextLma << ", limit: "
    327                   << m_limit << std::endl;
    328         exit(1);
    329     }
    330 
    331     m_nextLma = pageAlign( m_nextLma );
    332 
    333     if(m_nextLma > m_pageLimit)
    334     {
    335         std::cerr << "Erreur pseg page overflow... nextLma: "
    336                   << std::hex << m_nextLma << ", limit: "
    337                   << m_pageLimit << std::endl;
    338         exit(1);
    339     }
    340 }
    341 
    342 /////////////////////////////////
    343 void PSeg::setPageSize(size_t pg)
    344 {
    345     if( pg == 0)
    346     {
    347         std::cerr << "PageSize must be positive" << std::endl;
    348         return;
    349     }
    350     pageSize() = pg;
    351 }
    352 
    353 ////////////////////////
    354 size_t& PSeg::pageSize()
    355 {
    356     static size_t m_pageSize;
    357     return m_pageSize;
    358 }
    359 
    360 /////////////////////////////////////////
    361 PSeg & PSeg::operator=( const PSeg &ref )
    362 {
    363     if ( &ref == this )
     354PSeg & PSeg::operator=(const PSeg &ref) {
     355    if (&ref == this) {
    364356        return *this;
     357    }
    365358
    366359    m_name = ref.m_name;
    367360    m_length = ref.m_length;
    368     m_limit = ref.m_limit;
    369     m_pageLimit = ref.m_pageLimit;
    370361    m_lma = ref.m_lma;
    371     m_nextLma = ref.m_nextLma;
    372362    m_vsegs = ref.m_vsegs;
    373363    m_type = ref.m_type;
     
    377367
    378368//////////////////////////////////////////
    379 void PSeg::print( std::ostream &o ) const
     369void PSeg::print(std::ostream &o) const
    380370{
    381371        o << "<Physical segment "
    382372          << std::showbase << m_name
    383373          << ", from: " << std::hex
    384       << m_lma << " to " << m_limit
     374      << m_lma
    385375      << ", size : "  << m_length
    386       << ", filled to: "  << m_nextLma
    387376      << ", type : "  << m_type
    388377      << ", containing: "<< std::endl;
     
    403392    m_length = length;
    404393    m_type = type;
    405 
    406     setLma(lma);
     394    m_lma = lma;
    407395}
    408396
    409397////////////////////////////////////
    410 PSeg::PSeg( const std::string &name):
     398PSeg::PSeg(const std::string &name):
    411399      m_lma(0),
    412       m_length(0),
    413       m_nextLma(0),
    414       m_limit(0)
    415 {
     400      m_length(0) {
    416401    m_name = name;
    417402}
    418403
    419 ////////////////////////
    420 PSeg::PSeg( paddr_t lma):
    421       m_name("No name"),
    422       m_lma(0),
    423       m_length(0),
    424       m_nextLma(0),
    425       m_limit(0)
    426 {
    427     setLma(lma);
    428 }
    429 
    430 ////////////
    431 PSeg::PSeg()
    432     :
    433       m_name("Empty section"),
    434       m_lma(0),
    435       m_length(0),
    436       m_nextLma(0),
    437       m_limit(0)
    438 {
    439 }
    440 
    441 /////////////////////////////
    442 PSeg::PSeg( const PSeg &ref )
    443     : m_name("To be copied"),
    444       m_lma(0),
    445       m_length(0),
    446       m_nextLma(0),
    447       m_limit(0)
    448 {
    449     (*this) = ref;
    450 }
    451 
    452 PSeg::~PSeg()
    453 {
    454 }
     404
     405////////////////////////////////////
     406PSeg::PSeg(const PSeg& pseg) {
     407    m_name = pseg.m_name;
     408    m_length = pseg.m_length;
     409    m_lma = pseg.m_lma;
     410    m_vsegs = pseg.m_vsegs;
     411    m_type = pseg.m_type;
     412
     413    (*this) = pseg;
     414}
     415
     416PSeg::~PSeg() {}
    455417
    456418
Note: See TracChangeset for help on using the changeset viewer.