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; }
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; }
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; }
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; }
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); }
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); }
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; }
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; }
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); } } } } }
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; }
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;
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; } }