Ignore:
Timestamp:
Mar 6, 2019, 4:37:15 PM (5 years ago)
Author:
alain
Message:

Introduce three new types of vsegs (KCODE,KDATA,KDEV)
to map the kernel vsegs in the process VSL and GPT.
This now used by both the TSAR and the I86 architectures.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/hal/tsar_mips32/core/hal_vmm.c

    r587 r623  
    22 * hal_vmm.c - Virtual Memory Manager Initialisation for TSAR
    33 *
    4  * Authors  Alain Greiner (2016,2017)
     4 * Authors  Alain Greiner (2016,2017,2018,2019)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    2626#include <hal_vmm.h>
    2727#include <hal_gpt.h>
     28#include <process.h>
    2829#include <vseg.h>
    2930#include <xlist.h>
     
    3233
    3334//////////////////////////////////////////////////////////////////////////////////////////
    34 // This file contains the TSAR specific code to initialize the Virtual Memory Manager.
    35 // The "kentry" vseg contains the kernel code executed when a core enter/exit the kernel,
    36 // in case of Interrupt, Exception, or Syscall.
    37 // For the TSAR architecture, the kernel uses physical addresses, and this code must be
    38 // identity mapped. The following function is called by the generic vmm_init() function
    39 // and identity map all pages of the "kentry" vseg.
    40 // We dont take the locks protecting the VSL and the GPT, because there is no concurrent
    41 // accesses to VMM during VMM initialization.
     35// This file contains the TSAR specific code used to initialize the kernel process VMM,
     36// or to update an user process VMM with informations related to the kernel vsegs.
     37// As the TSAR architure does not use the DATA MMU, but use only the DATA extension
     38// address register to access local and remote kernel data, the kernel VSL contains only
     39// one "kcode" segment, and the kernel GPT contains only one big page in PT1[0] slot.
    4240//////////////////////////////////////////////////////////////////////////////////////////
    4341
    44 ////////////////////////////////////
    45 error_t  hal_vmm_init( vmm_t * vmm )
     42// extern global variables
     43extern process_t process_zero;
     44
     45//////////////////////////////////////////////////////////////////////////////////////////
     46// This function is called by the process_zero_init() function during kernel_init.
     47// It initializes the VMM of the kernel proces_zero (containing all kernel threads)
     48// in the local cluster.
     49//////////////////////////////////////////////////////////////////////////////////////////
     50error_t  hal_vmm_kernel_init( boot_info_t * info )
    4651{
    47     error_t error;
     52    error_t   error;
    4853
    49     // map all pages of "kentry" vseg
    50     uint32_t vpn;
    51     uint32_t attr;
    52     attr = GPT_MAPPED | GPT_SMALL | GPT_EXECUTABLE | GPT_CACHABLE | GPT_GLOBAL;
    53     for( vpn = CONFIG_VMM_KENTRY_BASE;
    54          vpn < (CONFIG_VMM_KENTRY_BASE + CONFIG_VMM_KENTRY_SIZE); vpn++ )
     54    // get pointer on kernel GPT
     55    gpt_t * gpt = &process_zero.vmm.gpt;
     56
     57    // get cluster identifier
     58    cxy_t cxy = local_cxy;
     59
     60    // allocate memory for kernel GPT
     61    error = hal_gpt_create( gpt );
     62
     63    if( error )
    5564    {
    56         error = hal_gpt_set_pte( XPTR( local_cxy , &vmm->gpt ),
    57                                  vpn,
    58                                  attr,
    59                                  (local_cxy<<20) | (vpn & 0xFFFFF) );
    60 
    61         if( error ) return error;
     65        printk("\n[PANIC] in %s : cannot allocate kernel GPT in cluster %x\n",
     66        __FUNCTION__ , cxy );
     67        hal_core_sleep();
    6268    }
    6369
    64     // scan the VSL to found the "kentry" vseg
    65     xptr_t         root_xp = XPTR( local_cxy , &vmm->vsegs_root );
    66     xptr_t         iter_xp;
    67     xptr_t         vseg_xp;
    68     vseg_t       * vseg;
    69     bool_t         found = false;
    70  
    71     XLIST_FOREACH( root_xp , iter_xp )
     70    // compute attr and ppn for one PTE1
     71    uint32_t attr  = 0x8A800000;           // bits : V,C,X,G
     72    uint32_t ppn   = (cxy << 20) >> 9;     // physical page index is 0
     73
     74    // set PTE1  in slot[0]
     75    error = hal_gpt_set_pte( XPTR( cxy , gpt ) , 0 , attr , ppn );
     76
     77    if( error )
    7278    {
    73         vseg_xp = XLIST_ELEMENT( iter_xp , vseg_t , xlist );
    74         vseg    = (vseg_t *)GET_PTR( vseg_xp );
    75 
    76         // set the IDENT flag in "kentry" vseg descriptor
    77         if( vseg->vpn_base == CONFIG_VMM_KENTRY_BASE )
    78         {
    79             vseg->flags |= VSEG_IDENT;
    80             found = true;
    81             break;
    82         }
     79        printk("\n[PANIC] in %s : cannot initialize kernel GPT in cluster %x\n",
     80        __FUNCTION__ , cxy );
     81        hal_core_sleep();
    8382    }
    8483
    85     if( found == false ) return 0XFFFFFFFF;
    86 
    87     return 0;
     84    // create kcode vseg and register it in kernel VSL
     85    vseg_t * vseg = vmm_create_vseg( &process_zero,
     86                                     VSEG_TYPE_CODE,
     87                                     info->kcode_base,
     88                                     info->kcode_size,
     89                                     0, 0,                  // file ofset and file size (unused)
     90                                     XPTR_NULL,             // no mapper
     91                                     local_cxy );
     92    if( vseg == NULL )
     93    {
     94        printk("\n[PANIC] in %s : cannot register vseg to VSL in cluster %x\n",
     95        __FUNCTION__ , cxy );
     96        hal_core_sleep();
     97    }
    8898
    8999}  // end hal_vmm_init()
    90100
     101//////////////////////////////////////////////////////////////////////////////////////////
     102// This function is called by the vmm_init() function to update the VMM of an user
     103// process identified by the <process> argument.
     104// It registers in the user VSL the "kcode" vseg, registered in the local kernel VSL,
     105// and register in the user GPT the big page[0] mapped in the local kernel GPT.
     106//////////////////////////////////////////////////////////////////////////////////////////
     107error_t hal_vmm_kernel_update( process_t * process )
     108{
     109    error_t error;
     110    uint32_t attr;
     111    uint32_t ppn;
    91112
     113// TODO check ppn value in kernel GPT (must be 0)
     114
     115    // get cluster identifier
     116    cxy_t cxy = local_cxy;
     117
     118    // get extended pointer on user GPT
     119    xptr_t gpt_xp = XPTR( cxy , &process->vmm.gpt );
     120
     121    // get ppn and attributes from slot[0] in kernel GPT
     122    hal_gpt_get_pte( gpt_xp , 0 , &attr , &ppn );
     123
     124// check ppn and attributes
     125assert( (attr == 0x8A800000) && (ppn == ((cxy << 20) >> 9)),  __FUNCTION__,
     126"bad ppn = %x or attr = %x in slot[0] of kernel GPT\n", ppn , attr );
     127 
     128    // update user GPT : set PTE1 in slot[0]
     129    error = hal_gpt_set_pte( gpt_xp , 0 , attr , ppn );
     130
     131    if( error )
     132    {
     133        printk("\n[ERROR] in %s : cannot update GPT in cluster %x\n",
     134        __FUNCTION__ , cxy );
     135        return -1;
     136    }
     137
     138    // get pointer on the unique vseg registered in kernel VSL
     139    xptr_t root_xp = XPTR( cxy , &process_zero.vmm.vsegs_root );
     140    vseg_t * vseg = XLIST_FIRST( root_xp , vseg_t , xlist );
     141
     142// check vsegs_nr
     143assert( (process_zero.vmm.vsegs_nr == 1 ) , __FUNCTION__,
     144"bad vsegs number in kernel VSL\n" );
     145
     146    // update user VSL : register one new vseg for kcode
     147    vseg_t * new = vmm_create_vseg( process,
     148                                    vseg->type,
     149                                    vseg->min,
     150                                    vseg->max - vseg->min,
     151                                    0, 0,                  // file ofset and file size (unused)
     152                                    XPTR_NULL,             // no mapper
     153                                    local_cxy );
     154    if( new == NULL )
     155    {
     156        printk("\n[ERROR] in %s : cannot update VSL in cluster %x\n",
     157        __FUNCTION__ , cxy );
     158        return -1;
     159    }
     160}
     161
     162
Note: See TracChangeset for help on using the changeset viewer.