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

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

📁 你想没有硬件就跑μc OS吗
💻 HTM
📖 第 1 页 / 共 5 页
字号:
	ARMword	process_id;  	//CP15 process id register
	mmu_ops_t	ops;				
	union{
		sa_mmu_t	sa_mmu;
		arm7100_mmu_t  arm7100_mmu;
	}u;
} mmu_state_t;

typedef struct mmu_ops_s{
	int (*init)(ARMul_State *state);/*initilization*/	
	void (*exit)(ARMul_State *state);/*free on exit*/ 
	fault_t (*read_byte)(ARMul_State *state, ARMword va, ARMword *data);
	fault_t (*write_byte)(ARMul_State *state, ARMword va, ARMword data);
	fault_t (*read_halfword)(ARMul_State *state, ARMword va, ARMword *data);
	fault_t (*write_halfword)(ARMul_State *state, ARMword va,ARMword data);
	fault_t (*read_word)(ARMul_State *state, ARMword va,ARMword *data);
	fault_t (*write_word)(ARMul_State *state, ARMword va,ARMword data);
	fault_t (*load_instr)(ARMul_State *state, ARMword va, ARMword *instr);
	void (*mcr)(ARMul_State *state, ARMword instr, ARMword val);
	ARMword (*mrc)(ARMul_State *state, ARMword instr);
}mmu_ops_t;
</CODE></PRE></TD></TR></TBODY></TABLE>
      <P>数据结构ARMul_State中类型为mmu_state_t的mmu代表模拟中MMU的状态。mmu_state_t中的ops提供具体mmu的接口函数,同时包括一个联合结构u用于具体mmu实现的数据结构。</P>
      <P><A name=IDAAEKTB><SPAN class=atitle3>4. 
      与具体CPU类型无关的MMU模拟子模块</SPAN></A><BR>与具体CPU类型无关的MMU模拟子模块是实现MMU模拟的基础,它实现了TLB,TTW, 
      访问控制,CACHE, Write Buffer,Read 
      Buffer等MMU要素的模拟,并且提供了较统一的接口,可以较灵活地组合实现具体MMU模拟。</P>
      <P>TLB的实现(mmu/tlb.[ch])<BR 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">TLB是一个表,它的表项包含地址映射信息和访问控制信息,地址转换信息只有在该表中查询不到时,才通过TTW在内存中查找。</P>
      <P>数据结构</P>
      <P>TLB 映射类型</P><A name=IDAMEKTB><B></B></A><BR>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>
typedef enum tlb_mapping_t {
	TLB_INVALID = 0,
	TLB_SMALLPAGE = 1,
	TLB_LARGEPAGE = 2,
	TLB_SECTION = 3
} tlb_mapping_t;
</CODE></PRE></TD></TR></TBODY></TABLE>
      <P>TLB 表项</P><A name=IDAUEKTB><B></B></A><BR>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>
typedef struct tlb_entry_t {
	ARMword		virt_addr;  	//virtual address
	ARMword		phys_addr; 	//physical address
	ARMword		perms;     	//access permission
	ARMword		domain;   	//access domain
	tlb_mapping_t	mapping;	//tlb mapping type
} tlb_entry_t;
</CODE></PRE></TD></TR></TBODY></TABLE>
      <P>TLB 表</P><A name=IDA2EKTB><B></B></A><BR>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>
typedef struct tlb_s{
	int num;			/*num of tlb entry*/
	int cycle;			/*current tlb cycle,used for allocate tlb_entry*/
	tlb_entry_t	*entrys;
}tlb_t; 
</CODE></PRE></TD></TR></TBODY></TABLE>
      <P>接口函数</P><A name=IDAEFKTB><B></B></A><BR>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>
   int mmu_tlb_init(tlb_t *tlb_t, int num);
   初始化TLB
void mmu_tlb_exit(tlb_t *tlb_t);
   释放TLB
void mmu_tlb_invalidate_all(ARMul_State *state, tlb_t *tlb_t);
  无效所有的tlb_entry
void mmu_tlb_invalidate_entry(ARMul_State *state, tlb_t *tlb_t, ARMword virt_addr);
  无效包含指定virt_addr的tlb_entry.
tlb_entry_t * mmu_tlb_search(ARMul_State *state, tlb_t *tlb_t, ARMword virt_addr);
   根据virt_addr查找tlb_entry
   </CODE></PRE></TD></TR></TBODY></TABLE>
      <P>TTW的实现(mmu/tlb.[ch])<BR 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">ARM系统中通过2级映射,实现了页式地址转换。</P>
      <P>接口函数</P><A name=IDAQFKTB><B></B></A><BR>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>
