Пример #1
0
void
handle_mmu_bus_fault(struct pt_regs *regs)
{
	int cause;
	int select;
#ifdef DEBUG
	int index;
	int page_id;
	int acc, inv;
#endif
	pgd_t* pgd = (pgd_t*)per_cpu(current_pgd, smp_processor_id());
	pmd_t *pmd;
	pte_t pte;
	int miss, we, writeac;
	unsigned long address;
	unsigned long flags;

	cause = *R_MMU_CAUSE;

	address = cause & PAGE_MASK; /* get faulting address */
	select = *R_TLB_SELECT;

#ifdef DEBUG
	page_id = IO_EXTRACT(R_MMU_CAUSE,  page_id,   cause);
	acc     = IO_EXTRACT(R_MMU_CAUSE,  acc_excp,  cause);
	inv     = IO_EXTRACT(R_MMU_CAUSE,  inv_excp,  cause);
	index   = IO_EXTRACT(R_TLB_SELECT, index,     select);
#endif
	miss    = IO_EXTRACT(R_MMU_CAUSE,  miss_excp, cause);
	we      = IO_EXTRACT(R_MMU_CAUSE,  we_excp,   cause);
	writeac = IO_EXTRACT(R_MMU_CAUSE,  wr_rd,     cause);

	D(printk("bus_fault from IRP 0x%lx: addr 0x%lx, miss %d, inv %d, we %d, acc %d, dx %d pid %d\n",
		 regs->irp, address, miss, inv, we, acc, index, page_id));

	/* leave it to the MM system fault handler */
	if (miss)
		do_page_fault(address, regs, 0, writeac);
        else
		do_page_fault(address, regs, 1, we);

        /* Reload TLB with new entry to avoid an extra miss exception.
	 * do_page_fault may have flushed the TLB so we have to restore
	 * the MMU registers.
	 */
	local_save_flags(flags);
	local_irq_disable();
	pmd = (pmd_t *)(pgd + pgd_index(address));
	if (pmd_none(*pmd))
		goto exit;
	pte = *pte_offset_kernel(pmd, address);
	if (!pte_present(pte))
		goto exit;
	*R_TLB_SELECT = select;
	*R_TLB_HI = cause;
	*R_TLB_LO = pte_val(pte);
exit:
	local_irq_restore(flags);
}
Пример #2
0
int main()
{
#ifdef CONFIG_ARM_LPAE
  do_page_fault();
#else
  do_page_fault();
  do_sect_fault();
#endif
  return 0;
}
Пример #3
0
void
handle_mmu_bus_fault(struct pt_regs *regs)
{
	int cause;
	int select;
#ifdef DEBUG
	int index;
	int page_id;
	int acc, inv;
#endif
	pgd_t* pgd = (pgd_t*)per_cpu(current_pgd, smp_processor_id());
	pmd_t *pmd;
	pte_t pte;
	int miss, we, writeac;
	unsigned long address;
	unsigned long flags;

	cause = *R_MMU_CAUSE;

	address = cause & PAGE_MASK; 
	select = *R_TLB_SELECT;

#ifdef DEBUG
	page_id = IO_EXTRACT(R_MMU_CAUSE,  page_id,   cause);
	acc     = IO_EXTRACT(R_MMU_CAUSE,  acc_excp,  cause);
	inv     = IO_EXTRACT(R_MMU_CAUSE,  inv_excp,  cause);
	index   = IO_EXTRACT(R_TLB_SELECT, index,     select);
#endif
	miss    = IO_EXTRACT(R_MMU_CAUSE,  miss_excp, cause);
	we      = IO_EXTRACT(R_MMU_CAUSE,  we_excp,   cause);
	writeac = IO_EXTRACT(R_MMU_CAUSE,  wr_rd,     cause);

	D(printk("bus_fault from IRP 0x%lx: addr 0x%lx, miss %d, inv %d, we %d, acc %d, dx %d pid %d\n",
		 regs->irp, address, miss, inv, we, acc, index, page_id));

	
	if (miss)
		do_page_fault(address, regs, 0, writeac);
        else
		do_page_fault(address, regs, 1, we);

	local_irq_save(flags);
	pmd = (pmd_t *)(pgd + pgd_index(address));
	if (pmd_none(*pmd))
		goto exit;
	pte = *pte_offset_kernel(pmd, address);
	if (!pte_present(pte))
		goto exit;
	*R_TLB_SELECT = select;
	*R_TLB_HI = cause;
	*R_TLB_LO = pte_val(pte);
exit:
	local_irq_restore(flags);
}
Пример #4
0
main()
{
    pthread_t pt;
    int ret;

    /* allocate a shared area for concurrent page fault / madvise() */
    ret = posix_memalign(&mem_addr, HUGE_PAGE_SIZE, MEM_ALLOC_SIZE);
    if (ret) {
        printf("posix_memalign: ret=%d\n", ret);
        _exit(1);
    }

    /* start a separate thread that does madvise() on the shared area */
    ret = pthread_create(&pt, NULL, do_madvise, NULL);
    if (ret) {
        printf("pthread_create: ret=%d\n", ret);
        _exit(1);
    }

    /* force page faults on the shared area in parallel to madvise() */
    do_page_fault();

    /* allocate and initialize a huge area to force page reclamation */
    do_reclaim();
}
asmlinkage void xtlb_tlbs_debug(struct pt_regs *regs)
{
	unsigned long addr;

	addr = regs->cp0_badvaddr;
	do_page_fault(regs, 1, addr);
}
Пример #6
0
asmlinkage void do_tlbs(struct pt_regs *regs)
{
// 	printk("do_tlbs status %p, cause %p, epc %p,bd %p.\n", 
// 		regs->cp0_status,
// 		regs->cp0_cause,
// 		regs->cp0_epc,
// 		read_c0_badvaddr());
	do_page_fault(regs, 1, read_c0_badvaddr());
}
/*
 * First Level Translation Fault Handler
 *
 * We enter here because the first level page table doesn't contain a valid
 * entry for the address.
 *
 * If the address is in kernel space (>= TASK_SIZE), then we are probably
 * faulting in the vmalloc() area.
 *
 * If the init_task's first level page tables contains the relevant entry, we
 * copy the it to this task.  If not, we send the process a signal, fixup the
 * exception, or oops the kernel.
 *
 * NOTE! We MUST NOT take any locks for this case. We may be in an interrupt
 * or a critical region, and should only copy the information from the master
 * page table, nothing more.
 */
static int __kprobes do_translation_fault(unsigned long addr,
					  unsigned int esr,
					  struct pt_regs *regs)
{
	if (addr < TASK_SIZE)
		return do_page_fault(addr, esr, regs);

	do_bad_area(addr, esr, regs);
	return 0;
}
/*
 * First Level Translation Fault Handler
 *
 * We enter here because the first level page table doesn't contain
 * a valid entry for the address.
 *
 * If the address is in kernel space (>= TASK_SIZE), then we are
 * probably faulting in the vmalloc() area.
 *
 * If the init_task's first level page tables contains the relevant
 * entry, we copy the it to this task.  If not, we send the process
 * a signal, fixup the exception, or oops the kernel.
 *
 * NOTE! We MUST NOT take any locks for this case. We may be in an
 * interrupt or a critical region, and should only copy the information
 * from the master page table, nothing more.
 */
int do_translation_fault(unsigned long addr, unsigned int fsr,
			 struct pt_regs *regs)
{
	struct task_struct *tsk;
	int offset;
	pgd_t *pgd, *pgd_k;
	pmd_t *pmd, *pmd_k;

	if (addr < TASK_SIZE)
		return do_page_fault(addr, fsr, regs);

	offset = __pgd_offset(addr);

	/*
	 * FIXME: CP15 C1 is write only on ARMv3 architectures.
	 * You really need to read the value in the page table
	 * register, not a copy.
	 */
	pgd = cpu_get_pgd() + offset;
	pgd_k = init_mm.pgd + offset;

	if (pgd_none(*pgd_k))
		goto bad_area;

#if 0	/* note that we are two-level */
	if (!pgd_present(*pgd))
		set_pgd(pgd, *pgd_k);
#endif

	pmd_k = pmd_offset(pgd_k, addr);
	pmd   = pmd_offset(pgd, addr);

	if (pmd_none(*pmd_k))
		goto bad_area;

	set_pmd(pmd, *pmd_k);
	return 0;

bad_area:
	tsk = current;

