Annotation of researchv9/sys.vax/sys/vmsubr.c, revision 1.1.1.1

1.1       root        1: /*     vmsubr.c        4.6     81/05/28        */
                      2: 
                      3: #include "../h/param.h"
                      4: #include "../h/systm.h"
                      5: #include "../h/dir.h"
                      6: #include "../h/user.h"
                      7: #include "../h/vm.h"
                      8: #include "../h/proc.h"
                      9: #include "../h/mtpr.h"
                     10: #include "../h/pte.h"
                     11: #include "../h/cmap.h"
                     12: #include "../h/inode.h"
                     13: #include "../h/buf.h"
                     14: #include "../h/text.h"
                     15: 
                     16: /*
                     17:  * Make uarea of process p addressible at kernel virtual
                     18:  * address uarea through sysmap locations starting at map.
                     19:  */
                     20: uaccess(p, map, uarea)
                     21:        register struct proc *p;
                     22:        struct pte *map;
                     23:        register struct user *uarea;
                     24: {
                     25:        register int i;
                     26:        register struct pte *mp = map;
                     27: 
                     28:        for (i = 0; i < UPAGES; i++) {
                     29:                *(int *)mp = 0;
                     30:                mp->pg_pfnum = p->p_addr[i].pg_pfnum;
                     31:                mp++;
                     32:        }
                     33:        vmaccess(map, (caddr_t)uarea, UPAGES);
                     34: }
                     35: 
                     36: /*
                     37:  * Validate the kernel map for size ptes which
                     38:  * start at ppte in the sysmap, and which map
                     39:  * kernel virtual addresses starting with vaddr.
                     40:  */
                     41: vmaccess(ppte, vaddr, size)
                     42:        register struct pte *ppte;
                     43:        register caddr_t vaddr;
                     44:        register int size;
                     45: {
                     46: 
                     47:        while (size != 0) {
                     48:                *(int *)ppte++ |= PG_V|PG_KW;
                     49:                mtpr(TBIS, vaddr);
                     50:                vaddr += NBPG;
                     51:                --size;
                     52:        }
                     53: }
                     54: 
                     55: /* 
                     56:  * Convert a pte pointer to
                     57:  * a virtual page number.
                     58:  */
                     59: ptetov(p, pte)
                     60:        register struct proc *p;
                     61:        register struct pte *pte;
                     62: {
                     63: 
                     64:        if (isatpte(p, pte))
                     65:                return (tptov(p, ptetotp(p, pte)));
                     66:        else if (isadpte(p, pte))
                     67:                return (dptov(p, ptetodp(p, pte)));
                     68:        else
                     69:                return (sptov(p, ptetosp(p, pte)));
                     70: }
                     71: 
                     72: /*
                     73:  * Convert a virtual page 
                     74:  * number to a pte address.
                     75:  */
                     76: struct pte *
                     77: vtopte(p, v)
                     78:        register struct proc *p;
                     79:        register unsigned v;
                     80: {
                     81: 
                     82:        if (isatsv(p, v))
                     83:                return (tptopte(p, vtotp(p, v)));
                     84:        else if (isadsv(p, v))
                     85:                return (dptopte(p, vtodp(p, v)));
                     86:        else 
                     87:                return (sptopte(p, vtosp(p, v)));
                     88: }
                     89: 
                     90: struct buf *vbmap();
                     91: /*
                     92:  * Initialize the page tables for paging from an inode,
                     93:  * by scouring up the indirect blocks in order.
                     94:  * Corresponding area of memory should have been vmemfree()d
                     95:  * first or just created.
                     96:  */
                     97: vinifod(pte, fileno, ip, bstart, count)
                     98:        register struct fpte *pte;
                     99:        int fileno;
                    100:        register struct inode *ip;
                    101:        daddr_t bstart;
                    102:        size_t count;
                    103: {
                    104:        register int i, j;
                    105:        struct buf *bp;
                    106:        int indx;
                    107:        register daddr_t *pp;
                    108: 
                    109:        if(ip->i_fstyp)
                    110:                panic("vinifod, fstyp");
                    111:        if(fileno < PG_FMIN)
                    112:                panic("vinifod, fileno");
                    113:        while (count > 0) {
                    114:                if (bstart < NADDR - 3) {
                    115:                        ((struct pte *)pte)->pg_vreadm = 0;
                    116:                        pte->pg_fod = 1;
                    117:                        pte->pg_source = fileno - PG_FMIN;
                    118:                        pte->pg_blkno = ip ? ip->i_un.i_addr[bstart] : 0;
                    119:                        if (pte->pg_blkno == 0) {
                    120:                                pte->pg_source = PG_FZERO - PG_FMIN;
                    121:                                pte->pg_blkno = 0;
                    122:                                cnt.v_nzfod += CLSIZE;
                    123:                        } else if (fileno == PG_FTEXT)
                    124:                                cnt.v_nexfod += CLSIZE;
                    125:                        else
                    126:                                panic("vinifod, vrpages set");
                    127:                        for (j = 1; j < CLSIZE; j++)
                    128:                                pte[j] = pte[0];
                    129:                        pte += CLSIZE;
                    130:                        bstart++;
                    131:                        count -= CLSIZE;
                    132:                } else {
                    133:                        mtpr(TBIA, 0);          /* conservative */
                    134:                        bp = vbmap(ip, bstart);
                    135:                        indx = (bstart - (NADDR - 3)) % NINDIR(ip->i_dev);
                    136:                        i = imin((NINDIR(ip->i_dev) - indx) * CLSIZE, count);
                    137:                        bstart += i / CLSIZE;
                    138:                        count -= i;
                    139:                        if (bp) {
                    140:                                pp = &bp->b_un.b_daddr[indx];
                    141:                                do {
                    142:                                        ((struct pte *)pte)->pg_vreadm = 0;
                    143:                                        pte->pg_fod = 1;
                    144:                                        pte->pg_blkno = *pp++;
                    145:                                        if (pte->pg_blkno) {
                    146:                                                pte->pg_source = fileno - PG_FMIN;
                    147:                                                if (fileno == PG_FTEXT)
                    148:                                                        cnt.v_nexfod += CLSIZE;
                    149:                                                else
                    150:                                                        panic("vinifod, vrpages set");
                    151:                                        } else {
                    152:                                                pte->pg_source = PG_FZERO - PG_FMIN;
                    153:                                                pte->pg_blkno = 0;
                    154:                                                cnt.v_nzfod += CLSIZE;
                    155:                                        }
                    156:                                        for (j = 1; j < CLSIZE; j++)
                    157:                                                pte[j] = pte[0];
                    158:                                        pte += CLSIZE;
                    159:                                } while ((i -= CLSIZE) > 0);
                    160:                                brelse(bp);
                    161:                        } else {
                    162:                                cnt.v_nzfod += i;
                    163:                                do {
                    164:                                        ((struct pte *)pte)->pg_vreadm = 0;
                    165:                                        pte->pg_fod = 1;
                    166:                                        pte->pg_source = PG_FZERO - PG_FMIN;
                    167:                                        distcl(pte);
                    168:                                        pte += CLSIZE;
                    169:                                } while ((i -= CLSIZE) > 0);
                    170:                        }
                    171:                }
                    172:        }
                    173:        mtpr(TBIA, 0);          /* necessary! */
                    174: }
                    175: 
                    176: /*
                    177:  * Vbmap returns a block full of indirect pointers for a given block offset
                    178:  * in a file.  It returns 0 if a missing address block was encountered,
                    179:  * in which case the pages can be normal zfod pages.
                    180:  */
                    181: struct buf *
                    182: vbmap(ip, bn)
                    183: register struct inode *ip;
                    184: daddr_t bn;
                    185: {
                    186:        register i;
                    187:        struct buf *bp;
                    188:        int j, sh;
                    189:        daddr_t nb;
                    190:        dev_t dev = ip->i_dev;
                    191: 
                    192:        if (bn < NADDR-3)
                    193:                panic("vbmap");
                    194:        if (ip == 0)
                    195:                return (0);
                    196: 
                    197:        /*
                    198:         * addresses NADDR-3, NADDR-2, and NADDR-1
                    199:         * have single, double, triple indirect blocks.
                    200:         * the first step is to determine
                    201:         * how many levels of indirection.
                    202:         */
                    203:        sh = 0;
                    204:        nb = 1;
                    205:        bn -= NADDR-3;
                    206:        for (j = 3; j > 0; j--) {
                    207:                sh += NSHIFT(dev);
                    208:                nb <<= NSHIFT(dev);
                    209:                if(bn < nb)
                    210:                        break;
                    211:                bn -= nb;
                    212:        }
                    213:        if (j == 0)
                    214:                goto noblk;
                    215: 
                    216:        /*
                    217:         * fetch the address from the inode
                    218:         */
                    219:        nb = ip->i_un.i_addr[NADDR-j];
                    220: 
                    221:        /*
                    222:         * fetch through the indirect blocks
                    223:         */
                    224:        for (;;) {
                    225:                if (nb == 0)
                    226:                        return (0);
                    227:                bp = bread(dev, nb);
                    228:                if (bp->b_flags & B_ERROR) {
                    229:                        brelse(bp);
                    230:                        goto noblk;
                    231:                }
                    232:                if (j == 3)
                    233:                        break;
                    234:                j++;
                    235:                sh -= NSHIFT(dev);
                    236:                i = (bn>>sh) & NMASK(dev);
                    237:                nb = bp->b_un.b_daddr[i];
                    238:                brelse(bp);
                    239:                if (nb == 0)
                    240:                        goto noblk;
                    241:        }
                    242:        return (bp);
                    243: 
                    244: noblk:
                    245:        return ((struct buf *)0);
                    246: }
                    247: 
                    248: getmemc(addr)
                    249:        caddr_t addr;
                    250: {
                    251:        register int c;
                    252:        struct pte savemap;
                    253: 
                    254:        savemap = mmap[0];
                    255:        *(int *)mmap = PG_V | PG_KR | btop(addr);
                    256:        mtpr(TBIS, vmmap);
                    257:        c = *(char *)&vmmap[(int)addr & PGOFSET];
                    258:        mmap[0] = savemap;
                    259:        mtpr(TBIS, vmmap);
                    260:        return (c & 0377);
                    261: }
                    262: 
                    263: putmemc(addr, val)
                    264:        caddr_t addr;
                    265: {
                    266:        struct pte savemap;
                    267: 
                    268:        savemap = mmap[0];
                    269:        *(int *)mmap = PG_V | PG_KW | btop(addr);
                    270:        mtpr(TBIS, vmmap);
                    271:        *(char *)&vmmap[(int)addr & PGOFSET] = val;
                    272:        mmap[0] = savemap;
                    273:        mtpr(TBIS, vmmap);
                    274: }
                    275: 
                    276: /*
                    277:  * Set a red zone in the kernel stack after the u. area.
                    278:  */
                    279: setredzone(pte, vaddr)
                    280:        register struct pte *pte;
                    281:        caddr_t vaddr;
                    282: {
                    283: 
                    284:        pte += (sizeof (struct user) + NBPG - 1) / NBPG;
                    285:        *(int *)pte &= ~PG_PROT;
                    286:        *(int *)pte |= PG_URKR;
                    287:        if (vaddr)
                    288:                mtpr(TBIS, vaddr + sizeof (struct user));
                    289: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.