source: soft/giet_vm/sys/vm_handler.c @ 238

Last change on this file since 238 was 238, checked in by alain, 11 years ago

Major evolution to support physical addresses larger than 32 bits.
The map.xml format has been modified: the vsegs associated to schedulers
are now explicitely defined and mapped in the page tables.

File size: 5.2 KB
RevLine 
[167]1///////////////////////////////////////////////////////////////////////////////////
2// File     : vm_handler.c
3// Date     : 01/07/2012
4// Author   : alain greiner
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7// The vm_handler.c and vm_handler.h files are part ot the GIET nano kernel.
8// They contains the kernel data structures and functions used to dynamically
9// handle the iommu page table.
10///////////////////////////////////////////////////////////////////////////////////
11
12#include <vm_handler.h>
13#include <sys_handler.h>
14#include <common.h>
15#include <giet_config.h>
[238]16#include <drivers.h>
[167]17
18/////////////////////////////////////////////////////////////////////////////
[228]19//     Global variable : IOMMU page table
[167]20/////////////////////////////////////////////////////////////////////////////
21
[228]22__attribute__((section (".iommu"))) page_table_t _iommu_ptab;
[167]23
24//////////////////////////////////////////////////////////////////////////////
25// _iommu_add_pte2()
26//////////////////////////////////////////////////////////////////////////////
[228]27void _iommu_add_pte2(
28        unsigned int ix1,
29        unsigned int ix2,
30        unsigned int ppn,
31        unsigned int flags) {
32    unsigned int ptba;
33    unsigned int * pt_ppn;
34    unsigned int * pt_flags;
[167]35
36    // get pointer on iommu page table
[228]37    page_table_t * pt = &_iommu_ptab;
[167]38
39    // get ptba and update PT2
[228]40    if ((pt->pt1[ix1] & PTE_V) == 0) {
[167]41        _puts("\n[GIET ERROR] in iommu_add_pte2 function\n");
42        _puts("the IOMMU PT1 entry is not mapped / ix1 = ");
[207]43        _putx( ix1 );
[167]44        _puts("\n");
45        _exit();
46    }
[228]47    else {
48        ptba = pt->pt1[ix1] << 12;
49        pt_flags = (unsigned int *) (ptba + 8 * ix2);
50        pt_ppn = (unsigned int *) (ptba + 8 * ix2 + 4);
[167]51        *pt_flags = flags;
[228]52        *pt_ppn = ppn;
[167]53    }
54} // end _iommu_add_pte2()
55
[228]56
[167]57//////////////////////////////////////////////////////////////////////////////
58// _iommu_inval_pte2()
59//////////////////////////////////////////////////////////////////////////////
[228]60void _iommu_inval_pte2(unsigned int ix1, unsigned int ix2) {
61    unsigned int ptba;
62    unsigned int * pt_flags;
[167]63
64    // get pointer on iommu page table
[228]65    page_table_t * pt = &_iommu_ptab;
[167]66
67    // get ptba and inval PTE2
[228]68    if ((pt->pt1[ix1] & PTE_V) == 0) {
[167]69        _puts("\n[GIET ERROR] in iommu_inval_pte2 function\n");
70        _puts("the IOMMU PT1 entry is not mapped / ix1 = ");
[207]71        _putx( ix1 );
[167]72        _puts("\n");
73        _exit();
74    }
[228]75    else {
76        ptba = pt->pt1[ix1] << 12;
77        pt_flags = (unsigned int *) (ptba + 8 * ix2);
[167]78        *pt_flags = 0;
79    }   
80} // end _iommu_inval_pte2()
81
[228]82
[167]83//////////////////////////////////////////////////////////////////////////////
84// _v2p_translate()
85// Returns 0 if success, 1 if PTE1 or PTE2 unmapped
86//////////////////////////////////////////////////////////////////////////////
[238]87unsigned int _v2p_translate( page_table_t*   pt,
88                             unsigned int    vpn,
89                             unsigned int*   ppn,       
90                             unsigned int*   flags ) 
91{
92    paddr_t                 ptba;
93    paddr_t                 pte2;
[167]94
[238]95    register unsigned int   pte2_msb;
96    register unsigned int   pte2_lsb;
97    register unsigned int   flags_value;
98    register unsigned int   ppn_value;
99
[228]100    unsigned int ix1 = vpn >> 9;
101    unsigned int ix2 = vpn & 0x1FF;
[238]102
[167]103    // check PTE1 mapping
[238]104    if ((pt->pt1[ix1] & PTE_V) == 0) return 1;
105    else 
106    {
[167]107        // get physical addresses of pte2
[238]108        ptba     = (paddr_t)(pt->pt1[ix1] & 0x0FFFFFFF) << 12;
109        pte2     = ptba + 8*ix2;
110        pte2_lsb = (unsigned int)pte2;
111        pte2_msb = (unsigned int)(pte2 >> 32);
[167]112
113        // gets ppn_value and flags_value, after temporary DTLB desactivation
[228]114        asm volatile (
[238]115                "li      $2,     0xFFFFFFFE  \n"     /* Mask for IE bits     */
116                "mfc0    $4,     $12         \n"     /* $4 <= SR             */ 
117                "and     $2,     $2,    $4   \n"
118                "mtc0    $2,     $12         \n"     /* disable Interrupts   */
[184]119
[238]120                "li      $3,     0xB         \n"     
121                "mtc2    $3,     $1          \n"     /* DTLB unactivated     */ 
[189]122
[238]123                "mtc2    %2,     $24         \n"     /* PADDR_EXT <= msb     */
124                "lw      %0,     0(%3)       \n"     /* read flags           */ 
125                "lw      %1,     4(%3)       \n"     /* read ppn             */
126                "mtc2    $0,     $24         \n"     /* PADDR_EXT <= 0       */
[184]127
[238]128                "li      $3,     0xF         \n" 
129                "mtc2    $3,     $1          \n"     /* DTLB activated       */
[189]130
[238]131                "mtc0    $4,     $12         \n"     /* restore SR           */
[228]132                : "=r" (flags_value), "=r" (ppn_value)
[238]133                : "r" (pte2_msb), "r" (pte2_lsb)
134                : "$2","$3","$4");
[167]135
136        // check PTE2 mapping
[238]137        if ((flags_value & PTE_V) == 0)  return 1; 
[167]138
139        // set return values
[228]140        *ppn = ppn_value;
141        *flags = flags_value;
[167]142    }
143    return 0;
[228]144} // end _v2p_translate()
[167]145
146// Local Variables:
147// tab-width: 4
148// c-basic-offset: 4
149// c-file-offsets:((innamespace . 0)(inline-open . 0))
150// indent-tabs-mode: nil
151// End:
[228]152// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
[167]153
154
Note: See TracBrowser for help on using the repository browser.