Changeset 623 for trunk/hal


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.

Location:
trunk/hal
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/hal/generic/hal_gpt.h

    r587 r623  
    7777/****************************************************************************************
    7878 * This function allocates physical memory for first level page table (PT1),
    79  * and initializes the page table descriptor.
     79 * and initializes the GPT descriptor, creating an empty GPT.
    8080 ****************************************************************************************
    8181 * @ gpt     : pointer on generic page table descriptor.
     
    126126
    127127/****************************************************************************************
    128  * This function map a - local or remote - GPT entry identified by its VPN, from values
    129  * defined by the <ppn> and <attr> arguments. It allocates physical memory in remote
    130  * cluster for the GPT PT2, using a RPC_PMEM_GET_PAGES, if required.
    131  ****************************************************************************************
    132  * @ gpt       : [in] pointer on the page table
     128 * This function maps in a - local or remote - GPT identified by the <gpt_xp> argument
     129 * an entry identified by the <vpn> argument, as defined by <ppn> and <attr> arguments.
     130 * It allocates physical memory for the GPT PT2, using a RPC_PMEM_GET_PAGES if required.
     131 ****************************************************************************************
     132 * @ gpt_xp    : [in] pointer on the page table
    133133 * @ vpn       : [in] virtual page number
    134134 * @ attr      : [in] generic attributes
     
    154154/****************************************************************************************
    155155 * This function returns in the <attr> and <ppn> arguments the current values stored
    156  * in a -local or remote - GPT entry, identified by the <gpt> and <vpn> arguments.
     156 * in a - local or remote - GPT entry, identified by the <gpt> and <vpn> arguments.
    157157 ****************************************************************************************
    158158 * @ gpt_xp    : [in]  extended pointer on the page table
  • trunk/hal/generic/hal_special.h

    r619 r623  
    3131
    3232struct thread_s;
     33struct gpt_s;
    3334
    3435///////////////////////////////////////////////////////////////////////////////////////////
     
    3738// ALMOS-MKH uses the following API to access the core protected registers.
    3839///////////////////////////////////////////////////////////////////////////////////////////
     40
     41/*****************************************************************************************
     42 * This function initialise - for architectures requiring it - the protected register(s)
     43 * containing the kernel_entry adresse(s) for interrupts / exceptions / syscalls.
     44 ****************************************************************************************/
     45void hal_set_kentry( void );
     46
     47/*****************************************************************************************
     48 * This function initializes - for architectures requiring it - the MMU registers
     49 * as required by the target architecture to execute the kernel threads attached
     50 * to kernel process zero. It is called by all cores in the kernel_init() function.
     51 *****************************************************************************************
     52 * @ gpt :  local pointer on the kernel page table descriptor.
     53 ****************************************************************************************/
     54void hal_mmu_init( struct gpt_s * gpt );
    3955
    4056/*****************************************************************************************
     
    103119/*****************************************************************************************
    104120 * This function makes an uncachable read to a 32 bits variable in local memory.
     121 *****************************************************************************************
    105122 * @ ptr     : pointer on the variable
    106123 * @ returns the value
     
    137154/*****************************************************************************************
    138155 * This function returns information on MMU exceptions :
     156 *****************************************************************************************
    139157 * @ mmu_ins_excp_code : [out] instruction fetch exception code
    140158 * @ mmu_ins_bad_vaddr : [out] instruction fetch faulty virtual address
  • trunk/hal/generic/hal_vmm.h

    r457 r623  
    11/*
    2  * hal_vmm.h - Generic Virtual Memory Manager initialisation
     2 * hal_vmm.h - Kernel Virtual Memory Manager initialisation
    33 *
    4  * Authors  Alain Greiner (2016,2017)
     4 * Authors  Alain Greiner (2016,2017,2018,2019)
    55 *
    66 * Copyright (c) UPMC Sorbonne Universites
     
    2222 */
    2323
    24 #ifndef _HAL_PPM_H_
    25 #define _HAL_PPM_H_
     24#ifndef _HAL_VMM_H_
     25#define _HAL_VMM_H_
    2626
    2727#include <hal_kernel_types.h>
     
    2929
    3030/////////////////////////////////////////////////////////////////////////////////////////
    31 //    Generic Virtual Memory Manager initialisation (implementation in hal_vmm.c)
     31//    Kernel Virtual Memory Manager initialisation (implementation in hal_vmm.c)
    3232//
    3333// Any arch-specific implementation must implement this API.
     
    3636/****  Forward declarations  ****/
    3737
    38 struct vmm_s;
     38struct process_s;
     39struct boot_info_s;
    3940
    4041/****************************************************************************************
    41  * This function makes all architecture specific initialisations
    42  * in the VSL (Virtual segments List) and in the GPT (Generic Page Table).
     42 * Depending on the hardware architecture, this function creates (i.e. allocates memory
     43 * and initializes) the VSL (Virtual segments List) and the GPT (Generic Page Table),
     44 * for all vsegs required by the kernel process.
    4345 ****************************************************************************************
    44  * @ vmm   : pointer on virtual memory manager.
     46 * @ info  : local pointer on boot_info (for kernel segments base & size).
    4547 * @ return 0 if success / return ENOMEM if failure.
    4648 ***************************************************************************************/
    47 error_t hal_vmm_init( struct vmm_s * vmm );
     49error_t hal_vmm_kernel_init( struct boot_info_s * info );
    4850
    49 #endif  /* HAL_PPM_H_ */
     51/****************************************************************************************
     52 * Depending on the hardware architecture, this function updates the VMM of an user
     53 * process identified by the <process> argument. It registers in VSL and GPT all
     54 * kernel vsegs required by this architecture.
     55 ****************************************************************************************
     56 * @ process   : local pointer on user process descriptor.
     57 * @ return 0 if success / return ENOMEM if failure.
     58 ***************************************************************************************/
     59error_t hal_vmm_kernel_update( struct process_s * process );
     60
     61#endif  /* HAL_VMM_H_ */
  • trunk/hal/tsar_mips32/core/hal_gpt.c

    r611 r623  
    141141#endif
    142142
    143     // check page size
    144     assert( (CONFIG_PPM_PAGE_SIZE == 4096) ,
    145     "for TSAR, the page size must be 4 Kbytes\n" );
     143// check page size
     144assert( (CONFIG_PPM_PAGE_SIZE == 4096) , "for TSAR, the page size must be 4 Kbytes\n" );
    146145
    147146    // allocates 2 physical pages for PT1
     
    287286    vpn_t      vpn;
    288287
    289     assert( (process != NULL) , "NULL process pointer\n");
     288// check argument
     289assert( (process != NULL) , "NULL process pointer\n");
    290290
    291291    // get pointer on gpt
     
    295295    pt1 = (uint32_t *)gpt->ptr;
    296296
    297     printk("\n***** Generic Page Table for process %x : &gpt = %x / &pt1 = %x\n\n",
     297    printk("\n***** Tsar Page Table for process %x : &gpt = %x / &pt1 = %x\n\n",
    298298    process->pid , gpt , pt1 );
    299299
     
    334334
    335335
     336/////////////////////////////////////////////////////////////////////////////////////
     337// FOr the TSAR architecture, this function allocates a first level PT1 (8 Kbytes),
     338// and maps one single big page for the kerne code segment in slot[0].
     339/////////////////////////////////////////////////////////////////////////////////////
     340void hal_gpt_build_kpt( cxy_t   cxy,
     341                        gpt_t * gpt )
     342{
     343    error_t error;
     344
     345    // allocate memory for one gpt
     346    error = hal_gpt_create( gpt );
     347
     348    if( error )
     349    {
     350        printk("\n[PANIC] in %s : cannot allocate kernel GPT in cluster %x\n",
     351        __FUNCTION__ , cxy );
     352        hal_core_sleep();
     353    }
     354
     355    // compute attr and ppn for one PTE1
     356    uint32_t attr  = 0xCA800000;           // bits : V,T,C,X,G
     357    uint32_t ppn   = (cxy << 20) >> 9;
     358
     359    // set PTE1
     360    error = hal_gpt_set_pte( XPTR( cxy , gpt ) , 0 , attr , ppn );
     361
     362    if( error )
     363    {
     364        printk("\n[PANIC] in %s : cannot initialize kernel GPT in cluster %x\n",
     365        __FUNCTION__ , cxy );
     366        hal_core_sleep();
     367    }
     368}
     369
    336370//////////////////////////////////////////
    337371error_t hal_gpt_set_pte( xptr_t    gpt_xp,
     
    390424        if( small == 0 )     // map a big page in PT1
    391425    {
    392         assert( (pte1 == 0) ,
    393                 "try to set a big page in a mapped PT1 entry / PT1[%d] = %x\n", ix1 , pte1 );
    394      
     426
     427// check PT1 entry not mapped
     428assert( (pte1 == 0) , "try to set a big page in a mapped PT1 entry\n" );
     429
     430// check VPN aligned
     431assert( (ix2 == 0) , "illegal vpn for a big page\n" );
     432
     433// check PPN aligned
     434assert( ((ppn & 0x1FF) == 0) , "illegal ppn for a big page\n" );
     435
    395436        // set the PTE1 value in PT1
    396437        pte1 = (tsar_attr  & TSAR_MMU_PTE1_ATTR_MASK) | ((ppn >> 9) & TSAR_MMU_PTE1_PPN_MASK);
  • trunk/hal/tsar_mips32/core/hal_special.c

    r619 r623  
    3333struct thread_s;
    3434
     35
     36//////////////////////////////////////////////////////////////////////////////////
     37//   Extern global variables
     38//////////////////////////////////////////////////////////////////////////////////
     39
     40extern cxy_t local_cxy;
     41extern void  hal_kentry_enter( void );
     42
     43/////////////////////////////////////////////////////////////////////////////////
     44// For the TSAR architecture, this function register the physical address of
     45// the first level page table (PT1) in the PTPR register.
     46// It activates the intructions MMU, and de-activates the data MMU.
     47/////////////////////////////////////////////////////////////////////////////////
     48void hal_mmu_init( gpt_t * gpt )
     49{
     50
     51    // set PT1 base address in mmu_ptpr register
     52    uint32_t ptpr = (((uint32_t)gpt->ptr) >> 13) | (local_cxy << 19);
     53    asm volatile ( "mtc2   %0,   $0         \n" : : "r" (ptpr) );
     54
     55    // set ITLB | ICACHE | DCACHE bits in mmu_mode register
     56    asm volatile ( "ori    $26,  $0,  0xB   \n"
     57                   "mtc2   $26,  $1         \n" );
     58}
     59
     60////////////////////////////////////////////////////////////////////////////////
     61// For the TSAR architecture, this function registers the address of the
     62// hal_kentry_enter() function in the MIPS32 cp0_ebase register.
     63////////////////////////////////////////////////////////////////////////////////
     64void hal_set_kentry( void )
     65{
     66    uint32_t kentry = (uint32_t)(&hal_kentry_enter);
     67
     68    asm volatile("mtc0   %0,  $15,  1" : : "r" (kentry) );
     69}
     70
    3571////////////////////////////////
    3672inline gid_t hal_get_gid( void )
  • 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
  • trunk/hal/tsar_mips32/kernel.ld

    r570 r623  
    44 * loadable segments, that MUST be identity mapped for the TSAR architecture.
    55 *
    6  * WARNING the seg_kentry_base and seg_kcode_base defined below must be kept coherent
     6 * WARNING : the seg_kentry_base and seg_kcode_base defined below must be coherent
    77 * with the values defined in the boot_config.h file used by the TSAR bootloader.
    88 **************************************************************************************/
Note: See TracChangeset for help on using the changeset viewer.