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

Last change on this file since 347 was 345, checked in by cfuguet, 10 years ago

giet_vm optimizations:

  • Several modifications in GIET_VM in order to support compilation with GCC optimizations (-O2) activated.
  • Adding missing volatile in some global variables.
  • Using ioread and iowrite utility functions in peripheral drivers which prevent GCC to remove writes or reads in hardware memory mapped registers.
  • Code refactoring of stdio printf functions. Now, shr_printf and tty_printf function reuse the same function body. The only difference is that shr_printf wraps printf function call with TTY get lock and release lock.
  • Property svn:executable set to *
File size: 5.2 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    volatile unsigned int pte2_msb;
98    volatile 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                "mtc2    %2,     $24         \n"     /* PADDR_EXT <= msb     */
129                "lw      %0,     0(%3)       \n"     /* read flags           */ 
130                "lw      %1,     4(%3)       \n"     /* read ppn             */
131                "mtc2    $0,     $24         \n"     /* PADDR_EXT <= 0       */
132
133                "mtc2    $2,     $1          \n"     /* restore MMU_MODE     */
134                : "=r" (flags_value), "=r" (ppn_value)
135                : "r"  (pte2_msb)   , "r"  (pte2_lsb)
136                : "$2", "$3");
137
138    // restore saved status register
139    _it_restore( &save_sr );
140
141    // check PTE2 mapping
142    if ( (flags_value & PTE_V) == 0 )  return 1;
143
144    // set return values
145    *ppn   = ppn_value;
146    *flags = flags_value;
147
148    return 0;
149} // end _v2p_translate()
150
151
152
153// Local Variables:
154// tab-width: 4
155// c-basic-offset: 4
156// c-file-offsets:((innamespace . 0)(inline-open . 0))
157// indent-tabs-mode: nil
158// End:
159// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
160
161
Note: See TracBrowser for help on using the repository browser.