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

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

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

File size: 5.3 KB
RevLine 
[167]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>
[238]16#include <drivers.h>
[167]17
18/////////////////////////////////////////////////////////////////////////////
[228]19//     Global variable : IOMMU page table
[167]20/////////////////////////////////////////////////////////////////////////////
21
[228]22__attribute__((section (".iommu"))) page_table_t _iommu_ptab;
[167]23
24//////////////////////////////////////////////////////////////////////////////
25// _iommu_add_pte2()
26//////////////////////////////////////////////////////////////////////////////
[228]27void _iommu_add_pte2(
28        unsigned int ix1,
29        unsigned int ix2,
30        unsigned int ppn,
[249]31        unsigned int flags) 
32{
[228]33    unsigned int ptba;
34    unsigned int * pt_ppn;
35    unsigned int * pt_flags;
[167]36
37    // get pointer on iommu page table
[228]38    page_table_t * pt = &_iommu_ptab;
[167]39
40    // get ptba and update PT2
[249]41    if ((pt->pt1[ix1] & PTE_V) == 0) 
[246]42    {
[249]43        _get_lock(&_tty_put_lock);
[167]44        _puts("\n[GIET ERROR] in iommu_add_pte2 function\n");
45        _puts("the IOMMU PT1 entry is not mapped / ix1 = ");
[207]46        _putx( ix1 );
[167]47        _puts("\n");
[249]48        _release_lock(&_tty_put_lock);
[167]49        _exit();
50    }
[249]51    else 
52    {
[228]53        ptba = pt->pt1[ix1] << 12;
54        pt_flags = (unsigned int *) (ptba + 8 * ix2);
55        pt_ppn = (unsigned int *) (ptba + 8 * ix2 + 4);
[167]56        *pt_flags = flags;
[228]57        *pt_ppn = ppn;
[167]58    }
59} // end _iommu_add_pte2()
60
[228]61
[167]62//////////////////////////////////////////////////////////////////////////////
63// _iommu_inval_pte2()
64//////////////////////////////////////////////////////////////////////////////
[228]65void _iommu_inval_pte2(unsigned int ix1, unsigned int ix2) {
66    unsigned int ptba;
67    unsigned int * pt_flags;
[167]68
69    // get pointer on iommu page table
[228]70    page_table_t * pt = &_iommu_ptab;
[167]71
72    // get ptba and inval PTE2
[246]73    if ((pt->pt1[ix1] & PTE_V) == 0)
74    {
[167]75        _puts("\n[GIET ERROR] in iommu_inval_pte2 function\n");
76        _puts("the IOMMU PT1 entry is not mapped / ix1 = ");
[207]77        _putx( ix1 );
[167]78        _puts("\n");
79        _exit();
80    }
[228]81    else {
82        ptba = pt->pt1[ix1] << 12;
83        pt_flags = (unsigned int *) (ptba + 8 * ix2);
[167]84        *pt_flags = 0;
85    }   
86} // end _iommu_inval_pte2()
87
[228]88
[167]89//////////////////////////////////////////////////////////////////////////////
90// _v2p_translate()
91// Returns 0 if success, 1 if PTE1 or PTE2 unmapped
92//////////////////////////////////////////////////////////////////////////////
[246]93unsigned int _v2p_translate(page_table_t * pt,
94                            unsigned int   vpn,
95                            unsigned int * ppn,
96                            unsigned int * flags) 
[238]97{
[246]98    paddr_t ptba;
99    paddr_t pte2;
[167]100
[246]101    register unsigned int pte2_msb;
102    register unsigned int pte2_lsb;
103    register unsigned int flags_value;
104    register unsigned int ppn_value;
[238]105
[228]106    unsigned int ix1 = vpn >> 9;
107    unsigned int ix2 = vpn & 0x1FF;
[238]108
[167]109    // check PTE1 mapping
[246]110    if ((pt->pt1[ix1] & PTE_V) == 0)
111    {
112        return 1;
113    }
[238]114    else 
115    {
[167]116        // get physical addresses of pte2
[246]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);
[167]121
122        // gets ppn_value and flags_value, after temporary DTLB desactivation
[228]123        asm volatile (
[238]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   */
[184]128
[238]129                "li      $3,     0xB         \n"     
130                "mtc2    $3,     $1          \n"     /* DTLB unactivated     */ 
[189]131
[238]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       */
[184]136
[238]137                "li      $3,     0xF         \n" 
138                "mtc2    $3,     $1          \n"     /* DTLB activated       */
[189]139
[238]140                "mtc0    $4,     $12         \n"     /* restore SR           */
[228]141                : "=r" (flags_value), "=r" (ppn_value)
[238]142                : "r" (pte2_msb), "r" (pte2_lsb)
143                : "$2","$3","$4");
[167]144
145        // check PTE2 mapping
[246]146        if ((flags_value & PTE_V) == 0) {
147            return 1;
148        }
[167]149
150        // set return values
[228]151        *ppn = ppn_value;
152        *flags = flags_value;
[167]153    }
154    return 0;
[228]155} // end _v2p_translate()
[167]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:
[228]163// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
[167]164
165
Note: See TracBrowser for help on using the repository browser.