00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include<linux/config.h>
00012 #include<linux/unistd.h>
00013 #include<linux/linkage.h>
00014 #include<linux/sched.h>
00015 #include<linux/vmalloc.h>
00016 #include <system_data_cells.h>
00017 #include <linux/mm.h>
00018 #include <ipldef.h>
00019 #include <mmgdef.h>
00020 #include <pfndef.h>
00021 #include <phddef.h>
00022 #include <rdedef.h>
00023 #include <ssdef.h>
00024 #include <starlet.h>
00025 #include <va_rangedef.h>
00026 #include <vmspte.h>
00027 #include <wsldef.h>
00028 #include <ipl.h>
00029 #include <queue.h>
00030 #include <mmg_functions.h>
00031 #include <exe_routines.h>
00032 #include <mmg_routines.h>
00033 #include <linux/slab.h>
00034 #include <internals.h>
00035
00036 #undef OLDINT
00037 #define OLDINT
00038
00039 #ifdef __x86_64__
00040 #undef OLDINT
00041 #endif
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 inline struct _rde * mmg_lookup_rde_va (void * va, struct _phd * const phd, int function, int ipl);
00054 inline struct _rde * mmg_search_rde_va (void * va, struct _rde *head, struct _rde **prev, struct _rde **next);
00055
00056 asmlinkage void exe_cntreg(void) {
00057 }
00058
00059 int vava=0;
00060
00061 int mmg_delpag(int acmode, void * va, struct _pcb * p, signed int pagedirection, struct _rde * rde, unsigned long newpte) {
00062 #ifdef CONFIG_VMS
00063
00064 int savipl=getipl();
00065 setipl(IPL__MMG);
00066 if ((unsigned long)va>=0x3ff000) {
00067
00068 }
00069
00070 pgd_t *pgd = 0;
00071 pud_t *pud = 0;
00072 pmd_t *pmd = 0;
00073 pte_t *pte = 0;
00074 unsigned long address=va;
00075
00076 struct mm_struct * mm = p->mm;
00077 if (mm==0)
00078 mm = p->active_mm;
00079
00080 if (va>=rde->rde_pq_first_free_va) {
00081
00082 }
00083
00084 pgd = pgd_offset(mm, address);
00085 pud = pud_offset(pgd, address);
00086 pmd = pmd_offset(pud, address);
00087 if (pmd && *(long *)pmd) {
00088 pte = pte_offset(pmd, address);
00089 }
00090
00091 if (vava)
00092 printk("va %lx %lx %lx %lx\n",pgd,pud,pmd,pte);
00093
00094 if (pte==0) {
00095 setipl(savipl);
00096 return SS__NORMAL;
00097 }
00098
00099 if (*(unsigned long*)pte==0) {
00100 setipl(savipl);
00101 return SS__NORMAL;
00102 }
00103
00104 struct _mypte * mypte = pte;
00105
00106 if (*(long *)pte&_PAGE_PRESENT)
00107 goto valid;
00108 if (mypte->pte_v_typ1) {
00109 if (mypte->pte_v_typ0) {
00110 *(unsigned long *)mypte=0;
00111 } else {
00112 mmg_dallocpagfil1(mypte->pte$v_pgflpag);
00113
00114
00115 *(unsigned long *)mypte=0;
00116
00117
00118 }
00119 }
00120 if (mypte->pte_v_typ1==0) {
00121 if (mypte->pte_v_typ0==0) {
00122 if (mypte->pte_v_pfn) {
00123 if (mem_map[mypte->pte_v_pfn].pfn$v_loc==PFN$C_FREPAGLST) {
00124 int ipl = vmslock(&SPIN_MMG, IPL__MMG);
00125 mmg_delpfnlst(PFN$C_FREPAGLST,mypte->pte$v_pfn);
00126 vmsunlock(&SPIN_MMG, ipl);
00127
00128 goto skipthis;
00129 }
00130
00131 if (mem_map[mypte->pte_v_pfn].pfn$v_loc==PFN$C_MFYPAGLST) {
00132
00133 mem_map[mypte->pte_v_pfn].pfn$l_page_state&=~PFN$M_MODIFY;
00134 int ipl = vmslock(&SPIN_MMG, IPL__MMG);
00135 mmg_delpfnlst(PFN$C_MFYPAGLST,mypte->pte$v_pfn);
00136 vmsunlock(&SPIN_MMG, ipl);
00137 goto skipthis;
00138 }
00139
00140
00141
00142 skipthis:
00143 {}
00144 } else {
00145
00146 }
00147 } else {
00148 }
00149 }
00150 goto out;
00151
00152 valid:
00153 {}
00154 struct _phd * phd = p->pcb_l_phd;
00155 struct _wsl * wsl = phd->phd_l_wslist;
00156 struct _pfn * pfn = &mem_map[mypte->pte_v_pfn];
00157 struct _wsl * wsle = &wsl[pfn->pfn_l_wslx_qw];
00158 if (wsle->wsl_v_pagtyp==WSL$C_PROCESS) {
00159 p->pcb_l_ppgcnt--;
00160 }
00161 wsle->wsl_pq_va=0;
00162 *(unsigned long*)pte=0;
00163 int ipl = vmslock(&SPIN_MMG, IPL__MMG);
00164 #ifdef OLDINT
00165 mmg_dallocpfn(pfn);
00166 #else
00167 mmg_dallocpfn(pfn-mem_map);
00168 #endif
00169 vmsunlock(&SPIN_MMG, ipl);
00170
00171 out:
00172
00173 #ifndef __arch_um__
00174 __flush_tlb();
00175 #endif
00176 setipl(savipl);
00177 return SS__NORMAL;
00178 #endif
00179 }
00180
00181 asmlinkage int exe_deltva(struct _va_range *inadr, struct _va_range *retadr, unsigned int acmode) {
00182
00183
00184 setipl(IPL__ASTDEL);
00185
00186 void * first=inadr->va_range_ps_start_va;
00187 void * last=inadr->va_range_ps_end_va;
00188 struct _pcb * p=ctl_gl_pcb;
00189 struct _rde * rde;
00190 unsigned long numpages=(last-first)/PAGE_SIZE;
00191 acmode=0;
00192 mmg_credel(acmode, first, last, mmg$delpag, inadr, retadr, acmode, p, numpages);
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205 asmlinkage int exe_expreg(unsigned int pagcnt, struct _va_range *retadr,unsigned int acmode, char region) {
00206 #ifdef __arch_um__
00207 int prot_pte=0x51|_PAGE_RW;
00208 #else
00209 int prot_pte=0x45|_PAGE_RW;
00210 #endif
00211 int sts = SS__NORMAL;
00212
00213
00214
00215
00216
00217 struct _rde * rde=mmg_lookup_rde_va(0x20000000, current->pcb$l_phd, LOOKUP_RDE_EXACT, IPL$_ASTDEL);
00218 if (rde==0) {
00219 int sts=exe_create_region_32(pagcnt*4096,prot_pte,0x187500,0,0,0,0x20000000);
00220 rde=mmg_lookup_rde_va(0x20000000, current->pcb$l_phd, LOOKUP_RDE_EXACT, IPL$_ASTDEL);
00221 rde->rde_pq_first_free_va=0x20000000;
00222
00223 retadr->va_range_ps_start_va=0x20000000;
00224 retadr->va_range_ps_end_va=0x20000000+pagcnt*4096-1;
00225
00226 goto out;
00227 return sts;
00228 }
00229
00230 out:
00231 rde->rde_pq_first_free_va+=pagcnt*4096;
00232
00233
00234 mmg_fast_create(ctl$gl_pcb,rde,retadr->va_range$ps_start_va,retadr->va_range$ps_end_va,pagcnt,prot_pte);
00235
00236
00237 return sts;
00238 }
00239
00240
00241 struct _mmg mymmg;
00242
00243 int inline mmg_inadrini(){
00244 }
00245
00246 int inline mmg_retadrini(){
00247 }
00248
00249 int inline insrde(struct _rde * elem, struct _rde * head) {
00250 struct _rde * tmp=head->rde_ps_va_list_flink;
00251 struct _rde * prev=head;
00252 while (tmp!=head && elem->rde_pq_start_va>tmp->rde$pq_start_va) {
00253 prev=tmp;
00254 tmp=tmp->rde_ps_va_list_flink;
00255 }
00256 #if 0
00257 if (head==tmp) {
00258 if (elem->rde_pq_start_va<prev->rde$pq_start_va) {
00259 prev=head;
00260 } else {
00261 prev=prev->rde_ps_va_list_blink;
00262 }
00263 }
00264 #endif
00265 insque(elem,prev);
00266 return 1;
00267 }
00268
00269 int mmg_crepag (int acmode, void * va, struct _pcb * p, signed int pagedirection, struct _rde * rde, unsigned long newpte);
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283 int mmg_credel(int acmode, void * first, void * last, void (* pagesubr)(), struct _va_range *inadr, struct _va_range *retadr, unsigned int acmodeagain, struct _pcb * p, int numpages) {
00284 unsigned long tmp=first;
00285
00286 int newpte=0;
00287
00288 if (((long)first & 0x80000000) || ((long)last & 0x80000000))
00289 return SS__NOPRIV;
00290
00291 mymmg.mmg_l_pagesubr=pagesubr;
00292
00293
00294 while (tmp<last) {
00295
00296 pagesubr(0,tmp,p,+PAGE_SIZE,0,newpte);
00297 tmp=tmp+PAGE_SIZE;
00298 }
00299 return SS__NORMAL;
00300 }
00301
00302
00303
00304
00305
00306
00307
00308
00309 asmlinkage int exe_cretva (struct _va_range *inadr, struct _va_range *retadr, unsigned int acmode) {
00310
00311
00312
00313
00314
00315 struct _rde * tmprde = mmg_lookup_rde_va (inadr->va_range$ps_start_va, current->pcb$l_phd, 0, 2);
00316 void * first=inadr->va_range_ps_start_va;
00317 void * last=inadr->va_range_ps_end_va;
00318
00319
00320
00321 struct _pcb * p=current;
00322 struct _rde * rde;
00323 unsigned long numpages=(last-first)/PAGE_SIZE;
00324 mmg_credel(acmode, first, last, mmg$crepag, inadr, retadr, acmode, p, numpages);
00325
00326
00327 }
00328
00329
00330
00331
00332
00333 int mmg_crepag (int acmode, void * va, struct _pcb * p, signed int pagedirection, struct _rde * rde, unsigned long newpte) {
00334
00335 pgd_t *pgd;
00336 pud_t *pud;
00337 pmd_t *pmd;
00338 pte_t *pte = 0;
00339 struct mm_struct * mm=current->mm;
00340 unsigned long address=va;
00341
00342
00343 if (va>=rde->rde_pq_first_free_va) {
00344
00345 }
00346
00347 pgd = pgd_offset(mm, address);
00348 pud = pud_alloc(mm, pgd, address);
00349 pmd = pmd_alloc(mm, pud, address);
00350 if (pmd) {
00351 #ifdef __i386__
00352 spin_lock(&mm->page_table_lock);
00353 #endif
00354 pte = pte_alloc(mm, pmd, address);
00355 #ifdef __i386__
00356 spin_unlock(&mm->page_table_lock);
00357 #endif
00358 }
00359
00360
00361 *(unsigned long *)pte=newpte;
00362
00363
00364 if ((long)(*(long *)pte)) {
00365 return SS__VA_IN_USE;
00366 } else {
00367
00368
00369 *(unsigned long *)pte=newpte;
00370 }
00371
00372 }
00373
00374
00375 inline struct _rde * mmg_lookup_rde_va (void * va, struct _phd * const phd, int function, int ipl) {
00376 struct _rde * head=&phd->phd_ps_p0_va_list_flink;
00377 struct _rde * rde, *prev, *next, *newrde;
00378 int savipl=getipl();
00379 if (ipl < IPL__ASTDEL) setipl(IPL$_ASTDEL);
00380
00381 newrde = mmg_search_rde_va(va, head, &prev, &next);
00382
00383 if (newrde) {
00384 if (ipl < IPL__ASTDEL) setipl(savipl);
00385 return newrde;
00386 }
00387
00388 if (function==LOOKUP_RDE_EXACT) {
00389 if (ipl < IPL__ASTDEL) setipl(savipl);
00390 return 0;
00391 }
00392
00393
00394
00395 if (head->rde_v_descend) {
00396 if (ipl < IPL__ASTDEL) setipl(savipl);
00397 return (prev);
00398 }
00399
00400 if (va < head->rde_pq_start_va) {
00401 if (ipl < IPL__ASTDEL) setipl(savipl);
00402 return (head);
00403 }
00404
00405 if (next != head) {
00406 if (ipl < IPL__ASTDEL) setipl(savipl);
00407 return (next);
00408 }
00409
00410 head++;
00411 if (!head->rde_v_descend) {
00412 if (ipl < IPL__ASTDEL) setipl(savipl);
00413 return (head);
00414 }
00415
00416 rde = head->rde_ps_va_list_blink;
00417 if (ipl < IPL__ASTDEL) setipl(savipl);
00418 return (newrde);
00419 }
00420
00421
00422
00423 inline struct _rde * mmg_search_rde_va (void * va, struct _rde *head, struct _rde **prev, struct _rde **next) {
00424 struct _rde * tmp=head;
00425 int dofirst=0;
00426 *prev=0;
00427 *next=head->rde_ps_va_list_flink;
00428
00429 while (head!=*next) {
00430 if (!head->rde_v_descend) {
00431 if ((tmp->rde_pq_start_va+tmp->rde$q_region_size) > va) goto out;
00432 } else {
00433 if (tmp->rde_pq_start_va <= va) goto out;
00434 }
00435 *prev=tmp;
00436 tmp=*next;
00437 *next=tmp->rde_ps_va_list_flink;
00438 }
00439 out:
00440 if (!head->rde_v_descend) {
00441 if ((tmp->rde_pq_start_va+tmp->rde$q_region_size) > va) dofirst=1;
00442 } else {
00443 if (tmp->rde_pq_start_va <= va) dofirst=1;
00444 }
00445 if (dofirst) {
00446 if (tmp->rde_pq_start_va<=va) return tmp;
00447 *next=tmp;
00448 return 0;
00449 } else {
00450 *prev=tmp;
00451 return 0;
00452 }
00453 }
00454
00455 int mmg_fast_create(struct _pcb * p, struct _rde *rde, void * start_va, void * end_va, unsigned long pages, unsigned long prot_pte) {
00456 unsigned long newpte;
00457 unsigned long page;
00458 unsigned long tmp=start_va;
00459 unsigned long new_pte;
00460
00461 for(page=0;page<pages;page++) {
00462 newpte=prot_pte|0;
00463 mmg_crepag(0,tmp,0,+PAGE_SIZE,0,newpte);
00464 tmp+=PAGE_SIZE;
00465 }
00466 }
00467
00468 int mmg_fast_create_gptx(struct _pcb * p, struct _rde *rde, void * start_va, void * end_va, unsigned long pages, unsigned long prot_pte) {
00469 unsigned long page;
00470 unsigned long tmp=start_va;
00471 struct _mypte newpte;
00472
00473 newpte.pte_l_all=prot_pte;
00474
00475 for(page=0;page<pages;page++) {
00476 mmg_crepag(0,tmp,0,+PAGE_SIZE,0,*(unsigned long *)&newpte);
00477 tmp+=PAGE_SIZE;
00478 newpte.pte_v_gptx++;
00479 }
00480 }
00481
00482 asmlinkage int exe_create_region_32_wrap (struct struct_args * s) {
00483 return exe_create_region_32(s->s1,s->s2,s->s3,s->s4,s->s5,s->s6,s->s7);
00484 }
00485
00486 asmlinkage int exe_create_region_32 ( unsigned long length, unsigned int region_prot, unsigned int flags, unsigned long long *return_region_id, void **return_va, unsigned long *return_length, unsigned long start_va) {
00487 struct _rde * rde;
00488 rde=kmalloc(sizeof(struct _rde),GFP_KERNEL);
00489 memset(rde,0,sizeof(struct _rde));
00490 rde->rde_b_type=30;
00491 rde->rde_pq_start_va=start_va;
00492 rde->rde_q_region_size=length;
00493 rde->rde_l_flags=flags;
00494 rde->rde_r_regprot.regprt$l_region_prot = region_prot;
00495 insrde(rde,¤t->pcb_l_phd->phd$ps_p0_va_list_flink);
00496 return SS__NORMAL;
00497 }
00498
00499 asmlinkage int exe_delete_region_32 (unsigned long long *region_id, unsigned int acmode, void **return_va, unsigned long *return_length) {
00500
00501 }
00502
00503 asmlinkage int exe_get_region_info (unsigned int function_code, unsigned long long *region_id, void *start_va, void *reserved, unsigned int buffer_length, void *buffer_address, unsigned int *return_length) {
00504
00505 }
00506
00507