- Timestamp:
- Jan 2, 2016, 4:57:40 PM (9 years ago)
- Location:
- soft/giet_vm/giet_common
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/giet_common/vmem.c
r534 r751 10 10 #include <vmem.h> 11 11 #include <ctx_handler.h> 12 #include <kernel_locks.h> 12 13 #include <giet_config.h> 14 15 ////////////////////////////////////////////////////////////////////////////////// 16 // Extern global variables (allocated in boot.c or kernel_init.c) 17 ////////////////////////////////////////////////////////////////////////////////// 18 19 extern spin_lock_t _ptabs_spin_lock[GIET_NB_VSPACE_MAX][X_SIZE][Y_SIZE]; 20 extern unsigned long long _ptabs_paddr[GIET_NB_VSPACE_MAX][X_SIZE][Y_SIZE]; 21 extern unsigned int _ptabs_next_pt2[GIET_NB_VSPACE_MAX][X_SIZE][Y_SIZE]; 22 extern unsigned int _ptabs_max_pt2; 13 23 14 24 /////////////////////////////////////////////////////// … … 104 114 105 115 116 //////////////////////////////////////////// 117 void _v2p_add_pte1( unsigned int vspace_id, 118 unsigned int x, 119 unsigned int y, 120 unsigned int vpn, // 20 bits right-justified 121 unsigned int flags, // 10 bits left-justified 122 unsigned int ppn, // 28 bits right-justified 123 unsigned int ident ) // identity mapping if non zero 124 { 125 unsigned int pte1; // PTE1 value 126 paddr_t paddr; // PTE1 physical address 127 128 // compute index in PT1 129 unsigned int ix1 = vpn >> 9; // 11 bits for ix1 130 131 // get PT1 physical base address 132 paddr_t pt1_base = _ptabs_paddr[vspace_id][x][y]; 133 134 if ( pt1_base == 0 ) 135 { 136 _printf("\n[GIET ERROR] in _v2p_add_pte1() : no PTAB in cluster[%d,%d]" 137 " containing processors\n", x , y ); 138 _exit(); 139 } 140 141 // get lock protecting PTAB[vspace_id][x][y] 142 _spin_lock_acquire( &_ptabs_spin_lock[vspace_id][x][y] ); 143 144 // compute pte1 physical address 145 paddr = pt1_base + 4*ix1; 146 147 // check PTE1 not already mapped 148 if ( ident == 0 ) 149 { 150 if ( _physical_read( paddr ) & PTE_V ) 151 { 152 _printf("\n[GIET ERROR] in _v2p_add_pte1() : vpn %x already mapped " 153 "in PTAB[%d,%d] for vspace %d\n", vpn , x , y , vspace_id ); 154 _spin_lock_release( &_ptabs_spin_lock[vspace_id][x][y] ); 155 _exit(); 156 } 157 } 158 159 // compute pte1 : 2 bits V T / 8 bits flags / 3 bits RSVD / 19 bits bppi 160 pte1 = PTE_V | (flags & 0x3FC00000) | ((ppn>>9) & 0x0007FFFF); 161 162 // write pte1 in PT1 163 _physical_write( paddr , pte1 ); 164 165 // release lock protecting PTAB[vspace_id][x][y] 166 _spin_lock_release( &_ptabs_spin_lock[vspace_id][x][y] ); 167 168 asm volatile ("sync"); 169 170 } // end _v2p_add_pte1() 171 172 173 174 /////////////////////////////////////////// 175 void _v2p_add_pte2( unsigned int vspace_id, 176 unsigned int x, 177 unsigned int y, 178 unsigned int vpn, // 20 bits right-justified 179 unsigned int flags, // 10 bits left-justified 180 unsigned int ppn, // 28 bits right-justified 181 unsigned int ident ) // identity mapping if non zero 182 { 183 unsigned int ix1; 184 unsigned int ix2; 185 paddr_t pt2_pbase; // PT2 physical base address 186 paddr_t pte2_paddr; // PTE2 physical address 187 unsigned int pt2_id; // PT2 index 188 unsigned int ptd; // PTD : entry in PT1 189 190 ix1 = vpn >> 9; // 11 bits for ix1 191 ix2 = vpn & 0x1FF; // 9 bits for ix2 192 193 // get page table physical base address 194 paddr_t pt1_pbase = _ptabs_paddr[vspace_id][x][y]; 195 196 if ( pt1_pbase == 0 ) 197 { 198 _printf("\n[GIET ERROR] in _v2p_add_pte2() : no PTAB for vspace %d " 199 "in cluster[%d,%d]\n", vspace_id , x , y ); 200 _exit(); 201 } 202 203 // get lock protecting PTAB[vspace_id][x][y] 204 _spin_lock_acquire( &_ptabs_spin_lock[vspace_id][x][y] ); 205 206 // get ptd in PT1 207 ptd = _physical_read( pt1_pbase + 4 * ix1 ); 208 209 if ((ptd & PTE_V) == 0) // undefined PTD: compute PT2 base address, 210 // and set a new PTD in PT1 211 { 212 // get a new pt2_id 213 pt2_id = _ptabs_next_pt2[vspace_id][x][y]; 214 _ptabs_next_pt2[vspace_id][x][y] = pt2_id + 1; 215 216 // check overflow 217 if (pt2_id == _ptabs_max_pt2) 218 { 219 _printf("\n[GIET ERROR] in _v2p_add_pte2() : PTAB[%d,%d,%d]" 220 " contains not enough PT2s\n", vspace_id, x, y ); 221 _spin_lock_release( &_ptabs_spin_lock[vspace_id][x][y] ); 222 _exit(); 223 } 224 225 pt2_pbase = pt1_pbase + PT1_SIZE + PT2_SIZE * pt2_id; 226 ptd = PTE_V | PTE_T | (unsigned int) (pt2_pbase >> 12); 227 228 // set PTD into PT1 229 _physical_write( pt1_pbase + 4*ix1, ptd); 230 } 231 else // valid PTD: compute PT2 base address 232 { 233 pt2_pbase = ((paddr_t)(ptd & 0x0FFFFFFF)) << 12; 234 } 235 236 // set PTE in PT2 : flags & PPN in two 32 bits words 237 pte2_paddr = pt2_pbase + 8 * ix2; 238 _physical_write(pte2_paddr , (PTE_V | flags) ); 239 _physical_write(pte2_paddr + 4 , ppn ); 240 241 // release lock protecting PTAB[vspace_id][x][y] 242 _spin_lock_release( &_ptabs_spin_lock[vspace_id][x][y] ); 243 244 asm volatile ("sync"); 245 246 } // end _v2p_add_pte2() 247 248 //////////////////////////////////////////// 249 void _v2p_del_pte1( unsigned int vspace_id, 250 unsigned int x, 251 unsigned int y, 252 unsigned int vpn ) // 20 bits right-justified 253 { 254 unsigned int ix1 = vpn >> 9; // 11 bits for ix1 255 256 // get page table physical base address 257 paddr_t pt1_pbase = _ptabs_paddr[vspace_id][x][y]; 258 259 // check PTAB defined 260 if ( pt1_pbase == 0 ) 261 { 262 _printf("\n[GIET ERROR] in _v2p_del_pte1() : no PTAB for vspace %d " 263 "in cluster[%d,%d]\n", vspace_id , x , y ); 264 _exit(); 265 } 266 267 // get ptd in PT1 268 paddr_t ptd_paddr = pt2_pbase + 4 * ix1; 269 unsigned int ptd = _physical_read( ptd_paddr ); 270 271 // check ptd valid 272 if ((ptd & PTE_V) == 0) 273 { 274 _printf("\n[GIET ERROR] in _v2p_del_pte1() : vpn %x not mapped in PT1" 275 "for vspace %d in cluster[%d,%d]\n", vpn , vspace_id , x , y ); 276 _exit(); 277 } 278 279 // invalidate PTD in PT1 280 _physical_write( ptd_paddr , 0 ); 281 282 } // end _v2p_del_pte1() 283 284 //////////////////////////////////////////// 285 void _v2p_del_pte2( unsigned int vspace_id, 286 unsigned int x, 287 unsigned int y, 288 unsigned int vpn ) // 20 bits right-justified 289 { 290 unsigned int ix1 = vpn >> 9; // 11 bits for ix1 291 unsigned int ix2 = vpn & 0x1FF; // 9 bits for ix2 292 293 // get page table physical base address 294 paddr_t pt1_pbase = _ptabs_paddr[vspace_id][x][y]; 295 296 // check PTAB defined 297 if ( pt1_pbase == 0 ) 298 { 299 _printf("\n[GIET ERROR] in _v2p_del_pte2() : no PTAB for vspace %d " 300 "in cluster[%d,%d]\n", vspace_id , x , y ); 301 _exit(); 302 } 303 304 // get ptd in PT1 305 unsigned int ptd = _physical_read( pt1_pbase + 4 * ix1 ); 306 307 // check ptd valid 308 if ((ptd & PTE_V) == 0) 309 { 310 _printf("\n[GIET ERROR] in _v2p_del_pte2() : vpn %x not mapped in PT1" 311 "for vspace %d in cluster[%d,%d]\n", vpn , vspace_id , x , y ); 312 _exit(); 313 } 314 315 // get PT2 physical base address 316 paddr_t pt2_pbase = ((paddr_t)(ptd & 0x0FFFFFFF)) << 12; 317 318 // invalidate PTE in PT2 319 paddr_t pte2_paddr = pt2_pbase + 8 * ix2; 320 _physical_write( pte2_paddr , 0 ); 321 322 asm volatile ("sync"); 323 324 } // end _v2p_del_pte2() 325 326 106 327 107 328 // Local Variables: -
soft/giet_vm/giet_common/vmem.h
r534 r751 85 85 unsigned int* flags ); 86 86 87 ////////////////////////////////////////////////////////////////////////////// 88 // This function registers a new PTE1 in the page table defined 89 // by the <vspace_id> argument, and the <x,y> coordinates. 90 // It updates only the first level PT1. 91 // This function checks that the PT1 entry is not already mapped, 92 // to enforce the rule: only one vseg in a given BPP. 93 // The 4 vsegs used by the boot code being packed in one single BPP, 94 // this verif is not done for all identity mapping vsegs. 95 ////////////////////////////////////////////////////////////////////////////// 96 void _v2p_add_pte1( unsigned int vspace_id, // vspace index 97 unsigned int x, // cluster X coordinate 98 unsigned int y, // cluster Y coordinate 99 unsigned int vpn, // 20 bits right-justified 100 unsigned int flags, // 10 bits left-justified 101 unsigned int ppn, // 28 bits right-justified 102 unsigned int ident ); // identity mapping if non zero 103 104 ////////////////////////////////////////////////////////////////////////////// 105 // This function registers a new PTE2 in the page table defined 106 // by the <vspace_id> argument, and the (x,y) coordinates. 107 // It updates both the first level PT1 and the second level PT2. 108 // As the set of PT2s is implemented as a fixed size array (no dynamic 109 // allocation), this function checks a possible overflow of the PT2 array. 110 // As a given entry in PT1 can be shared by several vsegs, mapped by 111 // different processors, we need to take the lock protecting PTAB[v][x][y]. 112 ////////////////////////////////////////////////////////////////////////////// 113 void _v2p_add_pte2( unsigned int vspace_id, // vspace index 114 unsigned int x, // cluster X coordinate 115 unsigned int y, // cluster Y coordinate 116 unsigned int vpn, // 20 bits right-justified 117 unsigned int flags, // 10 bits left-justified 118 unsigned int ppn, // 28 bits right-justified 119 unsigned int ident ); // identity mapping if non zero 120 121 ////////////////////////////////////////////////////////////////////////////// 122 // This function invalidate a PTE1 entry in the page table identified by the 123 // <vspace_id> argument and the <x,y> coordinates. The PTE1 entry is 124 // defined by the <vpn> virtual page number. 125 ////////////////////////////////////////////////////////////////////////////// 126 void _v2p_del_pte1( unsigned int vspace_id, // vspace index 127 unsigned int x, // cluster X coordinate 128 unsigned int y, // cluster Y coordinate 129 unsigned int vpn ); // 20 bits right-justified 130 131 ////////////////////////////////////////////////////////////////////////////// 132 // This function invalidate a PTE2 entry in the page table identified by the 133 // <vspace_id> argument and the <x,y> coordinates. The PTE2 entry is 134 // defined by the <vpn> virtual page number. The PT1 used to access the PTE2 135 // juis not modified. 136 ////////////////////////////////////////////////////////////////////////////// 137 void _v2p_del_pte2( unsigned int vspace_id, // vspace index 138 unsigned int x, // cluster X coordinate 139 unsigned int y, // cluster Y coordinate 140 unsigned int vpn ); // 20 bits right-justified 141 142 87 143 #endif 88 144
Note: See TracChangeset
for help on using the changeset viewer.