Changeset 23 for trunk/kernel/mm/vmm.c
- Timestamp:
- Jun 18, 2017, 10:06:41 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kernel/mm/vmm.c
r21 r23 29 29 #include <hal_gpt.h> 30 30 #include <printk.h> 31 #include <memcpy.h> 31 32 #include <rwlock.h> 32 33 #include <list.h> … … 94 95 95 96 // initialize local list of vsegs and radix-tree 97 vmm->vsegs_nr = 0; 96 98 list_root_init( &vmm->vsegs_root ); 97 vmm->vsegs_nr = 0;98 99 error = grdxt_init( &vmm->grdxt, 99 100 CONFIG_VMM_GRDXT_W1, … … 182 183 183 184 } // end vmm_init() 185 186 ////////////////////////////////////////// 187 error_t vmm_copy( process_t * dst_process, 188 process_t * src_process ) 189 { 190 error_t error; 191 192 vmm_t * src_vmm = &src_process->vmm; 193 vmm_t * dst_vmm = &dst_process->vmm; 194 195 // take the src_vmm vsegs_lock 196 rwlock_wr_lock( &src_vmm->vsegs_lock ); 197 198 // initialise dst_vmm vsegs_lock 199 rwlock_init( &dst_vmm->vsegs_lock ); 200 201 // initialise the dst_vmm vsegs list and the radix tree 202 dst_vmm->vsegs_nr = 0; 203 list_root_init( &dst_vmm->vsegs_root ); 204 error = grdxt_init( &dst_vmm->grdxt, 205 CONFIG_VMM_GRDXT_W1, 206 CONFIG_VMM_GRDXT_W2, 207 CONFIG_VMM_GRDXT_W3 ); 208 if( error ) 209 { 210 printk("\n[ERROR] in %s : cannot initialise radix tree for process %x\n", 211 __FUNCTION__ , dst_process->pid ); 212 return ENOMEM; 213 } 214 215 // loop on src_vmm list of vsegs to create 216 // and register vsegs copies in dst_vmm 217 list_entry_t * iter; 218 vseg_t * src_vseg; 219 vseg_t * dst_vseg; 220 LIST_FOREACH( &src_vmm->vsegs_root , iter ) 221 { 222 // get pointer on current src_vseg 223 src_vseg = LIST_ELEMENT( iter , vseg_t , list ); 224 225 // allocate memory for a new dst_vseg 226 dst_vseg = vseg_alloc(); 227 228 if( dst_vseg == NULL ) 229 { 230 // release all allocated vsegs 231 LIST_FOREACH( &dst_vmm->vsegs_root , iter ) 232 { 233 dst_vseg = LIST_ELEMENT( iter , vseg_t , list ); 234 vseg_free( dst_vseg ); 235 } 236 return ENOMEM; 237 } 238 239 // copy src_vseg to dst_vseg 240 vseg_init_from_ref( dst_vseg , XPTR( local_cxy , src_vseg ) ); 241 242 // register dst_vseg in dst_vmm 243 vseg_attach( dst_vmm , dst_vseg ); 244 } 245 246 // release the src_vmm vsegs_lock 247 rwlock_wr_unlock( &src_vmm->vsegs_lock ); 248 249 // initialize generic page table 250 error = hal_gpt_create( &dst_vmm->gpt ); 251 252 if( error ) 253 { 254 printk("\n[ERROR] in %s : cannot initialize page table\n", __FUNCTION__ ); 255 return ENOMEM; 256 } 257 258 // initialize STACK allocator 259 dst_vmm->stack_mgr.bitmap = 0; 260 dst_vmm->stack_mgr.vpn_base = CONFIG_VMM_STACK_BASE; 261 262 // initialize MMAP allocator 263 dst_vmm->mmap_mgr.vpn_base = CONFIG_VMM_MMAP_BASE; 264 dst_vmm->mmap_mgr.vpn_size = CONFIG_VMM_STACK_BASE - CONFIG_VMM_MMAP_BASE; 265 dst_vmm->mmap_mgr.first_free_vpn = CONFIG_VMM_MMAP_BASE; 266 uint32_t i; 267 for( i = 0 ; i < 32 ; i++ ) list_root_init( &dst_vmm->mmap_mgr.zombi_list[i] ); 268 269 // initialise instrumentation counters 270 dst_vmm->pgfault_nr = 0; 271 dst_vmm->u_err_nr = 0; 272 dst_vmm->m_err_nr = 0; 273 274 // copy base addresses 275 dst_vmm->kent_vpn_base = src_vmm->kent_vpn_base; 276 dst_vmm->args_vpn_base = src_vmm->args_vpn_base; 277 dst_vmm->envs_vpn_base = src_vmm->envs_vpn_base; 278 dst_vmm->heap_vpn_base = src_vmm->heap_vpn_base; 279 dst_vmm->code_vpn_base = src_vmm->code_vpn_base; 280 dst_vmm->data_vpn_base = src_vmm->data_vpn_base; 281 282 dst_vmm->entry_point = src_vmm->entry_point; 283 284 // HEAP TODO : new heap for child ??? 285 dst_vmm->heap_vseg = src_vmm->heap_vseg; 286 287 // initialize generic page table 288 error = hal_gpt_create( &dst_vmm->gpt ); 289 290 if( error ) 291 { 292 printk("\n[ERROR] in %s : cannot initialize page table\n", __FUNCTION__ ); 293 return ENOMEM; 294 } 295 296 // copy GPT content from src_vmm to dst_vmm, activating "Copy-On-Write" 297 // TODO register Copy-On_Write in page descriptors 298 bool_t cow = true; 299 hal_gpt_copy( &dst_vmm->gpt , &src_vmm->gpt , cow ); 300 301 hal_wbflush(); 302 303 return 0; 304 305 } // end vmm_copy() 184 306 185 307 /////////////////////////////////////// … … 659 781 error_t error; 660 782 661 // this function must be called by in the reference cluster662 if( process->is_ref == false);783 // this function must be called by a thread running in the reference cluster 784 if( GET_CXY( process->ref_xp ) != local_cxy ); 663 785 { 664 786 printk("\n[PANIC] in %s : not called in the reference cluster\n", __FUNCTION__ ); … … 796 918 paddr_t * paddr ) 797 919 { 798 uint32_t vaddr = (uint32_t)ptr; 799 800 thread_t * this = CURRENT_THREAD; 801 process_t * process = this->process; 920 process_t * process = CURRENT_THREAD->process; 802 921 803 922 if( ident ) // identity mapping 804 923 { 805 *paddr = (paddr_t)PADDR( local_cxy , vaddr );924 *paddr = (paddr_t)PADDR( local_cxy , (lpa_t)ptr ); 806 925 return 0; 807 926 } … … 814 933 uint32_t offset; 815 934 816 vpn = (vpn_t)( vaddr >> CONFIG_PPM_PAGE_SHIFT );817 offset = (uint32_t)( vaddr& CONFIG_PPM_PAGE_MASK );818 819 if( process->is_ref) // calling process is reference process935 vpn = (vpn_t)( (intptr_t)ptr >> CONFIG_PPM_PAGE_SHIFT ); 936 offset = (uint32_t)( ((intptr_t)ptr) & CONFIG_PPM_PAGE_MASK ); 937 938 if( local_cxy == GET_CXY( process->ref_xp) ) // calling process is reference process 820 939 { 821 940 error = vmm_get_pte( process, vpn , &attr , &ppn ); 822 941 } 823 else // use a RPC942 else // use a RPC 824 943 { 825 944 cxy_t ref_cxy = GET_CXY( process->ref_xp ); … … 828 947 } 829 948 830 if( error ) 831 { 832 printk("\n[ERROR] in %s : cannot get physical address for vaddr = %x\n", 833 __FUNCTION__ , vaddr ); 834 return error; 835 } 836 837 // return paddr 949 // set paddr 838 950 *paddr = (((paddr_t)ppn) << CONFIG_PPM_PAGE_SHIFT) | offset; 839 return 0; 951 952 return error; 840 953 841 954 } // end vmm_v2p_translate() 955 956 ////////////////////////////////////////////// 842 957 843 958
Note: See TracChangeset
for help on using the changeset viewer.