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

📄 cp0.c

📁 skyeye for pxa270
💻 C
字号:
/*        cp0.c - read/write for cp0 register         Copyright (C) 2003 Skyeye Develop Group        for help please send mail to <skyeye-developer@lists.sf.linuxforum.net>        This program is free software; you can redistribute it and/or modify        it under the terms of the GNU General Public License as published by        the Free Software Foundation; either version 2 of the License, or        (at your option) any later version.        This program is distributed in the hope that it will be useful,        but WITHOUT ANY WARRANTY; without even the implied warranty of        MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the        GNU General Public License for more details.        You should have received a copy of the GNU General Public License        along with this program; if not, write to the Free Software        Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*//* * 12/21/2007   Michael.Kang  <blackfin.kang@gmail.com> */#include "skyeye_config.h"#include "instr.h"#include "emul.h"#include <stdio.h>// Access to the System Coprocessor registers.extern FILE *skyeye_logfd;UInt32 read_cp0(MIPS_State* mstate, int n, int sel) {    	switch (n) {		case Index:                {                        #if 0                        mstate->cp0[Index] = clear_bits(x, 30, 17); //Shi yang 2006-08-11                        mstate->cp0[Index] = clear_bits(x, 7, 0);                        #endif                        //printf("In %s, Index,x=0x%x\n", __FUNCTION__, mstate->cp0[Index]);                        return mstate->cp0[Index];                }    		case Random:    		{			return get_random(mstate);    		}	    	case Count:    		{			return mstate->cp0[Count] + ((mstate->now - mstate->count_seed) / 2);	    	}    		case Cause:    		{			//printf("KSDBG:read cause=0x%x, pc=0x%x\n", mstate->cp0[Cause], mstate->pc);			return mstate->cp0[Cause];			//return mstate->cp0[Cause] | (mstate->events & bitsmask(Cause_IP_Last, Cause_IP_First));    		}		case EPC:                {                        //fprintf(stderr, "read EPC, EPC = 0x%x, pc=0x%x\n", mstate->cp0[EPC], mstate->pc);                        return mstate->cp0[EPC];                }		case PRId:		{			return 0x04030200; /* the id of au1200 */		}		case Config:		{			if(sel) /* config1 */				return 0x3E63318a; /* config1 for au1200 */			else				return 0x80008083; /* config0 for au1200 */		}	    	default:			return mstate->cp0[n];    }}void write_cp0(MIPS_State* mstate, int n, UInt32 x){    	switch (n) {		case Index:    		{			#if 0			mstate->cp0[Index] = clear_bits(x, 30, 17); //Shi yang 2006-08-11			mstate->cp0[Index] = clear_bits(x, 7, 0);			#endif			mstate->cp0[Index] = x;			//printf("In %s,Write Index,x=0x%x\n", __FUNCTION__, x);			break;    		}	    	case Random: //Random register is a read-only register    		{			break;    		}	    	case EntryLo0:    		{			//mstate->cp0[EntryLo0] = clear_bits(x, 7, 0); //Shi yang 2006-08-11			mstate->cp0[EntryLo0] = x;			//printf("In %s,Write lo,x=0x%x,pc=0x%x\n", __FUNCTION__, x, mstate->pc);			break;    		}		case EntryLo1:    		{			//mstate->cp0[EntryLo0] = clear_bits(x, 7, 0); //Shi yang 2006-08-11			mstate->cp0[EntryLo1] = x;			//printf("In %s,Write lo1,x=0x%x,pc=0x%x,\n", __FUNCTION__, x, mstate->pc);			break;    		}	    	case Context:    		{			mstate->cp0[Context] = clear_bits(x, 1, 0); //Shi yang 2006-08-11			break;    		}	    	case BadVAddr: //BadVAddr register is a read-only register    		{			break;    		}	    	case Count:    		{			mstate->count_seed = mstate->now;			mstate->cp0[Count] = x;			mstate->now = mstate->now + (mstate->cp0[Compare] - (mstate->cp0[Count] + ((mstate->now - mstate->count_seed) / 2))) * 2;			break;    		}	    	case EntryHi:    		{			mstate->asid = bits(x, 11, 6); //Shi yang 2006-08-11			mstate->cp0[EntryHi] = x & (bitsmask(5, 0) |				    	       bitsmask(vaddr_width - 1, 12) |				    	       bitsmask(11, 6));			break;    		}    		case Compare:    		{			//fprintf(stderr, "KSDBG: in %s,write 0x%x to compare\n", __FUNCTION__, x);			mstate->cp0[Compare] = x;			mstate->events = clear_bit(mstate->events, 7 + Cause_IP_First);			mstate->now = mstate->now + (mstate->cp0[Compare] - (mstate->cp0[Count] + ((mstate->now - mstate->count_seed) / 2))) * 2;			mstate->cp0[Cause] &= 0xFFFF7FFF; /* clear IP bit in cause register for timer */			break;    		}	    	case SR:    		{			mstate->cp0[SR] = x & ~(bitsmask(27, 26) | bitsmask(24, 23) | bitsmask(7, 6)); //Shi yang 2006-08-11			//leave_kernel_mode(mstate);			break;    		}	    	case Cause:    		{			//fprintf(stderr, "write cause, cause = 0x%x,pc=0x%x\n", x, mstate->pc);			mstate->events |= x & bitsmask(Cause_IP1, Cause_IP0);			break;    		}	    	case EPC:    		{			//fprintf(stderr, "write EPC, EPC = 0x%x, pc=0x%x\n", x, mstate->pc);			mstate->cp0[EPC] = x;			break;    		}	    	case PRId: //PRId register is a read-only register    		{			break;    		}    		default:			printf("Reg=0x%x, not implemented instruction in %s\n",n, __FUNCTION__);			break;    		}}int decode_cop0(MIPS_State* mstate, Instr instr){	// CP0 is usable in kernel more or when the CU bit in SR is set.    	if (!(mstate->mode & kmode) && !bit(mstate->cp0[SR], SR_CU0))		process_coprocessor_unusable(mstate, 0);    	/* Only COP0, MFC0 and MTC0 make sense, although the R3K    	 * manuals say nothing about handling the others.         */    	if (bit(instr, 25)) {		switch (funct(instr)) {			case TLBR:			{			    	// Read Indexed TLB Entry				TLBEntry* e = &mstate->tlb[bits(mstate->cp0[Index], 13, 6)]; //Shi yang 2006-08-11			    	mstate->cp0[EntryHi] = e->hi | (bits(e->asid, 5, 0) << 6);			    	mstate->cp0[EntryLo0] = e->lo_reg[0];				mstate->cp0[EntryLo1] = e->lo_reg[1];			    	return nothing_special;			}			case TLBWI:			{			    	// Write Indexed TLB Entry				//printf("TLBWI,index=0x%x, pc=0x%x\n", mstate->cp0[Index], mstate->pc);			    	set_tlb_entry(mstate, mstate->cp0[Index]); //Shi yang 2006-08-11			    	return nothing_special;			}			case TLBWR:			{		    		// Write Random TLB Entry				//printf("TLBWR,index=0x%x, pc=0x%x\n", get_random(mstate), mstate->pc);			    	set_tlb_entry(mstate, get_random(mstate));			    	return nothing_special;			}			case TLBP:			{		    		// Probe TLB For Matching Entry			    	VA va = mstate->cp0[EntryHi];				//printf("TLBP, va=0x%x\n", va);		    		TLBEntry* e = probe_tlb(mstate, va);				//printf("TLBP, index=0x%x\n", e->index);			    	mstate->cp0[Index] = (e) ? e->index : bitmask(31);			    	return nothing_special;			}			case RFE: //Shi yang 2006-08-11			{				printf("RFE, return from exp, pc=0x%x\n", mstate->pc);				// Exception Return				leave_kernel_mode(mstate);				return nothing_special;			}			case ERET:			{				mstate->cp0[SR] &= 0xFFFFFFFD; /* Set Exl bit to zero */ 				//fprintf(stderr, "ERET, return from exp, v0=0x%x, pc=0x%x,epc=0x%x\n", mstate->gpr[2], mstate->pc, mstate->cp0[EPC]);				mstate->pc =  mstate->cp0[EPC];				//fprintf(stderr, "ERET, return from exp, epc=0x%x\n", mstate->cp0[EPC]);				if(mstate->cp0[Cause] & 1 << Cause_IP2)					skyeye_config.mach->mach_set_intr(0);/* clear the corresponding interrupt status register */				mstate->pipeline = branch_nodelay;				return nothing_special;			}			default:				process_reserved_instruction(mstate);		    		return nothing_special;		}    	} else {		switch (rs(instr)) {			case MFCz:			{		    		// Move From System Control Coprocessor				mstate->gpr[rt(instr)] = read_cp0(mstate, rd(instr), sel(instr));			    	return nothing_special;			}			case DMFCz:			{		    		// Doubleword Move From System Control Coprocessor				process_reserved_instruction(mstate);				return nothing_special;			}			case CFCz:			{		    		// Move Control From Coprocessor			    	return nothing_special;			}			case MTCz:			{		    		// Move To System Control Coprocessor			    	write_cp0(mstate, rd(instr), mstate->gpr[rt(instr)]);			    	return nothing_special;			}			case DMTCz:			{			    	// Doubleword Move To System Control Coprocessor				process_reserved_instruction(mstate);			    	return nothing_special;			}			case CTCz:			{				process_reserved_instruction(mstate);		    		// Move Control To Coprocessor			    	return nothing_special;			}			case BCz:			{			    	// Branch On Coprocessor Condition	    			switch (rt(instr)) {				    	case BCzF:				    	case BCzT:				    	case BCzFL:				    	case BCzTL:						process_reserved_instruction(mstate);						return nothing_special;	    				default:						process_reserved_instruction(mstate);						return nothing_special;	    			}			}			default:				    	process_reserved_instruction(mstate);					return nothing_special;		}    	}    	return nothing_special;}int decode_cop1(MIPS_State* mstate, Instr instr){	 //fprintf(stderr, "in %s\n", __FUNCTION__); 	// CP0 is usable in kernel more or when the CU bit in SR is set.    	if (!(mstate->mode & kmode) && !bit(mstate->cp0[SR], SR_CU0))		process_coprocessor_unusable(mstate, 0);    	/* Only COP0, MFC0 and MTC0 make sense, although the R3K    	 * manuals say nothing about handling the others.         */	switch (function(instr)){				case WAIT:			return nothing_special;		default:			//process_reserved_instruction(mstate);                        break;	}	switch (fmt(instr)){		case CF:					if(fs(instr) == 0)				mstate->gpr[ft(instr)] = mstate->fir;			else				fprintf(stderr, "In %s, not implement for CFC1 instruction\n", __FUNCTION__);			break;										default:			//process_reserved_instruction(mstate);			fprintf(stderr, "In %s,not implement instruction 0x%x\n", __FUNCTION__, instr);			break;	}	return nothing_special;}

⌨️ 快捷键说明

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