示例#1
0
/*-------------------------------------------------------------------------
 * free_frm - free a frame 
 *-------------------------------------------------------------------------
 */
SYSCALL free_frm(int i, int pid) {
    STATWORD ps;
    disable(ps);
    int k = NFRAMES;
    if (frm_tab[i].fr_refcnt <= 0) {
        if (frm_tab[i].fr_type == FR_PAGE) {
            reset_page_tab(frm_tab[i].fr_vpno[pid]);
            init_frm(i);
        } else if (frm_tab[i].fr_type == FR_TBL) {
            pd_t *ptr = (pd_t*) (proctab[pid].pdbr);
            while (k > 0) {
                if (ptr->pd_base == (i + FRAME0)) {

                    init_page_dir(ptr);
                    ptr->pd_pres = 0;
                    break;
                }
                ptr++;
                k--;
            }
            init_frm(i);

        }

    } else {
        if (frm_tab[i].fr_type == FR_PAGE) {

            reset_page_tab(frm_tab[i].fr_vpno[pid]);
            frm_tab[i].fr_vpno[pid] = 0;
        }
    }

    restore(ps);
    return OK;
}
示例#2
0
/*-------------------------------------------------------------------------
 * get_frm - get a free frame according page replacement policy
 *-------------------------------------------------------------------------
 */
