- Timestamp:
- Sep 29, 2014, 10:47:26 AM (10 years ago)
- Location:
- soft/giet_vm/giet_common
- Files:
-
- 4 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_common/io.h
r345 r408 7 7 // Utility functions to write or read memory mapped hardware registers 8 8 /////////////////////////////////////////////////////////////////////////////////// 9 9 10 #ifndef IO_H 10 11 #define IO_H -
soft/giet_vm/giet_common/utils.c
r399 r408 22 22 extern static_scheduler_t* _schedulers[NB_PROCS_MAX<<(X_WIDTH+Y_WIDTH)]; 23 23 24 25 24 /////////////////////////////////////////////////////////////////////////////////// 26 25 // CP0 registers access functions 27 26 /////////////////////////////////////////////////////////////////////////////////// 28 27 29 /////////////////////////////////////////////////////////////////////////////////// 30 // Returns the value contained in CP0 SCHED register 31 // (virtual base address of the processor scheduler). 32 /////////////////////////////////////////////////////////////////////////////////// 28 ///////////////////////// 33 29 unsigned int _get_sched() 34 30 { … … 38 34 return ret; 39 35 } 40 /////////////////////////////////////////////////////////////////////////////////// 41 // Returns EPC register content. 42 /////////////////////////////////////////////////////////////////////////////////// 36 /////////////////////// 43 37 unsigned int _get_epc() 44 38 { … … 48 42 return ret; 49 43 } 50 /////////////////////////////////////////////////////////////////////////////////// 51 // Returns BVAR register content. 52 /////////////////////////////////////////////////////////////////////////////////// 44 //////////////////////// 53 45 unsigned int _get_bvar() 54 46 { … … 58 50 return ret; 59 51 } 60 /////////////////////////////////////////////////////////////////////////////////// 61 // Returns CR register content. 62 /////////////////////////////////////////////////////////////////////////////////// 52 ////////////////////// 63 53 unsigned int _get_cr() 64 54 { … … 68 58 return ret; 69 59 } 70 /////////////////////////////////////////////////////////////////////////////////// 71 // Returns SR register content 72 /////////////////////////////////////////////////////////////////////////////////// 60 ////////////////////// 73 61 unsigned int _get_sr() 74 62 { … … 78 66 return ret; 79 67 } 80 ////////////////////////////////////////////////////////////////////////////// 81 // This function set a new value for the CP0 status register. 82 ////////////////////////////////////////////////////////////////////////////// 83 void _set_sr(unsigned int val) 84 { 85 asm volatile( "mtc0 %0, $12 \n" 86 : 87 :"r" (val) ); 88 } 89 ////////////////////////////////////////////////////////////////////////////// 90 // Returns processor index 91 ////////////////////////////////////////////////////////////////////////////// 68 ////////////////////////// 92 69 unsigned int _get_procid() 93 70 { … … 97 74 return (ret & 0x3FF); 98 75 } 99 ////////////////////////////////////////////////////////////////////////////// 100 // Returns local time (32 bits value) 101 // boot_proctime() 102 ////////////////////////////////////////////////////////////////////////////// 76 //////////////////////////// 103 77 unsigned int _get_proctime() 104 78 { … … 108 82 return ret; 109 83 } 110 ////////////////////////////////////////////////////////////////////////////// 111 // Save SR value into save_sr_ptr variable and disable IRQs. 112 ////////////////////////////////////////////////////////////////////////////// 84 85 ///////////////////////////////////////////// 113 86 void _it_disable( unsigned int * save_sr_ptr) 114 87 { … … 123 96 *save_sr_ptr = sr; 124 97 } 125 126 ////////////////////////////////////////////////////////////////////////////// 127 // Restores previous SR value. 128 ////////////////////////////////////////////////////////////////////////////// 98 ////////////////////////////////////////////// 129 99 void _it_restore( unsigned int * save_sr_ptr ) 130 100 { … … 136 106 } 137 107 138 ////////////////////////////////////////////////////////////////////////////// 139 // This function set a new value in CP0 SCHED register. 140 // (virtual base address of the processor scheduler). 141 ////////////////////////////////////////////////////////////////////////////// 108 ///////////////////////////////// 142 109 void _set_sched(unsigned int val) 143 110 { … … 146 113 :"r" (val) ); 147 114 } 115 ////////////////////////////// 116 void _set_sr(unsigned int val) 117 { 118 asm volatile ( "mtc0 %0, $12 \n" 119 : 120 :"r" (val) ); 121 } 122 148 123 149 124 /////////////////////////////////////////////////////////////////////////////////// … … 151 126 /////////////////////////////////////////////////////////////////////////////////// 152 127 153 /////////////////////////////////////////////////////////////////////////////////// 154 // Returns PTPR register content. 155 /////////////////////////////////////////////////////////////////////////////////// 128 //////////////////////////// 156 129 unsigned int _get_mmu_ptpr() 157 130 { … … 161 134 return ret; 162 135 } 163 /////////////////////////////////////////////////////////////////////////////////// 164 // Returns MODE register content. 165 /////////////////////////////////////////////////////////////////////////////////// 136 //////////////////////////// 166 137 unsigned int _get_mmu_mode() 167 138 { … … 171 142 return ret; 172 143 } 173 ////////////////////////////////////////////////////////////////////////////// 174 // This function set a new value for the MMU PTPR register. 175 ////////////////////////////////////////////////////////////////////////////// 144 //////////////////////////////////// 176 145 void _set_mmu_ptpr(unsigned int val) 177 146 { 178 asm volatile ( "mtc2 %0, $0 147 asm volatile ( "mtc2 %0, $0 \n" 179 148 : 180 149 :"r" (val) 181 150 :"memory" ); 182 151 } 183 ////////////////////////////////////////////////////////////////////////////// 184 // This function set a new value for the MMU MODE register. 185 ////////////////////////////////////////////////////////////////////////////// 152 //////////////////////////////////// 186 153 void _set_mmu_mode(unsigned int val) 187 154 { 188 asm volatile ( "mtc2 %0, $1 155 asm volatile ( "mtc2 %0, $1 \n" 189 156 : 190 157 :"r" (val) 191 158 :"memory" ); 192 159 } 160 //////////////////////////////////////////// 161 void _set_mmu_dcache_inval(unsigned int val) 162 { 163 asm volatile ( "mtc2 %0, $7 \n" 164 : 165 :"r" (val) 166 :"memory" ); 167 } 168 193 169 194 170 //////////////////////////////////////////////////////////////////////////// … … 1033 1009 /////////////////////////////////////////////////////////////////////////////////// 1034 1010 // Invalidate all data cache lines corresponding to a memory 1035 // buffer (identified by an address and a size). 1036 // TODO This should be replaced by a write to the CP2 MMU_DCACHE_INVAL 1037 // register, to be more processor independant. 1038 /////////////////////////////////////////////////////////////////////////////////// 1039 void _dcache_buf_invalidate( void * buffer, 1040 unsigned int size) 1041 { 1042 unsigned int i; 1011 // buffer (identified by virtual base address and size). 1012 /////////////////////////////////////////////////////////////////////////////////// 1013 void _dcache_buf_invalidate( unsigned int buf_vbase, 1014 unsigned int buf_size ) 1015 { 1016 unsigned int offset; 1043 1017 unsigned int tmp; 1044 unsigned int line_size; 1018 unsigned int line_size; // bytes 1045 1019 1046 1020 // compute data cache line size based on config register (bits 12:10) … … 1048 1022 "mfc0 %0, $16, 1" 1049 1023 : "=r" (tmp) ); 1024 1050 1025 tmp = ((tmp >> 10) & 0x7); 1051 1026 line_size = 2 << tmp; 1052 1027 1053 1028 // iterate on cache lines 1054 for (i = 0; i < size; i += line_size) 1055 { 1056 asm volatile( 1057 " cache %0, %1" 1058 : :"i" (0x11), "R" (*((unsigned char *) buffer + i)) ); 1029 for ( offset = 0; offset < buf_size; offset += line_size) 1030 { 1031 _set_mmu_dcache_inval( buf_vbase + offset ); 1059 1032 } 1060 1033 } … … 1110 1083 if ( vobj_id != 0xFFFFFFFF ) 1111 1084 { 1112 *vaddr = vobjs[vobj_id].v addr;1085 *vaddr = vobjs[vobj_id].vbase; 1113 1086 *length = vobjs[vobj_id].length; 1114 1087 return 0; -
soft/giet_vm/giet_common/utils.h
r399 r408 45 45 46 46 /////////////////////////////////////////////////////////////////////////////////// 47 /////////////////////////////////////////////////////////////////////////////////// 47 48 // CP0 registers access functions 48 49 /////////////////////////////////////////////////////////////////////////////////// 49 50 /////////////////////////////////////////////////////////////////////////////////// 51 52 /////////////////////////////////////////////////////////////////////////////////// 53 // Returns CP0_SCHED register content 54 // (virtual base address of the processor scheduler) 55 /////////////////////////////////////////////////////////////////////////////////// 50 56 extern unsigned int _get_sched(void); 57 58 /////////////////////////////////////////////////////////////////////////////////// 59 // Returns CP0_EPC register content. 60 /////////////////////////////////////////////////////////////////////////////////// 51 61 extern unsigned int _get_epc(void); 62 63 /////////////////////////////////////////////////////////////////////////////////// 64 // Returns CP0_BVAR register content. 65 /////////////////////////////////////////////////////////////////////////////////// 52 66 extern unsigned int _get_bvar(void); 67 68 /////////////////////////////////////////////////////////////////////////////////// 69 // Returns CP0_CR register content. 70 /////////////////////////////////////////////////////////////////////////////////// 53 71 extern unsigned int _get_cr(void); 72 73 /////////////////////////////////////////////////////////////////////////////////// 74 // Returns CP0_SR register content. 75 /////////////////////////////////////////////////////////////////////////////////// 54 76 extern unsigned int _get_sr(void); 77 78 /////////////////////////////////////////////////////////////////////////////////// 79 // Returns CP0_PROCID register content. 80 // Processor identifier (12 bits) 81 /////////////////////////////////////////////////////////////////////////////////// 55 82 extern unsigned int _get_procid(void); 83 84 /////////////////////////////////////////////////////////////////////////////////// 85 // Returns CP0_TIME register content. 86 // Processor local time (32 bits) 87 /////////////////////////////////////////////////////////////////////////////////// 56 88 extern unsigned int _get_proctime(void); 57 89 90 /////////////////////////////////////////////////////////////////////////////////// 91 // Save CP0_SR value to variable pointed by save_sr_ptr and disable IRQs. 92 /////////////////////////////////////////////////////////////////////////////////// 58 93 extern void _it_disable( unsigned int* save_sr_ptr ); 94 95 /////////////////////////////////////////////////////////////////////////////////// 96 // Restore CP0_SR register from variable pointed by save_sr_ptr. 97 /////////////////////////////////////////////////////////////////////////////////// 59 98 extern void _it_restore( unsigned int* save_sr_ptr ); 60 99 100 /////////////////////////////////////////////////////////////////////////////////// 101 // Set a new value in CP0_SCHED register. 102 // (virtual base address of the processor scheduler) 103 /////////////////////////////////////////////////////////////////////////////////// 61 104 extern void _set_sched(unsigned int value); 105 106 /////////////////////////////////////////////////////////////////////////////////// 107 // Set a new value in CP0_SR register. 108 /////////////////////////////////////////////////////////////////////////////////// 62 109 extern void _set_sr(unsigned int value); 63 110 111 112 /////////////////////////////////////////////////////////////////////////////////// 64 113 /////////////////////////////////////////////////////////////////////////////////// 65 114 // CP2 registers access functions 66 115 /////////////////////////////////////////////////////////////////////////////////// 67 116 /////////////////////////////////////////////////////////////////////////////////// 117 118 /////////////////////////////////////////////////////////////////////////////////// 119 // Returns CP2_PTPR register value. 120 // Page table physical base address for the running context. 121 // Contains only the 27 MSB bits, right justified. 122 /////////////////////////////////////////////////////////////////////////////////// 68 123 extern unsigned int _get_mmu_ptpr(void); 124 125 /////////////////////////////////////////////////////////////////////////////////// 126 // Returns CP2_MODE register value. 127 // MMU current mode, defined by 4 bits, right justified: ITLB/DTLB/ICACHE/DCACHE 128 /////////////////////////////////////////////////////////////////////////////////// 69 129 extern unsigned int _get_mmu_mode(void); 70 130 131 /////////////////////////////////////////////////////////////////////////////////// 132 // Set a new value in CP2_PTPR register. 133 /////////////////////////////////////////////////////////////////////////////////// 71 134 extern void _set_mmu_ptpr(unsigned int value); 135 136 /////////////////////////////////////////////////////////////////////////////////// 137 // Set a new value in CP2_MODE register. 138 /////////////////////////////////////////////////////////////////////////////////// 72 139 extern void _set_mmu_mode(unsigned int value); 73 140 74 141 /////////////////////////////////////////////////////////////////////////////////// 142 // Set a value in CP2_DCACHE_INVAL register. 143 // It invalidates the data cache line, if the virtual address defined by the 144 // value argument hit in DCACHE. 145 /////////////////////////////////////////////////////////////////////////////////// 146 extern void _set_mmu_dcache_inval(unsigned int value); 147 148 149 150 /////////////////////////////////////////////////////////////////////////////////// 151 /////////////////////////////////////////////////////////////////////////////////// 75 152 // Physical addressing related functions 153 /////////////////////////////////////////////////////////////////////////////////// 76 154 /////////////////////////////////////////////////////////////////////////////////// 77 155 … … 163 241 char* source ); 164 242 165 extern void _dcache_buf_invalidate( void * buffer,166 unsigned int size );243 extern void _dcache_buf_invalidate( unsigned int buf_vbase, 244 unsigned int buf_size ); 167 245 168 246 extern unsigned int _heap_info( unsigned int* vaddr, -
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() -
soft/giet_vm/giet_common/vmem.h
r258 r408 1 1 /////////////////////////////////////////////////////////////////////////////////// 2 // File : vm _handler.h2 // File : vmem.h 3 3 // Date : 01/07/2012 4 4 // Author : alain greiner 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 define the data structures implementing the page tables, 9 // and the function used for VPN to PPN translation. 10 /////////////////////////////////////////////////////////////////////////////////// 11 // The virtual address format is 32 bits: structures in 3 fields: 12 // | 11 | 9 | 12 | 13 // | IX1 | IX2 | OFFSET | 14 // - The IX1 field is the index in the first level page table 15 // - The IX2 field is the index in the second level page table 16 // - The |IX1|IX2\ concatenation defines the VPN (Virtual Page Number) 17 /////////////////////////////////////////////////////////////////////////////////// 7 18 8 #ifndef _VM_HANDLER_H_ 9 #define _VM_HANDLER_H_ 10 11 #include <giet_config.h> 12 #include <mapping_info.h> 19 #ifndef _VMEM_H_ 20 #define _VMEM_H_ 13 21 14 22 ///////////////////////////////////////////////////////////////////////////////////// … … 18 26 #define PT1_SIZE 8192 19 27 #define PT2_SIZE 4096 28 29 #define VPN_MASK 0xFFFFF000 30 #define BPN_MASK 0xFFE00000 20 31 21 32 ///////////////////////////////////////////////////////////////////////////////////// … … 51 62 // Page table structure definition 52 63 ///////////////////////////////////////////////////////////////////////////////////// 64 53 65 typedef struct PageTable 54 66 { … … 57 69 } page_table_t; 58 70 59 60 ////////////////////////////////////////////////////////////////////////////////////61 // Global variable62 ////////////////////////////////////////////////////////////////////////////////////63 64 extern page_table_t _iommu_ptab;65 66 71 //////////////////////////////////////////////////////////////////////////////////// 67 72 // functions prototypes 68 73 //////////////////////////////////////////////////////////////////////////////////// 69 74 70 void _iommu_add_pte2( unsigned int ix1, 71 unsigned int ix2, 72 unsigned int ppn, 73 unsigned int flags ); 74 75 void _iommu_inval_pte2( unsigned int ix1, 76 unsigned int ix2 ); 77 75 /////////////////////////////////////////////////////////////////////////////////// 76 // This function makes a "vpn" to "ppn" translation, from the page table 77 // defined by the virtual address "pt". The MMU is supposed to be activated. 78 // It supports both small (4 Kbytes) & big (2 Mbytes) pages. 79 // It uses the address extension mechanism for physical addressing. 80 // Return 0 if success. Return 1 if PTE1 or PTE2 unmapped. 81 /////////////////////////////////////////////////////////////////////////////////// 78 82 unsigned int _v2p_translate( page_table_t* pt, 79 83 unsigned int vpn,
Note: See TracChangeset
for help on using the changeset viewer.