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
Line 
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>
16#include <drivers.h>
17
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//////////////////////////////////////////////////////////////////////////////
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;
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        _puts("\n[GIET ERROR] in iommu_add_pte2 function\n");
42        _puts("the IOMMU PT1 entry is not mapped / ix1 = ");
43        _putx( ix1 );
44        _puts("\n");
45        _exit();
46    }
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);
51        *pt_flags = flags;
52        *pt_ppn = ppn;
53    }
54} // end _iommu_add_pte2()
55
56
57//////////////////////////////////////////////////////////////////////////////
58// _iommu_inval_pte2()
59//////////////////////////////////////////////////////////////////////////////
60void _iommu_inval_pte2(unsigned int ix1, unsigned int ix2) {
61    unsigned int ptba;
62    unsigned int * pt_flags;
63
64    // get pointer on iommu page table
65    page_table_t * pt = &_iommu_ptab;
66
67    // get ptba and inval PTE2
68    if ((pt->pt1[ix1] & PTE_V) == 0) {
69        _puts("\n[GIET ERROR] in iommu_inval_pte2 function\n");
70        _puts("the IOMMU PT1 entry is not mapped / ix1 = ");
71        _putx( ix1 );
72        _puts("\n");
73        _exit();
74    }
75    else {
76        ptba = pt->pt1[ix1] << 12;
77        pt_flags = (unsigned int *) (ptba + 8 * ix2);
78        *pt_flags = 0;
79    }   
80} // end _iommu_inval_pte2()
81
82
83//////////////////////////////////////////////////////////////////////////////
84// _v2p_translate()
85// Returns 0 if success, 1 if PTE1 or PTE2 unmapped
86//////////////////////////////////////////////////////////////////////////////
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;
94
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
100    unsigned int ix1 = vpn >> 9;
101    unsigned int ix2 = vpn & 0x1FF;
102
103    // check PTE1 mapping
104    if ((pt->pt1[ix1] & PTE_V) == 0) return 1;
105    else 
106    {
107        // get physical addresses of pte2
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);
112
113        // gets ppn_value and flags_value, after temporary DTLB desactivation
114        asm volatile (
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   */
119
120                "li      $3,     0xB         \n"     
121                "mtc2    $3,     $1          \n"     /* DTLB unactivated     */ 
122
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       */
127
128                "li      $3,     0xF         \n" 
129                "mtc2    $3,     $1          \n"     /* DTLB activated       */
130
131                "mtc0    $4,     $12         \n"     /* restore SR           */
132                : "=r" (flags_value), "=r" (ppn_value)
133                : "r" (pte2_msb), "r" (pte2_lsb)
134                : "$2","$3","$4");
135
136        // check PTE2 mapping
137        if ((flags_value & PTE_V) == 0)  return 1; 
138
139        // set return values
140        *ppn = ppn_value;
141        *flags = flags_value;
142    }
143    return 0;
144} // end _v2p_translate()
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:
152// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
153
154
Note: See TracBrowser for help on using the repository browser.