	do_bad_area(tsk, tsk->active_mm, addr, fsr, regs);
	return 0;
}
Пример #9
0
/*
 * First Level Translation Fault Handler
 *
 * We enter here because the first level page table doesn't contain
 * a valid entry for the address.
 *
 * If the address is in kernel space (>= TASK_SIZE), then we are
 * probably faulting in the vmalloc() area.
 *
 * If the init_task's first level page tables contains the relevant
 * entry, we copy the it to this task.  If not, we send the process
 * a signal, fixup the exception, or oops the kernel.
 *
 * NOTE! We MUST NOT take any locks for this case. We may be in an
 * interrupt or a critical region, and should only copy the information
 * from the master page table, nothing more.
 */
int do_translation_fault(unsigned long addr, int error_code, struct pt_regs *regs)
{
	struct task_struct *tsk;
	struct mm_struct *mm;
	int offset;
	pgd_t *pgd, *pgd_k;
	pmd_t *pmd, *pmd_k;

	if (addr < TASK_SIZE)
		return do_page_fault(addr, error_code, regs);

	offset = __pgd_offset(addr);

	/*
	 * FIXME: CP15 C1 is write only on ARMv3 architectures.
	 */
	pgd = cpu_get_pgd() + offset;
	pgd_k = init_mm.pgd + offset;

	if (pgd_none(*pgd_k))
		goto bad_area;

#if 0	/* note that we are two-level */
	if (!pgd_present(*pgd))
		set_pgd(pgd, *pgd_k);
#endif

	pmd_k = pmd_offset(pgd_k, addr);
	pmd   = pmd_offset(pgd, addr);

	if (pmd_none(*pmd_k))
		goto bad_area;

	set_pmd(pmd, *pmd_k);
	return 0;

bad_area:
	tsk = current;
	mm  = tsk->active_mm;

	do_bad_area(tsk, mm, addr, error_code, regs);
	return 0;
}
Пример #10
0
Файл: mmap.c Проект: aquini/misc
int main(int argc, char *argv[])
{
	void *addr;
	size_t length;
	struct stat sb;
	struct tms tms;
	struct rusage r1, r2;
	int fd, next_opt;
	long hz, tvali, tvalf;
	double elapsed, us_time, sy_time;
	int fault_mode = PG_FAULT_NONE, mmap_mode = MMAP_MODE_NONE;
	int exit_wait = 0;
	int print_stats = 0;

	signal(SIGINT, signal_handler);
	signal(SIGTERM, signal_handler);

	prg_name = argv[0];
	do {
		next_opt = getopt_long(argc, argv, short_opts, long_opts, NULL);
		switch (next_opt) {
		case 'p':
			fault_mode = PG_FAULT_NONE;
			if (optarg) {
			        if (strcmp(optarg, "write") == 0)
					fault_mode = PG_FAULT_WRITE;

			        if (strcmp(optarg, "read") == 0)
					fault_mode = PG_FAULT_READ;

			        if (strcmp(optarg, "loop") == 0)
					fault_mode = PG_FAULT_RWLOOP;
			}
			break;

		case 'a':
			mmap_mode = MMAP_MODE_ANON;
			length = atol(optarg) * MB;
			fd = -1;
			break;

		case 'f':
			mmap_mode = MMAP_MODE_FILE;
			fd = open (optarg, O_RDWR);
			if (fd == -1) {
				perror ("open");
				return 1;
			}

			if (fstat (fd, &sb) == -1) {
				perror ("fstat");
				return 1;
			}

			length = sb.st_size;
			break;

		case 's':
			print_stats = 1;
			break;

		case 'w':
			exit_wait = 1;
			break;

		case 'h':
			print_usage(stdout, 0);

		case '?':
			print_usage(stderr, 1);

		case -1:
			break;

		default:
			abort();
		}
	} while (next_opt != -1);

	if (argc == 1 || mmap_mode == MMAP_MODE_NONE)
		print_usage(stderr, 2);

	addr = do_mmap(fd, length);
	if (mmap_mode == MMAP_MODE_FILE)
		close(fd);

	if (addr == MAP_FAILED) {
		perror("mmap");
		return 1;
	}

	if (print_stats) {
		hz = sysconf(_SC_CLK_TCK);
		if (hz == -1) {
			perror("sysconf");
			return 1;
		}

		tvali = times(&tms);

		if (getrusage(RUSAGE_SELF, &r1)) {
			perror("getrusage");
			return 1;
		}
	}

	do_page_fault(addr, length, fault_mode);

	if (print_stats) {
		if (getrusage(RUSAGE_SELF, &r2)) {
			perror("getrusage");
			return 1;
		}

		tvalf = times(&tms);

		elapsed = (double) (tvalf - tvali) / hz;
		us_time = (double) tms.tms_utime / hz;
		sy_time = (double) tms.tms_stime / hz;

		fprintf(stderr, "page faults: %lu minor; %lu major\n",
			r2.ru_minflt - r1.ru_minflt,
			r2.ru_majflt - r1.ru_majflt);

		fprintf(stderr, "time (secs): %0.3lf wall; "
			"%0.3lf user; %0.3lf system\n",
			elapsed, us_time, sy_time);

		fprintf(stderr, "throughput : %0.3lf kB/s \n",
			length / KB / elapsed);
	}

	if (exit_wait)
		wait_loop();

	return 0;
}
Пример #11
0
Файл: vmm.c Проект: ZZJC1306/VMM
//已更新二级页表
void do_response()

