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

📄 skyeye硬件模拟平台,第三部分 硬件仿真实现之三.htm

📁 你想没有硬件就跑μc OS吗
💻 HTM
📖 第 1 页 / 共 5 页
字号:
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>
typedef struct wb_entry_s{
	ARMword pa;	//phy_addr
	ARMbyte *data;//data
	int nb;	//number byte to write
}wb_entry_t;

typedef struct wb_s{
	int num; 	//wb_entry_t的总数
	int nb;	 	//wb_entry_t中最大字节数
	int first;	//循环队列头
	int last;	//循环队列尾
	int used;	//循环队列中已用wb_entry_t的个数
	wb_entry_t *entrys;
}wb_t;
</CODE></PRE></TD></TR></TBODY></TABLE>
      <P>接口函数</P><A name=IDAEYPTB><B></B></A><BR>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>
    /*初始化和释放*/
int	mmu_wb_init(wb_t *wb_t, int num, int nb);
void	mmu_wb_exit(wb_t *wb);
/*数据入Write Buffer*/
void	mmu_wb_write_bytess(ARMul_State *state, wb_t *wb_t, ARMword pa,
				ARMbyte *data, int n);
/*将Write Buffer中数据全部写入内存*/
void	mmu_wb_drain_all(ARMul_State *state, wb_t *wb_t);
</CODE></PRE></TD></TR></TBODY></TABLE>
      <P>Read Buffer的实现(mmu/rb.[hc])</P>
      <P>数据结构</P><A name=IDANYPTB><B></B></A><BR>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>
typedef struct rb_entry_s{
	ARMword	data[RB_WORD_NUM];//array to store data
	ARMword	va;	//first word va
	int	type;		//rb type
	fault_t	fault;	//fault set by rb alloc
}rb_entry_t;

typedef struct rb_s{
	int num;
	rb_entry_t *entrys;
}rb_t;
</CODE></PRE></TD></TR></TBODY></TABLE>
      <P>接口函数</P><A name=IDAVYPTB><B></B></A><BR>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>
    /*初始化和释放*/
int mmu_rb_init(rb_t *rb_t, int num);
void mmu_rb_exit(rb_t *rb_t);
rb_entry_t *mmu_rb_search(rb_t *rb_t, ARMword va);/*查找*/
void mmu_rb_invalidate_entry(rb_t *rb_t, int i);/*无效*/
void mmu_rb_invalidate_all(rb_t *rb_t);
void mmu_rb_load(ARMul_State *state, rb_t *rb_t, int i_rb, int type, ARMword va);/*装入*/
</CODE></PRE></TD></TR></TBODY></TABLE>
      <P><A name=IDA2YPTB><SPAN class=atitle3>5. 
      与具体CPU类型相关的MMU模拟子模块</SPAN></A><BR>与具体CPU类型相关的MMU模拟子模块建立在与具体CPU无关的MMU模拟实现子模块的基础上,通过实现具体CPU的mmu_ops_t,完成具体CPU的MMU模拟。以下详细介绍StrongARM的MMU实现。</P>
      <P><A name=IDACZPTB><SPAN class=atitle3>6. StrongARM 
      MMU的组成结构</SPAN></A><BR>StrongARM的MMU分成指令和数据两部分。指令部分包括一个指令TLB和一个指令CACHE,数据部分包括一个数据TLB,两个数据CACHE(main 
      CACHE和 mini CACHE),一个Write Buffer和一个Read Buffer。如图 0 3所示:</P>
      <P><A name=IDAJZPTB><B>图 0-3 StrongARM数据访问功能部件图</B></A><BR><IMG height=305 
      alt="图 0-3 StrongARM数据访问功能部件图" 
      src="SkyEye硬件模拟平台,第三部分 硬件仿真实现之三.files/image005.gif" width=435 border=0 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"></P>
      <P><A name=IDAWZPTB><SPAN class=atitle3>7. StrongARM 
      mmu_ops_t的实现</SPAN></A><BR></P><A name=IDA1ZPTB><B></B></A><BR>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>
mmu_ops_t sa_mmu_ops = {
	sa_mmu_init,
	sa_mmu_exit,
	sa_mmu_read_byte,
	sa_mmu_write_byte,
	sa_mmu_read_halfword,
	sa_mmu_write_halfword,
	sa_mmu_read_word,
	sa_mmu_write_word,
	sa_mmu_load_instr,
	sa_mmu_mcr,
	sa_mmu_mrc,
};
</CODE></PRE></TD></TR></TBODY></TABLE>
      <P>SA MMU的初始化</P><A name=IDAD0PTB><B></B></A><BR>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>
typedef struct sa_mmu_desc_s{
	int	i_tlb;
	cache_desc_t i_cache;
	int d_tlb;
	cache_desc_t main_d_cache;
	cache_desc_t mini_d_cache;
	int	rb;
	wb_desc_t	wb;
}sa_mmu_desc_t;

static sa_mmu_desc_t sa11xx_mmu_desc ={
	32,
	{32, 32, 16, CACHE_WRITE_BACK},
	32,
	{32, 32, 8, CACHE_WRITE_BACK},
	{32, 2, 8, CACHE_WRITE_BACK},
	4,
	{8, 16}
};

