source: soft/giet_vm/giet_common/vmem.c @ 400

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

Using the giet_lock_t structure in _get_lock() / _release_lock() functions,
to have only one lock per cache line.

  • Property svn:executable set to *
File size: 5.3 KB
Line 
1///////////////////////////////////////////////////////////////////////////////////
2// File     : vmem.c
3// Date     : 01/07/2012
4// Author   : alain greiner
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7// The vmem.c and vmem.h files are part ot the GIET-VM nano kernel.
8// They contain the kernel data structures and functions used to dynamically
9// handle the paged virtual memory.
10///////////////////////////////////////////////////////////////////////////////////
11
12#include <utils.h>
13#include <tty_driver.h>
14#include <vmem.h>
15#include <giet_config.h>
16#include <tty_driver.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( unsigned int ix1,
28                      unsigned int ix2,
29                      unsigned int ppn,
30                      unsigned int flags ) 
31{
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    {
42        _printf("\n[GIET ERROR] in iommu_add_pte2() : "
43                "IOMMU PT1 entry not mapped / ix1 = %d\n", ix1 );
44        _exit();
45    }
46    else 
47    {
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, 
61                        unsigned int ix2 ) 
62{
63    unsigned int ptba;
64    unsigned int * pt_flags;
65
66    // get pointer on iommu page table
67    page_table_t * pt = &_iommu_ptab;
68
69    // get ptba and inval PTE2
70    if ((pt->pt1[ix1] & PTE_V) == 0)
71    {
72        _printf("\n[GIET ERROR] in iommu_inval_pte2() "
73              "IOMMU PT1 entry not mapped / ix1 = %d\n", ix1 );
74        _exit();
75    }
76    else {
77        ptba = pt->pt1[ix1] << 12;
78        pt_flags = (unsigned int *) (ptba + 8 * ix2);
79        *pt_flags = 0;
80    }   
81} // end _iommu_inval_pte2()
82
83//////////////////////////////////////////////////////////////////////////////
84// This function makes a "vpn" to "ppn" translation, from the page table
85// defined by the virtual address "pt". The MMU is supposed to be activated.
86// It uses the address extension mechanism for physical addressing.
87// Return 0 if success. Return 1 if PTE1 or PTE2 unmapped.
88//////////////////////////////////////////////////////////////////////////////
89unsigned int _v2p_translate( page_table_t*  pt,
90                             unsigned int   vpn,
91                             unsigned int*  ppn,
92                             unsigned int*  flags ) 
93{
94    unsigned long long ptba;
95    unsigned long long pte2_paddr;
96
97    unsigned int pte2_msb;
98    unsigned int pte2_lsb;
99    unsigned int flags_value;
100    unsigned int ppn_value;
101
102    unsigned int ix1 = vpn >> 9;
103    unsigned int ix2 = vpn & 0x1FF;
104
105    unsigned int save_sr;
106
107    // get PTE1
108    unsigned int pte1 = pt->pt1[ix1];
109
110    // check PTE1 mapping
111    if ( (pte1 & PTE_V) == 0 )  return 1;
112
113    // get physical addresses of pte2 (two 32 bits words)
114    ptba       = (unsigned long long) (pte1 & 0x0FFFFFFF) << 12;
115    pte2_paddr = ptba + 8*ix2;
116    pte2_lsb   = (unsigned int) pte2_paddr;
117    pte2_msb   = (unsigned int) (pte2_paddr >> 32);
118
119    // disable interrupts and save status register
120    _it_disable( &save_sr );
121
122    // gets ppn_value and flags_value, after temporary DTLB desactivation
123    asm volatile (
124                "mfc2    $2,     $1          \n"     /* $2 <= MMU_MODE       */
125                "andi    $3,     $2,    0xb  \n"
126                "mtc2    $3,     $1          \n"     /* DTLB off             */
127
128                "move    $4,     %3          \n"     /* $4 <= pte_lsb        */
129                "mtc2    %2,     $24         \n"     /* PADDR_EXT <= msb     */
130                "lw      %0,     0($4)       \n"     /* read flags           */ 
131                "lw      %1,     4($4)       \n"     /* read ppn             */
132                "mtc2    $0,     $24         \n"     /* PADDR_EXT <= 0       */
133
134                "mtc2    $2,     $1          \n"     /* restore MMU_MODE     */
135                : "=r" (flags_value), "=r" (ppn_value)
136                : "r"  (pte2_msb)   , "r"  (pte2_lsb)
137                : "$2", "$3", "$4" );
138
139    // restore saved status register
140    _it_restore( &save_sr );
141
142    // check PTE2 mapping
143    if ( (flags_value & PTE_V) == 0 )  return 1;
144
145    // set return values
146    *ppn   = ppn_value;
147    *flags = flags_value;
148
149    return 0;
150} // end _v2p_translate()
151
152
153
154// Local Variables:
155// tab-width: 4
156// c-basic-offset: 4
157// c-file-offsets:((innamespace . 0)(inline-open . 0))
158// indent-tabs-mode: nil
159// End:
160// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
161
162
Note: See TracBrowser for help on using the repository browser.