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

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

Several bugs have been fixed to support TSAR multi-cluster architecture
such as the "tsarv4-generic_mmu" platform.

File size: 5.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        _putx( 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        _putx( 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_puts("\n\n********************** entering v2p_translate");
109_puts("\n - pt    = ");
110_putx( (unsigned int)pt );
111_puts("\n - vpn   = ");
112_putx( vpn << 12 );
113_puts("\n - ptba  = ");
114_putx( pt->pt1[ix1] << 12 ) ;
115_puts("\n - &pte2 = ");
116_putx( (pt->pt1[ix1] << 12) + 8*ix2 );
117_puts("\n - flags = ");
118_putx( *(unsigned int*)((pt->pt1[ix1] << 12) + 8*ix2) );
119_puts("\n");
120*/
121    // check PTE1 mapping
122    if ( (pt->pt1[ix1] & PTE_V) == 0 )
123    {
124        return 1;
125    }
126    else
127    {
128        // get physical addresses of pte2
129        ptba = pt->pt1[ix1] << 12;
130        pte2 = (unsigned int*)(ptba + 8*ix2);
131
132        // gets ppn_value and flags_value, after temporary DTLB desactivation
133        asm volatile ( "li      $27,    0xFFFFFFFE  \n"     /* Mask for IE bits     */
134                       "mfc0    $26,    $12         \n"     /* save SR              */ 
135                       "and     $27,    $26,    $27 \n"
136                       "mtc0    $27,    $12         \n"     /* disable Interrupts   */
137
138                       "li      $27,    0xB         \n"     
139                       "mtc2    $27,    $1          \n"     /* DTLB unactivated     */ 
140
141                       "move    $27,    %2          \n"     /* $27 <= pte2          */
142                       "lw      %0,     0($27)      \n"     /* read flags           */ 
143                       "lw      %1,     4($27)      \n"     /* read ppn             */
144
145                       "li      $27,    0xF         \n" 
146                       "mtc2    $27,    $1          \n"     /* DTLB activated       */
147
148                       "mtc0    $26,    $12         \n"     /* restore SR           */
149                        :"=r"(flags_value), "=r"(ppn_value)
150                        :"r"(pte2)
151                        :"$26","$27","$8" );
152
153        // check PTE2 mapping
154        if ( (flags_value & PTE_V) == 0 )
155        {
156            return 1;
157        }
158
159        // set return values
160        *ppn      = ppn_value;
161        *flags    = flags_value;
162    }
163    return 0;
164}       // end _v2p_translate()
165
166// Local Variables:
167// tab-width: 4
168// c-basic-offset: 4
169// c-file-offsets:((innamespace . 0)(inline-open . 0))
170// indent-tabs-mode: nil
171// End:
172
173// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
174
Note: See TracBrowser for help on using the repository browser.