Ignore:
Timestamp:
Sep 29, 2014, 10:47:26 AM (10 years ago)
Author:
alain
Message:

Introducing a physical memory allocator (pmem.c & pmem.h files).

Location:
soft/giet_vm/giet_common
Files:
4 added
5 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/giet_common/io.h

    r345 r408  
    77// Utility functions to write or read memory mapped hardware registers
    88///////////////////////////////////////////////////////////////////////////////////
     9
    910#ifndef IO_H
    1011#define IO_H
  • soft/giet_vm/giet_common/utils.c

    r399 r408  
    2222extern static_scheduler_t* _schedulers[NB_PROCS_MAX<<(X_WIDTH+Y_WIDTH)];
    2323
    24 
    2524///////////////////////////////////////////////////////////////////////////////////
    2625//         CP0 registers access functions
    2726///////////////////////////////////////////////////////////////////////////////////
    2827
    29 ///////////////////////////////////////////////////////////////////////////////////
    30 // Returns the value contained in CP0 SCHED register
    31 // (virtual base address of the processor scheduler).
    32 ///////////////////////////////////////////////////////////////////////////////////
     28/////////////////////////
    3329unsigned int _get_sched()
    3430{
     
    3834    return ret;
    3935}
    40 ///////////////////////////////////////////////////////////////////////////////////
    41 // Returns EPC register content.
    42 ///////////////////////////////////////////////////////////////////////////////////
     36///////////////////////
    4337unsigned int _get_epc()
    4438{
     
    4842    return ret;
    4943}
    50 ///////////////////////////////////////////////////////////////////////////////////
    51 // Returns BVAR register content.
    52 ///////////////////////////////////////////////////////////////////////////////////
     44////////////////////////
    5345unsigned int _get_bvar()
    5446{
     
    5850    return ret;
    5951}
    60 ///////////////////////////////////////////////////////////////////////////////////
    61 // Returns CR register content.
    62 ///////////////////////////////////////////////////////////////////////////////////
     52//////////////////////
    6353unsigned int _get_cr()
    6454{
     
    6858    return ret;
    6959}
    70 ///////////////////////////////////////////////////////////////////////////////////
    71 // Returns SR register content
    72 ///////////////////////////////////////////////////////////////////////////////////
     60//////////////////////
    7361unsigned int _get_sr()
    7462{
     
    7866    return ret;
    7967}
    80 //////////////////////////////////////////////////////////////////////////////
    81 // This function set a new value for the CP0 status register.
    82 //////////////////////////////////////////////////////////////////////////////
    83 void _set_sr(unsigned int val)
    84 {
    85     asm volatile( "mtc0      %0,     $12    \n"
    86                   :
    87                   :"r" (val) );
    88 }
    89 //////////////////////////////////////////////////////////////////////////////
    90 // Returns processor index
    91 //////////////////////////////////////////////////////////////////////////////
     68//////////////////////////
    9269unsigned int _get_procid()
    9370{
     
    9774    return (ret & 0x3FF);
    9875}
    99 //////////////////////////////////////////////////////////////////////////////
    100 // Returns local time (32 bits value)
    101 // boot_proctime()
    102 //////////////////////////////////////////////////////////////////////////////
     76////////////////////////////
    10377unsigned int _get_proctime()
    10478{
     
    10882    return ret;
    10983}
    110 //////////////////////////////////////////////////////////////////////////////
    111 // Save SR value into save_sr_ptr variable and disable IRQs.
    112 //////////////////////////////////////////////////////////////////////////////
     84
     85/////////////////////////////////////////////
    11386void _it_disable( unsigned int * save_sr_ptr)
    11487{
     
    12396    *save_sr_ptr = sr;
    12497}
    125 
    126 //////////////////////////////////////////////////////////////////////////////
    127 // Restores previous SR value.
    128 //////////////////////////////////////////////////////////////////////////////
     98//////////////////////////////////////////////
    12999void _it_restore( unsigned int * save_sr_ptr )
    130100{
     
    136106}
    137107
    138 //////////////////////////////////////////////////////////////////////////////
    139 // This function set a new value in CP0 SCHED register.
    140 // (virtual base address of the processor scheduler).
    141 //////////////////////////////////////////////////////////////////////////////
     108/////////////////////////////////
    142109void _set_sched(unsigned int val)
    143110{
     
    146113                   :"r" (val) );
    147114}
     115//////////////////////////////
     116void _set_sr(unsigned int val)
     117{
     118    asm volatile ( "mtc0     %0,     $12            \n"
     119                   :
     120                   :"r" (val) );
     121}
     122
    148123
    149124///////////////////////////////////////////////////////////////////////////////////
     
    151126///////////////////////////////////////////////////////////////////////////////////
    152127
    153 ///////////////////////////////////////////////////////////////////////////////////
    154 // Returns PTPR register content.
    155 ///////////////////////////////////////////////////////////////////////////////////
     128////////////////////////////
    156129unsigned int _get_mmu_ptpr()
    157130{
     
    161134    return ret;
    162135}
    163 ///////////////////////////////////////////////////////////////////////////////////
    164 // Returns MODE register content.
    165 ///////////////////////////////////////////////////////////////////////////////////
     136////////////////////////////
    166137unsigned int _get_mmu_mode()
    167138{
     
    171142    return ret;
    172143}
    173 //////////////////////////////////////////////////////////////////////////////
    174 // This function set a new value for the MMU PTPR register.
    175 //////////////////////////////////////////////////////////////////////////////
     144////////////////////////////////////
    176145void _set_mmu_ptpr(unsigned int val)
    177146{
    178     asm volatile ( "mtc2     %0,     $0            \n"
     147    asm volatile ( "mtc2     %0,     $0      \n"
    179148                   :
    180149                   :"r" (val)
    181150                   :"memory" );
    182151}
    183 //////////////////////////////////////////////////////////////////////////////
    184 // This function set a new value for the MMU MODE register.
    185 //////////////////////////////////////////////////////////////////////////////
     152////////////////////////////////////
    186153void _set_mmu_mode(unsigned int val)
    187154{
    188     asm volatile ( "mtc2     %0,     $1             \n"
     155    asm volatile ( "mtc2     %0,     $1      \n"
    189156                   :
    190157                   :"r" (val)
    191158                   :"memory" );
    192159}
     160////////////////////////////////////////////
     161void _set_mmu_dcache_inval(unsigned int val)
     162{
     163    asm volatile ( "mtc2     %0,     $7      \n"
     164                   :
     165                   :"r" (val)
     166                   :"memory" );
     167}
     168
    193169
    194170////////////////////////////////////////////////////////////////////////////
     
    10331009///////////////////////////////////////////////////////////////////////////////////
    10341010// Invalidate all data cache lines corresponding to a memory
    1035 // buffer (identified by an address and a size).
    1036 // TODO This should be replaced by a write to the CP2 MMU_DCACHE_INVAL
    1037 // register, to be more processor independant.
    1038 ///////////////////////////////////////////////////////////////////////////////////
    1039 void _dcache_buf_invalidate( void * buffer,
    1040                              unsigned int size)
    1041 {
    1042     unsigned int i;
     1011// buffer (identified by virtual base address and size).
     1012///////////////////////////////////////////////////////////////////////////////////
     1013void _dcache_buf_invalidate( unsigned int buf_vbase,
     1014                             unsigned int buf_size )
     1015{
     1016    unsigned int offset;
    10431017    unsigned int tmp;
    1044     unsigned int line_size;
     1018    unsigned int line_size;   // bytes
    10451019
    10461020    // compute data cache line size based on config register (bits 12:10)
     
    10481022                 "mfc0 %0, $16, 1"
    10491023                 : "=r" (tmp) );
     1024
    10501025    tmp = ((tmp >> 10) & 0x7);
    10511026    line_size = 2 << tmp;
    10521027
    10531028    // iterate on cache lines
    1054     for (i = 0; i < size; i += line_size)
    1055     {
    1056         asm volatile(
    1057                 " cache %0, %1"
    1058                 : :"i" (0x11), "R" (*((unsigned char *) buffer + i)) );
     1029    for ( offset = 0; offset < buf_size; offset += line_size)
     1030    {
     1031        _set_mmu_dcache_inval( buf_vbase + offset );
    10591032    }
    10601033}
     
    11101083    if ( vobj_id != 0xFFFFFFFF )
    11111084    {
    1112         *vaddr  = vobjs[vobj_id].vaddr;
     1085        *vaddr  = vobjs[vobj_id].vbase;
    11131086        *length = vobjs[vobj_id].length;
    11141087        return 0;
  • soft/giet_vm/giet_common/utils.h

    r399 r408  
    4545
    4646///////////////////////////////////////////////////////////////////////////////////
     47///////////////////////////////////////////////////////////////////////////////////
    4748//     CP0 registers access functions
    4849///////////////////////////////////////////////////////////////////////////////////
    49 
     50///////////////////////////////////////////////////////////////////////////////////
     51
     52///////////////////////////////////////////////////////////////////////////////////
     53// Returns CP0_SCHED register content
     54// (virtual base address of the processor scheduler)
     55///////////////////////////////////////////////////////////////////////////////////
    5056extern unsigned int _get_sched(void);
     57
     58///////////////////////////////////////////////////////////////////////////////////
     59// Returns CP0_EPC register content.
     60///////////////////////////////////////////////////////////////////////////////////
    5161extern unsigned int _get_epc(void);
     62
     63///////////////////////////////////////////////////////////////////////////////////
     64// Returns CP0_BVAR register content.
     65///////////////////////////////////////////////////////////////////////////////////
    5266extern unsigned int _get_bvar(void);
     67
     68///////////////////////////////////////////////////////////////////////////////////
     69// Returns CP0_CR register content.
     70///////////////////////////////////////////////////////////////////////////////////
    5371extern unsigned int _get_cr(void);
     72
     73///////////////////////////////////////////////////////////////////////////////////
     74// Returns CP0_SR register content.
     75///////////////////////////////////////////////////////////////////////////////////
    5476extern unsigned int _get_sr(void);
     77
     78///////////////////////////////////////////////////////////////////////////////////
     79// Returns CP0_PROCID register content.
     80// Processor identifier (12 bits)
     81///////////////////////////////////////////////////////////////////////////////////
    5582extern unsigned int _get_procid(void);
     83
     84///////////////////////////////////////////////////////////////////////////////////
     85// Returns CP0_TIME register content.
     86// Processor local time (32 bits)
     87///////////////////////////////////////////////////////////////////////////////////
    5688extern unsigned int _get_proctime(void);
    5789
     90///////////////////////////////////////////////////////////////////////////////////
     91// Save CP0_SR value to variable pointed by save_sr_ptr and disable IRQs.
     92///////////////////////////////////////////////////////////////////////////////////
    5893extern void         _it_disable( unsigned int* save_sr_ptr );
     94
     95///////////////////////////////////////////////////////////////////////////////////
     96// Restore CP0_SR register from variable pointed by save_sr_ptr.
     97///////////////////////////////////////////////////////////////////////////////////
    5998extern void         _it_restore( unsigned int* save_sr_ptr );
    6099
     100///////////////////////////////////////////////////////////////////////////////////
     101// Set a new value in CP0_SCHED register.
     102// (virtual base address of the processor scheduler)
     103///////////////////////////////////////////////////////////////////////////////////
    61104extern void         _set_sched(unsigned int value);
     105
     106///////////////////////////////////////////////////////////////////////////////////
     107// Set a new value in CP0_SR register.
     108///////////////////////////////////////////////////////////////////////////////////
    62109extern void         _set_sr(unsigned int value);
    63110
     111
     112///////////////////////////////////////////////////////////////////////////////////
    64113///////////////////////////////////////////////////////////////////////////////////
    65114//     CP2 registers access functions
    66115///////////////////////////////////////////////////////////////////////////////////
    67 
     116///////////////////////////////////////////////////////////////////////////////////
     117
     118///////////////////////////////////////////////////////////////////////////////////
     119// Returns CP2_PTPR register value.
     120// Page table physical base address for the running context.
     121// Contains only the 27 MSB bits, right justified.
     122///////////////////////////////////////////////////////////////////////////////////
    68123extern unsigned int _get_mmu_ptpr(void);
     124
     125///////////////////////////////////////////////////////////////////////////////////
     126// Returns CP2_MODE register value.
     127// MMU current mode, defined by 4 bits, right justified: ITLB/DTLB/ICACHE/DCACHE
     128///////////////////////////////////////////////////////////////////////////////////
    69129extern unsigned int _get_mmu_mode(void);
    70130
     131///////////////////////////////////////////////////////////////////////////////////
     132// Set a new value in CP2_PTPR register.
     133///////////////////////////////////////////////////////////////////////////////////
    71134extern void         _set_mmu_ptpr(unsigned int value);
     135
     136///////////////////////////////////////////////////////////////////////////////////
     137// Set a new value in CP2_MODE register.
     138///////////////////////////////////////////////////////////////////////////////////
    72139extern void         _set_mmu_mode(unsigned int value);
    73140
    74141///////////////////////////////////////////////////////////////////////////////////
     142// Set a value in  CP2_DCACHE_INVAL register.
     143// It invalidates the data cache line, if the virtual address defined by the
     144// value argument hit in DCACHE.
     145///////////////////////////////////////////////////////////////////////////////////
     146extern void         _set_mmu_dcache_inval(unsigned int value);
     147
     148
     149
     150///////////////////////////////////////////////////////////////////////////////////
     151///////////////////////////////////////////////////////////////////////////////////
    75152//     Physical addressing related functions
     153///////////////////////////////////////////////////////////////////////////////////
    76154///////////////////////////////////////////////////////////////////////////////////
    77155
     
    163241                             char*        source );
    164242
    165 extern void         _dcache_buf_invalidate( void * buffer,
    166                                             unsigned int size );
     243extern void         _dcache_buf_invalidate( unsigned int buf_vbase,
     244                                            unsigned int buf_size );
    167245
    168246extern unsigned int _heap_info( unsigned int* vaddr,
  • soft/giet_vm/giet_common/vmem.c

    r351 r408  
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
    7 // The vmem.c and vmem.h files are part ot the GIET-VM nano kernel.
    8 // They contain the kernel data structures and functions used to dynamically
    9 // handle the paged virtual memory.
    10 ///////////////////////////////////////////////////////////////////////////////////
    117
    128#include <utils.h>
    13 #include <tty_driver.h>
    149#include <vmem.h>
    1510#include <giet_config.h>
    16 #include <tty_driver.h>
    1711
    18 /////////////////////////////////////////////////////////////////////////////
    19 //     Global variable : IOMMU page table
    20 /////////////////////////////////////////////////////////////////////////////
    21 
    22 __attribute__((section (".iommu"))) page_table_t _iommu_ptab;
    23 
    24 //////////////////////////////////////////////////////////////////////////////
    25 // _iommu_add_pte2()
    26 //////////////////////////////////////////////////////////////////////////////
    27 void _iommu_add_pte2( unsigned int ix1,
    28                       unsigned int ix2,
    29                       unsigned int ppn,
    30                       unsigned int flags )
    31 {
    32     unsigned int ptba;
    33     unsigned int * pt_ppn;
    34     unsigned int * pt_flags;
    35 
    36     // get pointer on iommu page table
    37     page_table_t * pt = &_iommu_ptab;
    38 
    39     // get ptba and update PT2
    40     if ((pt->pt1[ix1] & PTE_V) == 0)
    41     {
    42         _printf("\n[GIET ERROR] in iommu_add_pte2() : "
    43                 "IOMMU PT1 entry not mapped / ix1 = %d\n", ix1 );
    44         _exit();
    45     }
    46     else
    47     {
    48         ptba = pt->pt1[ix1] << 12;
    49         pt_flags = (unsigned int *) (ptba + 8 * ix2);
    50         pt_ppn = (unsigned int *) (ptba + 8 * ix2 + 4);
    51         *pt_flags = flags;
    52         *pt_ppn = ppn;
    53     }
    54 } // end _iommu_add_pte2()
    55 
    56 
    57 //////////////////////////////////////////////////////////////////////////////
    58 // _iommu_inval_pte2()
    59 //////////////////////////////////////////////////////////////////////////////
    60 void _iommu_inval_pte2( unsigned int ix1,
    61                         unsigned int ix2 )
    62 {
    63     unsigned int ptba;
    64     unsigned int * pt_flags;
    65 
    66     // get pointer on iommu page table
    67     page_table_t * pt = &_iommu_ptab;
    68 
    69     // get ptba and inval PTE2
    70     if ((pt->pt1[ix1] & PTE_V) == 0)
    71     {
    72         _printf("\n[GIET ERROR] in iommu_inval_pte2() "
    73               "IOMMU PT1 entry not mapped / ix1 = %d\n", ix1 );
    74         _exit();
    75     }
    76     else {
    77         ptba = pt->pt1[ix1] << 12;
    78         pt_flags = (unsigned int *) (ptba + 8 * ix2);
    79         *pt_flags = 0;
    80     }   
    81 } // end _iommu_inval_pte2()
    82 
    83 //////////////////////////////////////////////////////////////////////////////
    84 // This function makes a "vpn" to "ppn" translation, from the page table
    85 // defined by the virtual address "pt". The MMU is supposed to be activated.
    86 // It uses the address extension mechanism for physical addressing.
    87 // Return 0 if success. Return 1 if PTE1 or PTE2 unmapped.
    88 //////////////////////////////////////////////////////////////////////////////
    89 unsigned int _v2p_translate( page_table_t*  pt,
     12//////////////////////////////////////////////////
     13unsigned int _v2p_translate( page_table_t*  ptab,
    9014                             unsigned int   vpn,
    9115                             unsigned int*  ppn,
     
    10630
    10731    // get PTE1
    108     unsigned int pte1 = pt->pt1[ix1];
     32    unsigned int pte1 = ptab->pt1[ix1];
    10933
    11034    // check PTE1 mapping
    111     if ( (pte1 & PTE_V) == 0 )  return 1;
     35    if ( (pte1 & PTE_V) == 0 )
     36    {
     37        _printf("\n[VMEM ERROR] _v2p_translate() : pte1 unmapped\n");
     38        _exit();
     39    }
    11240
    113     // get physical addresses of pte2 (two 32 bits words)
    114     ptba       = (unsigned long long) (pte1 & 0x0FFFFFFF) << 12;
    115     pte2_paddr = ptba + 8*ix2;
    116     pte2_lsb   = (unsigned int) pte2_paddr;
    117     pte2_msb   = (unsigned int) (pte2_paddr >> 32);
     41    // test big/small page
     42    if ( (pte1 & PTE_T) == 0 )  // big page
     43    {
     44        // set return values
     45        *ppn   = ((pte1 << 9) & 0x0FFFFE00) | (vpn & 0X000001FF);
     46        *flags = pte1 & 0xFFC00000;
     47    }
     48    else                        // small page
     49    {
    11850
    119     // disable interrupts and save status register
    120     _it_disable( &save_sr );
     51        // get physical addresses of pte2 (two 32 bits words)
     52        ptba       = (unsigned long long) (pte1 & 0x0FFFFFFF) << 12;
     53        pte2_paddr = ptba + 8*ix2;
     54        pte2_lsb   = (unsigned int) pte2_paddr;
     55        pte2_msb   = (unsigned int) (pte2_paddr >> 32);
    12156
    122     // gets ppn_value and flags_value, after temporary DTLB desactivation
    123     asm volatile (
     57        // disable interrupts and save status register
     58        _it_disable( &save_sr );
     59
     60        // get ppn_value and flags_value, using a physical read
     61        // after temporary DTLB desactivation
     62        asm volatile (
    12463                "mfc2    $2,     $1          \n"     /* $2 <= MMU_MODE       */
    12564                "andi    $3,     $2,    0xb  \n"
     
    12766
    12867                "move    $4,     %3          \n"     /* $4 <= pte_lsb        */
    129                 "mtc2    %2,     $24         \n"     /* PADDR_EXT <= msb    */
     68                "mtc2    %2,     $24         \n"     /* PADDR_EXT <= pte_msb */
    13069                "lw      %0,     0($4)       \n"     /* read flags           */
    13170                "lw      %1,     4($4)       \n"     /* read ppn             */
     
    13776                : "$2", "$3", "$4" );
    13877
    139     // restore saved status register
    140     _it_restore( &save_sr );
     78        // restore saved status register
     79        _it_restore( &save_sr );
    14180
    142     // check PTE2 mapping
    143     if ( (flags_value & PTE_V) == 0 )  return 1;
     81        // set return values
     82        *ppn   = ppn_value   & 0x0FFFFFFF;
     83        *flags = flags_value & 0xFFC00000;
    14484
    145     // set return values
    146     *ppn   = ppn_value;
    147     *flags = flags_value;
    148 
     85        // check PTE2 mapping
     86        if ( (flags_value & PTE_V) == 0 )
     87        {
     88            _printf("\n[VMEM ERROR] _v2p_translate() : pte2 unmapped\n");
     89            _exit();
     90        }
     91    }
    14992    return 0;
    15093} // end _v2p_translate()
  • soft/giet_vm/giet_common/vmem.h

    r258 r408  
    11///////////////////////////////////////////////////////////////////////////////////
    2 // File     : vm_handler.h
     2// File     : vmem.h
    33// Date     : 01/07/2012
    44// Author   : alain greiner
    55// Copyright (c) UPMC-LIP6
    66///////////////////////////////////////////////////////////////////////////////////
     7// The vmem.c and vmem.h files are part ot the GIET-VM nano kernel.
     8// They define  the data structures implementing the page tables,
     9// and the function used for VPN to PPN translation.
     10///////////////////////////////////////////////////////////////////////////////////
     11// The virtual address format is 32 bits: structures in 3 fields:
     12//             |  11  |  9   |   12   |
     13//             | IX1  | IX2  | OFFSET |
     14// - The IX1 field is the index in the first level page table
     15// - The IX2 field is the index in the second level page table
     16// - The |IX1|IX2\ concatenation defines the VPN (Virtual Page Number)
     17///////////////////////////////////////////////////////////////////////////////////
    718
    8 #ifndef _VM_HANDLER_H_
    9 #define _VM_HANDLER_H_
    10 
    11 #include <giet_config.h>
    12 #include <mapping_info.h>
     19#ifndef _VMEM_H_
     20#define _VMEM_H_
    1321
    1422/////////////////////////////////////////////////////////////////////////////////////
     
    1826#define PT1_SIZE    8192
    1927#define PT2_SIZE    4096
     28
     29#define VPN_MASK    0xFFFFF000
     30#define BPN_MASK    0xFFE00000
    2031
    2132/////////////////////////////////////////////////////////////////////////////////////
     
    5162// Page table structure definition
    5263/////////////////////////////////////////////////////////////////////////////////////
     64
    5365typedef struct PageTable
    5466{
     
    5769} page_table_t;
    5870
    59 
    60 ////////////////////////////////////////////////////////////////////////////////////
    61 // Global variable
    62 ////////////////////////////////////////////////////////////////////////////////////
    63 
    64 extern page_table_t _iommu_ptab;
    65 
    6671////////////////////////////////////////////////////////////////////////////////////
    6772// functions prototypes
    6873////////////////////////////////////////////////////////////////////////////////////
    6974
    70 void _iommu_add_pte2( unsigned int ix1,
    71                       unsigned int ix2,
    72                       unsigned int ppn,
    73                       unsigned int flags );
    74 
    75 void _iommu_inval_pte2( unsigned int ix1,
    76                         unsigned int ix2 );
    77 
     75///////////////////////////////////////////////////////////////////////////////////
     76// This function makes a "vpn" to "ppn" translation, from the page table
     77// defined by the virtual address "pt". The MMU is supposed to be activated.
     78// It supports both small (4 Kbytes) & big (2 Mbytes) pages.
     79// It uses the address extension mechanism for physical addressing.
     80// Return 0 if success. Return 1 if PTE1 or PTE2 unmapped.
     81///////////////////////////////////////////////////////////////////////////////////
    7882unsigned int _v2p_translate( page_table_t* pt,
    7983                             unsigned int  vpn,
Note: See TracChangeset for help on using the changeset viewer.