source: soft/giet_vm/memo/src/pseg.cpp @ 251

Last change on this file since 251 was 238, checked in by alain, 11 years ago

Major evolution to support physical addresses larger than 32 bits.
The map.xml format has been modified: the vsegs associated to schedulers
are now explicitely defined and mapped in the page tables.

File size: 9.7 KB
Line 
1/* -*- c++ -*-
2 *
3 * GIET_VM_LGPL_HEADER_BEGIN
4 *
5 * This file is part of SoCLib, GNU LGPLv2.1.
6 *
7 * SoCLib is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; version 2.1 of the License.
10 *
11 * SoCLib is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with SoCLib; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 * GIET_VM_LGPL_HEADER_END
22 *
23 * Copyright (c) UPMC, Lip6, SoC
24 *         Mohamed Lamine Karaoui <Mohamed.Karaoui@lip6.fr>, 2012
25 */
26
27#include <algorithm>
28#include <string.h>
29#include <cassert>
30#include <cstring>
31#include <stdexcept>
32
33#include <iostream>
34#include <sstream>
35#include <iomanip>
36
37#include "pseg.h"
38#include "exception.h"
39
40
41/*
42 * VSeg
43 */
44
45//////////////////////////////////////
46const std::string & VSeg::name() const
47{
48        return m_name;
49}
50
51//////////////////////////////////////
52const std::string & VSeg::file() const
53{
54        return m_file;
55}
56
57///////////////////////////
58uintptr_t VSeg::vma() const
59{
60        return m_vma;
61}
62
63/////////////////////////
64paddr_t VSeg::lma() const
65{
66        return m_lma;
67}
68
69///////////////////////////
70size_t VSeg::length() const
71{
72        return m_length;
73}
74
75/////////////////////////
76size_t VSeg::type() const
77{
78        return m_type;
79}
80
81/////////////////////////////////////////
82void VSeg::print( std::ostream &o ) const
83{
84        o << std::hex << std::noshowbase
85      << "<Virtual segment from(vaddr): 0x" 
86      << std::setw (8) << std::setfill('0') 
87      << m_vma << ", to(paddr) 0x"
88      << std::setw (16) << std::setfill('0') 
89      << m_lma << ", size: 0x"
90      << std::setw (8) << std::setfill('0') 
91      << m_length  << ",ident: " 
92      << (m_ident ? "yes" : "no") << ", in(file): "
93      << m_file << ", name: " << m_name << ">";
94}
95
96/////////////
97VSeg::~VSeg()
98{
99}
100
101/////////////////////////////////////////
102VSeg & VSeg::operator=( const VSeg &ref )
103{
104    if ( &ref == this )
105        return *this;
106
107    m_name = ref.m_name,
108    m_file = ref.m_file;
109    m_vma = ref.m_vma;
110    m_lma = ref.m_lma;
111    m_length = ref.m_length;
112    m_ident = ref.m_ident;
113        return *this;
114}
115
116////////////
117VSeg::VSeg()
118    : 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)
124{
125}
126
127////////////////////////////////////
128VSeg::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)
140{
141}
142
143/////////////////////////////
144VSeg::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)
151{
152    (*this) = ref;
153}
154
155
156/*
157 * PSeg
158 */
159
160/////////////////////////
161paddr_t PSeg::lma() const
162{
163        return m_lma;
164}
165
166///////////////////////////
167paddr_t PSeg::limit() const
168{
169        return m_limit;
170}
171
172/////////////////////////////
173paddr_t PSeg::length() const
174{
175        return m_length;
176}
177
178/////////////////////////
179size_t PSeg::type() const
180{
181        return m_type;
182}
183
184/////////////////////////////
185paddr_t PSeg::nextLma() const
186{
187        return m_nextLma;
188}
189
190//////////////////////////////////////
191const std::string & PSeg::name() const
192{
193        return m_name;
194}
195
196//////////////////////// initialisation used[][] ??? (AG)
197void PSeg::check() const
198{
199
200    if(this->m_type == PSEG_TYPE_PERI)
201        return;
202
203    std::vector<VSeg>::const_iterator it;
204    size_t    size = m_vsegs.size();
205    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++)
209    {
210        paddr_t it_limit = (*it).lma() + (*it).length();
211        for(j=0; j< i; j++)
212        {
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
219            {
220                error = 2;
221            }
222            if( (used[j][0] < (*it).lma()) and ((*it).lma() < used[j][1]) ) // lma  within
223            {
224                error = 3;
225            }
226            if(  ((used[j][0] < it_limit) and (it_limit < used[j][1] )) ) // limit no within
227            {
228                error = 4;
229                std::cout << "base: " << std::hex << (*it).lma() << std::endl;
230                std::cout << "limit: " << std::hex << it_limit << std::endl;
231                std::cout << "used[j][0]: " << std::hex << used[j][0] << std::endl;
232                std::cout << "used[j][1]: " << std::hex << used[j][1] << std::endl;
233            }
234            if(error)
235            {
236                std::ostringstream err;
237                err << " Error" << error << " ,ovelapping Buffers:" << std::endl
238                    << *it << std::endl << m_vsegs[j] << std::endl; 
239                throw exception::RunTimeError( err.str().c_str() );
240            }
241
242        }
243        used[i][0] = (*it).lma();
244        used[i][1] = it_limit;
245    }
246}
247
248//////////////////////////////////////
249void PSeg::setName(std::string& name )
250{
251    m_name = name;
252}
253
254/////////////////////////////////////////////////////////
255paddr_t PSeg::align( paddr_t toAlign, unsigned alignPow2)
256{
257    return ((toAlign + (1 << alignPow2) - 1 ) >> alignPow2) << alignPow2; 
258}
259
260//////////////////////////////////////////
261paddr_t PSeg::pageAlign( paddr_t toAlign )
262{
263    size_t pgs = pageSize();
264    size_t pageSizePow2 = __builtin_ctz(pgs);
265   
266    return align(toAlign, pageSizePow2); 
267}
268
269////////////////////////////////
270void 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/////////////////////////////////////
282void 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}
290
291////////////////////////////
292void PSeg::add( VSeg& vseg )
293{
294    vseg.m_lma = m_nextLma;
295//    incNextLma(vseg.length());   //for the next vseg
296    m_vsegs.push_back(vseg); 
297}
298
299/////////////////////////////////
300void PSeg::addIdent( VSeg& vseg )
301{
302    vseg.m_lma = vseg.m_vma;
303    m_vsegs.push_back(vseg); 
304}
305
306/////////////////////////////////////////
307void PSeg::setNextLma( paddr_t nextLma)
308{
309    m_nextLma = nextLma;
310    confNextLma();
311}
312
313//////////////////////////////////
314void PSeg::incNextLma( size_t inc)
315{
316    m_nextLma += inc;
317    confNextLma();
318}
319
320////////////////////////
321void 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/////////////////////////////////
343void 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////////////////////////
354size_t& PSeg::pageSize()
355{
356    static size_t m_pageSize;
357    return m_pageSize;
358}
359
360/////////////////////////////////////////
361PSeg & PSeg::operator=( const PSeg &ref )
362{
363    if ( &ref == this )
364        return *this;
365
366    m_name = ref.m_name;
367    m_length = ref.m_length;
368    m_limit = ref.m_limit;
369    m_pageLimit = ref.m_pageLimit;
370    m_lma = ref.m_lma;
371    m_nextLma = ref.m_nextLma;
372    m_vsegs = ref.m_vsegs;
373    m_type = ref.m_type;
374
375        return *this;
376}
377
378//////////////////////////////////////////
379void PSeg::print( std::ostream &o ) const
380{
381        o << "<Physical segment "
382          << std::showbase << m_name
383          << ", from: " << std::hex
384      << m_lma << " to " << m_limit
385      << ", size : "  << m_length
386      << ", filled to: "  << m_nextLma
387      << ", type : "  << m_type
388      << ", containing: "<< std::endl;
389        std::vector<VSeg>::const_iterator it;
390        for(it = m_vsegs.begin(); it < m_vsegs.end(); it++)
391    o << " " << *it << std::endl;
392
393    o << ">";
394}
395
396////////////////////////////////////
397PSeg::PSeg( const std::string &name,
398            paddr_t           lma,
399            paddr_t           length,
400            size_t            type)
401{
402    m_name = name;
403    m_length = length;
404    m_type = type;
405
406    setLma(lma);
407}
408
409////////////////////////////////////
410PSeg::PSeg( const std::string &name):
411      m_lma(0),
412      m_length(0),
413      m_nextLma(0),
414      m_limit(0)
415{
416    m_name = name;
417}
418
419////////////////////////
420PSeg::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////////////
431PSeg::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/////////////////////////////
442PSeg::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
452PSeg::~PSeg()
453{
454}
455
456
457
458// Local Variables:
459// tab-width: 4
460// c-basic-offset: 4
461// c-file-offsets:((innamespace . 0)(inline-open . 0))
462// indent-tabs-mode: nil
463// End:
464
465// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
466
Note: See TracBrowser for help on using the repository browser.