コード例 #1
0
int32_t halt(uint8_t status)
{
	// uint32_t flags;
	// cli_and_save(flags);
	pcb_t* parent_process = curr_process->parent_process;

	if(curr_process == curr_process->parent_process)
	{
		// We need to actually handle this case
		printf("YOU CAN CHECK OUT, BUT YOU CAN NEVER LEAVE...\n");
		while(1); 
		uint8_t fexec[33] = "shell";

		curr_process->process_id = 0;
		execute(fexec);
		//sti();	
		return -1;	
	}
	
	else
	{
		// saving return value
		retval = (uint32_t)status;

		//modify open_processes to indicate that current process is not running anymore

		open_processes ^= (MASK >> curr_process->process_id);

		//clear parent process' child flag
		parent_process->child_flag = 0;

		// restore TSS
		tss.esp0 = parent_process->k_sp;
		//tss.ss0 = curr_process->ss0;

		//restore paging
		set_PDBR(parent_process->PD_ptr);

		uint32_t p_sp = parent_process->k_sp;
		uint32_t p_bp = parent_process->k_bp;

		asm volatile("movl %0, %%esp"::"g"(p_sp):"memory"); 
		asm volatile("movl %0, %%ebp"::"g"(p_bp):"memory");
		
		uint32_t halting_task = (next_available - 1) % 7;
		task_queue[halting_task] = -1;
		next_available = halting_task;

		//context_switch(parent_process->process_id);
		
		curr_process = curr_process->parent_process;
		//go back to parent's instruction pointer
		asm volatile("jmp ret_halt");	
		
	}
	 
	return 183;
}
コード例 #2
0
/*
 * PDE_t* task_mem_init(uint32_t PID)
 * 	 Description: Initializes the PD for a new process
 *   Inputs: PID - The process ID of the new process
 *   Return Value: A pointer to the new page directory
 */
PDE_t* task_mem_init(uint32_t PID)
{
	if(PID < 0 || PID > 6)
		return NULL;

	cur_PD = PD[PID];
	map_4MB_page(PGRM_IMG, PGRM_PAGE[PID], 1, 1);

	//test_paging();

	set_PDBR(cur_PD);

	return cur_PD;
}
コード例 #3
0
void context_switch(int new_pid)
{
	if(new_pid == -1)
	{
		send_eoi(0);
		return;
	}

	uint32_t process_bp = _8MB - (_8KB)*(new_pid) - 4;
	pcb_t* new_process = (pcb_t *) (process_bp & 0xFFFFE000);

	set_PDBR(new_process->PD_ptr);

	tss.esp0 = new_process->k_sp;
	uint32_t p_sp = new_process->k_sp;
	uint32_t p_bp = new_process->k_bp;

	process_buf = new_process->file_fds[1].file_pos;

	process_id = new_pid;
	asm volatile("movl %%esp, %0":"=g"(curr_process->k_sp));
	asm volatile("movl %%ebp, %0":"=g"(curr_process->k_bp));
	curr_process = new_process;

	asm volatile("movl %0, %%esp"::"g"(p_sp):"memory");
	asm volatile("movl %0, %%ebp"::"g"(p_bp):"memory");
	// uint32_t process_bp = _8MB - (_8KB)*(new_pid) - 4;
	// pcb_t* new_process = (pcb_t *) (process_bp & 0xFFFFE000);


	// set_PDBR(curr_process->PD_ptr);

	// tss.esp0 = new_process->esp0;
	// tss.ss0 = new_process->ss0;


	send_eoi(0);
	// sti();
	// return;

}
コード例 #4
0
/*
 * void init_PD()
 * 	 Description: Sets all entries in the page directory
 *   Inputs: none
 *   Return Value: none
 */
