Ignore:
Timestamp:
Jul 16, 2012, 10:26:27 AM (12 years ago)
Author:
alain
Message:

Fix several bugs to use the vci_block_device with MMU activated

File:
1 edited

Legend:

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

    r165 r167  
    3131// As most applications use only a limited number of segments, the number of PT2s
    3232// actually used by a given virtual space is generally smaller than 2048, and is
    33 // defined in the MAPPING_INFO_BINARY data structure (using the length field).
    34 // The value is calculated and put in _max_pt2 indexed by the vspace_id.
    35 // The physical alignment constraints, is ensured by the align flag in the MAPPING_INFO
    36 // structure.
     33// defined by the (GIET_NB_PT2_MAX) configuration parameter.
    3734// The max number of virtual spaces (GIET_NB_VSPACE_MAX) is a configuration parameter.
    3835//
    39 // Each page table (one page table per virtual space) is monolithic:
    40 // - a first 8K aligned PT1[2148] array, indexed by the (ix1) field of VPN.
     36// Each page table (one page table per virtual space) is monolithic, and
     37// contains one PT1 and (GIET_NB_PT2_MAX) PT2s. The PT1 is addressed using the ix1 field
     38// (11 bits) of the VPN, and the selected PT2 is addressed using the ix2 field (9 bits).
     39// - PT1[2048] : a first 8K aligned array of unsigned int, indexed by the (ix1) field of VPN.
     40//   Each entry in the PT1 contains a 32 bits PTD. The MSB bit PTD[31] is
     41//   the PTD valid bit, and LSB bits PTD[19:0] are the 20 MSB bits of the physical base
     42//   address of the selected PT2.
    4143//   The PT1 contains 2048 PTD of 4 bytes => 8K bytes.
    42 // - an aray of array PT2[1024][_max_pt2[vspace_id]], indexed by
    43 //   the (ix2) field of the VPN, and by the PT2 index (pt2_id).
    44 //   Each PT2 contains 512 PTE2 of 8bytes => 4Kbytes * _max_pt2[vspace_id]
    45 // The size of each page table is 8K + (_max_pt2[vspace_id])*4K bytes.
    46 // All page tables must be stored in the seg_kernel_pt segment (at address
    47 // seg_kernel_pt_base)
     44// - PT2[1024][GIET_NB_PT2_MAX] : an array of array of unsigned int.
     45//   Each PT2[1024] must be 4K aligned,  and each entry in a PT2 contains two unsigned int:
     46//   the first word contains the protection flags, and the second word contains the PPN.
     47//   Each PT2 contains 512 PTE2 of 8bytes => 4K bytes.
     48// The total size of a page table is finally = 8K + (GIET_NB_PT2_MAX)*4K bytes.
    4849////////////////////////////////////////////////////////////////////////////////////
    4950
     
    5556#include <stdarg.h>
    5657
    57 
    5858#if !defined(GIET_NB_VSPACE_MAX)
    5959# error The GIET_NB_VSPACE_MAX value must be defined in the 'giet_config.h' file !
    6060#endif
    6161
     62#if !defined(GIET_NB_PT2_MAX)
     63# error The GIET_NB_PT2_MAX value must be defined in the 'giet_config.h' file !
     64#endif
     65
    6266////////////////////////////////////////////////////////////////////////////
    6367//  Page Tables global variables
     
    6670// Next free PT2 index array
    6771unsigned int  _next_free_pt2[GIET_NB_VSPACE_MAX] =
    68                          { [0 ... GIET_NB_VSPACE_MAX-1] = 0 };
    69 
    70 // Max number of PT2 array
    71 unsigned int  _max_pt2[GIET_NB_VSPACE_MAX] =
    7272                         { [0 ... GIET_NB_VSPACE_MAX-1] = 0 };
    7373
     
    439439// allocation), this function checks a possible overflow of the PT2 array.
    440440//
    441 // The parametre global is a boolean taht indicate wether a global vseg is
     441// The global parameter is a boolean indicating wether a global vseg is
    442442// being mapped.
    443443//////////////////////////////////////////////////////////////////////////////
     
    445445                   unsigned int    vpn,           
    446446                   unsigned int    flags,
    447                    unsigned int    ppn,
    448                    unsigned char   global )
     447                   unsigned int    ppn )
    449448{
    450449    unsigned int    ix1;
     
    458457    ix2 = vpn  & 0x1FF;         //  9 bits
    459458
    460        
    461     unsigned int max_pt2   = _max_pt2[vspace_id];
    462     if(max_pt2 == 0)
    463     {
    464         boot_puts("Unfound page table for vspace ");
    465         boot_putw(vspace_id);
    466         boot_puts("\n");
    467         boot_exit();
    468     }
    469 
    470     page_table_t* pt    = (page_table_t *)_ptabs[vspace_id];
     459    page_table_t* pt = (page_table_t *)_ptabs[vspace_id];
    471460    if ( (pt->pt1[ix1] & PTE_V) == 0 )   // set a new PTD in PT1
    472461    {
    473462        pt2_id = _next_free_pt2[vspace_id];
    474         if ( pt2_id == max_pt2 )
     463        if ( pt2_id == GIET_NB_PT2_MAX )
    475464        {
    476465            boot_puts("\n[BOOT ERROR] in boot_add_pte() function\n");
     
    557546                          vpn,
    558547                          flags,
    559                           ppn,
    560                           0 );
     548                          ppn );
    561549            vpn++;
    562550            ppn++;
     
    593581                          vpn,
    594582                          flags,
    595                           ppn,
    596                           1 );
     583                          ppn );
    597584            vpn++;
    598585            ppn++;
     
    616603// This function compute the physical base address for a vseg
    617604// as specified in the mapping info data structure.
    618 // It updates the pbase field of the vseg.
    619 // It updates the page allocator (nextfreepage field of the pseg),
    620 // and checks a possible pseg overflow.
     605// It updates the pbase and the length fields of the vseg.
     606// It updates the pbase and vbase fields of all vobjs in the vseg.
     607// It updates the next_base field of the pseg.
     608// It checks a possible pseg overflow.
    621609// It is a global vseg if vspace_id = (-1)
    622610///////////////////////////////////////////////////////////////////////////
     
    641629    else                                // unconstrained mapping
    642630    {
    643         vseg->pbase = pseg->base + (pseg->next_free_page<<12);
     631        vseg->pbase = pseg->next_base;
     632
     633        // test alignment constraint
     634        if ( vobj[vseg->vobj_offset].align )
     635        {
     636            vseg->pbase = align_to( vseg->pbase, vobj[vseg->vobj_offset].align );
     637        }
    644638    }
    645639   
    646     // loop on vobjs to computes the length of the vseg,
    647     // initialise the vaddr and paddr fields of all vobjs,
    648     // and initialise the page table pointers array
     640    // loop on vobjs to (1) computes the length of the vseg,
     641    // (2) initialise the vaddr and paddr fields of all vobjs,
     642    // (3) initialise the page table pointers array
     643
    649644    cur_vaddr = vseg->vbase;
    650645    cur_paddr = vseg->pbase;
     
    659654        }
    660655
    661         // set vaddr/paddr
     656        // set vaddr/paddr for current vobj
    662657        vobj[vobj_id].vaddr = cur_vaddr;       
    663658        vobj[vobj_id].paddr = cur_paddr; 
     
    667662        cur_paddr += vobj[vobj_id].length;
    668663
    669         // initialise _ptabs[] and _max_pt2[]
     664        // initialise _ptabs[] if current vobj is a PTAB
    670665        if ( vobj[vobj_id].type == VOBJ_TYPE_PTAB )
    671666        {
    672             if(vobj[vobj_id].length < (PT1_SIZE + PT2_SIZE) ) // max_pt2 >= 1
     667            if(vobj[vobj_id].length < (PT1_SIZE + PT2_SIZE*GIET_NB_PT2_MAX) )
    673668            {
    674669                boot_puts( "\n[BOOT ERROR] in boot_vseg_map() function: " );
     
    684679                boot_exit();
    685680            }
    686             _ptabs[vspace_id]   = (page_table_t*)vobj[vobj_id].paddr;
    687             _max_pt2[vspace_id] = (vobj[vobj_id].length - PT1_SIZE) / PT2_SIZE;
    688         }
    689     }
     681            _ptabs[vspace_id] = (page_table_t*)vobj[vobj_id].paddr;
     682        }
     683    } // end for vobjs
    690684   
    691685    //set the vseg length
    692     unsigned int plength = pseg->length;
    693     unsigned int vlength = cur_paddr - vseg->pbase;
    694     vseg->length = align_to(vlength, 12);
     686    vseg->length = align_to( (cur_paddr - vseg->pbase), 12);
    695687
    696688    // checking pseg overflow
    697689    if ( (vseg->pbase < pseg->base) ||
    698          ((vseg->pbase + vlength) > (pseg->base + plength)) )
     690         ((vseg->pbase + vseg->length) > (pseg->base + pseg->length)) )
    699691    {
    700692        boot_puts("\n[BOOT ERROR] in boot_vseg_map() function\n");
    701         boot_puts("impossible identity mapping for virtual segment: ");
     693        boot_puts("impossible mapping for virtual segment: ");
    702694        boot_puts( vseg->name );
    703695        boot_puts("\n");
     
    717709    }
    718710
    719     // computes number of pages
    720     pages = vseg->length >> 12;
    721     if ( (vseg->length & 0xFFF) != 0 ) pages++;
    722 
    723     // set the next free physical address
    724     if ( vseg->ident != 0 )
    725             ;            // nothing to do
    726     else                               
    727         pseg->next_free_page = pseg->next_free_page + pages;
     711    // set the next_base field in vseg
     712    if ( vseg->ident == 0 )
     713        pseg->next_base = vseg->pbase + vseg->length;
    728714
    729715#if BOOT_DEBUG_PT
    730 boot_puts("- vseg ");
    731716boot_puts( vseg->name );
    732 boot_puts(" : vbase = ");
     717boot_puts(" : len = ");
     718boot_putw( vseg->length );
     719boot_puts(" / vbase = ");
    733720boot_putw( vseg->vbase );
    734721boot_puts(" / pbase = ");
     
    816803    for ( pseg_id = 0 ; pseg_id < header->psegs ; pseg_id++ )
    817804    {
    818         pseg[pseg_id].next_free_page = 0;
     805        pseg[pseg_id].next_base = pseg[pseg_id].base;
    819806    }
    820807
     
    860847
    861848#if BOOT_DEBUG_PT
    862 boot_puts(">>> page table physical address = ");
    863 boot_putw((unsigned)_ptabs[vspace_id]);
     849boot_puts("\n>>> page table physical address = ");
     850boot_putw((unsigned int)_ptabs[vspace_id]);
    864851boot_puts("\n");
    865852#endif
Note: See TracChangeset for help on using the changeset viewer.