ppc_mmu.c

来自「skyeye是一个可以模拟嵌入式硬件开发板的系统软件」· C语言 代码 · 共 2,269 行 · 第 1/5 页

C
2,269
字号
			if(offset >= 0x919C0 && offset <= 0x919E0){				switch(offset){					case 0x919C0:						gCPU.cpm_reg.cpcr = data;						/* set FLG bit to zero, that means we are ready for new command*/						/* get sub block code */						if((0x1f & (gCPU.cpm_reg.cpcr >> 21)) == 0x4){							;/* we */								if((0xf & gCPU.cpm_reg.cpcr) == 0x0){							/* INIT Rx and Tx Param in SCC1 */							}						}						gCPU.cpm_reg.cpcr &= ~(1 << 16);						return r;					default:						break;					}			}			if(offset >= 0x91A00 && offset <= 0x91A1F){                                switch(offset){                                        case 0x91A00:                                                gCPU.cpm_reg.scc[0].gsmrl = data;						if(gCPU.cpm_reg.scc[0].gsmrl & 0x00000020)							; /* Enable Receive */						if(gCPU.cpm_reg.scc[0].gsmrl & 0x00000010)							; /* Enable Transmit */                                                return r;					case 0x91A04:                                                gCPU.cpm_reg.scc[0].gsmrh = data;                                                return r;                                        default:                                                fprintf(stderr,"in %s, error when read CCSR.addr=0x%x, \				pc=0x%x\n",__FUNCTION__, addr, gCPU.pc);                                                skyeye_exit(-1);                                }                        }			/* CPM MUX I/O */			if(offset >= 0x91B00 && offset <= 0x91B1F){				switch(offset){                                        case 0x91B08:                                                gCPU.cpm_reg.mux.cmxscr = data;                                                return r;                                        default:                                                fprintf(stderr,"in %s, error when read CCSR.addr=0x%x, \                                pc=0x%x\n",__FUNCTION__, addr, gCPU.pc);                                                skyeye_exit(-1);                                }			}			/* Input/Output port */                        if(offset >= 0x90D00 && offset <= 0x90D70){                                switch(offset){					case 0x90D00:                                                gCPU.cpm_reg.ioport.pdira = data;                                                return r;                                        case 0x90D04:                                                gCPU.cpm_reg.ioport.ppara = data;                                                return r;					case 0x90D08:                                                gCPU.cpm_reg.ioport.psora = data;                                                return r;					case 0x90D0C:						gCPU.cpm_reg.ioport.podra = data;						return r;					case 0x90D10:                                                gCPU.cpm_reg.ioport.pdata = data;                                                return r;                                        default:                                                fprintf(stderr,"in %s, error when write io port.addr=0x%x, \                                pc=0x%x\n",__FUNCTION__, addr, gCPU.pc);						return r;                                                //skyeye_exit(-1);                                }                        }			/* DMA */			if(offset >= 0x21100 && offset <= 0x21300){				switch(offset){					case 0x21110:						/* source attribute register for DMA0 */						gCPU.dma.satr0 = data;						return r;					case 0x21118:						gCPU.dma.satr0 = data;						return r;					default:                                                fprintf(stderr,"in %s, error when write dma.addr=0x%x, \                                pc=0x%x\n",__FUNCTION__, addr, gCPU.pc);						return r;                                                //skyeye_exit(-1);				}			}			/* BRG */			if(offset >= 0x919F0 && offset <= 0x919FC){				gCPU.cpm_reg.brgc[(offset - 0x919F0)/4] = data;                                return r;			}			if(offset >= 0x80000 && offset < 0x8C000){				//printf("DBG_CPM:in %s,offset=0x%x,data=0x%x,pc=0x%x\n",__FUNCTION__, offset, data, gCPU.pc);                                *((sint32 *)&gCPU.cpm_reg.dpram[offset - 0x80000]) = ppc_word_to_BE(data);                                return r;                        }			if(offset >= 0x8C00 && offset <= 0x8DFC)			{				switch(offset){				case 0x8C20:					gCPU.pci_atmu.potar1 = data;					return r;				case 0x8C24:					gCPU.pci_atmu.potear1 = data;					return r;				case 0x8C28:					gCPU.pci_atmu.powbar1 = data;					return r;				case 0x8C2C:					gCPU.pci_atmu.reserv1 = data;					return r;				case 0x8C30:					gCPU.pci_atmu.powar1 = data;					return r;				default:					fprintf(stderr,"in %s, error when write to PCI_ATMU.addr=0x%x,pc=0x%x\n",__FUNCTION__,addr,gCPU.pc);					//skyeye_exit(-1);					return r;				}			}			if(offset >= 0x40000 && offset <= 0x4FFF0){				switch(offset){                                        case 0x41020:                                                /* source attribute register for DMA0 */                                                gCPU.pci_global.gcr = data;                                                return r;                                        default:                                                fprintf(stderr,"in %s, error when write global.addr=0x%x,pc=0x%x\n",__FUNCTION__, addr, gCPU.pc);                                                return r;                                                //skyeye_exit(-1);                                }			}			switch(offset){				case 0x0:					gCPU.ccsr.ccsr = data;					break;				 case 0x90C80:                                        gCPU.sccr = data;                                        break;				case 0x50D4:                                        gCPU.lb_ctrl.lcrr = data;                                        return r;				case 0x3008:					gCPU.i2c_reg.i2ccr = data;					return r;				case 0xe0e10:                                        gCPU.debug_ctrl.ddrdllcr = data;                                        return r;				case 0x8000:					gCPU.pci_cfg.cfg_addr = data;					return r;				case 0x8004:                                        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 )))                        *((int *)&boot_rom[p - boot_rom_start_addr]) = ppc_word_to_BE(data);		else if((p >= init_ram_start_addr) && (p < (init_ram_start_addr + init_ram_size)))			*((int *)&init_ram[p - init_ram_start_addr]) = ppc_word_to_BE(data);		else if((p >= 0x0) && (p < (0x0 + DDR_RAM_SIZE))){			fprintf(prof_file, "DDR_ram write:addr=0x%x,data=0x%x\n", p, data);			//*((int *)&ddr_ram[p]) = ppc_word_to_BE(data);			*((int *)&ddr_ram[p]) = ppc_word_to_BE(data);			ddr_write_counter++;			}                else{                        fprintf(stderr,"in %s, can not find address 0x%x,pc=0x%x\n", __FUNCTION__, p, gCPU.pc);                        skyeye_exit(-1);                }	}	return r;}int FASTCALL ppc_write_effective_half(uint32 addr, uint16 data){		uint32 p;	int r;	if (!((r=ppc_effective_to_physical(addr, PPC_MMU_WRITE, &p)))) {		//printf("DBG:in %s,addr=0x%x,p=0x%x, data=0x%x\n", __FUNCTION__, addr,p, data);		//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,pc=0x%x\n", data, offset,gCPU.pc);			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 >= 0x5000 && offset <= 0x5038){				gCPU.lb_ctrl.br[(offset - 0x5000)/0x8] = data;				return r;			}			if(offset >= 0x91A00 && offset <= 0x91A1F){                                switch(offset){                                        case 0x91A00:                                                gCPU.cpm_reg.scc[0].gsmrl = data;                                                return r;					case 0x91A04:						gCPU.cpm_reg.scc[0].gsmrh = data;						return r;					case 0x91A08:						gCPU.cpm_reg.scc[0].psmr = data;                                                return r;					case 0x91A14:						gCPU.cpm_reg.scc[0].sccm = data;						return r;											case 0x91A10:						gCPU.cpm_reg.scc[0].scce = data;						return r;                                        default:                                                fprintf(stderr,"in %s, error when read CCSR.addr=0x%x, \                                pc=0x%x\n",__FUNCTION__, addr, gCPU.pc);                                                skyeye_exit(-1);                                }                        }			if(offset >= 0x919C0 && offset <= 0x919E0){				switch(offset){					case 0x919C0:						gCPU.cpm_reg.cpcr = 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);				}			}			if(offset >= 0x80000 && offset < 0x8C000){				//printf("DBG_CPM:in %s,offset=0x%x,data=0x%x,pc=0x%x\n",__FUNCTION__, offset, data, gCPU.pc);                                *((sint16 *)&gCPU.cpm_reg.dpram[offset - 0x80000]) = ppc_half_to_BE(data);                                return r;                        }			switch(offset){				case 0x0:					gCPU.ccsr.ccsr = data;					break;				case 0x90C80:                                        gCPU.sccr = data;                                        break;				case 0x8004:					gCPU.pci_cfg.cfg_data = data;					break;				case 0x8006:					gCPU.pci_cfg.cfg_data = data;					break;				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 )))                        *((sint16 *)&boot_rom[p - boot_rom_start_addr]) = ppc_half_to_BE(data);		else if((p >= init_ram_start_addr) && (p < (init_ram_start_addr + init_ram_size)))			*((sint16 *)&init_ram[p - init_ram_start_addr]) = ppc_half_to_BE(data);		else if((p >= 0x0) && (p < (0x0 + DDR_RAM_SIZE))){                        fprintf(prof_file, "DDR_ram write:addr=0x%x,data=0x%x\n", p, data);                        *((sint16 *)&ddr_ram[p]) = ppc_half_to_BE(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;}int FASTCALL ppc_write_effective_byte(uint32 addr, uint8 data){	uint32 p;        int r;        if (!((r=ppc_effective_to_physical(addr, PPC_MMU_WRITE, &p)))) {                //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){                                                            				//printf("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;}/*************************************************************************** *	DMA Interface */bool	ppc_dma_write(uint32 dest, const void *src, uint32 size){	if (dest > boot_romSize || (dest+size) > boot_romSize) return false;		byte *ptr;	ppc_direct_physical_memory_handle(dest, ptr);		memcpy(ptr, src, size);	return true;}bool	ppc_dma_read(void *dest, uint32 src, uint32 size){	if (src > boot_romSize || (src+size) > boot_romSize) return false;		byte *ptr;	ppc_direct_physical_memory_handle(src, ptr);		memcpy(dest, ptr, size);	return true;}bool	ppc_dma_set(uint32 dest, int c, uint32 size){	if (dest > boot_romSize || (dest+size) > boot_romSize) return false;		byte *ptr;	ppc_direct_physical_memory_handle(dest, ptr);		memset(ptr, c, size);	return true;}/*************************************************************************** *	DEPRECATED prom interface */bool ppc_prom_set_sdr1(uint32 newval, bool quiesce){	return ppc_mmu_set_sdr1(newval, quiesce);}bool ppc_prom_effective_to_physical(uint32 *result, uint32 ea){	return ppc_effective_to_physical(ea, PPC_MMU_READ|PPC_MMU_SV|PPC_MMU_NO_EXC, result) == PPC_MMU_OK;}bool ppc_prom_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)) {

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?