📄 ppc_mmu.c
字号:
//printf("DBG:in %s,addr=0x%x,p=0x%x, data=0x%x, pc=0x%x\n", __FUNCTION__, addr,p, data, gCPU.pc); //printf("DBG:ccsr=0x%x,CCSR_BASE=0x%x",gCPU.ccsr.ccsr,GET_CCSR_BASE(gCPU.ccsr.ccsr)); if(p >= GET_CCSR_BASE(gCPU.ccsr.ccsr) && p <(GET_CCSR_BASE(gCPU.ccsr.ccsr) + CCSR_MEM_SIZE)){ int offset = p - GET_CCSR_BASE(gCPU.ccsr.ccsr); //printf("DBG:write to CCSR,value=0x%x,offset=0x%x\n", data, offset); if(offset >= 0xC08 && offset <= 0xCF0){ if(offset & 0x8){ gCPU.law.lawbar[(offset - 0xC08)/0x20] = data; }else{ gCPU.law.lawar[(offset - 0xC10)/0x20] = data; } return r; } if(offset >= 0x80000 && offset < 0x8C000){ //fprintf(prof_file,"DBG_CPM:in %s,offset=0x%x,data=0x%x,pc=0x%x\n",__FUNCTION__, offset, data, gCPU.pc); *((byte *)&gCPU.cpm_reg.dpram[offset - 0x80000]) = data; return r; } switch(offset){ case 0x0: gCPU.ccsr.ccsr = data; break; case 0x3000: gCPU.i2c_reg.i2cadr = data; return r; case 0x3004: gCPU.i2c_reg.i2cfdr = data; return r; case 0x3008: gCPU.i2c_reg.i2ccr = data; return r; case 0x300C: gCPU.i2c_reg.i2csr = data; return r; case 0x3010: gCPU.i2c_reg.i2cdr = data; /* set bit of MIF */ gCPU.i2c_reg.i2csr |= 0x02; return r; case 0x3014: gCPU.i2c_reg.i2cdfsrr = data; return r; case 0x8004: gCPU.pci_cfg.cfg_data = data; return r; case 0x8005: gCPU.pci_cfg.cfg_data = data; return r; default: fprintf(stderr,"in %s, error when write to CCSR.addr=0x%x,pc=0x%x\n",__FUNCTION__,addr,gCPU.pc); skyeye_exit(-1); } } else if((p >= boot_rom_start_addr) && (p < (boot_rom_start_addr + boot_romSize ))) *((byte *)&boot_rom[p - boot_rom_start_addr]) = data; else if((p >= init_ram_start_addr) && (p < (init_ram_start_addr + init_ram_size))) *((byte *)&init_ram[p - init_ram_start_addr]) = data; else if((p >= 0x0) && (p < (0x0 + DDR_RAM_SIZE))){ *((byte *)&ddr_ram[p]) = data; } else{ fprintf(stderr,"in %s, can not find address 0x%x,pc=0x%x\n", __FUNCTION__, p, gCPU.pc); skyeye_exit(-1); } } return r;}void ppc_mmu_tlb_invalidate(){ gCPU.effective_code_page = 0xffffffff;}/*pagetable:min. 2^10 (64k) PTEGsPTEG = 64byteThe page table can be any size 2^n where 16 <= n <= 25.A PTEG contains eightPTEs of eight bytes each; therefore, each PTEG is 64 bytes long.*/bool FASTCALL ppc_mmu_set_sdr1(uint32 newval, bool quiesce){ /* if (newval == gCPU.sdr1)*/ quiesce = false; PPC_MMU_TRACE("new pagetable: sdr1 = 0x%08x\n", newval); uint32 htabmask = SDR1_HTABMASK(newval); uint32 x = 1; uint32 xx = 0; int n = 0; while ((htabmask & x) && (n < 9)) { n++; xx|=x; x<<=1; } if (htabmask & ~xx) { PPC_MMU_TRACE("new pagetable: broken htabmask (%05x)\n", htabmask); return false; } uint32 htaborg = SDR1_HTABORG(newval); if (htaborg & xx) { PPC_MMU_TRACE("new pagetable: broken htaborg (%05x)\n", htaborg); return false; } gCPU.pagetable_base = htaborg<<16; gCPU.sdr1 = newval; gCPU.pagetable_hashmask = ((xx<<10)|0x3ff); PPC_MMU_TRACE("new pagetable: sdr1 accepted\n"); PPC_MMU_TRACE("number of pages: 2^%d pagetable_start: 0x%08x size: 2^%d\n", n+13, gCPU.pagetable_base, n+16); if (quiesce) { //prom_quiesce(); } return true;}bool FASTCALL ppc_mmu_page_create(uint32 ea, uint32 pa){ uint32 sr = gCPU.sr[EA_SR(ea)]; uint32 page_index = EA_PageIndex(ea); // 16 bit uint32 VSID = SR_VSID(sr); // 24 bit uint32 api = EA_API(ea); // 6 bit (part of page_index) uint32 hash1 = (VSID ^ page_index); uint32 pte, pte2; uint32 h = 0; int j; for (j=0; j<2; j++) { uint32 pteg_addr = ((hash1 & gCPU.pagetable_hashmask)<<6) | gCPU.pagetable_base; int i; for (i=0; i<8; i++) { if (ppc_read_physical_word(pteg_addr, &pte)) { PPC_MMU_ERR("read physical in address translate failed\n"); return false; } if (!(pte & PTE1_V)) { // free pagetable entry found pte = PTE1_V | (VSID << 7) | h | api; pte2 = (PA_RPN(pa) << 12) | 0; if (ppc_write_physical_word(pteg_addr, pte) || ppc_write_physical_word(pteg_addr+4, pte2)) { return false; } else { // ok return true; } } pteg_addr+=8; } hash1 = ~hash1; h = PTE1_H; } return false;}inline bool FASTCALL ppc_mmu_page_free(uint32 ea){ return true;}inline int FASTCALL ppc_direct_physical_memory_handle(uint32 addr, byte *ptr){ if (addr < boot_romSize) { ptr = &boot_rom[addr]; return PPC_MMU_OK; } return PPC_MMU_FATAL;}int FASTCALL ppc_direct_effective_memory_handle(uint32 addr, byte *ptr){ uint32 ea; int r; if (!((r = ppc_effective_to_physical(addr, PPC_MMU_READ, &ea)))) { return ppc_direct_physical_memory_handle(ea, ptr); } return r;}int FASTCALL ppc_direct_effective_memory_handle_code(uint32 addr, byte *ptr){ uint32 ea; int r; if (!((r = ppc_effective_to_physical(addr, PPC_MMU_READ | PPC_MMU_CODE, &ea)))) { return ppc_direct_physical_memory_handle(ea, ptr); } return r;}inline int FASTCALL ppc_read_physical_qword(uint32 addr, Vector_t *result){ if (addr < boot_romSize) { // big endian VECT_D(*result,0) = ppc_dword_from_BE(*((uint64*)(boot_rom+addr))); VECT_D(*result,1) = ppc_dword_from_BE(*((uint64*)(boot_rom+addr+8))); return PPC_MMU_OK; } return io_mem_read128(addr, (uint128 *)result);}inline int FASTCALL ppc_read_physical_dword(uint32 addr, uint64 *result){ if (addr < boot_romSize) { // big endian *result = ppc_dword_from_BE(*((uint64*)(boot_rom+addr))); return PPC_MMU_OK; } int ret = io_mem_read64(addr, result); *result = ppc_bswap_dword(result); return ret;}int FASTCALL ppc_read_physical_word(uint32 addr, uint32 *result){ if (addr < boot_romSize) { // big endian *result = ppc_word_from_BE(*((uint32*)(boot_rom+addr))); return PPC_MMU_OK; } int ret = io_mem_read(addr, result, 4); *result = ppc_bswap_word(result); return ret;}inline int FASTCALL ppc_read_physical_half(uint32 addr, uint16 *result){ if (addr < boot_romSize) { // big endian *result = ppc_half_from_BE(*((uint16*)(boot_rom+addr))); return PPC_MMU_OK; } uint32 r; int ret = io_mem_read(addr, r, 2); *result = ppc_bswap_half(r); return ret;}inline int FASTCALL ppc_read_physical_byte(uint32 addr, uint8 *result){ if (addr < boot_romSize) { // big endian *result = boot_rom[addr]; return PPC_MMU_OK; } uint32 r; int ret = io_mem_read(addr, r, 1); *result = r; return ret;}inline int FASTCALL ppc_read_effective_code(uint32 addr, uint32 *result){ if (addr & 3) { // EXC..bla return PPC_MMU_FATAL; } uint32 p; int r; if (!((r=ppc_effective_to_physical(addr, PPC_MMU_READ | PPC_MMU_CODE, &p)))) { return ppc_read_physical_word(p, result); } return r;}inline int FASTCALL ppc_read_effective_qword(uint32 addr, Vector_t *result){ uint32 p; int r; addr &= ~0x0f; if (!(r = ppc_effective_to_physical(addr, PPC_MMU_READ, &p))) { return ppc_read_physical_qword(p, result); } return r;}inline int FASTCALL ppc_read_effective_dword(uint32 addr, uint64 *result){ uint32 p; int r; if (!(r = ppc_effective_to_physical(addr, PPC_MMU_READ, &p))) {#if 0 if (EA_Offset(addr) > 4088) { // read overlaps two pages.. tricky byte *r1, *r2; byte b[14]; ppc_effective_to_physical((addr & ~0xfff)+4089, PPC_MMU_READ, &p); if ((r = ppc_direct_physical_memory_handle(p, r1))) return r; if ((r = ppc_effective_to_physical((addr & ~0xfff)+4096, PPC_MMU_READ, &p))) return r; if ((r = ppc_direct_physical_memory_handle(p, r2))) return r; memmove(&b[0], r1, 7); memmove(&b[7], r2, 7); memmove(&result, &b[EA_Offset(addr)-4089], 8); result = ppc_dword_from_BE(result); return PPC_MMU_OK; } else { return ppc_read_physical_dword(p, result); }#endif } return r;}inline int FASTCALL ppc_write_physical_qword(uint32 addr, Vector_t *data){ if (addr < boot_romSize) { // big endian *((uint64*)(boot_rom+addr)) = ppc_dword_to_BE(VECT_D(*data,0)); *((uint64*)(boot_rom+addr+8)) = ppc_dword_to_BE(VECT_D(*data,1)); return PPC_MMU_OK; } if (io_mem_write128(addr, (uint128 *)data) == IO_MEM_ACCESS_OK) { return PPC_MMU_OK; } else { return PPC_MMU_FATAL; }}inline int FASTCALL ppc_write_physical_dword(uint32 addr, uint64 data){ if (addr < boot_romSize) { // big endian *((uint64*)(boot_rom+addr)) = ppc_dword_to_BE(data); return PPC_MMU_OK; } if (io_mem_write64(addr, ppc_bswap_dword(data)) == IO_MEM_ACCESS_OK) { return PPC_MMU_OK; } else { return PPC_MMU_FATAL; }}inline int FASTCALL ppc_write_physical_word(uint32 addr, uint32 data){ if (addr < boot_romSize) { // big endian *((uint32*)(boot_rom+addr)) = ppc_word_to_BE(data); return PPC_MMU_OK; } return io_mem_write(addr, ppc_bswap_word(data), 4);}inline int FASTCALL ppc_write_effective_qword(uint32 addr, Vector_t data){ uint32 p; int r; addr &= ~0x0f; if (!((r=ppc_effective_to_physical(addr, PPC_MMU_WRITE, &p)))) { return ppc_write_physical_qword(p, &data); } return r;}inline int FASTCALL ppc_write_effective_dword(uint32 addr, uint64 data){ uint32 p; int r; if (!((r=ppc_effective_to_physical(addr, PPC_MMU_WRITE, &p)))) { if (EA_Offset(addr) > 4088) { // write overlaps two pages.. tricky byte *r1, *r2; byte b[14]; ppc_effective_to_physical((addr & ~0xfff)+4089, PPC_MMU_WRITE, &p); if ((r = ppc_direct_physical_memory_handle(p, r1))) return r; if ((r = ppc_effective_to_physical((addr & ~0xfff)+4096, PPC_MMU_WRITE, &p))) return r; if ((r = ppc_direct_physical_memory_handle(p, r2))) return r; data = ppc_dword_to_BE(data); memmove(&b[0], r1, 7); memmove(&b[7], r2, 7); memmove(&b[EA_Offset(addr)-4089], &data, 8); memmove(r1, &b[0], 7); memmove(r2, &b[7], 7); return PPC_MMU_OK; } else { return ppc_write_physical_dword(p, data); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -