⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ppc_mmu.c

📁 SkyEye是一个可以运行嵌入式操作系统的硬件仿真工具
💻 C
📖 第 1 页 / 共 5 页
字号:
                //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 + -