00001
00002
00003
00004
00005
00006 #include <system_data_cells.h>
00007 #include <linux/mm.h>
00008 #include <pfndef.h>
00009 #include <vmspte.h>
00010 #include <misc_routines.h>
00011 #include <mmg_routines.h>
00012 #include <internals.h>
00013
00014 int lasteech=0;
00015
00016 #undef OLDINT
00017 #define OLDINT
00018
00019 #ifdef __x86_64__
00020 #undef OLDINT
00021 #endif
00022
00023 struct _mypfn {
00024 #ifdef OLDINT
00025 struct _mypfn * pfn_l_flink;
00026 struct _mypfn * pfn_l_blink;
00027 #else
00028 int pfn_l_flink;
00029 int pfn_l_blink;
00030 #endif
00031 };
00032
00033 inline static int spinned() {
00034 struct _spl * spl = &SPIN_MMG;
00035 return test_bit(0,&spl->spl_l_spinlock);
00036 }
00037
00038 signed long mmg_rempfnh(unsigned long type);
00039 #ifdef OLDINT
00040 signed long mmg_rempfn(unsigned long type, struct _pfn * pfn);
00041 #else
00042 signed long mmg_rempfn(unsigned long type, int pfn);
00043 #endif
00044
00045 signed long mmg_allocpfn(void) {
00046 if (getipl()<8)
00047 panic("allocpfn\n");
00048 signed long pfn=mmg_rempfnh(PFN$C_FREPAGLST);
00049 if (pfn>=0) {
00050
00051
00052 }
00053 if (pfn>=0) {
00054 mmg_delconpfn(ctl$gl_pcb,pfn);
00055 }
00056 return pfn;
00057 }
00058
00059 signed long mmg_rempfnh(unsigned long type) {
00060 return mmg_rempfn(type,pfn$al_head[type]);
00061 }
00062
00063 #ifdef OLDINT
00064 signed long mmg_rempfn(unsigned long type, struct _pfn * pfn) {
00065 struct _mypfn * h;
00066 #else
00067 signed long mmg_rempfn(unsigned long type, int pfn) {
00068 int h;
00069 #endif
00070 if (getipl()<8)
00071 panic("rempfn\n");
00072 if (!spinned())
00073 panic("rempfn not spinlocked\n");
00074 if (0) {
00075 int k,l,m[24];
00076 l=pfn_al_head[0];
00077 for(k=0;k<24;k++) {
00078 printk("%lx ",l);
00079 m[k]=mem_map[l].pfn_l_blink;
00080 l=mem_map[l].pfn_l_flink;
00081 }
00082 printk("\n");
00083 l=pfn_al_head[0];
00084 for(k=0;k<24;k++) {
00085 printk("%lx ",m[k]);
00086 }
00087 printk("\n");
00088 }
00089 if (type==PFN_C_FREPAGLST)
00090 if (sch_gl_freecnt<(1+4)) return -1;
00091 if (type==PFN_C_MFYPAGLST)
00092 if (sch_gl_mfycnt<1) return -1;
00093 if (pfn_al_head[type]==0)
00094 return -1;
00095 if (pfn && pfn_al_head[type]==pfn$al_tail[type]) {
00096 pfn_al_head[type]=pfn$al_tail[type]=0;
00097 goto out;
00098 }
00099
00100
00101 if (pfn==pfn_al_head[type]) {
00102 #ifdef OLDINT
00103 h=pfn_al_head[type]=((struct _pfn *) pfn$al_head[type])->pfn$l_flink;
00104 h->pfn_l_blink=0;
00105 #else
00106 h=pfn_al_head[type]=mem_map[pfn$al_head[type]].pfn$l_flink;
00107 mem_map[h].pfn_l_blink=0;
00108 #endif
00109 pfn_al_head[type]=h;
00110 goto out;
00111 }
00112
00113 if (pfn==pfn_al_tail[type]) {
00114 #ifdef OLDINT
00115 h=pfn_al_tail[type]=((struct _pfn *) pfn$al_tail[type])->pfn$l_blink;
00116 h->pfn_l_flink=0;
00117 #else
00118 h=pfn_al_tail[type]=mem_map[pfn$al_tail[type]].pfn$l_blink;
00119 mem_map[h].pfn_l_flink=0;
00120 #endif
00121 pfn_al_tail[type]=h;
00122 goto out;
00123 }
00124
00125
00126 #ifdef OLDINT
00127 struct _mypfn * cur=pfn;
00128 struct _mypfn * prev=cur->pfn_l_blink;
00129 struct _mypfn * next=cur->pfn_l_flink;
00130 prev->pfn_l_flink=next;
00131 next->pfn_l_blink=prev;
00132 #else
00133 struct _mypfn * cur=&mem_map[pfn];
00134 int prev=cur->pfn_l_blink;
00135 int next=cur->pfn_l_flink;
00136 mem_map[prev].pfn_l_flink=next;
00137 mem_map[next].pfn_l_blink=prev;
00138 #endif
00139
00140
00141 #if 0
00142 if (h->pfn_l_flink==0) panic("eech %x\n",lasteech);
00143
00144 if (pfn->pfn_l_refcnt)
00145 panic("refcnt\n");
00146 #endif
00147 out:
00148 if (type==PFN_C_FREPAGLST) sch$gl_freecnt--;
00149 if (type==PFN_C_MFYPAGLST) sch$gl_mfycnt--;
00150 #if 0
00151 if (((struct _pfn *) pfn_al_head[type])->pfn$l_flink==0) {
00152 panic("eech4\n");
00153 }
00154 #endif
00155 lasteech=1;
00156 #ifdef OLDINT
00157 return (((unsigned long)pfn-(unsigned long)mem_map)/sizeof(struct _pfn));
00158 #else
00159 return pfn;
00160 #endif
00161 }
00162
00163 signed long mmg_allocontig(unsigned long num) {
00164 #ifdef OLDINT
00165 struct _pfn * p, * first=pfn_al_head[PFN$C_FREPAGLST], * next;
00166 struct _mypfn * h, * m;
00167 #else
00168 int p, first=pfn_al_head[PFN$C_FREPAGLST], next;
00169 int h, m;
00170 #endif
00171 unsigned long done=0, c;
00172 lasteech=2;
00173 if (sch_gl_freecnt<(num+4)) return -1;
00174 if (!pfn_al_head)
00175 return -1;
00176 while(!done) {
00177 for(p=first,c=1;c<num;c++) {
00178 next=p++;
00179 #ifdef OLDINT
00180 if (next->pfn_l_flink!=p) goto out;
00181 #else
00182 if (mem_map[next].pfn_l_flink!=p) goto out;
00183 #endif
00184 }
00185 done=1;
00186 out:
00187 #ifdef OLDINT
00188 if (!done) first=first->pfn_l_flink;
00189 #else
00190 if (!done) first=mem_map[first].pfn_l_flink;
00191 #endif
00192 }
00193
00194 if (first==pfn_al_head) {
00195 #ifdef OLDINT
00196 h=pfn_al_head[PFN$C_FREPAGLST]=p->pfn$l_flink;
00197 h->pfn_l_blink=0;
00198 #else
00199 h=pfn_al_head[PFN$C_FREPAGLST]=mem_map[p].pfn$l_flink;
00200 mem_map[h].pfn_l_blink=0;
00201 #endif
00202 } else {
00203 h=first;
00204 #ifdef OLDINT
00205 ((struct _mypfn *)h->pfn_l_blink)->pfn$l_flink=p->pfn$l_flink;
00206 ((struct _mypfn *)((struct _mypfn *)h->pfn_l_blink)->pfn$l_flink)->pfn$l_blink=h->pfn$l_blink;
00207 #else
00208 mem_map[mem_map[h].pfn_l_blink].pfn$l_flink=mem_map[p].pfn$l_flink;
00209 mem_map[mem_map[mem_map[h].pfn_l_blink].pfn$l_flink].pfn$l_blink=mem_map[h].pfn$l_blink;
00210 #endif
00211 }
00212
00213 #if 0
00214
00215 if (p->pfn_l_refcnt)
00216 panic("refcnt\n");
00217 #endif
00218 sch_gl_freecnt-=num;
00219 #ifdef OLDINT
00220 for(c=first-&mem_map[0];num;c++,num--) {
00221 #else
00222 for(c=first;num;c++,num--) {
00223 #endif
00224 mmg_delconpfn(ctl$gl_pcb,c);
00225 }
00226 #ifdef OLDINT
00227 return (((unsigned long)first-(unsigned long)mem_map)/sizeof(struct _pfn));
00228 #else
00229 return first;
00230 #endif
00231 }
00232
00233
00234 #ifdef OLDINT
00235 signed long mmg_inspfn(unsigned long type, struct _pfn * pfn, struct _pfn * list) {
00236 struct _mypfn * m=pfn, * tmp;
00237 #else
00238 signed long mmg_inspfn(unsigned long type, int pfn, int list) {
00239 int m=pfn, tmp;
00240 #endif
00241 if (getipl()<8)
00242 panic("inspfn\n");
00243 if (!spinned())
00244 panic("inspfn not spinlocked\n");
00245
00246 lasteech=3;
00247
00248 #ifdef OLDINT
00249 pfn->pfn_v_loc=type;
00250 #else
00251 mem_map[pfn].pfn_v_loc=type;
00252 #endif
00253
00254 if (list) {
00255 tmp=list;
00256 } else {
00257 tmp=pfn_al_head[type];
00258 #ifdef OLDINT
00259 while (tmp!=pfn_al_tail[type] && pfn>tmp->pfn$l_flink) {
00260 tmp=tmp->pfn_l_flink;
00261 #else
00262 while (tmp!=pfn_al_tail[type] && pfn>mem_map[tmp].pfn$l_flink) {
00263 tmp=mem_map[tmp].pfn_l_flink;
00264 #endif
00265 }
00266 }
00267
00268 mypfncheckaddr();
00269
00270
00271 if (m && pfn_al_head[type]==0 && pfn$al_tail[type]==0) {
00272 pfn_al_head[type]=m;
00273 pfn_al_tail[type]=m;
00274 #ifdef OLDINT
00275 m->pfn_l_blink=0;
00276 m->pfn_l_flink=0;
00277 #else
00278 mem_map[m].pfn_l_blink=0;
00279 mem_map[m].pfn_l_flink=0;
00280 #endif
00281 goto out;
00282 }
00283
00284
00285 if (m<pfn_al_head[type]) {
00286 #ifdef OLDINT
00287 m->pfn_l_flink=pfn$al_head[type];
00288 m->pfn_l_blink=0;
00289 tmp->pfn_l_blink=m;
00290 #else
00291 mem_map[m].pfn_l_flink=pfn$al_head[type];
00292 mem_map[m].pfn_l_blink=0;
00293 mem_map[tmp].pfn_l_blink=m;
00294 #endif
00295 pfn_al_head[type]=m;
00296 goto out;
00297 }
00298
00299
00300 #ifdef OLDINT
00301 if (m>tmp && tmp->pfn_l_flink==0) {
00302 tmp->pfn_l_flink=m;
00303 m->pfn_l_flink=0;
00304 m->pfn_l_blink=pfn$al_tail[type];
00305 #else
00306 if (m>tmp && mem_map[tmp].pfn_l_flink==0) {
00307 mem_map[tmp].pfn_l_flink=m;
00308 mem_map[m].pfn_l_flink=0;
00309 mem_map[m].pfn_l_blink=pfn$al_tail[type];
00310 #endif
00311 pfn_al_tail[type]=m;
00312 goto out;
00313 }
00314
00315
00316 #ifdef OLDINT
00317 if (m>tmp && m<tmp->pfn_l_flink) {
00318 m->pfn_l_flink=tmp->pfn$l_flink;
00319 m->pfn_l_blink=tmp;
00320 ((struct _mypfn *)tmp->pfn_l_flink)->pfn$l_blink=m;
00321 tmp->pfn_l_flink=m;
00322 #else
00323 if (m>tmp && m<mem_map[tmp].pfn_l_flink) {
00324 mem_map[m].pfn_l_flink=mem_map[tmp].pfn$l_flink;
00325 mem_map[m].pfn_l_blink=tmp;
00326 mem_map[mem_map[tmp].pfn_l_flink].pfn$l_blink=m;
00327 mem_map[tmp].pfn_l_flink=m;
00328 #endif
00329 goto out;
00330 }
00331
00332 #if 0
00333
00334
00335 if (mem_map[pfn].pfn_l_refcnt)
00336 panic("refcnt\n");
00337 #endif
00338
00339 out:
00340
00341
00342 mypfncheckaddr();
00343 if (type==PFN_C_FREPAGLST) sch$gl_freecnt++;
00344 if (type==PFN_C_MFYPAGLST) sch$gl_mfycnt++;
00345 }
00346
00347 signed long mmg_dallocpfn(struct _pfn * pageframe) {
00348 signed long pfn=mmg_inspfn(PFN$C_FREPAGLST,pageframe,0);
00349 #if 0
00350 #ifdef __i386__
00351
00352 pageframe->pfn_l_pt_pfn = (void*) 0x42424242;
00353 #endif
00354 #endif
00355 return pfn;
00356
00357 }
00358
00359 signed long mmg_inspfnh(unsigned long type, struct _pfn * pfn) {
00360 return mmg_inspfn(type,pfn,pfn$al_head[type]);
00361 }
00362
00363 signed long mmg_inspfnt(unsigned long type, struct _pfn * pfn) {
00364 return mmg_inspfn(type,pfn,pfn$al_tail[type]);
00365 }
00366
00367
00368 #ifdef OLDINT
00369 signed long mmg_allocontig_align(unsigned long num) {
00370 struct _pfn * p, * first=pfn_al_head[PFN$C_FREPAGLST], * next;
00371 struct _mypfn * h, * m;
00372 #else
00373 signed long mmg_allocontig_align(unsigned long num) {
00374 int p, first=pfn_al_head[PFN$C_FREPAGLST], next;
00375 int h, m;
00376 #endif
00377 p = 0;
00378
00379 if (0) {
00380 int k,l,m[24];
00381 l=pfn_al_head[0];
00382 for(k=0;k<24;k++) {
00383 printk("%lx ",l);
00384 m[k]=mem_map[l].pfn_l_blink;
00385 l=mem_map[l].pfn_l_flink;
00386 }
00387 printk("\n");
00388 l=pfn_al_head[0];
00389 for(k=0;k<24;k++) {
00390 printk("%lx ",m[k]);
00391 }
00392 printk("\n");
00393 }
00394 unsigned long done=0, c;
00395 unsigned long count=0;
00396 lasteech=4;
00397 if (sch_gl_freecnt<(num+4)) return -1;
00398 if (!pfn_al_head[PFN$C_FREPAGLST])
00399 return -1;
00400 while(!done) {
00401 #ifdef OLDINT
00402 if (!(((unsigned long)page_address(first)) & ( (num<<PAGE_SHIFT)-1))) {
00403 #else
00404 if (!(((unsigned long)page_address(&mem_map[first])) & ( (num<<PAGE_SHIFT)-1))) {
00405 #endif
00406 for(p=first,c=1;c<num;c++) {
00407 next=p++;
00408 #ifdef OLDINT
00409 if (next->pfn_l_flink!=p) goto out;
00410 #else
00411
00412 if (mem_map[next].pfn_l_flink!=p) goto out;
00413 #endif
00414 }
00415 done=1;
00416 }
00417 out:
00418 count++;
00419 #ifdef OLDINT
00420 if ((first->pfn_l_flink==0) ) panic("eech3\n");
00421 if (!done) first=first->pfn_l_flink;
00422 #else
00423 if ((mem_map[first].pfn_l_flink==0) ) panic("eech3\n");
00424 if (!done) first=mem_map[first].pfn_l_flink;
00425 #endif
00426 }
00427
00428 if (first==pfn_al_head[PFN$C_FREPAGLST]) {
00429 #ifdef OLDINT
00430 h=pfn_al_head[PFN$C_FREPAGLST]=p->pfn$l_flink;
00431 h->pfn_l_blink=0;
00432 #else
00433 h=pfn_al_head[PFN$C_FREPAGLST]=mem_map[p].pfn$l_flink;
00434 mem_map[h].pfn_l_blink=0;
00435 #endif
00436 } else {
00437 h=first;
00438 #ifdef OLDINT
00439 h->pfn_l_blink->pfn$l_flink=p->pfn$l_flink;
00440 h->pfn_l_blink->pfn$l_flink->pfn$l_blink=h->pfn$l_blink;
00441 #else
00442 mem_map[mem_map[h].pfn_l_blink].pfn$l_flink=mem_map[p].pfn$l_flink;
00443 mem_map[mem_map[mem_map[h].pfn_l_blink].pfn$l_flink].pfn$l_blink=mem_map[h].pfn$l_blink;
00444 #endif
00445 }
00446
00447 #if 0
00448
00449 if (p->pfn_l_refcnt)
00450 panic("refcnt\n");
00451 #endif
00452 sch_gl_freecnt-=num;
00453 #ifdef OLDINT
00454 for(c=first-&mem_map[0];num;c++,num--) {
00455 #else
00456 for(c=first;num;c++,num--) {
00457 #endif
00458 mmg_delconpfn(ctl$gl_pcb,c);
00459 }
00460 if (0) {
00461 int k,l,m[24];
00462 l=pfn_al_head[0];
00463 for(k=0;k<24;k++) {
00464 printk("%lx ",l);
00465 m[k]=mem_map[l].pfn_l_blink;
00466 l=mem_map[l].pfn_l_flink;
00467 }
00468 printk("\n");
00469 l=pfn_al_head[0];
00470 for(k=0;k<24;k++) {
00471 printk("%lx ",m[k]);
00472 }
00473 printk("\n");
00474 }
00475 #ifdef OLDINT
00476 return (((unsigned long)first-(unsigned long)mem_map)/sizeof(struct _pfn));
00477 #else
00478 return first;
00479 #endif
00480 }
00481
00482 mypfncheckaddr(){
00483 #if 0
00484
00485 int i,n=0,m=0;
00486 #ifdef OLDINT
00487 struct _mypfn *tmp2;
00488 #else
00489 int tmp2;
00490 #endif
00491 unsigned long tmp;
00492 tmp=pfn_al_head[PFN$C_FREPAGLST];
00493 tmp2=tmp;
00494 #ifdef OLDINT
00495 tmp2=tmp2->pfn_l_flink;
00496 #else
00497 tmp2=mem_map[tmp2].pfn_l_flink;
00498 #endif
00499 do {
00500 n++;
00501 #ifdef OLDINT
00502 if (tmp2!=(tmp2->pfn_l_flink->pfn$l_blink)) goto mypanic;
00503 if (tmp2!=(tmp2->pfn_l_blink->pfn$l_flink)) goto mypanic;
00504 tmp2=tmp2->pfn_l_flink;
00505 #else
00506 if (tmp2!=(mem_map[mem_map[tmp2].pfn_l_flink].pfn$l_blink)) goto mypanic;
00507 if (tmp2!=(mem_map[mem_map[tmp2].pfn_l_blink].pfn$l_flink)) goto mypanic;
00508 tmp2=mem_map[tmp2].pfn_l_flink;
00509 #endif
00510 } while (tmp2!=pfn_al_tail[PFN$C_FREPAGLST]);
00511 n--;
00512 tmp=pfn_al_tail[PFN$C_FREPAGLST];
00513 tmp2=tmp;
00514 #ifdef OLDINT
00515 tmp2=tmp2->pfn_l_blink;
00516 #else
00517 tmp2=mem_map[tmp2].pfn_l_blink;
00518 #endif
00519 do {
00520 m++;
00521 #ifdef OLDINT
00522 if (tmp2!=(tmp2->pfn_l_flink->pfn$l_blink)) goto mypanic;
00523 if (tmp2!=(tmp2->pfn_l_blink->pfn$l_flink)) goto mypanic;
00524 tmp2=tmp2->pfn_l_blink;
00525 #else
00526 if (tmp2!=(mem_map[mem_map[tmp2].pfn_l_flink].pfn$l_blink)) goto mypanic;
00527 if (tmp2!=(mem_map[mem_map[tmp2].pfn_l_blink].pfn$l_flink)) goto mypanic;
00528 tmp2=mem_map[tmp2].pfn_l_blink;
00529 #endif
00530 } while (tmp2!=pfn_al_head[PFN$C_FREPAGLST]);
00531 m--;
00532 if (n!=m) goto mypanic;
00533 return;
00534 mypanic:
00535 printk("mypanic %x %x %x %x %x\n",i,n,m,tmp,tmp2);
00536 #ifdef OLDINT
00537 printk("mypanic %x %x %x %x %x\n",tmp2->pfn_l_flink,tmp2->pfn$l_flink->pfn$l_blink,tmp2->pfn$l_blink,tmp2->pfn$l_blink->pfn$l_flink,42);
00538 #else
00539 printk("mypanic %x %x %x %x %x\n",mem_map[tmp2].pfn_l_flink,mem_map[mem_map[tmp2].pfn$l_flink].pfn$l_blink,mem_map[tmp2].pfn$l_blink,mem_map[mem_map[tmp2].pfn$l_blink].pfn$l_flink,42);
00540 #endif
00541 cli();
00542 while(1) {; };
00543 sickinsque(0x11111111,0x22222222);
00544 #endif
00545 }
00546
00547 #ifdef CONFIG_VMS
00548
00549 int mmg_relpfn(signed int pfn) {
00550 pte_t * pte = mem_map[pfn].pfn_q_pte_index;
00551 *(unsigned long *)pte&=~(_PAGE_PRESENT|_PAGE_TYP1);
00552 #ifndef __arch_um__
00553 __flush_tlb();
00554 #endif
00555 if (mem_map[pfn].pfn_l_page_state&PFN$M_MODIFY) {
00556
00557
00558 #ifdef OLDINT
00559 mmg_inspfn(PFN$C_MFYPAGLST,&mem_map[pfn],0);
00560 #else
00561 mmg_inspfn(PFN$C_MFYPAGLST,pfn,0);
00562 #endif
00563
00564 } else {
00565 #ifdef OLDINT
00566 mmg_inspfn(PFN$C_FREPAGLST,&mem_map[pfn],0);
00567 #else
00568 mmg_inspfn(PFN$C_FREPAGLST,pfn,0);
00569 #endif
00570 }
00571 }
00572
00573 mmg_delconpfn(struct _pcb * p, int pfn) {
00574 struct _pfn * pfnp=&mem_map[pfn];
00575 unsigned long * pte = pfnp->pfn_q_pte_index;
00576 if (pte) {
00577 *pte=pfnp->pfn_q_bak;
00578 #ifndef __arch_um__
00579 __flush_tlb();
00580 #endif
00581 mmg_decptref(p->pcb$l_phd,pte);
00582 pfnp->pfn_q_pte_index=0;
00583 }
00584 }
00585
00586 mmg_delpfnlst(int type, int pfn) {
00587 #ifdef OLDINT
00588 mmg_rempfn(type,&mem_map[pfn]);
00589 #else
00590 mmg_rempfn(type,pfn);
00591 #endif
00592 mmg_relpfn(pfn);
00593 }
00594
00595 #endif
00596