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

📄 ppc_mmu.c

📁 SkyEye是一个可以运行嵌入式操作系统的硬件仿真工具
💻 C
📖 第 1 页 / 共 5 页
字号:
/* *	PearPC *	ppc_mmu.cc * *	Copyright (C) 2003, 2004 Sebastian Biallas (sb@biallas.net) *	Portions Copyright (C) 2004 Daniel Foesch (dfoesch@cs.nmsu.edu) *	Portions Copyright (C) 2004 Apple Computer, Inc. * *	This program is free software; you can redistribute it and/or modify *	it under the terms of the GNU General Public License version 2 as *	published by the Free Software Foundation. * *	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., 675 Mass Ave, Cambridge, MA 02139, USA. *//*	Pages marked: v.??? *	From: IBM PowerPC MicroProcessor Family: Altivec(tm) Technology... *		Programming Environments Manual */#include "debug.h"#include "tracers.h"#include "sysendian.h"#include "io.h"#include "ppc_cpu.h"#include "ppc_fpu.h"#include "ppc_vec.h"#include "ppc_mmu.h"#include "ppc_exc.h"#include "ppc_tools.h"#include "ppc_memory.h"#include "ppc_e500_exc.h"#define DEFAULT_CCSR_MEM 0xFF700000#define CCSR_MEM_SIZE 0x100000#define GET_CCSR_BASE(reg)(((reg >> 8)&0xFFF) << 20)e500_mmu_t e500_mmu;ppc_tlb_entry_t l1_i_vsp[4]; /* instruction, filled by TLB1 hit */ppc_tlb_entry_t l1_i_tlb4k[64]; /* instruction, filled by TLB0 hit */ppc_tlb_entry_t l1_d_vsp[4]; /* data, filled by TLB1 hit */ppc_tlb_entry_t l1_d_tlb4k[64]; /* data, filled by TLB0 hit */#define L2_TLB0_SIZE 256#define L2_TLB1_SIZE 16ppc_tlb_entry_t l2_tlb0_4k[L2_TLB0_SIZE]; /* unified, filled by tlbwe instruction */ppc_tlb_entry_t l2_tlb1_vsp[L2_TLB1_SIZE]; /* filled by tlbwe insructions *//*ea = effective addressif translation is an instruction address then	as = MSR[IS];else // data address translation	as = MSR[DS]for all TLB entries	if !TLB[entry].v then		next // compare next TLB entry	if as != TLB[entry].ts then		next // compare next TLB entry	if TLB[entry].tid == 0 then		goto pid_match	for all PID registers		if this PID register == TLB[entry].tid then			goto pid_match	endfor	next // no PIDs matched 	pid_match://translation match	mask = ~(1024 << (2 * TLB[entry].tsize)) - 01	if (ea & mask) != TLB[entry].epn then		next // no address match	real address = TLB[entry].rpn | (ea & ~mask) // real address computed	end translation --success	endfor	end translation tlb miss*/int ppc_effective_to_physical(uint32 addr, int flags, uint32 *result){	int i,j;	uint32 mask;	ppc_tlb_entry_t *entry;	int tlb1_index;	int pid_match = 0;	i = 0;	/* walk over tlb0 and tlb1 to find the entry */	while(i++ < (L2_TLB0_SIZE + L2_TLB1_SIZE)){		if(i > (L2_TLB0_SIZE - 1)){			tlb1_index = i - L2_TLB0_SIZE;			entry = &l2_tlb1_vsp[tlb1_index];		}		else			entry = &l2_tlb0_4k[i];		if(!entry->v)			continue;		/* FIXME, not check ts bit now */		if(entry->ts & 0x0)			continue;		if(entry->tid != 0){			for(j = 0; j < 3; j++){				if(e500_mmu.pid[j] == entry->tid)					break;			}			if(e500_mmu.pid[j] != entry->tid)				continue;		}		if(i > (L2_TLB0_SIZE - 1)){			int k,s = 1;			for(k = 0; k < entry->size; k++)				s = s * 4; 			mask = ~((1024 * (s - 1) - 0x1) + 1024);		}		else			mask = ~(1024 * 4 - 0x1);		if(entry->size != 0xb){			if((addr & mask) != ((entry->epn << 12) & mask))				continue;			*result = (entry->rpn << 12) | (addr & ~mask); // get real address		}		else {/*if 4G size is mapped, we will not do address check */			//fprintf(stderr,"warning:4G address is used.\n");			if(addr < (entry->epn << 12))				continue;			 *result = (entry->rpn << 12) | (addr - (entry->epn << 12)); // get real address		}		return PPC_MMU_OK;	}	if(ppc_exception(DATA_TLB, 0, addr))		return PPC_MMU_EXC;	return PPC_MMU_FATAL;	}int e500_mmu_init(){	/* the initial tlb map of real hardware */	ppc_tlb_entry_t * entry = &l2_tlb1_vsp[0];	entry->v = 1; /* entry is valid */	entry->ts = 0; /* address space 0 */	entry->tid = 0; /* TID value for shared(global) page */	entry->epn = 0xFFFFF; /* Address of last 4k byte in address space*/	entry->rpn = 0xFFFFF; /* Address of last 4k byte in address space*/	entry->size = 0x1; /* 4k byte page size */	/* usxrw should be initialized to 010101 */	entry->usxrw |= 0x15; /* Full supervisor mode access allowed */	entry->usxrw &= 0x15; /* No user mode access allowed */	entry->wimge = 0x8; /* Caching-inhibited, non-coherent,big-endian*/	entry->x = 0; /* Reserved system attributes */	entry->u = 0; /* User attribute bits */	entry->iprot = 1; /* Page is protected from invalidation */	gCPU.ccsr.ccsr = 0xFF700;	e500_mmu.tlbcfg[0] = 0x4110200;	e500_mmu.tlbcfg[1] = 0x101bc010;	gCPU.lb_ctrl.lcrr = 0x80000008;	gCPU.i2c_reg.i2csr = 0x81;	gCPU.i2c_reg.i2cdfsrr = 0x10;	gCPU.pic_ram.ctpr0 = 0x0000000F;	gCPU.pic_global.svr = 0xFFFF;}int FASTCALL ppc_read_effective_word(uint32 addr, uint32 *result){	uint32 p;	int r;	if (!(r = ppc_effective_to_physical(addr, PPC_MMU_READ, &p))) {		//printf("DBG:ccsr=0x%x,CCSR_BASE=0x%x\n",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:in %s,read CCSR,offset=0x%x,pc=0x%x\n", __FUNCTION__, offset, gCPU.pc);			if(offset >= 0x919C0 && offset <= 0x919E0){                                switch(offset){                                        case 0x919C0:                                                *result = gCPU.cpm_reg.cpcr;                                                return r;                                        default:	                                        fprintf(stderr,"in %s, error when read CCSR.offset=0x%x,pc=0x%x\n",__FUNCTION__, offset, gCPU.pc);                                        	skyeye_exit(-1);                                }                        }			 if(offset >= 0x2000 && offset <= 0x2E58){                                switch(offset){                                        case 0x2E44:                                                *result = gCPU.ddr_ctrl.err_disable;                                                return r;                                        default:                                                fprintf(stderr,"in %s, error when read CCSR.offset=0x%x,pc=0x%x\n",__FUNCTION__, offset, gCPU.pc);                                                skyeye_exit(-1);                                }                        }			                        /**                         *  PIC Register Address Map                         */                        if(offset >= 0x50000 && offset <= 0x600B0){				if(offset >= 0x50000 && offset <= 0x50170){					int index = (offset - 0x50000) >> 4;					if(index & 0x1)						*result = gCPU.pic_ram.eidr[index >> 1];					else						*result = gCPU.pic_ram.eivpr[index >> 1];					return r;				}				if(offset >= 0x50200 && offset <= 0x505F0){					int index = (offset - 0x50200) >> 4;					if(index & 0x1)						*result = gCPU.pic_ram.iidr[index >> 1];					else						*result = gCPU.pic_ram.iivpr[index >> 1];					return r;				}				                                switch(offset){					case 0x60080:						*result = gCPU.pic_ram.ctpr0;						return r;					case 0x600a0:						*result = gCPU.pic_percpu.iack0;						return r;                                        default:                                                fprintf(stderr,"in %s, error when write pic ram,offset=0x%x,pc=0x%x\n",__FUNCTION__, offset, gCPU.pc);                                                break;				}                        }					/**                         * Interrupt Controller                         */                        if(offset >= 0x90C00 && offset <= 0x90C7F){                                switch(offset){                                        case 0x90C08:                                                *result = gCPU.int_ctrl.sipnr_h;                                                return r;                                        case 0x90C0C:                                                *result = gCPU.int_ctrl.sipnr_l;                                                return r;                                        case 0x90C14:                                                *result = gCPU.int_ctrl.scprr_h;                                                return r;                                        case 0x90C18:                                                *result = gCPU.int_ctrl.scprr_l;                                                return r;                                        case 0x90C1C:                                                *result = gCPU.int_ctrl.simr_h;                                                return r;                                        case 0x90C20:                                                *result = gCPU.int_ctrl.simr_l;                                                return r;                                        default:                                                fprintf(stderr,"in %s, error when read interrupt controller,offset=0x%x,pc=0x%x\n",__FUNCTION__, offset, gCPU.pc);                                                return r;                                }                        }			if(offset >= 0x91A00 && offset <= 0x91A3F){                                int i = (0x20 & offset) >> 5;                                offset = 0x1f & offset;                                switch(offset){                                        case 0x0:                                                *result = gCPU.cpm_reg.scc[i].gsmrl;                                                return r;                                        default:                                                fprintf(stderr,"in %s, error when read CCSR.offset=0x%x, \                                pc=0x%x\n",__FUNCTION__, offset, gCPU.pc);                                                skyeye_exit(-1);                                }                        }			/* CPM MUX I/O */                        if(offset >= 0x91B00 && offset <= 0x91B1F){                                switch(offset){                                        case 0x91B08:                                                *result = gCPU.cpm_reg.mux.cmxscr;                                                return r;					case 0x91B04:						*result = gCPU.cpm_reg.mux.cmxfcr;						return r;                                        default:                                                fprintf(stderr,"in %s, error when read CCSR.offset=0x%x, \                                pc=0x%x\n",__FUNCTION__, offset, gCPU.pc);                                                skyeye_exit(-1);                                }                        }			/* PIC Global register */			if(offset >= 0x40000 && offset <= 0x4FFF0){				 switch(offset){					case 0x41000:						*result = gCPU.pic_global.frr= 0x370002; /* according to 8560 manual */						return r;					case 0x400a0:						*result = gCPU.pic_global.iack;						return r;					case 0x410f0:						*result = gCPU.pic_global.tfrr;						return r;                                        case 0x41020:                                                /* source attribute register for DMA0 */                                                *result = gCPU.pic_global.gcr;                                                return r;					case 0x410e0:                                                *result = gCPU.pic_global.svr;                                                return r;					case 0x41120:						*result = gCPU.pic_global.gtvpr0; 						return r;					case 0x41160:						*result = gCPU.pic_global.gtvpr1;									return r;					case 0x41170:                                                *result = gCPU.pic_global.gtdr1;                                                return r;                                        case 0x411a0:                                                *result = gCPU.pic_global.gtvpr2;                                                return r;                                        case 0x411B0:                                                *result = gCPU.pic_global.gtdr2;                                                returnr;					case 0x411E0:						*result = gCPU.pic_global.gtvpr3;                                                returnr;                                        default:                                                fprintf(stderr,"in %s, error when read global.offset=0x%x, \                                pc=0x%x\n",__FUNCTION__, offset, gCPU.pc);                                                return r;                                                //skyeye_exit(-1);                                }                        }			/* DMA */                        if(offset >= 0x21100 && offset <= 0x21300){                                switch(offset){                                        case 0x21110:                                                /* source attribute register for DMA0 */                                                *result = gCPU.dma.satr0;                                                return r;                                        case 0x21118:                                                *result = gCPU.dma.satr0;                                                return r;                                        default:                                                fprintf(stderr,"in %s, error when read dma.offset=0x%x, \                                pc=0x%x\n",__FUNCTION__, offset, gCPU.pc);                                                return r;                                                //skyeye_exit(-1);                                }                        }			/* Input/Output port */			if(offset >= 0x90D00 && offset <= 0x90D70){                                switch(offset){					case 0x90D00:						*result = gCPU.cpm_reg.ioport.pdira;						return r;                                        case 0x90D04:                                                *result = gCPU.cpm_reg.ioport.ppara;                                                return r;					case 0x90D08:                                                *result = gCPU.cpm_reg.ioport.psora;                                                return r;					case 0x90D0C:                                                *result = gCPU.cpm_reg.ioport.podra ;                                                return r;                                        case 0x90D10:                                                *result = gCPU.cpm_reg.ioport.pdata;                                                return r;					case 0x90D20:                                                *result = gCPU.cpm_reg.ioport.pdirb;                                                return r;                                        case 0x90D24:

⌨️ 快捷键说明

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