void init_PD()
{
	// Fill the page directory with blank entries
	PDE_default.present = 0;
	PDE_default.read_write = 0;
	PDE_default.user_super = 0;
	PDE_default.write_through = 0;
	PDE_default.cache_disabled = 0;
	PDE_default.accessed = 0;
	PDE_default.reserved = 0;
	PDE_default.page_size = 0;
	PDE_default.global = 0;
	PDE_default.avail = 0;
	PDE_default.page_table_base = 0;

	int i;
	for(i = 0; i < NUM_PDE; i++)
	{
		PD[0][i] = PDE_default;
	}

	// int i, j;
	// for(i = 0; i < NUM_PD; i++)
	// {
	// 	for(j = 0; j < NUM_PDE; j++)
	// 	{
	// 		PD[i][j] = PDE_default;
	// 	}
	// }

 	cur_PD = PD[0];

	// Set up video memory PDE
	int video_offset;
	video_offset = get_PDE_offset(VIDEO_MEM);

	PDE_t PDE_video;
	PDE_video = PDE_default;
	PDE_video.global = 1;
	PDE_video.read_write = 1;
	SET_PDE_4KB_PT(PDE_video, PT[0]);
	cur_PD[video_offset] = PDE_video;

	// Set up kernel memory PDE
	int kernel_offset;
	kernel_offset = get_PDE_offset(KERNEL_MEM);

	PDE_t PDE_kernel;
	PDE_kernel = PDE_default;
	PDE_kernel.global = 1;
	PDE_kernel.read_write = 1;
	SET_PDE_4MB_PAGE(PDE_kernel, KERNEL_MEM);
	cur_PD[kernel_offset] = PDE_kernel;

	// Pass the address of the page directory into the PBDR
 	set_PDBR(cur_PD);

 	// Copy all of PD[0] into all other PDs
 	int j, k;
 	for(j = 1; j < NUM_PD; j++)
 	{
		for(k = 0; k < NUM_PDE; k++)
		{
			PD[j][k] = PD[0][k];
		}
	}

}
コード例 #5
0
ファイル: resched.c プロジェクト: michalt25/CSC501_PA3
/*------------------------------------------------------------------------
 * resched  --  reschedule processor to highest priority ready process
 *
 * Notes:   Upon entry, currpid gives current process id.
 *      Proctab[currpid].pstate gives correct NEXT state for
 *          current process if other than PRREADY.
 *------------------------------------------------------------------------
 */
int resched()
{
    STATWORD        PS;
    register struct pentry  *optr;  /* pointer to old process entry */
    register struct pentry  *nptr;  /* pointer to new process entry */

    disable(PS);
    /* no switch needed if current process priority higher than next*/

    if ( ( (optr= &proctab[currpid])->pstate == PRCURR) &&
       (lastkey(rdytail)<optr->pprio)) {
        restore(PS);
        return(OK);
    }
    
#ifdef STKCHK
    /* make sure current stack has room for ctsw */
    asm("movl   %esp, currSP");
    if (currSP - optr->plimit < 48) {
        kprintf("Bad SP current process, pid=%d (%s), lim=0x%lx, currently 0x%lx\n",
            currpid, optr->pname,
            (unsigned long) optr->plimit,
            (unsigned long) currSP);
        panic("current process stack overflow");
    }
#endif  

    /* force context switch */

    if (optr->pstate == PRCURR) {
        optr->pstate = PRREADY;
        insert(currpid,rdyhead,optr->pprio);
    }

    /* remove highest priority process at end of ready list */

    nptr = &proctab[ (currpid = getlast(rdytail)) ];
    nptr->pstate = PRCURR;      /* mark it currently running    */
#ifdef notdef
#ifdef  STKCHK
    if ( *( (int *)nptr->pbase  ) != MAGIC ) {
        kprintf("Bad magic pid=%d value=0x%lx, at 0x%lx\n",
            currpid,
            (unsigned long) *( (int *)nptr->pbase ),
            (unsigned long) nptr->pbase);
        panic("stack corrupted");
    }
    /*
     * need ~16 longs of stack space below, so include that in check
     *  below.
     */
    if (nptr->pesp - nptr->plimit < 48) {
        kprintf("Bad SP pid=%d (%s), lim=0x%lx will be 0x%lx\n",
            currpid, nptr->pname,
            (unsigned long) nptr->plimit,
            (unsigned long) nptr->pesp);
        panic("stack overflow");
    }
#endif  /* STKCHK */
#endif  /* notdef */
#ifdef  RTCLOCK
    preempt = QUANTUM;      /* reset preemption counter */
#endif
#ifdef  DEBUG
    PrintSaved(nptr);
#endif

    // When performing a context switch between processes we must also
    // switch between memory spaces. This is accomplished by adjusting
    // the PDBR register with every context switch. 
    //
    // 5 - Context switch
    //      - every process has separate page directory
    //      - before ctxsw() load CR3 with the process' PDBR
    set_PDBR(VA2VPNO(nptr->pd));
#if DUSTYDEBUG
    kprintf("switching to process %d\n", (nptr - proctab));
#endif

    ctxsw(&optr->pesp, optr->pirmask, &nptr->pesp, nptr->pirmask);

#ifdef  DEBUG
    PrintSaved(nptr);
#endif
    
    /* The OLD process returns here when resumed. */
    restore(PS);
    return OK;
}
コード例 #6
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));
      }
    }