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

📄 arm7100_mmu.c

📁 这是Skyeye 0.9 版本的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	
}
      
return NO_FAULT;
    
}
  


//      if ((virt_addr & 3) && (state->mmu.control & CONTROL_ALIGN_FAULT)) {

    if ((virt_addr & 3) && (datatype == ARM_WORD_TYPE)
	&& (state->mmu.control & CONTROL_ALIGN_FAULT) || \
(virt_addr & 1)
	&& (datatype == ARM_HALFWORD_TYPE)
	&& (state->mmu.control & CONTROL_ALIGN_FAULT))
    {
      
fprintf (stderr, "SKYEYE, a71_mmu_write ALIGNMENT_FAULT\n");
      
return ALIGNMENT_FAULT;
    
}
  
if (state->mmu.control & CONTROL_CACHE)
    {
      
cache_line_t * cache;
      

cache = mmu_cache_search (state, CACHE (), virt_addr);
      
if (cache)
	{
	  
if (datatype == ARM_WORD_TYPE)
	    
cache->data[(virt_addr >> 2) & 3] = data;
	  

	  else if (datatype == ARM_HALFWORD_TYPE)
	    {
	      
temp = cache->data[(virt_addr >> 2) & 3];
	      
offset = (((ARMword) state->bigendSig * 2) ^ (virt_addr & 2)) << 3;	/* bit offset into the word */
	      
cache->data[(virt_addr >> 2) & 3] = \

		(temp & ~(0xffffL << offset)) | ((data & 0xffffL) << offset);
	    
}
	  else if (datatype == ARM_BYTE_TYPE)
	    {
	      
temp = cache->data[(virt_addr >> 2) & 3];
	      
offset = (((ARMword) state->bigendSig * 3) ^ (virt_addr & 3)) << 3;	/* bit offset into the word */
	      
cache->data[(virt_addr >> 2) & 3] = \

		(temp & ~(0xffL << offset)) | ((data & 0xffL) << offset);
	    
}
	
}
    
}
  
fault = translate (state, virt_addr, TLB (), &tlb);
  
if (fault)
    {
      
return fault;
    
}
  
fault = check_access (state, virt_addr, tlb, 0);
  
if (fault)
    {
      
return fault;
    
}
  

phys_addr = (tlb->phys_addr & tlb_masks[tlb->mapping]) | 

    (virt_addr & ~tlb_masks[tlb->mapping]);
  

if (datatype == ARM_BYTE_TYPE)
    
mem_write_byte (state, phys_addr, data);
  

  else if (datatype == ARM_HALFWORD_TYPE)
    
mem_write_halfword (state, phys_addr, data);
  

  else if (datatype == ARM_WORD_TYPE)
    
mem_write_word (state, phys_addr, data);
  

  else
    {
      
printf ("SKYEYE:2  a71_mmu_write error: unknown data type %d \n",
	       datatype);
      
exit (-1);
    
}
  
return NO_FAULT;

}



static ARMword 

a71_mmu_mrc (ARMul_State * state, ARMword instr, ARMword * value) 

{
  
mmu_regnum_t creg = BITS (16, 19) & 15;
  
ARMword data;
  

switch (creg)
    {
    
case MMU_ID:
      

//              printf("mmu_mrc read ID     ");

#if 0

#ifdef MMU_V4

	data = 0x41018100;	/* v4 */
      

#else	/* 
 */
	data = 0x41007100;	/* v3 */
      

#endif	/* 
 */
#endif	/* 
 */
	//data = 0x41007100; 

	data = skyeye_config.cpu->cpu_val;
      

break;
    
case MMU_CONTROL:
      

//              printf("mmu_mrc read CONTROL");

	data = state->mmu.control;
      
break;
    
case MMU_TRANSLATION_TABLE_BASE:
      

//              printf("mmu_mrc read TTB    ");

	data = state->mmu.translation_table_base;
      
break;
    
case MMU_DOMAIN_ACCESS_CONTROL:
      

//              printf("mmu_mrc read DACR   ");

	data = state->mmu.domain_access_control;
      
break;
    
case MMU_FAULT_STATUS:
      

//              printf("mmu_mrc read FSR    ");

	data = state->mmu.fault_status;
      
break;
    
case MMU_FAULT_ADDRESS:
      

//              printf("mmu_mrc read FAR    ");

	data = state->mmu.fault_address;
      
break;
    
default:
      
printf ("mmu_mrc read UNKNOWN - reg %d\n", creg);
      
data = 0;
      
break;
    
}
  

//      printf("\t\t\t\t\tpc = 0x%08x\n", state->Reg[15]);

    *value = data;
  
return data;

}



static void 

a71_mmu_mcr (ARMul_State * state, ARMword instr, ARMword value) 

