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

Last change on this file since 210 was 210, checked in by karaoui, 12 years ago

Avoid incremmentinting Pseg of "PERI" type, to permit multiple mapping.

File size: 9.2 KB
Line 
1/* -*- c++ -*-
2 *
3 * SOCLIB_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 * SOCLIB_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
45const std::string & VSeg::name() const
46{
47        return m_name;
48}
49
50const std::string & VSeg::file() const
51{
52        return m_file;
53}
54
55uintptr_t VSeg::vma() const
56{
57        return m_vma;
58}
59
60uintptr_t VSeg::lma() const
61{
62        return m_lma;
63}
64
65size_t VSeg::length() const
66{
67        return m_length;
68}
69
70size_t VSeg::type() const
71{
72        return m_type;
73}
74
75void VSeg::print( std::ostream &o ) const
76{
77        o << std::hex << std::noshowbase
78      << "<Virtual segment from(vaddr): 0x" 
79      << std::setw (8) << std::setfill('0') 
80      << m_vma << ", to(paddr) 0x"
81      << std::setw (8) << std::setfill('0') 
82      << m_lma << ", size: 0x"
83      << std::setw (8) << std::setfill('0') 
84      << m_length  << ",ident: " 
85      << (m_ident ? "yes" : "no") << ", in(file): "
86      << m_file << ", name: " << m_name << ">";
87}
88
89VSeg::~VSeg()
90{
91//    std::cout << "Deleted VSeg " << *this << std::endl;
92}
93
94VSeg & VSeg::operator=( const VSeg &ref )
95{
96    if ( &ref == this )
97        return *this;
98
99    //std::cout << "Copying " << ref << " to " << *this << std::endl;
100    m_name = ref.m_name,
101    m_file = ref.m_file;
102    m_vma = ref.m_vma;
103    m_lma = ref.m_lma;
104    m_length = ref.m_length;
105    m_ident = ref.m_ident;
106        return *this;
107}
108
109VSeg::VSeg()
110    : m_name("No Name"),
111      m_file("Empty section"),
112      m_vma(0),
113      m_length(0),
114      m_loadable(false),
115      m_ident(0)
116{
117    //std::cout << "New empty VSeg " << *this << std::endl;
118}
119
120VSeg::VSeg(std::string& binaryName, std::string& name, uintptr_t vma, size_t length, bool loadable, bool ident)
121    : m_name(name),
122      m_file(binaryName),
123      m_vma(vma),
124      m_length(length),
125      m_loadable(loadable),
126      m_ident(ident)
127{
128    //std::cout << "New VSeg " << *this << std::endl;
129}
130
131VSeg::VSeg( const VSeg &ref )
132    : m_name("To be copied"),
133      m_file("Empty"),
134      m_vma(0),
135      m_length(0),
136      m_loadable(false),
137      m_ident(0)
138{
139    //std::cout << "New VSeg " << *this << " copied from " << ref << std::endl;
140    (*this) = ref;
141}
142
143
144
145
146/*
147 * PSeg
148 */
149uintptr_t PSeg::lma() const
150{
151        return m_lma;
152}
153
154uintptr_t PSeg::limit() const
155{
156        return m_limit;
157}
158
159size_t PSeg::length() const
160{
161        return m_length;
162}
163
164size_t PSeg::type() const
165{
166        return m_type;
167}
168
169uintptr_t PSeg::nextLma() const
170{
171        return m_nextLma;
172}
173
174const std::string & PSeg::name() const
175{
176        return m_name;
177}
178
179void PSeg::check() const
180{
181
182    if(this->m_type == PSEG_TYPE_PERI)
183        return;
184
185    std::vector<VSeg>::const_iterator it;
186    size_t size = m_vsegs.size();
187    size_t used[size][2];//lma, lma+length
188    size_t i,j,error=0;
189   
190    for(it = m_vsegs.begin(), i= 0; it < m_vsegs.end(); it++, i++)
191    {
192        size_t it_limit = (*it).lma() + (*it).length();
193        for(j=0; j< i; j++)
194        {
195           if(  (used[j][0] == (*it).lma() /*and (*it).length()?*/) ) //not the same lma ,
196            {
197                error = 1;
198                std::cout << "ok \n";
199            }
200           if(  (used[j][1] == it_limit /*and (*it).legth()?*/))  // and not the same limit
201            {
202                error = 2;
203            }
204           if(  ((used[j][0] < (*it).lma()) and ((*it).lma() < used[j][1] )) ) //lma  within the used slice
205            {
206                error = 3;
207            }
208           if(  ((used[j][0] < it_limit) and (it_limit < used[j][1] )) )//limit not within the used slice
209            {
210                error = 4;
211                std::cout << "base: " << std::hex << (*it).lma() << std::endl;
212                std::cout << "limit: " << std::hex << it_limit << std::endl;
213                std::cout << "used[j][0]: " << std::hex << used[j][0] << std::endl;
214                std::cout << "used[j][1]: " << std::hex << used[j][1] << std::endl;
215            }
216            if(error)
217            {
218                std::ostringstream err;
219                err << " Error" << error << " ,ovelapping Buffers:" << std::endl
220                    << *it << std::endl << m_vsegs[j] << std::endl; 
221                throw exception::RunTimeError( err.str().c_str() );
222            }
223
224        }
225        used[i][0] = (*it).lma();
226        used[i][1] = it_limit;
227    }
228}
229
230void PSeg::setName(std::string& name )
231{
232    m_name = name;
233}
234
235size_t PSeg::align( unsigned toAlign, unsigned alignPow2)
236{
237    return ((toAlign + (1 << alignPow2) - 1 ) >> alignPow2) << alignPow2;//page aligned
238}
239
240
241size_t PSeg::pageAlign( size_t toAlign )
242{
243    size_t pgs = pageSize();
244    size_t pageSizePow2 = __builtin_ctz(pgs);
245   
246    return align(toAlign, pageSizePow2);//page aligned
247
248}
249
250void PSeg::setLma( uintptr_t lma )
251{
252    m_lma = lma;
253   
254    m_nextLma = pageAlign(lma);//page aligned
255
256    m_pageLimit = pageAlign(m_lma+m_length); 
257
258    m_limit = (m_lma + m_length);
259
260}
261
262void PSeg::setLength( size_t length )
263{
264    m_length = length;
265
266    m_pageLimit = pageAlign(m_lma+m_length); 
267
268    m_limit = (m_lma + m_length);
269
270    //std::cout << std::hex << " length seted, m_limit: " << m_limit  << std::endl;
271    //std::cout << *this <<std::endl;
272}
273
274void PSeg::add( VSeg& vseg )
275{
276    vseg.m_lma = m_nextLma;
277    incNextLma(vseg.length());//for the next vseg
278    m_vsegs.push_back(vseg); 
279}
280
281void PSeg::addIdent( VSeg& vseg )
282{
283    vseg.m_lma = vseg.m_vma;
284    incNextLma(vseg.length());//to keep track of space used
285    m_vsegs.push_back(vseg); 
286}
287
288void PSeg::setNextLma( uintptr_t nextLma)
289{
290    m_nextLma = nextLma;
291
292    confNextLma();
293}
294
295void PSeg::incNextLma( size_t inc_next)
296{
297
298    m_nextLma += inc_next;
299
300    confNextLma();
301}
302
303void PSeg::confNextLma()
304{
305    if(m_nextLma > m_limit)
306    {
307        std::cerr << "Erreur pseg overflow... nextLma: "
308                  << std::hex << m_nextLma << ", limit: " 
309                  << m_limit << std::endl;
310        exit(1); 
311    }
312
313    m_nextLma = pageAlign( m_nextLma );
314
315    if(m_nextLma > m_pageLimit)
316    {
317        std::cerr << "Erreur pseg page overflow... nextLma: "
318                  << std::hex << m_nextLma << ", limit: " 
319                  << m_pageLimit << std::endl;
320        exit(1); 
321    }
322}
323
324void PSeg::setPageSize(size_t pg)
325{
326    if( pg == 0)
327    {
328        std::cerr << "PageSize must be positive" << std::endl;
329        return;
330    }
331    pageSize() = pg;
332}
333
334size_t& PSeg::pageSize()
335{
336    static size_t m_pageSize;
337    return m_pageSize;
338}
339
340PSeg & PSeg::operator=( const PSeg &ref )
341{
342    if ( &ref == this )
343        return *this;
344
345    //std::cout << "Copying " << ref << " to " << *this << std::endl;
346
347    m_name = ref.m_name;
348    m_length = ref.m_length;
349    m_limit = ref.m_limit;
350    m_pageLimit = ref.m_pageLimit;
351    m_lma = ref.m_lma;
352    m_nextLma = ref.m_nextLma;
353    m_vsegs = ref.m_vsegs;
354
355        return *this;
356}
357
358void PSeg::print( std::ostream &o ) const
359{
360        o << "<Physical segment "
361          << std::showbase << m_name
362          << ", from: " << std::hex
363      << m_lma << " to " << m_limit
364      << ", size : "  << m_length
365      << ", filled to: "  << m_nextLma
366      << ", containing: "<< std::endl;
367        std::vector<VSeg>::const_iterator it;
368        for(it = m_vsegs.begin(); it < m_vsegs.end(); it++)
369    o << " " << *it << std::endl;
370
371    o << ">";
372}
373
374PSeg::PSeg( const std::string &name,
375                uintptr_t lma,
376                size_t length,
377                size_t type)
378{
379    m_name = name;
380    m_length = length;
381    m_type = type;
382
383    setLma(lma);
384    //std::cout <<"New PSeg :"<< *this ;         
385}
386
387PSeg::PSeg( const std::string &name):
388      m_lma(0),
389      m_length(0),
390      m_nextLma(0),
391      m_limit(0)
392{
393    m_name = name;
394}
395
396PSeg::PSeg( uintptr_t lma):
397      m_name("No name"),
398      m_lma(0),
399      m_length(0),
400      m_nextLma(0),
401      m_limit(0)
402{
403    setLma(lma);
404}
405
406
407PSeg::PSeg()
408    :
409      m_name("Empty section"),
410      m_lma(0),
411      m_length(0),
412      m_nextLma(0),
413      m_limit(0)
414{
415    //std::cout << "New empty PSeg " << *this << std::endl;
416}
417
418PSeg::PSeg( const PSeg &ref )
419    : m_name("To be copied"),
420      m_lma(0),
421      m_length(0),
422      m_nextLma(0),
423      m_limit(0)
424{
425    //std::cout << "New PSeg " << *this << " copied from " << ref << std::endl;
426    (*this) = ref;
427}
428
429PSeg::~PSeg()
430{
431//    std::cout << "Deleted PSeg " << *this << std::endl;
432}
433
434
435
436// Local Variables:
437// tab-width: 4
438// c-basic-offset: 4
439// c-file-offsets:((innamespace . 0)(inline-open . 0))
440// indent-tabs-mode: nil
441// End:
442
443// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
444
Note: See TracBrowser for help on using the repository browser.