Example #1
0
hwaddr_t page_translate(lnaddr_t addr) {
    LinearAddress lnaddr;
    lnaddr.val = addr;
    Log("lnaddr = 0x%x", addr);
    // Log("lnaddr.offset = 0x%x", lnaddr.offset);
    // Log("lnaddr.page   = 0x%x", lnaddr.page);
    // Log("lnaddr.dir    = 0x%x", lnaddr.dir);
    // Log("CR3 = 0x%x", cpu.cr3.val);

    uint32_t pdir_entry_addr   = (cpu.cr3.page_directory_base << 12) + (lnaddr.dir << 2);
    Log("pdir_entry_addr = 0x%x", pdir_entry_addr);
    PDE pdir_entry;
    pdir_entry.val = hwaddr_read(pdir_entry_addr, 4);
    Log("pdir_entry = 0x%x", pdir_entry.val);
    Assert(pdir_entry.present, "Page directory entry's present bit is 0.");

    uint32_t ptable_entry_addr = (pdir_entry.page_frame << 12) + (lnaddr.page << 2);
    Log("ptable_entry_addr = 0x%x", ptable_entry_addr);
    PTE ptable_entry;
    ptable_entry.val = hwaddr_read(ptable_entry_addr, 4);
    Log("ptable_entry = 0x%x", ptable_entry.val);
    Assert(ptable_entry.present, "Page table entry's present bit is 0.");

    addr = (ptable_entry.page_frame << 12) + lnaddr.offset;
    Log("hwaddr = 0x%x", addr);
    return addr;
}
Example #2
0
hwaddr_t page_translate(lnaddr_t addr, size_t len)
{
    hwaddr_t hwaddr = -1;
    hwaddr_t __hwaddr = -1;

    if ( tlb_read(addr, &hwaddr) ) {
        test(hwaddr != -1, "tlb hit and wrong: return %x", hwaddr);
        return hwaddr;
    }
    
    test(hwaddr == -1, "tlb miss and wrong");
    Lnaddr lnaddr;
    PDE dir_entry;
    PTE page_entry;

    lnaddr.val = addr;

    hwaddr_t dir_addr = cpu.cr3.page_directory_base << 12;

    dir_entry.val = hwaddr_read(dir_addr + 4 * lnaddr.dir, 4);
    if (!dir_entry.present) {
        Test(0, "dir fault: eip %#x, vaddr %#x, dir %#x, page %#x, offset %#x", cpu.eip, addr, lnaddr.dir, lnaddr.page, lnaddr.offset);
        assert(0);
    }
    page_entry.val = hwaddr_read((dir_entry.page_frame << 12) + 4 * lnaddr.page, 4);
    if (!page_entry.present) {
        Test(0, "page fault: eip %#x, vaddr %#x, dir %#x, page %#x, offset %#x", cpu.eip, addr, lnaddr.dir, lnaddr.page, lnaddr.offset);
        assert(0);
    }
    __hwaddr = (page_entry.page_frame << 12) + lnaddr.offset;

    tlb_insert(addr, page_entry);

    return __hwaddr;
}
Example #3
0
hwaddr_t page_translate(lnaddr_t addr) {
	if (!(cpu.cr0.protect_enable == 1 && cpu.cr0.paging == 1)) return addr;
	lnaddrdevide lnaddr;
	lnaddr.val=addr;
	int set;
	for (set=0; set<64; set++) 
		if (tlb[set].vaild && tlb[set].flag==((lnaddr.dir<<10)+lnaddr.page)) {
			return (tlb[set].data<<12)+lnaddr.offset;
		}
	
//	printf("%x\n", cpu.cr3.page_directory_base);
	PDE dir;
	dir.val=hwaddr_read((cpu.cr3.page_directory_base<<12)+lnaddr.dir*4, 4);
//	if (dir.val!=1208327) 
//	printf("%d\n", dir.val);
	if (dir.present==0) panic("the page is empty addr=%x\n", addr);
	PTE page;
	page.val=hwaddr_read((dir.page_frame<<12)+lnaddr.page*4, 4);
	assert(page.present==1);
	bool find=false;
	for (set=0; set<64; set++) 
		if (tlb[set].vaild==false) {
			tlb[set].vaild=true;
			tlb[set].data=page.page_frame;
			tlb[set].flag=(lnaddr.dir<<10)+lnaddr.page;
			find=true;
		}
	if (find==false) {
		set=addr%0x3f;
		tlb[set].vaild=true;
		tlb[set].flag=(lnaddr.dir<<10)+lnaddr.page;
		tlb[set].data=page.page_frame;
	}
	return (page.page_frame<<12)+lnaddr.offset;
}
Example #4
0
hwaddr_t page_translate(lnaddr_t addr){
	
	if ((cpu.cr0.protect_enable==0) || (cpu.cr0.paging==0)) return addr;
	/*
	uint16_t dir = addr >>22;
	uint16_t page = (addr >> 12) & 0x3ff;
	uint16_t offset = addr & 0xfff;
	uint32_t page_base= hwaddr_read((cpu.cr3.page_directory_base<<12) + dir*4, 4) >> 12;
	return offset + ((hwaddr_read((page_base<<12) + page*4, 4) >> 12) << 12);
	*/
	ln_addr lnaddr;
	lnaddr.val= addr;
	int i;
	for (i=0; i< NR_TLB; i++){
		if (tlb[i].valid&&(tlb[i].tag== lnaddr.tag)) break;
		if (!tlb[i].valid) break;
	}
	//if (i==NR_TLB) i=addr % NR_TLB;
	if (tlb[i].valid==0 || i==NR_TLB){
		if (i==NR_TLB) i=addr % NR_TLB;
		hwaddr_t pde_addr =(cpu.cr3.page_directory_base<<12)+lnaddr.dir*sizeof(PDE);
		PDE pde;
		pde.val=hwaddr_read(pde_addr, 4);
		hwaddr_t pte_addr = (pde.page_frame<< 12)+lnaddr.page*sizeof(PTE);
		PTE pte;
		pte.val= hwaddr_read(pte_addr, 4);
		tlb[i].tag= lnaddr.tag;
		tlb[i].valid = true;
		tlb[i].pte=pte;
	}
	return (tlb[i].pte.page_frame<< 12)+ lnaddr.offset;
	
}
Example #5
0
void page_debug(lnaddr_t addr){
	line_addr lnaddr;
	lnaddr.val = addr;
	printf("lnaddr = 0x%x, dir = 0x%x, page = 0x%x, offset = 0x%x\n", lnaddr.val, lnaddr.dir, lnaddr.page, lnaddr.offset);
	printf("cr3.page_directory_base = 0x%x, dir_entry_addr = 0x%x\n", cpu.cr3.page_directory_base, (cpu.cr3.page_directory_base << 12) + 4 * lnaddr.dir);
	PDE dir_entry;
	dir_entry.val = hwaddr_read((cpu.cr3.page_directory_base << 12) + lnaddr.dir * 4, 4);
	printf("page directory: present = %x, page_frame << 12 = 0x%x\n", dir_entry.present, dir_entry.page_frame<<12);

	PTE page_table_entry;
	page_table_entry.val = hwaddr_read((dir_entry.page_frame << 12) + 4 * lnaddr.page, 4);
	printf("page table item: present = %x, page_frame << 12 = 0x%x\n", page_table_entry.present, page_table_entry.page_frame<<12);

	printf("--->hwaddr = 0x%x\n",  (page_table_entry.page_frame << 12) + lnaddr.offset);
}
Example #6
0
uint32_t lnaddr_read(lnaddr_t addr, size_t len) {
#ifdef PAGING
    if (cpu.cr0.protect_enable && cpu.cr0.paging)
        addr = page_translate(addr);
#endif
	return hwaddr_read(addr, len);
}
Example #7
0
PTE page_read(lnaddr_t addr){
	line_addr lnaddr;
	lnaddr.val = addr;

	// first level page table - page directory entry
	PDE dir_entry;
	//Log("addr = 0x%x, dir = 0x%x, cr3.val = 0x%x, dir_entry_addr = 0x%x", addr, lnaddr.dir,cpu.cr3.val, (cpu.cr3.page_directory_base << 12) + 4 * lnaddr.dir);
	dir_entry.val = hwaddr_read((cpu.cr3.page_directory_base << 12) + 4 * lnaddr.dir, 4);
	Assert(dir_entry.present == 1, "dir_entry is not valid!  addr = 0x%x, dir = 0x%x", addr, lnaddr.dir);

	// second level page table - page table entry
	PTE page_table_entry;
	page_table_entry.val = hwaddr_read((dir_entry.page_frame << 12) + 4 * lnaddr.page, 4);
	Assert(page_table_entry.present == 1, "page_table_entry is not valid!  addr = 0x%x, page_frame = 0x%x, page_table_entry = 0x%x", 
			addr, dir_entry.page_frame, page_table_entry.val);
	return page_table_entry;
}
Example #8
0
PTE page_read(lnaddr_t addr, uint32_t len) {
    lnaddr_st lnaddr;
    lnaddr.val = addr;

    PDE dir_entry;
    dir_entry.val =
        hwaddr_read((cpu.cr._3.page_directory_base << 12) + 4 * lnaddr.dir, 4);
//	Assert(lnaddr.offset + len <= limit, "Cross page! %x %x", lnaddr.offset, len);
    Assert(dir_entry.present == 1, "dir_entry is not valid!  0x%x", addr);

    PTE pg_tbl_entry;
    pg_tbl_entry.val = hwaddr_read((dir_entry.page_frame << 12) + 4 * lnaddr.page, 4);
    Assert(pg_tbl_entry.present == 1, "pg_tbl_entry is not valid!  0x%x %x %x",
           addr, dir_entry.page_frame, pg_tbl_entry.val);

//	hwaddr_t hwaddr = (pg_tbl_entry.page_frame << 12) + lnaddr.offset;
    return pg_tbl_entry;
}
Example #9
0
void bmr_io_handler(ioaddr_t addr, size_t len, bool is_write) {
	int ret;
	if(is_write) {
		if(addr - BMR_PORT == 0) {
			if(bmr_base[0] & 0x1) {
				/* DMA start command */
				if(bmr_base[0] & 0x8) {
					/* DMA read */

					/* the address of Physical Region Descriptor Table */
					hwaddr_t prdt_addr = *(uint32_t *)(bmr_base + 4);

					hwaddr_t addr = hwaddr_read(prdt_addr, 4);
					uint32_t hi_entry = hwaddr_read(prdt_addr + 4, 4);
					uint16_t byte_cnt = hi_entry & 0xffff;

					sector = (ide_port_base[6] & 0x1f) << 24 | ide_port_base[5] << 16
						| ide_port_base[4] << 8 | ide_port_base[3];
					disk_idx = sector << 9;
					fseek(disk_fp, disk_idx, SEEK_SET);

					ret = fread((void *)hwa_to_va(addr), byte_cnt, 1, disk_fp);
					assert(ret == 1|| feof(disk_fp));

					/* We only implement PRDT of single entry. */
					assert(hi_entry & 0x80000000);

					/* finish */
					ide_port_base[7] = 0x40;
					i8259_raise_intr(IDE_IRQ);
				}
				else {
					/* DMA write is not implemented */
					assert(0);
				}
			}
		}
	}
}
Example #10
0
static int cmd_x(char *args){
    int num;
    uint32_t addr;
    uint32_t result;
    sscanf(args, "%d %x", &num, &addr);
    int i = 0;
    for( ; i<num; i++){
        result = hwaddr_read(addr, 4);
        printf("addr: \t0x%08x \tval: \t0x%08x\n", addr, result);
        addr += 4;
    }
    return 0;
}
Example #11
0
hwaddr_t page_translate(lnaddr_t addr){
	if(cpu.cr0.protect_enable==1&&cpu.cr0.paging==1){

		if(addr>=0xa0000&&addr<0xafa00)
			return addr;
		uint32_t hwaddr_base;	
		PDE my_pde;
		PTE my_pte;
		hwaddr_t my_hwaddr;
		uint32_t dir=((addr>>22)&0x3ff)<<2;
		uint32_t page=((addr>>12)&0x3ff)<<2;
		uint32_t offset=addr&0xfff;

		if(TLB_read(addr,&hwaddr_base))
		{
			return (hwaddr_base<<12)+offset;
		}
		my_pde.val=hwaddr_read((cpu.cr3.page_directory_base<<12)+dir,4);//page directory
		
	if(my_pde.present==0){
			Log("%x",addr);
			Assert(0,"eip=%x",cpu.eip);
			return addr;
		}
		my_pte.val=hwaddr_read((my_pde.page_frame<<12)+page,4);//page table
		if(my_pte.present==0){
			Log("my_pte=%x",my_pde.page_frame);
			assert(0);
			return addr;
		}
		if(TLB_write(my_pte.page_frame, addr)==false)
			printf("fail to write\n");
		my_hwaddr=(my_pte.page_frame<<12)+offset;
		return my_hwaddr;
	}
	else
		return addr;
Example #12
0
static int cmd_x(char *args)
{
	char *arg = strtok(NULL," ");
	int n = chartoint(args);
	arg = arg + strlen(arg) + 1;
	int len = strlen(arg);
	int i, m, re=0;
	for(i = len - 1, m = 1; len >= 2; len--){
		re = re + (arg[i] - '0') * m;
		m = m << 4;
	}
	for(i = 0; i < n;i++)
    		printf("0x%x\n", hwaddr_read(re + i, 4));
	return 0;
}
int eval(int p, int q)
{
    if(p > q)
    {
        printf("Error:bad expersion!\n");
        return 0;
    }
    else if(p == q)
    {
        if(tokens[q].type == IDENTIFIER || tokens[q].type == REG)
        {
            if(tokens[q].type == IDENTIFIER)
            {
                int tmpAddr = addrOfIdentify(tokens[q].str) ;
                if(tmpAddr != -1)
                    return tmpAddr;
                if(tokens[q].str[0] == '0' && tokens[q].str[1] == 'x')
                {
                    int i = strlen(tokens[q].str) - 1;
                    int tmp16 = 1;
                    int tmpResult = 0;
                    for( ; i > 1; i--)
                    {
                        char c = tokens[q].str[i];
                        if(c >= '0' && c <= '9')
                            c = c- '0';
                        if(c >= 'a' && c <= 'f')
                            c = c - 'a' + 10;
                        if(c >= 'A' && c <= 'F')
                            c = c -'A' + 10;
                        tmpResult = tmpResult + c * tmp16;
                        tmp16 *= 16;
                    }
                    return tmpResult;
                }
                return atoi(tokens[q].str);
            }
            else
            {
                return intFromReg(tokens[q].str + 1);
            }
        }
        else
        {
            printf("Error:while p == q, result should be a number\n");
            return 0;
        }
    }
    else if(check_parentheses(p, q))
    {
        return eval(p + 1, q - 1);
    }
    else
    {
        //we should do more here
        int opPosi = -1;
        int var1;
        int var2;
        opPosi = posiOfDomiOper(p, q);
        //printf("opPosi:%d\n", opPosi);
        if(opPosi == -1)
        {
            var1 = p;
            var2 = p;
            printf("Error : dominant operator find error\n");
        }
        else if(opPosi == p)
        {
            var2 = eval(opPosi + 1, q);
            var1 = var2;
            //printf("var2:%d\n", var2);
        }
        else
        {
            var1 = eval(p, opPosi - 1);
            var2 = eval(opPosi + 1, q);
        }
        //printf("opPosi: %d, var1:%d, vqr2 :%d", opPosi, var1, var2);
        switch(tokens[opPosi].type)
        {
        case '+':
            return var1 + var2;
        case '-':
            return var1 - var2;
        case '*':
                return var1 * var2;
        case '/':
            return var1 / var2;
        case EQ:
            return var1 == var2;
        case UEQ:
            return var1 != var2;
        case AND:
            return var1 && var2;
        case OR:
            return var1 || var2;
        case GREATER:
            return var1 > var2;
        case LOWER:
            return var1 < var2;
        case GEQ:
            return var1 >= var2;
        case LEQ:
            return var1 <= var2;
        case ADDR:
            return hwaddr_read(var2, 1);
        }
        return 0;
    }
}