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

Last change on this file since 257 was 249, checked in by alain, 11 years ago

Various modifications to support IO Bridge,
and MEMC configuration interface.

File size: 5.3 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
12#include <vm_handler.h>
13#include <sys_handler.h>
14#include <common.h>
15#include <giet_config.h>
16#include <drivers.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(
28        unsigned int ix1,
29        unsigned int ix2,
30        unsigned int ppn,
31        unsigned int flags) 
32{
33    unsigned int ptba;
34    unsigned int * pt_ppn;
35    unsigned int * pt_flags;
36
37    // get pointer on iommu page table
38    page_table_t * pt = &_iommu_ptab;
39
40    // get ptba and update PT2
41    if ((pt->pt1[ix1] & PTE_V) == 0) 
42    {
43        _get_lock(&_tty_put_lock);
44        _puts("\n[GIET ERROR] in iommu_add_pte2 function\n");
45        _puts("the IOMMU PT1 entry is not mapped / ix1 = ");
46        _putx( ix1 );
47        _puts("\n");
48        _release_lock(&_tty_put_lock);
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//////////////////////////////////////////////////////////////////////////////
63// _iommu_inval_pte2()
64//////////////////////////////////////////////////////////////////////////////
65void _iommu_inval_pte2(unsigned int ix1, unsigned int ix2) {
66    unsigned int ptba;
67    unsigned int * pt_flags;
68
69    // get pointer on iommu page table
70    page_table_t * pt = &_iommu_ptab;
71
72    // get ptba and inval PTE2
73    if ((pt->pt1[ix1] & PTE_V) == 0)
74    {
75        _puts("\n[GIET ERROR] in iommu_inval_pte2 function\n");
76        _puts("the IOMMU PT1 entry is not mapped / ix1 = ");
77        _putx( ix1 );
78        _puts("\n");
79        _exit();
80    }
81    else {
82        ptba = pt->pt1[ix1] << 12;
83        pt_flags = (unsigned int *) (ptba + 8 * ix2);
84        *pt_flags = 0;
85    }   
86} // end _iommu_inval_pte2()
87
88
89//////////////////////////////////////////////////////////////////////////////
90// _v2p_translate()
91// Returns 0 if success, 1 if PTE1 or PTE2 unmapped
92//////////////////////////////////////////////////////////////////////////////
93unsigned int _v2p_translate(page_table_t * pt,
94                            unsigned int   vpn,
95                            unsigned int * ppn,
96                            unsigned int * flags) 
97{
98    paddr_t ptba;
99    paddr_t pte2;
100
101    register unsigned int pte2_msb;
102    register unsigned int pte2_lsb;
103    register unsigned int flags_value;
104    register unsigned int ppn_value;
105
106    unsigned int ix1 = vpn >> 9;
107    unsigned int ix2 = vpn & 0x1FF;
108
109    // check PTE1 mapping
110    if ((pt->pt1[ix1] & PTE_V) == 0)
111    {
112        return 1;
113    }
114    else 
115    {
116        // get physical addresses of pte2
117        ptba     = (paddr_t) (pt->pt1[ix1] & 0x0FFFFFFF) << 12;
118        pte2     = ptba + 8 * ix2;
119        pte2_lsb = (unsigned int) pte2;
120        pte2_msb = (unsigned int) (pte2 >> 32);
121
122        // gets ppn_value and flags_value, after temporary DTLB desactivation
123        asm volatile (
124                "li      $2,     0xFFFFFFFE  \n"     /* Mask for IE bits     */
125                "mfc0    $4,     $12         \n"     /* $4 <= SR             */ 
126                "and     $2,     $2,    $4   \n"
127                "mtc0    $2,     $12         \n"     /* disable Interrupts   */
128
129                "li      $3,     0xB         \n"     
130                "mtc2    $3,     $1          \n"     /* DTLB unactivated     */ 
131
132                "mtc2    %2,     $24         \n"     /* PADDR_EXT <= msb     */
133                "lw      %0,     0(%3)       \n"     /* read flags           */ 
134                "lw      %1,     4(%3)       \n"     /* read ppn             */
135                "mtc2    $0,     $24         \n"     /* PADDR_EXT <= 0       */
136
137                "li      $3,     0xF         \n" 
138                "mtc2    $3,     $1          \n"     /* DTLB activated       */
139
140                "mtc0    $4,     $12         \n"     /* restore SR           */
141                : "=r" (flags_value), "=r" (ppn_value)
142                : "r" (pte2_msb), "r" (pte2_lsb)
143                : "$2","$3","$4");
144
145        // check PTE2 mapping
146        if ((flags_value & PTE_V) == 0) {
147            return 1;
148        }
149
150        // set return values
151        *ppn = ppn_value;
152        *flags = flags_value;
153    }
154    return 0;
155} // end _v2p_translate()
156
157// Local Variables:
158// tab-width: 4
159// c-basic-offset: 4
160// c-file-offsets:((innamespace . 0)(inline-open . 0))
161// indent-tabs-mode: nil
162// End:
163// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
164
165
Note: See TracBrowser for help on using the repository browser.