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

Last change on this file since 248 was 246, checked in by meunier, 11 years ago

Cosmétique + gestion du reset de l'irq du timer ou de l'xicu lors d'un task_switch

File size: 5.2 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    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        _puts("\n[GIET ERROR] in iommu_add_pte2 function\n");
43        _puts("the IOMMU PT1 entry is not mapped / ix1 = ");
44        _putx( ix1 );
45        _puts("\n");
46        _exit();
47    }
48    else {
49        ptba = pt->pt1[ix1] << 12;
50        pt_flags = (unsigned int *) (ptba + 8 * ix2);
51        pt_ppn = (unsigned int *) (ptba + 8 * ix2 + 4);
52        *pt_flags = flags;
53        *pt_ppn = ppn;
54    }
55} // end _iommu_add_pte2()
56
57
58//////////////////////////////////////////////////////////////////////////////
59// _iommu_inval_pte2()
60//////////////////////////////////////////////////////////////////////////////
61void _iommu_inval_pte2(unsigned int ix1, unsigned int ix2) {
62    unsigned int ptba;
63    unsigned int * pt_flags;
64
65    // get pointer on iommu page table
66    page_table_t * pt = &_iommu_ptab;
67
68    // get ptba and inval PTE2
69    if ((pt->pt1[ix1] & PTE_V) == 0)
70    {
71        _puts("\n[GIET ERROR] in iommu_inval_pte2 function\n");
72        _puts("the IOMMU PT1 entry is not mapped / ix1 = ");
73        _putx( ix1 );
74        _puts("\n");
75        _exit();
76    }
77    else {
78        ptba = pt->pt1[ix1] << 12;
79        pt_flags = (unsigned int *) (ptba + 8 * ix2);
80        *pt_flags = 0;
81    }   
82} // end _iommu_inval_pte2()
83
84
85//////////////////////////////////////////////////////////////////////////////
86// _v2p_translate()
87// Returns 0 if success, 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    paddr_t ptba;
95    paddr_t pte2;
96
97    register unsigned int pte2_msb;
98    register unsigned int pte2_lsb;
99    register unsigned int flags_value;
100    register unsigned int ppn_value;
101
102    unsigned int ix1 = vpn >> 9;
103    unsigned int ix2 = vpn & 0x1FF;
104
105    // check PTE1 mapping
106    if ((pt->pt1[ix1] & PTE_V) == 0)
107    {
108        return 1;
109    }
110    else 
111    {
112        // get physical addresses of pte2
113        ptba     = (paddr_t) (pt->pt1[ix1] & 0x0FFFFFFF) << 12;
114        pte2     = ptba + 8 * ix2;
115        pte2_lsb = (unsigned int) pte2;
116        pte2_msb = (unsigned int) (pte2 >> 32);
117
118        // gets ppn_value and flags_value, after temporary DTLB desactivation
119        asm volatile (
120                "li      $2,     0xFFFFFFFE  \n"     /* Mask for IE bits     */
121                "mfc0    $4,     $12         \n"     /* $4 <= SR             */ 
122                "and     $2,     $2,    $4   \n"
123                "mtc0    $2,     $12         \n"     /* disable Interrupts   */
124
125                "li      $3,     0xB         \n"     
126                "mtc2    $3,     $1          \n"     /* DTLB unactivated     */ 
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                "li      $3,     0xF         \n" 
134                "mtc2    $3,     $1          \n"     /* DTLB activated       */
135
136                "mtc0    $4,     $12         \n"     /* restore SR           */
137                : "=r" (flags_value), "=r" (ppn_value)
138                : "r" (pte2_msb), "r" (pte2_lsb)
139                : "$2","$3","$4");
140
141        // check PTE2 mapping
142        if ((flags_value & PTE_V) == 0) {
143            return 1;
144        }
145
146        // set return values
147        *ppn = ppn_value;
148        *flags = flags_value;
149    }
150    return 0;
151} // end _v2p_translate()
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.