Changeset 624 for trunk/hal/tsar_mips32


Ignore:
Timestamp:
Mar 12, 2019, 1:37:38 PM (5 years ago)
Author:
alain
Message:

Fix several bugs to use the instruction MMU in kernel mode
in replacement of the instruction address extension register,
and remove the "kentry" segment.

This version is running on the tsar_generic_iob" platform.

One interesting bug: the cp0_ebase defining the kernel entry point
(for interrupts, exceptions and syscalls) must be initialized
early in kernel_init(), because the VFS initialisation done by
kernel_ini() uses RPCs, and RPCs uses Inter-Processor-Interrup.

Location:
trunk/hal/tsar_mips32
Files:
4 edited

Legend:

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

    r623 r624  
    174174} // end hal_gpt_create()
    175175
    176 
    177176///////////////////////////////////
    178177void hal_gpt_destroy( gpt_t * gpt )
     
    334333
    335334
    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 /////////////////////////////////////////////////////////////////////////////////////
    340 void 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 
    370335//////////////////////////////////////////
    371336error_t hal_gpt_set_pte( xptr_t    gpt_xp,
     
    617582}  // end hal_gpt_reset_pte()
    618583
     584
     585/* unused until now (march 2019) [AG]
     586
     587//////////////////////////////////////
     588void hal_gpt_reset_range( gpt   * gpt,
     589                          vpn_t   vpn_min,
     590                          vpn_t   vpn_max )
     591{
     592    vpn_t      vpn;         // current vpn
     593
     594    uint32_t * pt1;         // PT1 base address
     595    uint32_t   pte1;        // PT1 entry value
     596
     597    ppn_t      pt2_ppn;     // PPN of PT2
     598    uint32_t * pt2;         // PT2 base address
     599
     600    uint32_t   ix1;         // index in PT1
     601    uint32_t   ix2;         // index in PT2
     602
     603    // get PT1
     604    pt1 = gpt->ptr;
     605
     606    // initialize current index
     607    vpn = vpn_min;
     608
     609    // loop on pages
     610    while( vpn <= vpn_max )
     611    {
     612        // get ix1 index from vpn
     613        ix1 = TSAR_MMU_IX1_FROM_VPN( vpn );
     614
     615        // get PTE1
     616        pte1 = pt1[ix1]
     617
     618            if( (pte1 & TSAR_MMU_MAPPED) == 0 )     // PT1[ix1] unmapped
     619        {
     620            // update vpn (next big page)
     621            (vpn = ix1 + 1) << 9;
     622        }
     623            if( (pte1 & TSAR_MMU_SMALL) == 0 )      // it's a PTE1 (big page)
     624            {
     625            // unmap the big page
     626            pt1[ix1] = 0;
     627                hal_fence();
     628           
     629            // update vpn (next big page)
     630            (vpn = ix1 + 1) << 9;
     631        }
     632        else                                    // it's a PTD1 (small page)
     633        {
     634            // compute PT2 base address
     635            pt2_ppn = TSAR_MMU_PTBA_FROM_PTE1( pte1 );
     636            pt2     = GET_PTR( ppm_ppn2base( pt2_ppn ) );
     637
     638            // get ix2 index from vpn
     639            ix2 = TSAR_MMU_IX2_FROM_VPN( vpn );
     640
     641            // unmap the small page
     642            pt2[2*ix2]   = 0;         
     643            hal_fence();       
     644
     645            // update vpn (next small page)
     646            vpn++;
     647        }
     648    }
     649}  // hal_gpt_reset_range()
     650*/
     651
    619652//////////////////////////////////////
    620653error_t hal_gpt_lock_pte( gpt_t * gpt,
  • trunk/hal/tsar_mips32/core/hal_special.c

    r623 r624  
    263263void hal_core_sleep( void )
    264264{
    265     thread_t * this = CURRENT_THREAD;
    266 
    267     printk("\n*** thread[%x,%x] on core[%x,%d]/n"
    268            "  sr = %X / sp = %X / ra = %X\n",
    269            this->process->pid, this->trdid, local_cxy, this->core->lid, 
    270            hal_get_sr(), hal_get_sp(), hal_get_ra() );
    271 
    272         while( 1 ) asm volatile ("nop");
     265        while( 1 ) asm volatile ("wait");
    273266}
    274267
  • trunk/hal/tsar_mips32/core/hal_vmm.c

    r623 r624  
    2727#include <hal_gpt.h>
    2828#include <process.h>
     29#include <thread.h>
    2930#include <vseg.h>
    3031#include <xlist.h>
     
    4142
    4243// extern global variables
    43 extern process_t process_zero;
     44extern process_t            process_zero;
     45extern chdev_directory_t    chdev_dir;
    4446
    4547//////////////////////////////////////////////////////////////////////////////////////////
    4648// This function is called by the process_zero_init() function during kernel_init.
    4749// It initializes the VMM of the kernel proces_zero (containing all kernel threads)
    48 // in the local cluster.
     50// in the local cluster: it registers one "kcode" vseg in kernel VSL, and registers
     51// one big page in slot[0] of kernel GPT.
    4952//////////////////////////////////////////////////////////////////////////////////////////
    5053error_t  hal_vmm_kernel_init( boot_info_t * info )
     
    6871    }
    6972
     73#if DEBUG_HAL_VMM
     74thread_t * this = CURRENT_THREAD;
     75printk("\n[%s] thread[%x,%x] enter in cluster %x / gpt %x\n",
     76__FUNCTION__, this->process->pid, this->trdid, local_cxy, gpt );
     77#endif
     78
    7079    // 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]
     80    uint32_t attr = GPT_MAPPED | GPT_READABLE | GPT_CACHABLE | GPT_EXECUTABLE | GPT_GLOBAL;
     81    uint32_t ppn  = cxy << 20;   
     82
     83    // register PTE1  in slot[0] of kernel GPT
    7584    error = hal_gpt_set_pte( XPTR( cxy , gpt ) , 0 , attr , ppn );
    7685
     
    8190        hal_core_sleep();
    8291    }
     92
     93#if DEBUG_HAL_VMM
     94printk("\n[%s] thread[%x,%x] created PT1[0] : ppn %x / attr %x\n",
     95__FUNCTION__, this->process->pid, this->trdid, ppn, attr );
     96#endif
    8397
    8498    // create kcode vseg and register it in kernel VSL
    8599    vseg_t * vseg = vmm_create_vseg( &process_zero,
    86                                      VSEG_TYPE_CODE,
     100                                     VSEG_TYPE_KCODE,
    87101                                     info->kcode_base,
    88102                                     info->kcode_size,
     
    97111    }
    98112
    99 }  // end hal_vmm_init()
     113#if DEBUG_HAL_VMM
     114printk("\n[%s] thread[%x,%x] registered kcode vseg[%x,%x]\n",
     115__FUNCTION__, this->process->pid, this->trdid, info->kcode_base, info->kcode_size );
     116hal_vmm_display( &process_zero , true );
     117#endif
     118
     119    return 0;
     120
     121}  // end hal_kernel_vmm_init()
    100122
    101123//////////////////////////////////////////////////////////////////////////////////////////
     
    111133    uint32_t ppn;
    112134
    113 // TODO check ppn value in kernel GPT (must be 0)
     135#if DEBUG_HAL_VMM
     136thread_t * this = CURRENT_THREAD;
     137printk("\n[%s] thread[%x,%x] enter in cluster %x \n",
     138__FUNCTION__, this->process->pid, this->trdid, local_cxy );
     139hal_vmm_display( process , true );
     140hal_vmm_display( &process_zero , true );
     141#endif
    114142
    115143    // get cluster identifier
    116144    cxy_t cxy = local_cxy;
    117145
     146    // get extended pointer on kernel GPT
     147    xptr_t k_gpt_xp = XPTR( cxy , &process_zero.vmm.gpt );
     148
     149    // get ppn and attributes from slot[0] of kernel GPT
     150    hal_gpt_get_pte( k_gpt_xp , 0 , &attr , &ppn );
     151
     152#if DEBUG_HAL_VMM
     153printk("\n[%s] thread[%x,%x] get PT1[0] ( ppn %x / attr %x ) from kernel  GPT\n",
     154__FUNCTION__, this->process->pid, this->trdid, ppn, attr );
     155#endif
     156
    118157    // 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
    125 assert( (attr == 0x8A800000) && (ppn == ((cxy << 20) >> 9)),  __FUNCTION__,
    126 "bad ppn = %x or attr = %x in slot[0] of kernel GPT\n", ppn , attr );
    127  
     158    xptr_t u_gpt_xp = XPTR( cxy , &process->vmm.gpt );
     159
    128160    // update user GPT : set PTE1 in slot[0]
    129     error = hal_gpt_set_pte( gpt_xp , 0 , attr , ppn );
     161    error = hal_gpt_set_pte( u_gpt_xp , 0 , attr , ppn );
    130162
    131163    if( error )
    132164    {
    133         printk("\n[ERROR] in %s : cannot update GPT in cluster %x\n",
     165        printk("\n[ERROR] in %s : cannot update user GPT in cluster %x\n",
    134166        __FUNCTION__ , cxy );
    135167        return -1;
    136168    }
    137169
     170#if DEBUG_HAL_VMM
     171printk("\n[%s] thread[%x,%x] registered PT1[0] ( ppn %x / attr %x ) to user GPT\n",
     172__FUNCTION__, this->process->pid, this->trdid, ppn, attr );
     173#endif
     174
    138175    // 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 );
     176    xptr_t   root_xp = XPTR( cxy , &process_zero.vmm.vsegs_root );
     177    xptr_t   vseg_xp = XLIST_FIRST( root_xp , vseg_t , xlist );
     178    vseg_t * vseg    = GET_PTR( vseg_xp );
    141179
    142180// check vsegs_nr
    143 assert( (process_zero.vmm.vsegs_nr == 1 ) , __FUNCTION__,
    144 "bad vsegs number in kernel VSL\n" );
     181assert( (process_zero.vmm.vsegs_nr == 1 ) ,
     182"bad vsegs number in kernel VSL = %d\n", process_zero.vmm.vsegs_nr );
    145183
    146184    // update user VSL : register one new vseg for kcode
     
    154192    if( new == NULL )
    155193    {
    156         printk("\n[ERROR] in %s : cannot update VSL in cluster %x\n",
     194        printk("\n[ERROR] in %s : cannot update user VSL in cluster %x\n",
    157195        __FUNCTION__ , cxy );
    158196        return -1;
    159197    }
    160 }
    161 
    162 
     198
     199#if DEBUG_HAL_VMM
     200printk("\n[%s] thread[%x,%x] created vseg %s ( base %x / size %x ) to user VSL\n",
     201__FUNCTION__, this->process->pid, this->trdid,
     202vseg_type_str(vseg->type) , vseg->min, (vseg->max - vseg->min) );
     203hal_vmm_display( process , true );
     204#endif
     205
     206    return 0;
     207
     208}  // end hal_vmm_kernel_update()
     209
     210//////////////////////////////////////////
     211void hal_vmm_display( process_t * process,
     212                      bool_t      mapping )
     213{
     214    vmm_t * vmm = &process->vmm;
     215    gpt_t * gpt = &vmm->gpt;
     216
     217    // get pointers on TXT0 chdev
     218    xptr_t    txt0_xp  = chdev_dir.txt_tx[0];
     219    cxy_t     txt0_cxy = GET_CXY( txt0_xp );
     220    chdev_t * txt0_ptr = GET_PTR( txt0_xp );
     221
     222    // get extended pointer on remote TXT0 lock
     223    xptr_t  lock_xp = XPTR( txt0_cxy , &txt0_ptr->wait_lock );
     224
     225    // get locks protecting the VSL and the GPT
     226    remote_rwlock_rd_acquire( XPTR( local_cxy , &vmm->vsegs_lock ) );
     227    remote_rwlock_rd_acquire( XPTR( local_cxy , &vmm->gpt_lock ) );
     228
     229    // get TXT0 lock
     230    remote_busylock_acquire( lock_xp );
     231
     232    nolock_printk("\n***** VSL and GPT for process %x in cluster %x\n",
     233    process->pid , local_cxy );
     234
     235    // scan the list of vsegs
     236    xptr_t         root_xp = XPTR( local_cxy , &vmm->vsegs_root );
     237    xptr_t         iter_xp;
     238    xptr_t         vseg_xp;
     239    vseg_t       * vseg;
     240    XLIST_FOREACH( root_xp , iter_xp )
     241    {
     242        vseg_xp = XLIST_ELEMENT( iter_xp , vseg_t , xlist );
     243        vseg    = GET_PTR( vseg_xp );
     244
     245        nolock_printk(" - %s : base = %X / size = %X / npages = %d\n",
     246        vseg_type_str( vseg->type ) , vseg->min , vseg->max - vseg->min , vseg->vpn_size );
     247
     248        if( mapping )
     249        {
     250            vpn_t    vpn     = vseg->vpn_base;
     251            vpn_t    vpn_max = vpn + vseg->vpn_size;
     252            ppn_t    ppn;
     253            uint32_t attr;
     254
     255            while( vpn < vpn_max )
     256            {
     257                hal_gpt_get_pte( XPTR( local_cxy , gpt ) , vpn , &attr , &ppn );
     258
     259                if( attr & GPT_MAPPED )
     260                {
     261                    if( attr & GPT_SMALL )
     262                    {
     263                        nolock_printk("    . SMALL : vpn = %X / attr = %X / ppn = %X\n",
     264                        vpn , attr , ppn );
     265                        vpn++;
     266                    }
     267                    else
     268                    {
     269                        nolock_printk("    . BIG   : vpn = %X / attr = %X / ppn = %X\n",
     270                        vpn , attr , ppn );
     271                        vpn += 512;
     272                    }
     273                }
     274                else
     275                {
     276                    vpn++;
     277                }
     278            }
     279        }
     280    }
     281
     282    // release TXT0 lock
     283    remote_busylock_release( lock_xp );
     284
     285    // release the VSK and GPT locks
     286    remote_rwlock_rd_release( XPTR( local_cxy , &vmm->vsegs_lock ) );
     287    remote_rwlock_rd_release( XPTR( local_cxy , &vmm->gpt_lock ) );
     288
     289}  // hal_vmm_display()
     290
  • trunk/hal/tsar_mips32/kernel.ld

    r623 r624  
    11/***************************************************************************************
    22 * This is the linker script for the ALMOS-MKH kernel code on the TSAR architecture.
    3  * It describes the memory layout for the "kernel.elf" binary file, containing three
     3 * It describes the memory layout for the "kernel.elf" binary file, containing the two
    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 coherent
     6 * WARNING : the 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 **************************************************************************************/
     
    1010/* Define the kernel code base addresses */
    1111
    12 seg_kcode_base  = 0x00008000;
    13 seg_kentry_base = 0x00004000;
     12seg_kcode_base  = 0x00004000;
    1413
    15 /* Set the entry point (e_entry field in the "kernel.elf" file header) */
     14/* Define the e_entry field in the "kernel.elf" file header) */
    1615
    1716ENTRY(kernel_init)
     
    2423        seg_kcode :
    2524        {
     25                *(.kentry)
     26                *(.switch)
    2627                *(.text)
    2728                *(.rodata*)
     
    3536                *(.kidle)
    3637                *(.kdata*)
     38        *(.scommon)
     39        *(.bss)
     40        *(.eh*)
    3741                *(.data*)
    3842        }
    39 
    40     . = seg_kentry_base;
    41     seg_kentry :
    42     {
    43                 *(.kentry)
    44                 *(.switch)
    45     }
    4643}
Note: See TracChangeset for help on using the changeset viewer.