typedef	struct sa_mmu_s{
	/*指令部分*/
	tlb_t	i_tlb;			/*指令tlb*/
	cache_t	i_cache;	/*指令cache*/
	/*数据部分*/	
	tlb_t	d_tlb;			/*数据tlb*/
	cache_t	main_d_cache;/*main cache*/
	cache_t	mini_d_cache;/*mini cache*/
	rb_t	rb_t;			/*Read Buffer*/
	wb_t	wb_t;			/*Write Buffer*/
}sa_mmu_t;
</CODE></PRE></TD></TR></TBODY></TABLE>
      <P>int sa_mmu_init(ARMul_State *state);<BR 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">sa_mmu_desc_t 是SA 
      MMU参数描述的数据结构,sa_mmu_t实现SA MMU 
      的数据表示。sa_mmu_init根据sa11xx_mmu_desc,完成对state-&gt;u.sa_mmu的初始化。</P>
      <P>SA MMU的数据读操作</P><A name=IDAP0PTB><B></B></A><BR>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>
static fault_t
sa_mmu_read(ARMul_State *state, ARMword va, ARMword *data, ARMword datatype)
{
	fault_t fault;
	rb_entry_t *rb;
	tlb_entry_t *tlb;
	cache_line_t *cache;
	ARMword pa, real_va,temp,offset;
	/*根据CP15 process id register转换地址*/
	va = mmu_pid_va_map(va);
	real_va=va;
	if (MMU_Disabled){
		/*如果MMU关闭,直接从内存读取*/
	        if (datatype==ARM_BYTE_TYPE)
                        *data = mem_read_byte(state, va);
                else if (datatype==ARM_HALFWORD_TYPE)
                        *data = mem_read_halfword(state, va);
                else if (datatype==ARM_WORD_TYPE)
                        *data = mem_read_word(state, va);
                else {
                        printf("SKYEYE:1 sa_mmu_read error: unknown data type %d\n",datatype);
                        exit(-1);
                }
	
		return 0;
	}

	/*align 异常检查*/
	if (((va &amp; 3 ) &amp;&amp; (datatype==ARM_WORD_TYPE) &amp;&amp; MMU_Aligned) || \
	    ((va &amp; 1 ) &amp;&amp; (datatype==ARM_HALFWORD_TYPE) &amp;&amp; MMU_Aligned) ){
		d_msg("align\n");
		return ALIGNMENT_FAULT;
	} // else
        va &amp;= ~(WORD_SIZE - 1);
		
	/*TTW得到tlb*/
	fault = translate(state, va, D_TLB(), &amp;tlb);
	if (fault){
		d_msg("translate\n");
		return fault;
	}
	/*访问控制检查*/
	fault = check_access(state, va, tlb, 1);
	if (fault)
		return fault;
	/*首先在Read Buffer中查找数据*/
	rb = mmu_rb_search(RB(), va);
	if (rb){
		if (rb-&gt;fault)
			return rb-&gt;fault;
		*data = rb-&gt;data[(va &amp; (rb_masks[rb-&gt;type]-1))&gt;&gt;WORD_SHT];
		goto datatrans; 
		//return 0;
	};
	/*其次查找main cache*/
	cache = mmu_cache_search(state, MAIN_D_CACHE(), va);
	if (cache){
		*data = cache-&gt;data[va_cache_index(va, MAIN_D_CACHE())];
		goto datatrans; 
		//return 0;
	}
	/*最后查找mini cache*/
	cache = mmu_cache_search(state, MINI_D_CACHE(), va);
	if (cache){
		*data = cache-&gt;data[va_cache_index(va, MINI_D_CACHE())];
		goto datatrans; 
		//return 0;
	}
	/*计算物理地址*/
	pa = tlb_va_to_pa(tlb, va);
   	/*如果在[0xe0000000, 0xe8000000]区间,执行mmu_cache_soft_flush*/
	if ((pa &gt;= 0xe0000000) &amp;&amp; (pa &lt; 0xe8000000)){
		if (tlb_c_flag(tlb)){
			if (tlb_b_flag(tlb)){
				mmu_cache_soft_flush(state, MAIN_D_CACHE(), pa);
			}else{
				mmu_cache_soft_flush(state, MINI_D_CACHE(), pa);
			}
		}
		return 0;
	}
	/*如果B=1,必须先清空Write Buffer*/
	if (tlb_b_flag(tlb))
		mmu_wb_drain_all(state, WB());
	if (tlb_c_flag(tlb) &amp;&amp; MMU_DCacheEnabled){
		/*如果C=1,并且Data Cache开启,将数据读入Cache*/
		cache_t *cache_t;
		if (tlb_b_flag(tlb))
			cache_t = MAIN_D_CACHE();
		else
			cache_t = MINI_D_CACHE();
		cache = mmu_cache_alloc(state, cache_t, va, pa);
		*data = cache-&gt;data[va_cache_index(va, cache_t)];
	}else{ 
		/*直接从内存读取*/
        	if (datatype==ARM_BYTE_TYPE)
                        *data = mem_read_byte(state, pa|(real_va&amp;3));
                else if (datatype==ARM_HALFWORD_TYPE)
                        *data = mem_read_halfword(state, 
pa|(real_va&amp;2));
                else if (datatype==ARM_WORD_TYPE)

⌨️ 快捷键说明

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