SYSCALL get_frm(int* avail) {
    int i, j;
    STATWORD ps;
    disable(ps);
    for (i = 0; i < NFRAMES; i++) {
        if (frm_tab[i].fr_status == FRM_UNMAPPED) {
            init_frm(i);
            *avail = i;
            frm_tab[i].fr_status = FRM_MAPPED;
            //kprintf("get_frm returned %d\n",*avail);
            break;
        }
    }
    if (i == NFRAMES) {
        //  kprintf("Ran out of free frames\n");
        //indicates that we ran out of free frames. Implement page replacement policy and return a new frame as per the page replacement policy
        if (page_replace_policy == LRU) {
            *avail = next_frame();
            //kprintf("get_frm returned %d\n",*avail);
        } else {
            *avail = getframe_fifoqueue();
        }
        if (check_update_bs(*avail, frm_tab[*avail].fr_curr_bs, currpid) == OK) {
            frm_tab[*avail].fr_refcnt--;
            for (j = NPROC - 1; j > 0; j--) {
                if (frm_tab[*avail].fr_vpno[j] > 0 && frm_tab[*avail].fr_type == FR_PAGE) {
                    //kprintf("fr_vpno[%d] = 0x%x\n",j,frm_tab[*avail].fr_vpno[j]);
                    free_frm(*avail, j);
                }
            }

            //kprintf("ran out of free frames\n");
        }
        frm_tab[*avail].fr_status = FRM_MAPPED;
    }
    //kprintf("get_frm returned %d\n",*avail);
    frm_tab[*avail].fr_pid = currpid;
    restore(ps);
    //kprintf("To be implemented!\n");
    return OK;
}
示例#3
0
文件: pfint.c 项目: dichen001/CSC501
SYSCALL pfint()
{
  	unsigned long cr2,physical_addr;
  	virt_addr_t * vaddr;
    int vp,s,o,avail,*store,*pageth;
  	unsigned int p,q,pt;
    pd_t *pd;
    pt_t *new_pt;
    STATWORD ps;
	// Disable interrupts
    disable(ps);
    if(GDB)
      kprintf("\n*************pfint is running!************\n");
  // Get the faulted address. The processor loads the CR2 register
  // with the 32-bit address that generated the exception.
  /* 1. Get the faulted address. */
    cr2 = read_cr2();
    vaddr = (virt_addr_t *)(&cr2); 
    if(GDB)
      kprintf("&cr2=%x, cr2=%x, &vaddr=%x, vaddr=%x\n",&cr2,cr2,&vaddr,vaddr);
  /* 2. Let 'vp' be the virtual page number of the page containing of the faulted address */
    vp = a2pno(cr2);
    if(GDB)
      kprintf("vp=%d,\n",vp);
  /* 3. Let pd point to the current page directory. */
    pd = proctab[currpid].pdbr;
    if(GDB)
      kprintf("pd=%x,\n",pd);
  /* 4. Check that a is a legal address (i.e., it has been mapped). 
     If it is not, print an error message and kill the process. */  
    pageth = getmem( sizeof(int *) );
    store = getmem( sizeof(int *) );
    if( SYSERR == bsm_lookup(currpid, vp, store, pageth)){
      kprintf("ERROR: This virtual address hasn't been mapped!\n");
      kill(currpid);
    }
  /* 5. Let p be the upper ten bits of a. [p represents page dirctory offset] */
  /* 6. Let q be the bits [21:12] of a. [p represents page table offset.]
  /* 7.1 Let pt point to the pth page table.*/
    p = vaddr->pd_offset;
    q = vaddr->pt_offset;
    pt = vaddr->pg_offset;
    if(GDB)
      kprintf("p=%d,q=%d,pt=%d\n",p,q,pt);
  /* 7.2  If the pth page table does not exist obtain a frame for it and initialize it. */
    if(pd[p].pd_pres != 1){
      if(GDB)
        kprintf("**obtain a frame for the new page table. \n");
      avail = get_frm();  //get the id of a new frame from frm_tab[];
      if (avail == -1) {
            if(GDB)
              kprintf("Could not create page table!\n");
            restore(ps);
            return SYSERR;
      }
      //initialize frame[avail], update the process_id and frame_type of this frame.
      init_frm(avail, currpid, FR_TBL);
      frm_tab[avail].fr_upper_t = pa2frid((unsigned long) pd);
      if(GDB)
        kprintf("upper page table @frame[%d]  pd=%x, a2pno(pd)=%d\n",frm_tab[avail].fr_upper_t, pd, a2pno((unsigned long) pd));
      new_pt = frid2pa(avail);
      init_pt(new_pt);
      //update this page_table_entry in the page_directory.
      pd[p].pd_pres = 1;
      pd[p].pd_write = 1;
      pd[p].pd_user = 0; // not sure about the usage;
      pd[p].pd_pwt = 0;
      pd[p].pd_pcd = 0;
      pd[p].pd_acc = 0;
      pd[p].pd_mbz = 0;
      pd[p].pd_fmb = 0;
      pd[p].pd_global = 0;
      pd[p].pd_avail = 0; // not in use right now.
      pd[p].pd_base = a2pno((unsigned long) new_pt);  /* location of page table */
      if(GDB)
        kprintf("New page_table(%x)@frame[%d] updated in page_directory[%d]@(frame[%d])\n",
        new_pt, avail, p, frm_tab[avail].fr_upper_t);
      if(GDB)
        kprintf("q=%d, new_pt[q]=%x, new_pt=%x, pd[p].pd_base=%d\n",
        q, new_pt[q], new_pt, pd[p].pd_base);
    }
    //if the page table has already existed, just need to refcnt++;
    else
    {
      int avail = pd[p].pd_base -1024;
      frm_tab[avail].fr_refcnt++;
      if(GDB)
        kprintf("frm_tab[%d].fr_refcnt = %d, frame_type: %d\n",avail, frm_tab[avail].fr_refcnt, frm_tab[avail].fr_type);
    }
/* 8.1 Using the backing store map, find the store s and page offset o which correspond to vp. */
    //already saved in 'store' and 'pageth'
    s = *store;
    o = *pageth;
/* 8.2 In the inverted page table increment the reference count of the frame which holds pt. 
   This indicates that one more of pt's entries is marked "present." */
    avail = find_frm(currpid,vp);
    if (avail == -1)
    {
      if(GDB)
        kprintf("allocating a page for the page fault\n");

      avail = get_frm();
      if(avail == -1)
      {
        if(GDB)
          kprintf("ATTENTION! Frames full. ###Replacement NEEDED!###\n");
        int frame_number = proctab[currpid].nframes-1;
        int frame_id = proc_frames[currpid][0];
        //update_proc_frames(pid,frame_number);
        int i;
        for (i = 0; i+1 < frame_number; ++i)
        {
          proc_frames[currpid][i] = proc_frames[currpid][i+1];
        }
        proctab[currpid].nframes = frame_number;

        int pid = frm_tab[frame_id].fr_pid;
        int upper_id = frm_tab[frame_id].fr_upper_t;    
        vp = frm_tab[frame_id].fr_vpno;
        if(GDB)
          kprintf("currpid=%d, frame[%d].pid=%d .vpno=%d, upper_frame[%d].ref=%d\n",currpid,frame_id,pid,vp,upper_id,frm_tab[upper_id].fr_refcnt);
        p = vp>>10;
        q = vp &0x003ff;        
        new_pt = vp2pa(pd[p].pd_base);
        new_pt[q].pt_pres  = 0;
        new_pt[q].pt_write = 1;
        new_pt[q].pt_base  = 0;
        if(GDB)
          kprintf("pd_offset=%d, pt_offset=%d, pt_dirty=%d\n",p,q,new_pt[q].pt_dirty);
        if(new_pt[q].pt_dirty == 1)
        {
          //write back and 
          pageth = getmem( sizeof(int *) );
          store = getmem( sizeof(int *) );
          if( SYSERR == bsm_lookup(currpid, vp, store, pageth)){
            kprintf("ERROR: This virtual address hasn't been mapped!\n");
            kill(currpid);
          }
          if(GDB)
            kprintf("maping found: {pid: %d, vpno: %d, store: %d, pageth: %d}\n",currpid,vp,*store,*pageth);
          write_bs((char *)new_pt, *store, *pageth);
        }
        init_pt(new_pt);
        reset_frm(frame_id);

        frm_tab[upper_id].fr_refcnt -= 2; //it is 2, not 1.
        if(frm_tab[upper_id].fr_refcnt <= 0){
          //mark the appropriate entry in pd as being not present, and free pt.
        }

        //invalidate the TLB entry for the page vp using the invlpg instruction
        if(pid == currpid) {
          set_PDBR(currpid);
        }
      }
      else
      {
        init_frm(avail, currpid, FR_PAGE);
        frm_tab[avail].fr_upper_t = pd[p].pd_base-FRAME0;
        if(GDB)
          kprintf("upper page table @frame[%d]\n",frm_tab[avail].fr_upper_t);
        frm_tab[avail].fr_vpno = vp;
        

        int counter =  proctab[currpid].nframes;      
        proc_frames[currpid][counter] = frm_tab[avail].fr_id;
        proctab[currpid].nframes++;
        if(GDB)
          kprintf("proc_frames[%d][%d] = frame[%d]\n",currpid,counter,avail);


        // Add this frame to head of the frame list within the bs of this process
        //(frm_tab[avail].bs_next)->fr_vpno
        //, proctab[currpid].bsmap[s].frames->bs_next
        if(GDB)
          kprintf("&frm_tab[avail].bs_next = %x\n",frm_tab[avail].bs_next, &frm_tab[avail].bs_next);
        if(GDB)
          kprintf("proctab[%d].bsmap[%d].frames = %x, ->vpno=%d, ->bs_next=%x\n",currpid, s, proctab[currpid].bsmap[s].frames, proctab[currpid].bsmap[s].frames->fr_vpno, proctab[currpid].bsmap[s].frames->bs_next);
        frm_tab[avail].bs_next = getmem(sizeof(fr_map_t *));
        frm_tab[avail].bs_next =  proctab[currpid].bsmap[s].frames;
        proctab[currpid].bsmap[s].frames = &frm_tab[avail];
        fr_map_t *frame = proctab[currpid].bsmap[s].frames;
        int i = frame->fr_vpno;
        if(GDB)
          kprintf("i = %d\n",i);
        if(GDB)
          kprintf("~~~frame[%d] linked to frame[%d]\n", avail, frame->bs_next==NULL?-1:frame->bs_next->fr_id);
        if(GDB)
          kprintf("frame[%d].bs_next = %x, &**=%x\n",avail,frm_tab[avail].bs_next, &frm_tab[avail].bs_next);
        if(GDB)
          kprintf("proctab[%d].bsmap[%d].frames = %x, ->vpno=%d, ->bs_next=%x\n",currpid, s, proctab[currpid].bsmap[s].frames, proctab[currpid].bsmap[s].frames->fr_vpno, proctab[currpid].bsmap[s].frames->bs_next);

        
        if(GDB)
          kprintf("Mapping frame[%d](ppno[%d]) to {pid[%d], vpno[%d]} -> {bs[%d],offset:%d}\n",
          avail,frid2vpno(avail),currpid,vp,s,o);

        physical_addr = frid2pa(avail);
        read_bs(physical_addr,s,o);
        if(GDB)
          kprintf("copied from bs[%d]:offset[%d] to vp[%d]@(%x)\n",s,o,vp,vp2pa(vp));
      }
    }
示例#4
0
/*------------------------------------------------------------------------
 *  sysinit  --  initialize all Xinu data structeres and devices
 *------------------------------------------------------------------------
 */
LOCAL
sysinit()
{
	static	long	currsp;
	int	i,j;
	struct	pentry	*pptr;
	struct	sentry	*sptr;
	struct	mblock	*mptr;
	SYSCALL pfintr();

	

	numproc = 0;			/* initialize system variables */
	nextproc = NPROC-1;
	nextsem = NSEM-1;
	nextqueue = NPROC;		/* q[0..NPROC-1] are processes */

	/* initialize free memory list */
	/* PC version has to pre-allocate 640K-1024K "hole" */
	if (maxaddr+1 > HOLESTART) {
		memlist.mnext = mptr = (struct mblock *) roundmb(&end);
		mptr->mnext = (struct mblock *)HOLEEND;
		mptr->mlen = (int) truncew(((unsigned) HOLESTART -
	     		 (unsigned)&end));
        mptr->mlen -= 4;

		mptr = (struct mblock *) HOLEEND;
		mptr->mnext = 0;
		mptr->mlen = (int) truncew((unsigned)maxaddr - HOLEEND -
	      		NULLSTK);
/*
		mptr->mlen = (int) truncew((unsigned)maxaddr - (4096 - 1024 ) *  4096 - HOLEEND - NULLSTK);
*/
	} else {
		/* initialize free memory list */
		memlist.mnext = mptr = (struct mblock *) roundmb(&end);
		mptr->mnext = 0;
		mptr->mlen = (int) truncew((unsigned)maxaddr - (int)&end -
			NULLSTK);
	}
	

	for (i=0 ; i<NPROC ; i++)	/* initialize process table */
		proctab[i].pstate = PRFREE;	

#ifdef	MEMMARK
	_mkinit();			/* initialize memory marking */
#endif

#ifdef	RTCLOCK
	clkinit();			/* initialize r.t.clock	*/
#endif

	mon_init();     /* init monitor */

#ifdef NDEVS
	for (i=0 ; i<NDEVS ; i++ ) {	    
	    init_dev(i);
	}
#endif

	pptr = &proctab[NULLPROC];	/* initialize null process entry */
	pptr->pstate = PRCURR;
	for (j=0; j<7; j++)
		pptr->pname[j] = "prnull"[j];
	pptr->plimit = (WORD)(maxaddr + 1) - NULLSTK;
	pptr->pbase = (WORD) maxaddr - 3;
/*
	pptr->plimit = (WORD)(maxaddr + 1) - NULLSTK - (4096 - 1024 )*4096;
	pptr->pbase = (WORD) maxaddr - 3 - (4096-1024)*4096;
*/
	pptr->pesp = pptr->pbase-4;	/* for stkchk; rewritten before used */
	*( (int *)pptr->pbase ) = MAGIC;
	pptr->paddr = (WORD) nulluser;
	pptr->pargs = 0;
	pptr->pprio = 0;
	currpid = NULLPROC;

	for (i=0 ; i<NSEM ; i++) {	/* initialize semaphores */
		(sptr = &semaph[i])->sstate = SFREE;
		sptr->sqtail = 1 + (sptr->sqhead = newqueue());
	}

	rdytail = 1 + (rdyhead=newqueue());/* initialize ready list */

	//OS proj 3 modify
	//OS proj 3 modify
	init_bsm(); //initialize 16 Backing stores
	init_frm(); //initialize 1024 frames
	set_evec(14,pfintr);

	return(OK);
}
示例#5
0
/*------------------------------------------------------------------------
 *  nulluser  -- initialize system and become the null process (id==0)
 *------------------------------------------------------------------------
 */
nulluser()				/* babysit CPU when no one is home */
{
        int userpid;
	unsigned long temp;

	console_dev = SERIAL0;		/* set console to COM0 */

	initevec();

	kprintf("system running up!\n");
	sysinit();

	enable();		/* enable interrupts */

	sprintf(vers, "PC Xinu %s", VERSION);
	kprintf("\n\n%s\n", vers);
	if (reboot++ < 1)
		kprintf("\n");
	else
		kprintf("   (reboot %d)\n", reboot);


	kprintf("%d bytes real mem\n",
		(unsigned long) maxaddr+1);
#ifdef DETAIL	
	kprintf("    %d", (unsigned long) 0);
	kprintf(" to %d\n", (unsigned long) (maxaddr) );
#endif	

	kprintf("%d bytes Xinu code\n",
		(unsigned long) ((unsigned long) &end - (unsigned long) start));
#ifdef DETAIL	
	kprintf("    %d", (unsigned long) start);
	kprintf(" to %d\n", (unsigned long) &end );
#endif

#ifdef DETAIL	
	kprintf("%d bytes user stack/heap space\n",
		(unsigned long) ((unsigned long) maxaddr - (unsigned long) &end));
	kprintf("    %d", (unsigned long) &end);
	kprintf(" to %d\n", (unsigned long) maxaddr);
#endif	
	
	kprintf("clock %sabled\n", clkruns == 1?"en":"dis");
/*
initialize_pagedirectory();
initialize_pagetable();
get_frame(1,FR_DIR,0);
get_frame(1,FR_TBL,0);
get_frame(1,FR_TBL,0);
get_frame(1,FR_TBL,0);
get_frame(1,FR_TBL,0);
*/

	init_frm();
	init_bsm();

	temp = create_ps() ;
	write_cr3(0x400000);
	set_evec(14,pfintr);
    
	proctab[currpid].pdbr = temp;
//	pageq.next= &pageq;	//Always points to head
	myheadq = NULL;		//actual pointer used by page replacement policyi
	currq = NULL;
	pcurrq = NULL;
    

    /* create a process to execute the user's main program */
	userpid = create(main,INITSTK,INITPRIO,INITNAME,INITARGS);
	enable_paging();
	resume(userpid);

	while (TRUE)
		/* empty */;
}