fault_t translate(ARMul_State *state, ARMword virt_addr, tlb_t *tlb_t, tlb_entry_t **tlb)
{
	/*首先查找TLB表,如果没有找到,执行TTW并更新TLB表*/

	*tlb = mmu_tlb_search(state, tlb_t, virt_addr);/*查找tlb*/
	if (!*tlb) {
		/* 没有找到,进行TTW*/
		ARMword l1addr, l1desc; /*一级描述符地址、一级描述符*/
		tlb_entry_t entry;

		l1addr = state-&gt;mmu.translation_table_base &amp; 0xFFFFC000;
		l1addr = (l1addr | (virt_addr &gt;&gt; 18)) &amp; ~3;	/*计算一级描述符地址*/
		l1desc = mem_read_word(state, l1addr);	/*读取一级描述符*/
		switch (l1desc &amp; 3) {
		case 0:
		case 3:
			return SECTION_TRANSLATION_FAULT;
		case 1:
			/*页式变换*/
			{
				ARMword l2addr, l2desc; /*二级描述符的地址,二级描述符*/

				l2addr = l1desc &amp; 0xFFFFFC00;
				/*计算二级描述符的地址*/
				l2addr = (l2addr | ((virt_addr &amp; 0x000FF000) &gt;&gt; 10)) &amp; ~3;
				/*读取二级描述符*/
				l2desc = mem_read_word(state, l2addr);

				entry.virt_addr = virt_addr;
				entry.phys_addr = l2desc;
				entry.perms = l2desc &amp; 0x00000FFC;
				entry.domain = (l1desc &gt;&gt; 5) &amp; 0x0000000F;
				switch (l2desc &amp; 3) {
				case 0:
				case 3:
					state-&gt;mmu.last_domain = entry.domain;
					return PAGE_TRANSLATION_FAULT;
				case 1:
					entry.mapping = TLB_LARGEPAGE; /*大页*/
					break;
				case 2:
					entry.mapping = TLB_SMALLPAGE; /*小页*/
					break;
				}
			}
			break;
		case 2:
			/*段变换*/
			entry.virt_addr = virt_addr;
			entry.phys_addr = l1desc;
			entry.perms = l1desc &amp; 0x00000C0C;
			entry.domain = (l1desc &gt;&gt; 5) &amp; 0x0000000F;
			entry.mapping = TLB_SECTION;
			break;
		}
		entry.virt_addr &amp;= tlb_masks[entry.mapping];
		entry.phys_addr &amp;= tlb_masks[entry.mapping];

		/* 更新tlb*/
		*tlb = &amp;tlb_t-&gt;entrys[tlb_t-&gt;cycle];
		tlb_t-&gt;cycle = (tlb_t-&gt;cycle + 1) % tlb_t-&gt;num;
		**tlb = entry;
	}
	state-&gt;mmu.last_domain = (*tlb)-&gt;domain;
	return NO_FAULT;
}
</CODE></PRE></TD></TR></TBODY></TABLE>
      <P>访问控制的实现(mmu/tlb.[ch])</P>
      <P>接口函数</P><A name=IDAZFKTB><B></B></A><BR>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>
fault_t check_access(ARMul_State *state, ARMword virt_addr, 
tlb_entry_t *tlb, int read);
</CODE></PRE></TD></TR></TBODY></TABLE>
      <P>CACHE的实现(mmu/cache.[ch])</P>
      <P>ARM系统中一般只实现组相联CACHE。组相联CACHE分成多组,一个组有包括多个CACHE line,一个32位地址可以由下图表示。</P>
      <TABLE width=500 border=1>
        <TBODY>
        <TR>
          <TD width=100>Tag</TD>
          <TD width=100>Set</TD>
          <TD width=100>Word</TD>
          <TD width=100>1</TD>
          <TD width=100>0</TD></TR></TBODY></TABLE>
      <P>数据结构</P>
      <P>Cache行</P><A name=IDAXGKTB><B></B></A><BR>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>
typedef struct cache_line_t{
	ARMword tag;	/* 	cache line align address |
						bit2: last half dirty
						bit1: first half dirty
						bit0: cache valid flag
				*/
	ARMword pa;		/*physical address*/
	ARMword *data; 	/*array of cached data*/
}cache_line_t;

#define TAG_VALID_FLAG 0x00000001
#define TAG_FIRST_HALF_DIRTY 0x00000002
#define TAG_LAST_HALF_DIRTY	0x00000004
</CODE></PRE></TD></TR></TBODY></TABLE>
      <P>Cache 组</P><A name=IDA5GKTB><B></B></A><BR>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>
typedef struct cache_set_s{
	cache_line_t	*lines;
	int cycle;			/*used for cache line allocation*/
}cache_set_t;
</CODE></PRE></TD></TR></TBODY></TABLE>
      <P>Cache 结构</P><A name=IDAHHKTB><B></B></A><BR>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>
typedef struct cache_s{
	int	width;		/*bytes in a line*/
	int way;		/*way of set asscociate*/
	int	set;		/*num of set*/
	int w_mode;		/*write back or write through*/
	//int a_mode;		/*alloc mode: random or round-bin*/
	cache_set_t *sets;
}cache_t;
</CODE></PRE></TD></TR></TBODY></TABLE>
      <P>接口函数</P><A name=IDAPHKTB><B></B></A><BR>
      <TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#cccccc 
        border=1><TBODY>
        <TR>
          <TD><PRE><CODE>
     /*Cache的初始化和释放*/
int mmu_cache_init(cache_t *cache_t, int width, int way, int set, int w_mode);
void mmu_cache_exit(cache_t *cache_t);
/*Cache 查找和分配*/
cache_line_t * mmu_cache_search(ARMul_State *state, cache_t *cache_t, ARMword va);
cache_line_t * mmu_cache_alloc(ARMul_State *state, cache_t *cache_t, ARMword va, ARMword pa);
/*Cache 操作*/
void mmu_cache_write_back(ARMul_State *state, cache_t *cache_t, cache_line_t *cache);
void mmu_cache_clean(ARMul_State *state, cache_t *cache_t, ARMword va);
void mmu_cache_invalidate(ARMul_State *state, cache_t *cache_t, ARMword va);
void mmu_cache_invalidate_all(ARMul_State *state, cache_t *cache_t);
void mmu_cache_soft_flush(ARMul_State *state, cache_t *cache_t, ARMword pa);
</CODE></PRE></TD></TR></TBODY></TABLE>
      <P>Write Buffer的实现(mmu/wb.[hc])</P>
      <P>用一个循环队列模拟Write Buffer。</P>
      <P>数据结构</P><A name=IDAZHKTB><B></B></A><BR>

⌨️ 快捷键说明

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