Changeset 408 for soft/giet_vm/giet_common/vmem.c
- Timestamp:
- Sep 29, 2014, 10:47:26 AM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_common/vmem.c
r351 r408 5 5 // Copyright (c) UPMC-LIP6 6 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 dynamically9 // handle the paged virtual memory.10 ///////////////////////////////////////////////////////////////////////////////////11 7 12 8 #include <utils.h> 13 #include <tty_driver.h>14 9 #include <vmem.h> 15 10 #include <giet_config.h> 16 #include <tty_driver.h>17 11 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 ////////////////////////////////////////////////////////////////////////////// 27 void _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 ////////////////////////////////////////////////////////////////////////////// 60 void _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 ////////////////////////////////////////////////////////////////////////////// 89 unsigned int _v2p_translate( page_table_t* pt, 12 ////////////////////////////////////////////////// 13 unsigned int _v2p_translate( page_table_t* ptab, 90 14 unsigned int vpn, 91 15 unsigned int* ppn, … … 106 30 107 31 // get PTE1 108 unsigned int pte1 = pt ->pt1[ix1];32 unsigned int pte1 = ptab->pt1[ix1]; 109 33 110 34 // check PTE1 mapping 111 if ( (pte1 & PTE_V) == 0 ) return 1; 35 if ( (pte1 & PTE_V) == 0 ) 36 { 37 _printf("\n[VMEM ERROR] _v2p_translate() : pte1 unmapped\n"); 38 _exit(); 39 } 112 40 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); 41 // test big/small page 42 if ( (pte1 & PTE_T) == 0 ) // big page 43 { 44 // set return values 45 *ppn = ((pte1 << 9) & 0x0FFFFE00) | (vpn & 0X000001FF); 46 *flags = pte1 & 0xFFC00000; 47 } 48 else // small page 49 { 118 50 119 // disable interrupts and save status register 120 _it_disable( &save_sr ); 51 // get physical addresses of pte2 (two 32 bits words) 52 ptba = (unsigned long long) (pte1 & 0x0FFFFFFF) << 12; 53 pte2_paddr = ptba + 8*ix2; 54 pte2_lsb = (unsigned int) pte2_paddr; 55 pte2_msb = (unsigned int) (pte2_paddr >> 32); 121 56 122 // gets ppn_value and flags_value, after temporary DTLB desactivation 123 asm volatile ( 57 // disable interrupts and save status register 58 _it_disable( &save_sr ); 59 60 // get ppn_value and flags_value, using a physical read 61 // after temporary DTLB desactivation 62 asm volatile ( 124 63 "mfc2 $2, $1 \n" /* $2 <= MMU_MODE */ 125 64 "andi $3, $2, 0xb \n" … … 127 66 128 67 "move $4, %3 \n" /* $4 <= pte_lsb */ 129 "mtc2 %2, $24 \n" /* PADDR_EXT <= msb*/68 "mtc2 %2, $24 \n" /* PADDR_EXT <= pte_msb */ 130 69 "lw %0, 0($4) \n" /* read flags */ 131 70 "lw %1, 4($4) \n" /* read ppn */ … … 137 76 : "$2", "$3", "$4" ); 138 77 139 // restore saved status register140 _it_restore( &save_sr );78 // restore saved status register 79 _it_restore( &save_sr ); 141 80 142 // check PTE2 mapping 143 if ( (flags_value & PTE_V) == 0 ) return 1; 81 // set return values 82 *ppn = ppn_value & 0x0FFFFFFF; 83 *flags = flags_value & 0xFFC00000; 144 84 145 // set return values 146 *ppn = ppn_value; 147 *flags = flags_value; 148 85 // check PTE2 mapping 86 if ( (flags_value & PTE_V) == 0 ) 87 { 88 _printf("\n[VMEM ERROR] _v2p_translate() : pte2 unmapped\n"); 89 _exit(); 90 } 91 } 149 92 return 0; 150 93 } // end _v2p_translate()
Note: See TracChangeset
for help on using the changeset viewer.