|
|
1.1 ! root 1: /* @(#)vmmac.h 1.1 86/02/03 SMI; from UCB 4.7 83/07/01 */ ! 2: ! 3: /* ! 4: * Virtual memory related conversion macros ! 5: */ ! 6: ! 7: /* Core clicks to number of pages of page tables needed to map that much */ ! 8: #define ctopt(x) (((x)+NPTEPG-1)/NPTEPG) ! 9: ! 10: /* Virtual page numbers to text|data|stack segment page numbers and back */ ! 11: #define vtotp(p, v) ((int)(v) - LOWPAGES) ! 12: #define vtodp(p, v) \ ! 13: ((int)((v) - ((p)->p_tsize ? \ ! 14: stoc(ctos((p)->p_tsize + LOWPAGES)) : LOWPAGES))) ! 15: #define vtosp(p, v) ((int)(btop(USRSTACK) - 1 - (v))) ! 16: #define tptov(p, i) ((unsigned)(i) + LOWPAGES) ! 17: #define dptov(p, i) \ ! 18: ((unsigned)((p)->p_tsize ? \ ! 19: (stoc(ctos((p)->p_tsize + LOWPAGES)) + (i)) : (LOWPAGES + (i)))) ! 20: #define sptov(p, i) ((unsigned)(btop(USRSTACK) - 1 - (i))) ! 21: ! 22: /* Tell whether virtual page numbers are in text|data|stack segment */ ! 23: #define isassv(p, v) ((v) >= (btop(USRSTACK) - (p)->p_ssize)) ! 24: #define isatsv(p, v) (((v) - LOWPAGES) < (p)->p_tsize) ! 25: #define isadsv(p, v) \ ! 26: ((v) >= ((p)->p_tsize ? \ ! 27: stoc(ctos((p)->p_tsize + LOWPAGES)) : LOWPAGES) && !isassv(p, v)) ! 28: ! 29: /* Tell whether pte's are text|data|stack */ ! 30: #define isaspte(p, pte) ((pte) > sptopte(p, (p)->p_ssize)) ! 31: #define isatpte(p, pte) ((pte) < dptopte(p, 0)) ! 32: #define isadpte(p, pte) (!isaspte(p, pte) && !isatpte(p, pte)) ! 33: ! 34: /* Text|data|stack pte's to segment page numbers and back */ ! 35: #define ptetotp(p, pte) ((pte) - (p)->p_p0br) ! 36: #define ptetodp(p, pte) (((pte) - (p)->p_p0br) - (p)->p_tsize) ! 37: #define ptetosp(p, pte) ((p)->p_p1br + P1PAGES - HIGHPAGES - 1 - (pte)) ! 38: ! 39: #define tptopte(p, i) ((p)->p_p0br + (i)) ! 40: #define dptopte(p, i) ((p)->p_p0br + ((p)->p_tsize + (i))) ! 41: #define sptopte(p, i) ((p)->p_p1br + P1PAGES - HIGHPAGES - 1 - (i)) ! 42: ! 43: /* Bytes to pages without rounding, and back */ ! 44: #define btop(x) (((unsigned)(x)) >> PGSHIFT) ! 45: #define ptob(x) ((caddr_t)((x) << PGSHIFT)) ! 46: ! 47: /* ! 48: * Turn virtual addresses into kernel map indices. Note that some ! 49: * trickery involving types and pointer conversions is employed, as ! 50: * well as misnomers and funny full unions; to whit: ! 51: * ! 52: * "Usrptmap" is an array of page table entries used to map virtual ! 53: * addresses, starting at (kernel virtual address) usrpt, to many ! 54: * different things (the funny full union). On the VAX, this mapped ! 55: * (kernel virtual) space is where the user page tables were allocated, ! 56: * hence the name. We at Sun use this virtual address space for all ! 57: * sorts of things, including addresses to reference peripherals (a ! 58: * misnomer). Usrptmap is managed throught the resource map named ! 59: * "kernelmap". kmx means kernelmap index, the index (into Usrptmap) ! 60: * returned by rmalloc(kernelmap, ...). ! 61: * ! 62: * kmxtob expects an (integer) kernel map index and returns the virtual ! 63: * address (through magic constants and implicit conversions) that is ! 64: * mapped by that pte. But the result is typed as a pte. (This is ! 65: * made sense on the VAX.) btokmx expects a (struct pte *) virtual ! 66: * address and returns the integer kernel map index. ! 67: * ! 68: * Recasts are often needed and used when invoking these macros. ! 69: */ ! 70: #define kmxtob(a) (usrpt + (a) * NPTEPG) ! 71: #define btokmx(b) (((b) - usrpt) / NPTEPG) ! 72: ! 73: /* User area address and pcb bases */ ! 74: #define uaddr(p) (&((p)->p_p0br[(p)->p_szpt * NPTEPG - UPAGES])) ! 75: #define pcbb(p) (p) ! 76: ! 77: /* Average new into old with aging factor time */ ! 78: #define ave(smooth, cnt, time) \ ! 79: smooth = ((time - 1) * (smooth) + (cnt)) / (time) ! 80: ! 81: /* Abstract machine dependent operations */ ! 82: #ifdef vax ! 83: #define setp0br(x) (u.u_pcb.pcb_p0br = (x), mtpr(P0BR, x)) ! 84: #define setp0lr(x) (u.u_pcb.pcb_p0lr = \ ! 85: (x) | (u.u_pcb.pcb_p0lr & AST_CLR), \ ! 86: mtpr(P0LR, x)) ! 87: #define setp1br(x) (u.u_pcb.pcb_p1br = (x), mtpr(P1BR, x)) ! 88: #define setp1lr(x) (u.u_pcb.pcb_p1lr = (x), mtpr(P1LR, x)) ! 89: #define initp1br(x) ((x) - P1PAGES) ! 90: #endif ! 91: #ifdef sun ! 92: #define setp0br(x) u.u_pcb.pcb_p0br = (x) ! 93: #define setp0lr(x) (u.u_pcb.pcb_p0lr = (x) | (u.u_pcb.pcb_p0lr & AST_CLR)) ! 94: #define setp1br(x) u.u_pcb.pcb_p1br = (x) ! 95: #define setp1lr(x) u.u_pcb.pcb_p1lr = (x) ! 96: #define initp1br(x) ((x) - P1PAGES - UPAGES) ! 97: #endif ! 98: ! 99: #define outofmem() wakeup((caddr_t)&proc[2]); ! 100: ! 101: /* ! 102: * Page clustering macros. ! 103: * ! 104: * dirtycl(pte) is the page cluster dirty? ! 105: * anycl(pte,fld) does any pte in the cluster has fld set? ! 106: * zapcl(pte,fld) = val set all fields fld in the cluster to val ! 107: * distcl(pte) distribute high bits to cluster; note that ! 108: * distcl copies everything but pg_pfnum, ! 109: * INCLUDING pg_m!!! ! 110: * ! 111: * In all cases, pte must be the low pte in the cluster, even if ! 112: * the segment grows backwards (e.g. the stack). ! 113: */ ! 114: #define H(pte) ((struct hpte *)(pte)) ! 115: ! 116: #if CLSIZE==1 ! 117: #define dirtycl(pte) dirty(pte) ! 118: #define anycl(pte,fld) ((pte)->fld) ! 119: #define zapcl(pte,fld) (pte)->fld ! 120: #define distcl(pte) ! 121: #endif ! 122: ! 123: #if CLSIZE==2 ! 124: #define dirtycl(pte) (dirty(pte) || dirty((pte)+1)) ! 125: #define anycl(pte,fld) ((pte)->fld || (((pte)+1)->fld)) ! 126: #define zapcl(pte,fld) (pte)[1].fld = (pte)[0].fld ! 127: #endif ! 128: ! 129: #if CLSIZE==4 ! 130: #define dirtycl(pte) \ ! 131: (dirty(pte) || dirty((pte)+1) || dirty((pte)+2) || dirty((pte)+3)) ! 132: #define anycl(pte,fld) \ ! 133: ((pte)->fld || (((pte)+1)->fld) || (((pte)+2)->fld) || (((pte)+3)->fld)) ! 134: #define zapcl(pte,fld) \ ! 135: (pte)[3].fld = (pte)[2].fld = (pte)[1].fld = (pte)[0].fld ! 136: #endif ! 137: ! 138: #ifndef distcl ! 139: #define distcl(pte) zapcl(H(pte),pg_high) ! 140: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.