{
	Ptr_PageTableItem ptr_pageTabIt;
	unsigned int RootPageSum, ChildPageSum,offAddr,SinglePageSum;
	unsigned int actAddr;
	/* 检查地址是否越界*/
	if (ptr_memAccReq->virAddr < 0 || ptr_memAccReq->virAddr >= VIRTUAL_MEMORY_SIZE)
	{
		do_error(ERROR_OVER_BOUNDARY);
		return;
	}
	/*检查进程编号是否符合要求*/
	if(ptr_memAccReq->processNum < 0||ptr_memAccReq->processNum >= PROCESSNUM){
		do_error(ERROR_PROCESS_NOT_FOUND);
		return;
	}
	/* 计算页号和页内偏移值 */
	SinglePageSum = PAGE_SIZE*CHILD_PAGE_SUM;
	RootPageSum = ptr_memAccReq->virAddr / SinglePageSum;
	ChildPageSum = (ptr_memAccReq->virAddr % SinglePageSum) / PAGE_SIZE;
	offAddr = ptr_memAccReq->virAddr % PAGE_SIZE;
	printf("页目录号为:%u\t,二级目录页号为:%u\t,页内偏移为:%u\n", RootPageSum,ChildPageSum, offAddr);
	/* 获取对应页表项 */
	ptr_pageTabIt = &pageTable[RootPageSum][ChildPageSum];
	/* 根据特征位决定是否产生缺页中断 */
	if (!ptr_pageTabIt->filled)
	{
		do_page_fault(ptr_pageTabIt);
	}else{
		LRU_ChangeAdd(ptr_pageTabIt->blockNum);
	}

	actAddr = ptr_pageTabIt->blockNum * PAGE_SIZE + offAddr;
	printf("实地址为%u\n", actAddr);
	if (ptr_pageTabIt->processNum != ptr_memAccReq->processNum) {
		do_error(ERROR_PROCESS_DISMATCH);
		return;
	}
	/*检查进程编号是否匹配*/
	if(ptr_memAccReq->processNum != ptr_pageTabIt->processNum){
		do_error(ERROR_PROCESS_DISMATCH);
		return;
	}
	/* 检查页面访问权限并处理访存请求 */
	switch (ptr_memAccReq->reqType)
	{
		case REQUEST_READ: //读请求
		{
			//ptr_pageTabIt->count++;
			//else 的地方已经加过了;这个count只是为了LFU代码,现在不需要了;
			if (!(ptr_pageTabIt->proType & READABLE)) //页面不可读
			{
				do_error(ERROR_READ_DENY);
				return;
			}
			/* 读取实存中的内容 */
			printf("读操作成功%02X\n", actMem[actAddr]);
			break;
		}
		case REQUEST_WRITE: //写请求
		{
			//ptr_pageTabIt->count++;
			if (!(ptr_pageTabIt->proType & WRITABLE)) //页面不可写
			{
				do_error(ERROR_WRITE_DENY);	
				return;
			}
			/* 向实存中写入请求的内容 */
			actMem[actAddr] = ptr_memAccReq->value;
			ptr_pageTabIt->edited = TRUE;			
			printf("写操作成功\n");
			break;
		}
		case REQUEST_EXECUTE: //执行请求
		{
			//ptr_pageTabIt->count++;
			if (!(ptr_pageTabIt->proType & EXECUTABLE)) //页面不可执行
			{
				do_error(ERROR_EXECUTE_DENY);
				return;
			}			
			printf("执行成功\n");
			break;
		}
		default: //非法请求类型
		{	
			do_error(ERROR_INVALID_REQUEST);
			return;
		}
	}

}
Пример #12
0
/* 响应请求 */
void do_response()
{
	Ptr_PageTableItem ptr_pageTabIt;
	Ptr_PageCatalogueItem ptr_pageCatalogueItem;
	unsigned int JGpageCatalogueNum, JGpageCatalogueOffset, pageNum, offAddr;
	unsigned int actAddr;
	
	/* 检查地址是否越界 */
	if (ptr_memAccReq->virAddr < 0 || ptr_memAccReq->virAddr >= VIRTUAL_MEMORY_SIZE)
	{
		do_error(ERROR_OVER_BOUNDARY);
		return;
	}
	
	/* 计算页号和页内偏移值 */
	//pageNum = ptr_memAccReq->virAddr / PAGE_SIZE;
	JGpageCatalogueNum = JGcalPageCatalogueNum();
	JGpageCatalogueOffset = JGcalPageCatalogueOffset();
	offAddr = ptr_memAccReq->virAddr % PAGE_SIZE;
	//printf("页号为:%u\t页内偏移为:%u\n", pageNum, offAddr);
	JGresponsePrint(JGpageCatalogueNum, JGpageCatalogueOffset, offAddr);

	/* 获取对应页表项 */
	ptr_pageCatalogueItem = &JGpageCatalogue[JGpageCatalogueNum];
	if (!ptr_pageCatalogueItem->filled)
		JGdo_page_catalogue_fault(ptr_pageCatalogueItem);
	pageNum = ptr_pageCatalogueItem->pageNum * PAGE_SIZE + JGpageCatalogueOffset;
	ptr_pageTabIt = &pageTable[pageNum];
	
	/* 根据特征位决定是否产生缺页中断 */
	if (!ptr_pageTabIt->filled)
	{
		do_page_fault(ptr_pageTabIt);
	}
	
	actAddr = ptr_pageTabIt->blockNum * PAGE_SIZE + offAddr;
	printf("实地址为:%u\n", actAddr);
	
	/* 检查页面访问权限并处理访存请求 */
	switch (ptr_memAccReq->reqType)
	{
		case REQUEST_READ: //读请求
		{
			ptr_pageTabIt->count++;
			if (!(ptr_pageTabIt->proType & READABLE)) //页面不可读
			{
				do_error(ERROR_READ_DENY);
				return;
			}
			/* 读取实存中的内容 */
			printf("读操作成功:值为%02X\n", actMem[actAddr]);
			break;
		}
		case REQUEST_WRITE: //写请求
		{
			ptr_pageTabIt->count++;
			if (!(ptr_pageTabIt->proType & WRITABLE)) //页面不可写
			{
				do_error(ERROR_WRITE_DENY);	
				return;
			}
			/* 向实存中写入请求的内容 */
			actMem[actAddr] = ptr_memAccReq->value;
			ptr_pageTabIt->edited = TRUE;			
			printf("写操作成功\n");
			break;
		}
		case REQUEST_EXECUTE: //执行请求
		{
			ptr_pageTabIt->count++;
			if (!(ptr_pageTabIt->proType & EXECUTABLE)) //页面不可执行
			{
				do_error(ERROR_EXECUTE_DENY);
				return;
			}			
			printf("执行成功\n");
			break;
		}
		default: //非法请求类型
		{	
			do_error(ERROR_INVALID_REQUEST);
			return;
		}
	}
}
Пример #13
0
/* 响应请求 */
void do_response()
{
	Ptr_PageTableItem ptr_pageTabIt;
	unsigned int pageNum1, offAddr ,pageNum2;
	unsigned int actAddr;
    int i,k;

	/* 检查地址是否越界 */
	if (ptr_memAccReq->virAddr < 0 || ptr_memAccReq->virAddr >= VIRTUAL_MEMORY_SIZE)
	{
		do_error(ERROR_OVER_BOUNDARY);
		return;
	}

	/* 计算页号和页内偏移值 */
	pageNum2 = ptr_memAccReq->virAddr / (PAGE_SIZE*PAGE_SUM1);
	pageNum1 = (ptr_memAccReq->virAddr - pageNum2*PAGE_SIZE*PAGE_SUM1 )/ PAGE_SIZE;
	offAddr = ptr_memAccReq->virAddr % PAGE_SIZE;
	printf("2级页号为:%u\t1级页号为: %u\t页内偏移为:%u\n", pageNum2 , pageNum1 , offAddr);

	/* 获取对应页表项 */
	ptr_pageTabIt = &pageTable[pageNum2][pageNum1];
	printf("请求的进程号为:%u\t页表的进程号为:%u\n",ptr_memAccReq->reqProcess,ptr_pageTabIt->processNum);
    if(ptr_pageTabIt->processNum!=ptr_memAccReq->reqProcess){
  //      printf("%u %u\n",ptr_pageTabIt->processNum,ptr_memAccReq->reqProcess);
        do_error(ERROR_VISIT_FAILED);
    }
    else{
	/* 根据特征位决定是否产生缺页中断 */
        if (!ptr_pageTabIt->filled)
        {
            do_page_fault(ptr_pageTabIt);
        }

        actAddr = ptr_pageTabIt->blockNum * PAGE_SIZE + offAddr;                         //虚实地址转换
        printf("实地址为:%u\n", actAddr);

        /* 检查页面访问权限并处理访存请求 */
        switch (ptr_memAccReq->reqType)
        {
            case REQUEST_READ: //读请求
            {
                for(k=0;k<PAGE_SUM2;k++)
                    for(i=0;i<PAGE_SUM1;i++)
                        pageTable[k][i].count=pageTable[k][i].count/10;
                ptr_pageTabIt->count=ptr_pageTabIt->count+1000000;
            //	ptr_pageTabIt->count++;
                if (!(ptr_pageTabIt->proType & READABLE)) //页面不可读
                {
                    do_error(ERROR_READ_DENY);
                    return;
                }
                /* 读取实存中的内容 */
                printf("读操作成功:值为%c\n", actMem[actAddr]);
                break;
            }
            case REQUEST_WRITE: //写请求
            {
               for(k=0;k<PAGE_SUM2;k++)
                    for(i=0;i<PAGE_SUM1;i++)
                        pageTable[k][i].count=pageTable[k][i].count/10;
                ptr_pageTabIt->count=ptr_pageTabIt->count+1000000;
            //	ptr_pageTabIt->count++;
                if (!(ptr_pageTabIt->proType & WRITABLE)) //页面不可写
                {
                    do_error(ERROR_WRITE_DENY);
                    return;
                }
                /* 向实存中写入请求的内容 */
                actMem[actAddr] = ptr_memAccReq->value;
                ptr_pageTabIt->edited = TRUE;
                printf("写操作成功\n");
                break;
            }
            case REQUEST_EXECUTE: //执行请求
            {
                for(k=0;k<PAGE_SUM2;k++)
                    for(i=0;i<PAGE_SUM1;i++)
                        pageTable[k][i].count=pageTable[k][i].count/10;
                ptr_pageTabIt->count=ptr_pageTabIt->count+1000000;
            //	ptr_pageTabIt->count++;
                if (!(ptr_pageTabIt->proType & EXECUTABLE)) //页面不可执行
                {
                    do_error(ERROR_EXECUTE_DENY);
                    return;
                }
                printf("执行成功\n");
                break;
            }
            default: //非法请求类型
            {
                do_error(ERROR_INVALID_REQUEST);
                return;
            }
        }
    }
}
Пример #14
0
void execute_protection_fault(struct pt_regs *regs)
{
	unsigned long badvadr = pt_badva(regs);

	do_page_fault(badvadr, FLT_IFETCH, regs);
}
Пример #15
0
void read_protection_fault(struct pt_regs *regs)
{
	unsigned long badvadr = pt_badva(regs);

	do_page_fault(badvadr, FLT_LOAD, regs);
}
Пример #16
0
static void trap_dispatch(struct frame *tf)
{

	switch(tf->tf_trapno) 
	{
		case T_PGFLT: 
		{	
			//print_frame(tf);
			do_page_fault(tf);
			break;
		}
		case T_GPFLT:
		{
			panic("GPFLT!\n");
			do_exit(curtask);
			break;
		}
		case T_BRKPT : 
		{
			print_frame(tf);
			panic("break point handler not implemented!\n");
			break;
		}
		case T_DIVIDE:
		{
			printk("CPU:%d USER T_DIVIDE\n",get_cpuid());
			do_exit(curtask);
		}
		case T_SYSCALL:
		{	
			tf->tf_regs.reg_eax = syscall_handler(tf); 
			break;
		}
		case IRQ_SPURIOUS: 
		{
			printk("CPU:%d Spurious interrupt on irq 7\n",get_cpuid());
			print_frame(tf);
			return;
		}
		case IRQ_TIMER : 
		{ 
			lapic_eoi();
			schedule_tick();
			break; 
		}
		case IRQ_KBD : 
		{
			irq_eoi();
			printk("CPU:%d IRQ_KBD \n",get_cpuid()); 
			inb(0x60);
			
			break;
		}
		case IRQ_SERIAL :
		{	
			panic("SERIAL handler not implemented!\n");
			break;
		}
		case IRQ_IDE0 : 
		case IRQ_IDE1 : 
		{	
			irq_eoi();
			do_hd_interrupt(tf);
			break;
		}
		case IRQ_ERROR :
		{ 
			print_frame(tf);
			panic("ERROR handler not implemented!\n");
			break;
		}
		default:
		{	
			 if (tf->tf_cs == _KERNEL_CS_) 
				panic("unhandled trap in kernel");
			 else {	
				print_frame(tf);
				return;	
			 }
			 break;
		}
	}
}
Пример #17
0
/* 响应请求 */
void do_response()
{
	Ptr_PageTableItem ptr_pageTabIt;
	unsigned int pageNum, offAddr;
/************************************************************************************/
	unsigned int firstPageNum, firstOffAddr;
/************************************************************************************/
	unsigned int actAddr;

	/* 检查地址是否越界 */
	if (ptr_memAccReq->virAddr < 0 || ptr_memAccReq->virAddr >= VIRTUAL_MEMORY_SIZE)
	{
		do_error(ERROR_OVER_BOUNDARY);
		return;
	}

	/************************************************************************************/
	printf("请求进程号: %u\n", ptr_memAccReq->proccessNum);
	/************************************************************************************/

	/* 计算页号和页内偏移值 */
	// pageNum = ptr_memAccReq->virAddr / PAGE_SIZE;
	// offAddr = ptr_memAccReq->virAddr % PAGE_SIZE;
	// printf("页号为:%u\t页内偏移为:%u\n", pageNum, offAddr);
/************************************************************************************/
	firstPageNum = ptr_memAccReq->virAddr / 32;
	firstOffAddr = (ptr_memAccReq->virAddr % 32) / PAGE_SIZE;
	offAddr = ptr_memAccReq->virAddr % PAGE_SIZE;
	printf("一级页表页号为:%u\t一级页表页内偏移为:%u\n", firstPageNum, firstOffAddr);
	printf("二级页表页号为:%u\t二级页表页内偏移为:%u\n", firstPageTable[firstPageNum].secondPageNum[firstOffAddr], offAddr);
/************************************************************************************/

	/* 获取对应页表项 */
	//ptr_pageTabIt = &pageTable[pageNum];
	ptr_pageTabIt =  &pageTable[firstPageTable[firstPageNum].secondPageNum[firstOffAddr]];


	/***********************************************************************************/
	if (ptr_memAccReq->proccessNum != ptr_pageTabIt->proccessNum) {
		ptr_pageTabIt->count++;
		ptr_pageTabIt->LRU_flag = 1;
		printf("权限不够,无法操作其他进程数据\n");
		return;
	}
	/***********************************************************************************/

	/* 根据特征位决定是否产生缺页中断 */
	//当前页表为空
	if (!ptr_pageTabIt->filled)
	{
		do_page_fault(ptr_pageTabIt);
	}

	actAddr = ptr_pageTabIt->blockNum * PAGE_SIZE + offAddr;
	printf("实地址为:%u\n", actAddr);

	/* 检查页面访问权限并处理访存请求 */
	switch (ptr_memAccReq->reqType)
	{
	case REQUEST_READ: //读请求
	{
		ptr_pageTabIt->count++;
		ptr_pageTabIt->LRU_flag = 1;
		if (!(ptr_pageTabIt->proType & READABLE)) //页面不可读
		{
			do_error(ERROR_READ_DENY);
			return;
		}
		/* 读取实存中的内容 */
		printf("读操作成功:值为%02X\n", actMem[actAddr]);
		break;
	}
	case REQUEST_WRITE: //写请求
	{
		ptr_pageTabIt->count++;
		ptr_pageTabIt->LRU_flag = 1;
		if (!(ptr_pageTabIt->proType & WRITABLE)) //页面不可写
		{
			do_error(ERROR_WRITE_DENY);
			return;
		}
		/* 向实存中写入请求的内容 */
		actMem[actAddr] = ptr_memAccReq->value;
		ptr_pageTabIt->edited = TRUE;
		printf("写操作成功\n");
		break;
	}
	case REQUEST_EXECUTE: //执行请求
	{
		ptr_pageTabIt->count++;
		ptr_pageTabIt->LRU_flag = 1;
		if (!(ptr_pageTabIt->proType & EXECUTABLE)) //页面不可执行
		{
			do_error(ERROR_EXECUTE_DENY);
			return;
		}
		printf("执行成功\n");
		break;
	}
	default: //非法请求类型
	{
		do_error(ERROR_INVALID_REQUEST);
		return;
	}
	}
}
Пример #18
0
/* 响应请求 */
void do_response()
{
	Ptr_PageTableItem ptr_pageTabIt;
	unsigned int pageNum, offAddr;
	unsigned int pageNum_1,pageNum_2;
	Ptr_PageTableItem ptr_pageTabIt_1,ptr_pageTabIt_2;
	unsigned int actAddr;
	int i=0;
	char s[4],str[4];
	/* 检查地址是否越界 */
	if (ptr_memAccReq->virAddr < 0 || ptr_memAccReq->virAddr >= VIRTUAL_MEMORY_SIZE)
	{
		do_error(ERROR_OVER_BOUNDARY);
		return;
	}
	
	/* 计算页号和页内偏移值 */
	pageNum = ptr_memAccReq->virAddr / PAGE_SIZE;
	pageNum_1=pageNum/8;//一级页表索引
	pageNum_2=pageNum%8;//二级页表索引
	offAddr = ptr_memAccReq->virAddr % PAGE_SIZE;
	printf("一级页表:%u  二级页表:%u 页内偏移为:%u\n",pageNum_1,pageNum_2,offAddr);
	printf("页号为:%u\t页内偏移为:%u\n", pageNum, offAddr);

	/* 获取对应页表项 */
	ptr_pageTabIt = &pageTable[pageNum];
	ptr_pageTabIt_1=prt_pageTable_1[pageNum_1];//一级页表
	ptr_pageTabIt=&ptr_pageTabIt_1[pageNum_2];//二级页表
	/*if(ptr_pageTabIt==ptr_pageTabIt_2)
		printf("%d %d  yes\n",ptr_pageTabIt,ptr_pageTabIt_2);
	else
		printf("%d %d  no\n",ptr_pageTabIt,ptr_pageTabIt_2);*/
	/* 根据特征位决定是否产生缺页中断 */
	if (!ptr_pageTabIt->filled)
	{
		do_page_fault(ptr_pageTabIt);
	}
	
	actAddr = ptr_pageTabIt->blockNum * PAGE_SIZE + offAddr;
	printf("实地址为:%u\n", actAddr);
	if(!(ptr_memAccReq->proccessNum&ptr_pageTabIt->proccessNum))//判断请求能否访问该页面
	{
		printf("该页属于进程:%s 进程%s不能访问\n",
				get_proNum_str(s,ptr_pageTabIt->proccessNum),get_proNum_str(str,ptr_memAccReq->proccessNum));
		return;
	}
	for(i = 0; i < PAGE_SUM; i++)
	{
		if(pageTable[i].filled)
		{
			pageTable[i].count_LRU++;
		}
	}
	ptr_pageTabIt->count_LRU=0;//更新LRU计数
	/* 检查页面访问权限并处理访存请求 */
	switch (ptr_memAccReq->reqType)
	{
		case REQUEST_READ: //读请求
		{
			ptr_pageTabIt->count++;
			ptr_pageTabIt->R=1;
			if (!(ptr_pageTabIt->proType & READABLE)) //页面不可读
			{
				do_error(ERROR_READ_DENY);
				return;
			}
			/* 读取实存中的内容 */
			printf("读操作成功:值为%c\n", actMem[actAddr]);
			break;
		}
		case REQUEST_WRITE: //写请求
		{
			ptr_pageTabIt->count++;
			ptr_pageTabIt->R=1;
			if (!(ptr_pageTabIt->proType & WRITABLE)) //页面不可写
			{
				do_error(ERROR_WRITE_DENY);	
				return;
			}
			/* 向实存中写入请求的内容 */
			actMem[actAddr] = ptr_memAccReq->value;
			ptr_pageTabIt->edited = TRUE;			
			printf("写操作成功\n");
			break;
		}
		case REQUEST_EXECUTE: //执行请求
		{
			ptr_pageTabIt->count++;
			ptr_pageTabIt->R=1;
			if (!(ptr_pageTabIt->proType & EXECUTABLE)) //页面不可执行
			{
				do_error(ERROR_EXECUTE_DENY);
				return;
			}			
			printf("执行成功\n");
			break;
		}
		default: //非法请求类型
		{	
			do_error(ERROR_INVALID_REQUEST);
			return;
		}
	}
}
Пример #19
0
void handle_interruption(int code, struct pt_regs *regs)
{
	unsigned long fault_address = 0;
	unsigned long fault_space = 0;
	struct siginfo si;

	switch(code) {

	case  1:
		/* High-priority machine check (HPMC) */
		pdc_console_restart();  /* switch back to pdc if HPMC */

		/* set up a new led state on systems shipped with a LED State panel */
		pdc_chassis_send_status(PDC_CHASSIS_DIRECT_HPMC);

		parisc_terminate("High Priority Machine Check (HPMC)",
				regs, code, 0);
		/* NOT REACHED */
		
	case  2:
		/* Power failure interrupt */
		printk(KERN_CRIT "Power failure interrupt !\n");
		return;

	case  3:
		/* Recovery counter trap */
		regs->gr[0] &= ~PSW_R;
		if (regs->iasq[0])
			handle_gdb_break(regs, TRAP_TRACE);
		/* else this must be the start of a syscall - just let it run */
		return;

	case  5:
		/* Low-priority machine check */

		pdc_chassis_send_status(PDC_CHASSIS_DIRECT_LPMC);

		flush_all_caches();
		cpu_lpmc(5, regs);
		return;

	case  6:
		/* Instruction TLB miss fault/Instruction page fault */
		fault_address = regs->iaoq[0];
		fault_space   = regs->iasq[0];
		break;

	case  8:
		/* Illegal instruction trap */
		die_if_kernel("Illegal instruction", regs, code);
		si.si_code = ILL_ILLOPC;
		goto give_sigill;

	case  9:
		/* Break instruction trap */
		handle_break(regs->iir,regs);
		return;
	
	case 10:
		/* Privileged operation trap */
		die_if_kernel("Privileged operation", regs, code);
		si.si_code = ILL_PRVOPC;
		goto give_sigill;
	
	case 11:
		/* Privileged register trap */
		if ((regs->iir & 0xffdfffe0) == 0x034008a0) {

			/* This is a MFCTL cr26/cr27 to gr instruction.
			 * PCXS traps on this, so we need to emulate it.
			 */

			if (regs->iir & 0x00200000)
				regs->gr[regs->iir & 0x1f] = mfctl(27);
			else
				regs->gr[regs->iir & 0x1f] = mfctl(26);

			regs->iaoq[0] = regs->iaoq[1];
			regs->iaoq[1] += 4;
			regs->iasq[0] = regs->iasq[1];
			return;
		}

		die_if_kernel("Privileged register usage", regs, code);
		si.si_code = ILL_PRVREG;
		/* Fall thru */
	give_sigill:
		si.si_signo = SIGILL;
		si.si_errno = 0;
		si.si_addr = (void *) regs->iaoq[0];
		force_sig_info(SIGILL, &si, current);
		return;

	case 12:
		/* Overflow Trap, let the userland signal handler do the cleanup */
		si.si_signo = SIGFPE;
		si.si_code = FPE_INTOVF;
		si.si_addr = (void *) regs->iaoq[0];
		force_sig_info(SIGFPE, &si, current);
		return;
	
	case 13:
		/* Conditional Trap 
		   The condition succees in an instruction which traps on condition  */
		si.si_signo = SIGFPE;
		/* Set to zero, and let the userspace app figure it out from
		   the insn pointed to by si_addr */
		si.si_code = 0;
		si.si_addr = (void *) regs->iaoq[0];
		force_sig_info(SIGFPE, &si, current);
		return;

	case 14:
		/* Assist Exception Trap, i.e. floating point exception. */
		die_if_kernel("Floating point exception", regs, 0); /* quiet */
		handle_fpe(regs);
		return;

	case 15: 
		/* Data TLB miss fault/Data page fault */	
		/* Fall thru */
	case 16:
		/* Non-access instruction TLB miss fault */
		/* The instruction TLB entry needed for the target address of the FIC
		   is absent, and hardware can't find it, so we get to cleanup */
		/* Fall thru */
	case 17:
		/* Non-access data TLB miss fault/Non-access data page fault */
		/* TODO: Still need to add slow path emulation code here */
		/* TODO: Understand what is meant by the TODO listed 
		   above this one. (Carlos) */
		fault_address = regs->ior;
		fault_space = regs->isr;
		break;

	case 18:
		/* PCXS only -- later cpu's split this into types 26,27 & 28 */
		/* Check for unaligned access */
		if (check_unaligned(regs)) {
			handle_unaligned(regs);
			return;
		}
		/* Fall Through */
	case 26: 
		/* PCXL: Data memory access rights trap */
		fault_address = regs->ior;
		fault_space   = regs->isr;
		break;

	case 19:
		/* Data memory break trap */
		regs->gr[0] |= PSW_X; /* So we can single-step over the trap */
		/* fall thru */
	case 21:
		/* Page reference trap */
		handle_gdb_break(regs, TRAP_HWBKPT);
		return;

	case 25:
		/* Taken branch trap */
		regs->gr[0] &= ~PSW_T;
		if (regs->iasq[0])
			handle_gdb_break(regs, TRAP_BRANCH);
		/* else this must be the start of a syscall - just let it
		 * run.
		 */
		return;

	case  7:  
		/* Instruction access rights */
		/* PCXL: Instruction memory protection trap */

		/*
		 * This could be caused by either: 1) a process attempting
		 * to execute within a vma that does not have execute
		 * permission, or 2) an access rights violation caused by a
		 * flush only translation set up by ptep_get_and_clear().
		 * So we check the vma permissions to differentiate the two.
		 * If the vma indicates we have execute permission, then
		 * the cause is the latter one. In this case, we need to
		 * call do_page_fault() to fix the problem.
		 */

		if (user_mode(regs)) {
			struct vm_area_struct *vma;

			down_read(&current->mm->mmap_sem);
			vma = find_vma(current->mm,regs->iaoq[0]);
			if (vma && (regs->iaoq[0] >= vma->vm_start)
				&& (vma->vm_flags & VM_EXEC)) {

				fault_address = regs->iaoq[0];
				fault_space = regs->iasq[0];

				up_read(&current->mm->mmap_sem);
				break; /* call do_page_fault() */
			}
			up_read(&current->mm->mmap_sem);
		}
		/* Fall Through */
	case 27: 
		/* Data memory protection ID trap */
		die_if_kernel("Protection id trap", regs, code);
		si.si_code = SEGV_MAPERR;
		si.si_signo = SIGSEGV;
		si.si_errno = 0;
		if (code == 7)
		    si.si_addr = (void *) regs->iaoq[0];
		else
		    si.si_addr = (void *) regs->ior;
		force_sig_info(SIGSEGV, &si, current);
		return;

	case 28: 
		/* Unaligned data reference trap */
		handle_unaligned(regs);
		return;

	default:
		if (user_mode(regs)) {
#ifdef PRINT_USER_FAULTS
			printk(KERN_DEBUG "\nhandle_interruption() pid=%d command='%s'\n",
			    current->pid, current->comm);
			show_regs(regs);
#endif
			/* SIGBUS, for lack of a better one. */
			si.si_signo = SIGBUS;
			si.si_code = BUS_OBJERR;
			si.si_errno = 0;
			si.si_addr = (void *) regs->ior;
			force_sig_info(SIGBUS, &si, current);
			return;
		}
		
		pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);

		parisc_terminate("Unexpected interruption", regs, code, 0);
		/* NOT REACHED */
	}

	if (user_mode(regs)) {
	    if (fault_space != regs->sr[7]) {
#ifdef PRINT_USER_FAULTS
		if (fault_space == 0)
			printk(KERN_DEBUG "User Fault on Kernel Space ");
		else
			printk(KERN_DEBUG "User Fault (long pointer) ");
		printk("pid=%d command='%s'\n", current->pid, current->comm);
		show_regs(regs);
#endif
		si.si_signo = SIGSEGV;
		si.si_errno = 0;
		si.si_code = SEGV_MAPERR;
		si.si_addr = (void *) regs->ior;
		force_sig_info(SIGSEGV, &si, current);
		return;
	    }
	}
	else {

	    /*
	     * The kernel should never fault on its own address space.
	     */

	    if (fault_space == 0) {
		pdc_chassis_send_status(PDC_CHASSIS_DIRECT_PANIC);
		parisc_terminate("Kernel Fault", regs, code, fault_address);
		/** NOT REACHED **/
	    }
	}

	local_irq_enable();
	do_page_fault(regs, code, fault_address);
}
Пример #20
0
/* 响应请求 */
void do_response()
{
	Ptr_PageTableItem ptr_pageTabIt;
	unsigned int pageNum, offAddr;
	unsigned int actAddr;

	//hzy end
	printf("进程ID:%d\n", ptr_memAccReq->ID);
	/* 检查地址是否越界 */
	if (ptr_memAccReq->virAddr < 0 || ptr_memAccReq->virAddr >= VIRTUAL_MEMORY_SIZE)
	{
		do_error(ERROR_OVER_BOUNDARY);
		return;
	}
	
	/* 计算页号和页内偏移值 */
	pageNum = ptr_memAccReq->virAddr / PAGE_SIZE;
	pageNum = outerpageTable[pageNum/16].pageIndex + pageNum%16;	//多级页表
	offAddr = ptr_memAccReq->virAddr % PAGE_SIZE;
	printf("页号为:%u\t页内偏移为:%u\n", pageNum, offAddr);

	/* 获取对应页表项 */
	ptr_pageTabIt = &pageTable[pageNum];
	
	if(ptr_pageTabIt->ID != ptr_memAccReq->ID)
	{
		printf("进程ID:%d 没有获得任何页表ID为%d的访问权限\n",ptr_memAccReq->ID,ptr_pageTabIt->ID);
		return ;
	}
	
	/* 根据特征位决定是否产生缺页中断 */
	if (!ptr_pageTabIt->filled)
	{
		do_page_fault(ptr_pageTabIt);
	}
	
	actAddr = ptr_pageTabIt->blockNum * PAGE_SIZE + offAddr;
	printf("实地址为:%u\n", actAddr);
	
	/* 检查页面访问权限并处理访存请求 */
	switch (ptr_memAccReq->reqType)
	{
		case REQUEST_READ: //读请求
		{
		//	ptr_pageTabIt->count++;
			update_NLRU(ptr_pageTabIt);
			if (!(ptr_pageTabIt->proType & READABLE)) //页面不可读
			{
				do_error(ERROR_READ_DENY);
				return;
			}
			/* 读取实存中的内容 */
			printf("读操作成功:值为%02X\n", actMem[actAddr]);
			break;
		}
		case REQUEST_WRITE: //写请求
		{
		//	ptr_pageTabIt->count++;
			update_NLRU(ptr_pageTabIt);
			if (!(ptr_pageTabIt->proType & WRITABLE)) //页面不可写
			{
				do_error(ERROR_WRITE_DENY);	
				return;
			}
			/* 向实存中写入请求的内容 */
			actMem[actAddr] = ptr_memAccReq->value;
			ptr_pageTabIt->edited = TRUE;			
			printf("写操作成功\n");
			break;
		}
		case REQUEST_EXECUTE: //执行请求
		{
		//	ptr_pageTabIt->count++;
			update_NLRU(ptr_pageTabIt);
			if (!(ptr_pageTabIt->proType & EXECUTABLE)) //页面不可执行
			{
				do_error(ERROR_EXECUTE_DENY);
				return;
			}			
			printf("执行成功\n");
			break;
		}
		default: //非法请求类型
		{	
			do_error(ERROR_INVALID_REQUEST);
			return;
		}
	}
}
Пример #21
0
void master_exception_handler (long exception, long error)
{
  switch (exception)
  {
  case 0:
    panic ("Exception: divide error!");
  case 1:
    panic ("Exception: debug!");
  case 2:
    panic ("Exception: NMI!");
  case 3:
    panic ("Exception: breakpoint!");
  case 4:
    panic ("Exception: overflow!");
  case 5:
    panic ("Exception: bounds check!");
  case 6:
    panic ("Exception: invalid opcode!");
  case 7:
    panic ("Exception: coprocessor not availiable!");
  case 8:
    panic ("Exception: double fault!");
  case 9:
    panic ("Exception: 9 (reserved)!");
  case 10:
    panic ("Exception: invalid TSS!");
  case 11:
    panic ("Exception: segment not present!");
  case 12:
    panic ("Exception: stack!");
  case 13:
    panic ("Exception: general protection!");
  case 14:

    //  
    //printf ("PF(pid=%u,", (int) current_proc->pid);
    //
    //    if (error & PAGE_FAULT_P)
    //  printf ("present,");
    //else
    //  printf ("not present,");
    //
    //if (error & PAGE_FAULT_RW)
    //  printf ("write,");
    //else
    //  printf ("read,");
    //  
    //if (error & PAGE_FAULT_US)
    //  printf ("user,");
    //else
    //  printf ("supervisor,");
    //
    //printf ("0x%x) ", (int) get_cr2());
    //

    do_page_fault (current_proc, get_cr2(), error);

    break;

  case 16:
    panic ("Exception: coprocessor error!");
  case BAD_INT:
    warning ("Unallowed int# used!");

  }
}
Пример #22
0
/* 响应请求 */
void do_response()
{
    Ptr_PageTableItem ptr_pageTabIt;
    unsigned int masterPageNum, pageNum, offAddr;
    unsigned int actAddr;
    int i;
    int count;
    while (TRUE)
    {
        if ((count = read(fd, ptr_memAccReq, sizeof(MemoryAccessRequest))) < 0)
        {
            if (errno == EAGAIN || errno == EWOULDBLOCK) {
                printf("本次读取结束.\n");
                return;
            } else {
                printf("read FIFO failed.\n");
                exit(1);
            }
        } else if (count < sizeof(MemoryAccessRequest)) {
            printf("本次读取结束.\n");
            return;
        }
        if (ptr_memAccReq->virAddr >= ptr_memAccReq->id * VIRTUAL_MEMORY_EACH && ptr_memAccReq->virAddr < (ptr_memAccReq->id + 1) * VIRTUAL_MEMORY_EACH)
        {
            switch(ptr_memAccReq->reqType)
            {
                case 0: //读请求
                    {
                        printf("产生请求:\nid:%d\t地址:%u\t类型:读取\n",ptr_memAccReq->id, ptr_memAccReq->virAddr);
                        break;
                    }
                case 1: //写请求
                    {
                        if (ptr_memAccReq->value >= 0 && ptr_memAccReq->value < 0xFFu)
                        {
                            printf("产生请求:\nid:%d\t地址:%u\t类型:写入\t值:%02X\n", ptr_memAccReq->id, ptr_memAccReq->virAddr, ptr_memAccReq->value);
                        } else {
                            do_error(ERROR_INVALID_REQUEST);
                        }
                        break;
                    }
                case 2:
                    {
                        printf("产生请求:\nid:%d\t地址:%u\t类型:执行\n", ptr_memAccReq->id, ptr_memAccReq->virAddr);
                        break;
                    }
                default:
                    do_error(ERROR_INVALID_REQUEST);
                    continue;
            }
        } else {
            do_error(ERROR_OVER_BOUNDARY);
            continue;
        }

        /* 计算页号和页内偏移值 */
        masterPageNum = ptr_memAccReq->virAddr / PAGE_SUM;
        pageNum = ptr_memAccReq->virAddr % PAGE_SUM / PAGE_SIZE;
        offAddr = ptr_memAccReq->virAddr % PAGE_SUM % PAGE_SIZE;
        printf("一级页号为:%u\t二级页号为:%u\t页内偏移为:%u\n", masterPageNum, pageNum, offAddr);

        /* 获取对应页表项 */
        ptr_pageTabIt = masterPageTable[masterPageNum].pages + pageNum;

        /* 根据特征位决定是否产生缺页中断 */
        if (!ptr_pageTabIt->filled)
        {
            do_page_fault(ptr_pageTabIt);
        }

        actAddr = ptr_pageTabIt->blockNum * PAGE_SIZE + offAddr;
        printf("实地址为:%u\n", actAddr);

        /* 检查页面访问权限并处理访存请求 */
        switch (ptr_memAccReq->reqType)
        {
            case REQUEST_READ: //读请求
                {
                    if (!(ptr_pageTabIt->proType & READABLE)) //页面不可读
                    {
                        do_error(ERROR_READ_DENY);
                        continue;
                    }
                    /* 读取实存中的内容 */
                    for (i = 0; i < PAGE_SUM; i++) 
                    {
                        pageTable[i].count /= 2;
                        if (pageTable + i == ptr_pageTabIt) 
                        {
                            pageTable[i].count += 128;
                        }
                    }
                    printf("读操作成功:值为%02X\n", actMem[actAddr]);
                    break;
                }
            case REQUEST_WRITE: //写请求
                {
                    if (!(ptr_pageTabIt->proType & WRITABLE)) //页面不可写
                    {
                        do_error(ERROR_WRITE_DENY);	
                        continue;
                    }
                    /* 向实存中写入请求的内容 */
                    for (i = 0; i < PAGE_SUM; i++) 
                    {
                        pageTable[i].count /= 2;
                        if (pageTable + i == ptr_pageTabIt) 
                        {
                            pageTable[i].count += 128;
                        }
                    }
                    actMem[actAddr] = ptr_memAccReq->value;
                    ptr_pageTabIt->edited = TRUE;			
                    printf("写操作成功\n");
                    break;
                }
            case REQUEST_EXECUTE: //执行请求
                {
                    if (!(ptr_pageTabIt->proType & EXECUTABLE)) //页面不可执行
                    {
                        do_error(ERROR_EXECUTE_DENY);
                        continue;
                    }
                    for (i = 0; i < PAGE_SUM; i++) 
                    {
                        pageTable[i].count /= 2;
                        if (pageTable + i == ptr_pageTabIt) 
                        {
                            pageTable[i].count += 128;
                        }
                    }
                    printf("执行成功\n");
                    break;
                }
            default: //非法请求类型
                {	
                    do_error(ERROR_INVALID_REQUEST);
                    continue;
                }
        }
    }
}
Пример #23
0
/* 响应请求 */
void do_response()
{
	Ptr_PageTableItem ptr_pageTabIt;
	unsigned int pageNum, offAddr,indexNum,ProcessNum;
	unsigned int actAddr;
	Ptr_MemoryAccessRequest aptr_memAccReq;
	int processCount, k, i, c;

	if(head==NULL){
	printf("hi\n");
		return;}
	aptr_memAccReq = head;
	head = head->next;
	ProcessNum =  aptr_memAccReq->ProcessNum;
	/* 检查地址是否越界 */
	if (aptr_memAccReq->virAddr < aptr_memAccReq->ProcessNum*256 || aptr_memAccReq->virAddr >= (aptr_memAccReq->ProcessNum+1)*256)
	{
		printf("viraddr=%d\t,processnum=%d\n",aptr_memAccReq->virAddr,ProcessNum);
		do_error(ERROR_OVER_BOUNDARY);
		return;
	}

	/* 计算页号和页内偏移值 */

	pageNum = (aptr_memAccReq->virAddr-ProcessNum*256) / PAGE_SIZE % INDEX_PAGE ;
	indexNum = (aptr_memAccReq->virAddr-ProcessNum*256) / PAGE_SIZE / INDEX_PAGE;
	offAddr = (aptr_memAccReq->virAddr-ProcessNum*256) % PAGE_SIZE;

	printf("进程号为:%u\t页目录为:%u\t页号为:%u\t页内偏移为:%u\n",ProcessNum,indexNum, pageNum, offAddr);

	/* 获取对应页表项 */
	ptr_pageTabIt = &pageIndex[ProcessNum][indexNum].index[pageNum];
	/* 根据特征位决定是否产生缺页中断 */
	if (!ptr_pageTabIt->filled)
	{
		do_page_fault(ptr_pageTabIt);
	}

	actAddr = ptr_pageTabIt->blockNum * PAGE_SIZE + offAddr;
	printf("实地址为:%u\n", actAddr);

    for(processCount=0;processCount<Process_SUM;processCount++)
        for (k = 0; k < INDEX_SUM; k++)
            for(i=0;i<INDEX_PAGE;i++)
            {
                pageIndex[processCount][k].index[i].visited = 0;
            }

	/* 检查页面访问权限并处理访存请求 */
	switch (aptr_memAccReq->reqType)
	{
		case REQUEST_READ: //读请求
		{
			ptr_pageTabIt->visited = 1;
			for(processCount=0;processCount<Process_SUM;processCount++)
                for (k = 0; k < INDEX_SUM; k++)
                    for(i=0;i<INDEX_PAGE;i++)
                    {
                        for(c = 7;c > 0;c--){
                            pageIndex[processCount][k].index[i].count[c] = pageIndex[processCount][k].index[i].count[c - 1];
                        }
                        pageIndex[processCount][k].index[i].count[0] = pageIndex[processCount][k].index[i].visited + '0';
                    }
			if (!(ptr_pageTabIt->proType & READABLE)) //页面不可读
			{
				do_error(ERROR_READ_DENY);
				return;
			}
			/* 读取实存中的内容 */
			printf("读操作成功:值为%02X\n", actMem[actAddr]);
			break;
		}
		case REQUEST_WRITE: //写请求
		{
			ptr_pageTabIt->visited = 1;
			for(processCount=0;processCount<Process_SUM;processCount++)
                for (k = 0; k < INDEX_SUM; k++)
                    for(i=0;i<INDEX_PAGE;i++)
                    {
                        for(c = 7;c > 0;c--){
                            pageIndex[processCount][k].index[i].count[c] = pageIndex[processCount][k].index[i].count[c - 1];
                        }
                        pageIndex[processCount][k].index[i].count[0] = pageIndex[processCount][k].index[i].visited + '0';
                    }
			if (!(ptr_pageTabIt->proType & WRITABLE)) //页面不可写
			{
				do_error(ERROR_WRITE_DENY);
				return;
			}
			/* 向实存中写入请求的内容 */
			actMem[actAddr] = aptr_memAccReq->value;
			ptr_pageTabIt->edited = TRUE;
			printf("写操作成功\n");
			break;
		}
		case REQUEST_EXECUTE: //执行请求
		{
			ptr_pageTabIt->visited = 1;
			for(processCount=0;processCount<Process_SUM;processCount++)
                for (k = 0; k < INDEX_SUM; k++)
                    for(i=0;i<INDEX_PAGE;i++)
                    {
                        for(c = 7;c > 0;c--){
                            pageIndex[processCount][k].index[i].count[c] = pageIndex[processCount][k].index[i].count[c - 1];
                        }
                        pageIndex[processCount][k].index[i].count[0] = pageIndex[processCount][k].index[i].visited + '0';
                    }
			if (!(ptr_pageTabIt->proType & EXECUTABLE)) //页面不可执行
			{
				do_error(ERROR_EXECUTE_DENY);
				return;
			}
			printf("执行成功\n");
			break;
		}
		default: //非法请求类型
		{
			do_error(ERROR_INVALID_REQUEST);
			return;
		}
	}
}
Пример #24
0
void do_response()
{
	Ptr_PageTableItem ptr_pageTabIt;
	unsigned int pageNum, offAddr;
	unsigned int actAddr;
	static int counter=10;
	if(--counter<=0) {
		div2(); counter=10;
	}

	if(ptr_memAccReq->reqType==REQUEST_SWITCH) 
	{
		do_switch();
		return;
	}	
	/* 检查地址是否越界 */
	if (ptr_memAccReq->virAddr < 0 || ptr_memAccReq->virAddr >= VIRTUAL_MEMORY_SIZE)
	{
		printf("error1\n");
		do_error(ERROR_OVER_BOUNDARY);
		return;
	}
	
	/* 计算页号和页内偏移值 */
	pageNum = ptr_memAccReq->virAddr / PAGE_SIZE;
	offAddr = ptr_memAccReq->virAddr % PAGE_SIZE;
	printf("页号为:%u\t页内偏移为:%u\n", pageNum, offAddr);

	/* 获取对应页表项 */
	ptr_pageTabIt = (*pageTable)[pageNum/8]+pageNum%8;;
	
	/* 根据特征位决定是否产生缺页中断 */
	if (!ptr_pageTabIt->filled)
	{
		do_page_fault(ptr_pageTabIt);
	}
	
	actAddr = ptr_pageTabIt->blockNum * PAGE_SIZE + offAddr;
	printf("实地址为:%u\n", actAddr);
	
	/* 检查页面访问权限并处理访存请求 */
	switch (ptr_memAccReq->reqType)
	{
		case REQUEST_READ: //读请求
		{
			ptr_pageTabIt->count++;
			aaaaaaccess(ptr_pageTabIt->blockNum);
			if (!(ptr_pageTabIt->proType & READABLE)) //页面不可读
			{
				printf("error2\n");
				do_error(ERROR_READ_DENY);
				return;
			}
			/* 读取实存中的内容 */
			printf("读操作成功:值为%02X\n", actMem[actAddr]);
			break;
		}
		case REQUEST_WRITE: //写请求
		{
			ptr_pageTabIt->count++;
			aaaaaaccess(ptr_pageTabIt->blockNum);
			if (!(ptr_pageTabIt->proType & WRITABLE)) //页面不可写
			{
				printf("error3\n");
				do_error(ERROR_WRITE_DENY);	
				return;
			}
			/* 向实存中写入请求的内容 */
			actMem[actAddr] = ptr_memAccReq->value;
			ptr_pageTabIt->edited = TRUE;			
			printf("写操作成功\n");
			break;
		}
		case REQUEST_EXECUTE: //执行请求
		{
			ptr_pageTabIt->count++;
			aaaaaaccess(ptr_pageTabIt->blockNum);
			if (!(ptr_pageTabIt->proType & EXECUTABLE)) //页面不可执行
			{
				printf("error4\n");
				do_error(ERROR_EXECUTE_DENY);
				return;
			}			
			printf("执行成功\n");
			break;
		}
		default: //非法请求类型
		{	
			printf("error5\n");
			do_error(ERROR_INVALID_REQUEST);
			return;
		}
	}
}
Пример #25
0
void write_protection_fault(struct pt_regs *regs)
{
	unsigned long badvadr = pt_badva(regs);

	do_page_fault(badvadr, FLT_STORE, regs);
}
Пример #26
0
/* 响应请求 */
void do_response()
{
	Ptr_PageTableItem ptr_pageTabIt;
	unsigned int pageNum, offAddr;
	unsigned int actAddr;
	
	/* 检查地址是否越界 */
	if (ptr_memAccReq->virAddr < 0 || ptr_memAccReq->virAddr >= VIRTUAL_MEMORY_SIZE)
	{
		do_error(ERROR_OVER_BOUNDARY);
		return;
	}
	
	/* 计算页号和页内偏移值 */
	pageNum = ptr_memAccReq->virAddr / PAGE_SIZE;
	offAddr = ptr_memAccReq->virAddr % PAGE_SIZE;
	printf("页号为:%u\t页内偏移为:%u\n", pageNum, offAddr);

	/* 获取对应页表项 */
	ptr_pageTabIt = &pageTable[pageNum];
	
	/*判断请求与页表项是否属于同一进程*/
	if(ptr_memAccReq->processNum != ptr_pageTabIt->processNum)
	{
		do_error(ERROR_OVER_PROCESS);
		return;
	}

	/* 根据特征位决定是否产生缺页中断 */
	if (!ptr_pageTabIt->filled)
	{
		do_page_fault(ptr_pageTabIt);
	}
	
	actAddr = ptr_pageTabIt->blockNum * PAGE_SIZE + offAddr;
	printf("实地址为:%u\n", actAddr);
	cpuTime++;
	
	/* 检查页面访问权限并处理访存请求 */
	switch (ptr_memAccReq->reqType)
	{
		case REQUEST_READ: //读请求
		{
			ptr_pageTabIt->count++;
			ptr_pageTabIt->time = cpuTime;
			if (!(ptr_pageTabIt->proType & READABLE)) //页面不可读
			{
				do_error(ERROR_READ_DENY);
				return;
			}
			/* 读取实存中的内容 */
			printf("读操作成功:值为%02X\n", actMem[actAddr]);
			break;
		}
		case REQUEST_WRITE: //写请求
		{
			ptr_pageTabIt->count++;
			ptr_pageTabIt->time = cpuTime;
			if (!(ptr_pageTabIt->proType & WRITABLE)) //页面不可写
			{
				do_error(ERROR_WRITE_DENY);	
				return;
			}
			/* 向实存中写入请求的内容 */
			actMem[actAddr] = ptr_memAccReq->value;
			ptr_pageTabIt->edited = TRUE;			
			printf("写操作成功\n");
			break;
		}
		case REQUEST_EXECUTE: //执行请求
		{
			ptr_pageTabIt->count++;
			ptr_pageTabIt->time = cpuTime;
			if (!(ptr_pageTabIt->proType & EXECUTABLE)) //页面不可执行
			{
				do_error(ERROR_EXECUTE_DENY);
				return;
			}			
			printf("执行成功\n");
			break;
		}
		default: //非法请求类型
		{	
			do_error(ERROR_INVALID_REQUEST);
			return;
		}
	}
}
Пример #27
0
/* 响应请求 */
void do_response()
{
	Ptr_PageTableItem ptr_pageTabIt;
	unsigned int pageNum1, pageNum2, offAddr;
	unsigned int actAddr,i;

	/* 检查地址是否越界 */
	if (ptr_memAccReq->virAddr < 0 || ptr_memAccReq->virAddr >= VIRTUAL_MEMORY_SIZE)
	{
		do_error(ERROR_OVER_BOUNDARY);
		return;
	}

	/* 计算页号和页内偏移值 */
	pageNum1 = ptr_memAccReq->virAddr / LV1_PAGE_SIZE;
	offAddr = ptr_memAccReq->virAddr % LV1_PAGE_SIZE;
	pageNum2 = offAddr / LV2_PAGE_SIZE;
	offAddr = offAddr % LV2_PAGE_SIZE;
	printf("页号为:%u\t页内偏移为:%u\n", pageNum1 * LV1_PAGE_SUM + pageNum2, offAddr);

	/* 获取对应页表项 */
	ptr_pageTabIt = &pageTable[ptr_memAccReq->FromProgress][pageNum1][pageNum2];                                
	/* 根据特征位决定是否产生缺页中断 */
	//printf("%u\t%u\t%u\n", ptr_memAccReq->FromProgress, pageNum1, pageNum2);
	if (!ptr_pageTabIt->filled)
	{
	    	//printf("everything ok\n");
	    for(i=0;i<8;i++)
	    {
	        actmemcount[ptr_memAccReq->FromProgress][pageNum1 * LV1_PAGE_SUM + pageNum2][i]=0;
	    }
		do_page_fault(ptr_pageTabIt);
	}
  //  if(ptr_memAccReq->FromProgress != ptr_pageTabIt->progressNum)
 //   {
 //       for(i=0;i<8;i++)
//	    {
//	        actmemcount[pageNum1 * LV1_PAGE_SUM + pageNum2][i]=0;
//	    }
//		do_page_fault(ptr_pageTabIt);
//    }
	actAddr = ptr_pageTabIt->blockNum * PAGE_SIZE + offAddr;
	printf("实地址为:%u\n", actAddr);
	switch (ptr_memAccReq->reqType)
	{
		case REQUEST_READ: //读请求
		{
			ptr_pageTabIt->count++;
			actmemcount[ptr_memAccReq->FromProgress][pageNum1 * LV1_PAGE_SUM + pageNum2][0]=1;
			/* 检查页面访问权限并处理访存请求 */
			/*if(ptr_memAccReq->FromProgress != ptr_pageTabIt->progressNum){
                printf("%d %d",ptr_memAccReq->FromProgress,ptr_pageTabIt->progressNum);
                do_error(ERROR_UNMATCHED_PROGRESS);
                return;
            }*/
			if (!(ptr_pageTabIt->proType & READABLE)) //页面不可读
			{
				do_error(ERROR_READ_DENY);
				return;
			}
			/* 读取实存中的内容 */
			printf("读操作成功:值为%02X\n", actMem[actAddr]);
			break;
		}
		case REQUEST_WRITE: //写请求
		{
			ptr_pageTabIt->count++;
			actmemcount[ptr_memAccReq->FromProgress][pageNum1 * LV1_PAGE_SUM + pageNum2][0]=1;
			/* 检查页面访问权限并处理访存请求 */
			/*if(ptr_memAccReq->FromProgress != ptr_pageTabIt->progressNum){
                printf("%d %d",ptr_memAccReq->FromProgress,ptr_pageTabIt->progressNum);
                do_error(ERROR_UNMATCHED_PROGRESS);
                return;
            }*/
			if (!(ptr_pageTabIt->proType & WRITABLE)) //页面不可写
			{
				do_error(ERROR_WRITE_DENY);
				return;
			}
			/* 向实存中写入请求的内容 */
			actMem[actAddr] = ptr_memAccReq->value;
			ptr_pageTabIt->edited = TRUE;
			printf("写操作成功\n");
			break;
		}
		case REQUEST_EXECUTE: //执行请求
		{
			ptr_pageTabIt->count++;
			actmemcount[ptr_memAccReq->FromProgress][pageNum1 * LV1_PAGE_SUM + pageNum2][0]=1;
			/* 检查页面访问权限并处理访存请求 */
			/*if(ptr_memAccReq->FromProgress != ptr_pageTabIt->progressNum){
                printf("%d %d",ptr_memAccReq->FromProgress,ptr_pageTabIt->progressNum);
                do_error(ERROR_UNMATCHED_PROGRESS);
                return;
            }*/
			if (!(ptr_pageTabIt->proType & EXECUTABLE)) //页面不可执行
			{
				do_error(ERROR_EXECUTE_DENY);
				return;
			}
			printf("执行成功\n");
			break;
		}
		default: //非法请求类型
		{
			do_error(ERROR_INVALID_REQUEST);
			return;
		}
	}
}
Пример #28
0
asmlinkage void do_tlbl(struct pt_regs *regs)
{	

	do_page_fault(regs, 0, read_c0_badvaddr());
}