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

Last change on this file since 170 was 170, checked in by alain, 12 years ago

Bug fix dans _v2p_translate() (in sys/vm_handler.c)

File size: 4.8 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// TODO : We must transfer here the functions used to statically build
12// the page tables associated to the various vspaces (now in boot_handler.c)
13//
14///////////////////////////////////////////////////////////////////////////////////
15
16#include <vm_handler.h>
17#include <sys_handler.h>
18#include <common.h>
19#include <giet_config.h>
20
21/////////////////////////////////////////////////////////////////////////////
22//      Global variable : IOMMU page table
23/////////////////////////////////////////////////////////////////////////////
24
25__attribute__((section (".iommu"))) page_table_t        _iommu_ptab;
26
27//////////////////////////////////////////////////////////////////////////////
28// _iommu_add_pte2()
29//////////////////////////////////////////////////////////////////////////////
30void _iommu_add_pte2( unsigned int      ix1,
31                      unsigned int      ix2,
32                      unsigned int      ppn,
33                      unsigned int      flags )
34{
35    unsigned int        ptba;
36    unsigned int*       pt_ppn;
37    unsigned int*       pt_flags;
38
39    // get pointer on iommu page table
40    page_table_t* pt = &_iommu_ptab;
41
42    // get ptba and update PT2
43    if ( (pt->pt1[ix1] & PTE_V) == 0 )
44    {
45        _puts("\n[GIET ERROR] in iommu_add_pte2 function\n");
46        _puts("the IOMMU PT1 entry is not mapped / ix1 = ");
47        _putw( ix1 );
48        _puts("\n");
49        _exit();
50    }
51    else
52    {
53        ptba      = pt->pt1[ix1] << 12;
54        pt_flags  = (unsigned int*)(ptba + 8*ix2);
55        pt_ppn    = (unsigned int*)(ptba + 8*ix2 + 4);
56        *pt_flags = flags;
57        *pt_ppn   = ppn;
58    }
59} // end _iommu_add_pte2()
60
61//////////////////////////////////////////////////////////////////////////////
62// _iommu_inval_pte2()
63//////////////////////////////////////////////////////////////////////////////
64void _iommu_inval_pte2( unsigned int    ix1,
65                        unsigned int    ix2 )
66{
67    unsigned int        ptba;
68    unsigned int*       pt_flags;
69
70    // get pointer on iommu page table
71    page_table_t* pt = &_iommu_ptab;
72
73    // get ptba and inval PTE2
74    if ( (pt->pt1[ix1] & PTE_V) == 0 )
75    {
76        _puts("\n[GIET ERROR] in iommu_inval_pte2 function\n");
77        _puts("the IOMMU PT1 entry is not mapped / ix1 = ");
78        _putw( ix1 );
79        _puts("\n");
80        _exit();
81    }
82    else
83    {
84        ptba      = pt->pt1[ix1] << 12;
85        pt_flags  = (unsigned int*)(ptba + 8*ix2);
86        *pt_flags = 0;
87    }   
88} // end _iommu_inval_pte2()
89
90//////////////////////////////////////////////////////////////////////////////
91// _v2p_translate()
92// Returns 0 if success, 1 if PTE1 or PTE2 unmapped
93//////////////////////////////////////////////////////////////////////////////
94unsigned int _v2p_translate( page_table_t*      pt,
95                             unsigned int       vpn,
96                             unsigned int*      ppn,           
97                             unsigned int*      flags ) 
98{
99    unsigned int    ptba;
100
101    register unsigned int*   pte2;
102    register unsigned int    flags_value;
103    register unsigned int    ppn_value;
104
105    unsigned int    ix1 = vpn >> 9;
106    unsigned int    ix2 = vpn & 0x1FF;
107
108    // check PTE1 mapping
109    if ( (pt->pt1[ix1] & PTE_V) == 0 )
110    {
111        return 1;
112    }
113    else
114    {
115        // get physical addresses of pte2
116        ptba = pt->pt1[ix1] << 12;
117        pte2 = (unsigned int*)(ptba + 8*ix2);
118
119        // gets ppn_value and flags_value, after temporary DTLB desactivation
120        asm volatile ( "move    $27, %2     \n"     /* $27 <= pte2      */
121                       "li      $26, 0xB    \n"     /* DTLB unactivated */
122                       "mtc2    $26, $1     \n"
123                       "lw      %0,  0($27) \n"     /* read flags       */ 
124                       "lw      %1,  4($27) \n"     /* read ppn         */
125                       "li      $26, 0xF    \n" 
126                       "mtc2    $26, $1     \n"     /* DTLB activated   */
127                        :"=r"(flags_value), "=r"(ppn_value)
128                        :"r"(pte2)
129                        :"$26" );
130
131        // check PTE2 mapping
132        if ( (flags_value & PTE_V) == 0 )
133        {
134            return 1;
135        }
136
137        // set return values
138        *ppn      = ppn_value;
139        *flags    = flags_value;
140    }
141    return 0;
142}       // end _v2p_translate()
143
144// Local Variables:
145// tab-width: 4
146// c-basic-offset: 4
147// c-file-offsets:((innamespace . 0)(inline-open . 0))
148// indent-tabs-mode: nil
149// End:
150
151// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
152
Note: See TracBrowser for help on using the repository browser.