{
  
mmu_regnum_t creg = BITS (16, 19) & 15;
  
if (!strncmp (skyeye_config.cpu->cpu_arch_name, "armv4", 5))
    

    {
      
switch (creg)
	{
	
case MMU_CONTROL:
	  

//              printf("mmu_mcr wrote CONTROL      ");

	    state->mmu.control = (value | 0x70) & 0xFFFF;
	  
break;
	
case MMU_TRANSLATION_TABLE_BASE:
	  

//              printf("mmu_mcr wrote TTB          ");

	    state->mmu.translation_table_base = value & 0xFFFFC000;
	  
break;
	
case MMU_DOMAIN_ACCESS_CONTROL:
	  

//              printf("mmu_mcr wrote DACR         ");

	    state->mmu.domain_access_control = value;
	  
break;
	  

//#ifdef MMU_V4

	case MMU_FAULT_STATUS:
	  
state->mmu.fault_status = value & 0xFF;
	  
break;
	
case MMU_FAULT_ADDRESS:
	  
state->mmu.fault_address = value;
	  
break;
	
case MMU_V4_CACHE_OPS:	/* incomplete */
	  
if ((BITS (5, 7) & 7) == 0)
	    {
	      
mmu_cache_invalidate_all (state, CACHE ());
	    
}
	  
break;
	
case MMU_V4_TLB_OPS:	/* incomplete */
	  
switch (BITS (5, 7) & 7)
	    {
	    
case 0:
	      
mmu_tlb_invalidate_all (state, TLB ());
	      
break;
	    
case 1:
	      
mmu_tlb_invalidate_entry (state, TLB (), value);
	      
break;
	    
}
	  
break;
	
default:
	  
printf ("mmu_mcr wrote UNKNOWN - reg %d\n", creg);
	  
break;
	
}
      

//#else

    }
  else
    {
      
switch (creg)
	{
	
case MMU_CONTROL:
	  

state->mmu.control = (value | 0x70) & 0xFFFF;
	  
break;
	
case MMU_TRANSLATION_TABLE_BASE:
	  

state->mmu.translation_table_base = value & 0xFFFFC000;
	  
break;
	
case MMU_DOMAIN_ACCESS_CONTROL:
	  

state->mmu.domain_access_control = value;
	  
break;
	
case MMU_V3_FLUSH_TLB:
	  

//              printf("mmu_mcr wrote FLUSH_TLB    ");

	    mmu_tlb_invalidate_all (state, TLB ());
	  
break;
	
case MMU_V3_FLUSH_TLB_ENTRY:
	  

//              printf("mmu_mcr wrote FLUSH_TLB_ENTRY");

	    mmu_tlb_invalidate_entry (state, TLB (), value);
	  
break;
	
case MMU_V3_FLUSH_CACHE:
	  

//              printf("mmu_mcr wrote FLUSH_CACHE    ");

	    mmu_cache_invalidate_all (state, CACHE ());
	  
break;
	
default:
	  
printf ("mmu_mcr wrote UNKNOWN - reg %d\n", creg);
	  
break;
	  

//#endif

	}
    
}
  

//      printf("\t\t\t\tpc = 0x%08x\n", state->Reg[15]);

}


static int 

a71_mmu_v2p_dbct (ARMul_State * state, ARMword virt_addr,
		  ARMword * phys_addr) 

{
  
tlb_entry_t * tlb;
  
ARMword temp, offset;
  
fault_t fault;
  
ARMword datatype = ARM_WORD_TYPE;
  
int ret = -1;
  

if ((virt_addr & 3) && (datatype == ARM_WORD_TYPE)
	&& (state->mmu.control & CONTROL_ALIGN_FAULT) || \
(virt_addr & 1)
	&& (datatype == ARM_HALFWORD_TYPE)
	&& (state->mmu.control & CONTROL_ALIGN_FAULT))
    {
      
fprintf (stderr, "SKYEYE, a71_mmu_read ALIGNMENT_FAULT\n");
      
goto out;
    
}
  
if (!(state->mmu.control & CONTROL_MMU))
    {
      

*phys_addr = virt_addr;
    

}
  else
    {
      

fault = translate (state, virt_addr, TLB (), &tlb);
      
if (fault)
	{
	  
goto out;
	
}
      
fault = check_access (state, virt_addr, tlb, 1);
      
if (fault)
	{
	  
goto out;
	
}
      

*phys_addr = (tlb->phys_addr & tlb_masks[tlb->mapping]) | 

	(virt_addr & ~tlb_masks[tlb->mapping]);
    
}
  
ret = 0;


out:
return (ret);

}




#undef CACHE

#undef TLB

  

mmu_ops_t arm7100_mmu_ops =
{
  
a71_mmu_init, 
a71_mmu_exit, 
a71_mmu_read_byte, 
a71_mmu_write_byte, 
a71_mmu_read_halfword, 
a71_mmu_write_halfword, 
a71_mmu_read_word, 
a71_mmu_write_word, 
a71_mmu_read_word,	// load instr

    a71_mmu_mcr, 
a71_mmu_mrc, 
a71_mmu_v2p_dbct	// ywc 2005-04-16 test

};






⌨️ 快捷键说明

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