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

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

Fix several bugs to use the vci_block_device with MMU activated

File size: 4.7 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    unsigned int*   pte2;
101    unsigned int    flags_value;
102    unsigned int    ppn_value;
103
104    unsigned int    ix1 = vpn >> 9;
105    unsigned int    ix2 = vpn & 0x1FF;
106
107    // check PTE1 mapping
108    if ( (pt->pt1[ix1] & PTE_V) == 0 )
109    {
110        return 1;
111    }
112    else
113    {
114        // get physical addresses of pte2
115        ptba = pt->pt1[ix1] << 12;
116        pte2 = (unsigned int*)(ptba + 8*ix2);
117
118        // gets ppn_value and flags_value, after temporary DTLB desactivation
119        asm volatile ( "li      $26, 0xB    \n"     /* DTLB unactivated */
120                       "mtc2    $26, $1     \n"
121                       "lw      %0,  0(%2)  \n"     /* read flags       */ 
122                       "lw      %1,  4(%2)  \n"     /* read ppn         */
123                       "li      $26, 0xF    \n" 
124                       "mtc2    $26, $1     \n"     /* DTLB activated   */
125                        :"=r"(flags_value), "=r"(ppn_value)
126                        :"r"(pte2)
127                        :"$26" );
128
129        // check PTE2 mapping
130        if ( (flags_value & PTE_V) == 0 )
131        {
132            return 1;
133        }
134
135        // set return values
136        *ppn      = ppn_value;
137        *flags    = flags_value;
138    }
139    return 0;
140}       // end _v2p_translate()
141
142// Local Variables:
143// tab-width: 4
144// c-basic-offset: 4
145// c-file-offsets:((innamespace . 0)(inline-open . 0))
146// indent-tabs-mode: nil
147// End:
148
149// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
150
Note: See TracBrowser for help on using the repository browser.