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

📄 mmugen.c

📁 FIC8120方案的 StartCell_Driver
💻 C
📖 第 1 页 / 共 2 页
字号:

//--WRITELEVEL1--------------------------------------------------------------

int WriteLevel1(void)
{
	unsigned long fields ;
	unsigned long physical ;
	unsigned long writevalue ;
	unsigned long i ;

	/* Check the table-entry number matches the virtual base address for this section */
	if( global.table_entry != (global.rule.v_base>>20) )
	{
		printf("MMU Table synchronisation error!\n  table_entry = %08lx, v_base = %08lx\n",
			global.table_entry, global.rule.v_base);
		return -1 ;
	}

	if (global.rule.entrytype == 'S' || global.rule.entrytype == 'F')
	{
		if(global.rule.entrytype == 'S')
		{
			fields = 0x12 | (global.rule.access[0]<<10)|(global.rule.domain<<5) | (global.rule.cb<<2) ;
		}
		else
		{
			fields = 0; //generate fault on access
		}
		physical = global.rule.p_base ;
		/* generate all the SECTION entries for this descriptor */
		for (i = global.rule.v_base; i<global.rule.v_end; )
		{
			writevalue = physical|fields ;
//			fwrite( &writevalue, 4, 1, global.outfile );
			global.base_address[global.MMUTableIndex++] = writevalue;
			global.table_entry++ ;
			physical += 0x100000 ;
			/* check for memory wrap-round */
			i+=0x100000 ;
			if (i==0x00000000) break;
		}
	}
	else
	{
		/* Coarse or Fine PAGE entry */
		 
		//level 1 table will maxmimum =4G/1M *4(B)=16KB,so level two table offset is from 0x4000(16K)
				
		if (global.rule.entrytype == 'C' )	  
		{
			//coarse page table split 1M to 256 entries and coarse page table base must 1k alignment (and of course if will be!)
			writevalue = 0x11 +(global.rule.domain<<5)+ global.level2_base_address;
//			fwrite( &writevalue, 4, 1, global.outfile );
			global.base_address[global.MMUTableIndex++] = writevalue;
			global.level2_base_address+=0x400;
			global.table_entry++ ;
		}
		else
		{
			//fine page table split 1M to 1024 entries and fine page table base must 4k alignment				
			global.level2_base_address=ALIGN(global.level2_base_address,SIZE_4K);
		
			writevalue = 0x13 + (global.rule.domain<<5)+global.level2_base_address;
//			fwrite( &writevalue, 4, 1, global.outfile );
			global.base_address[global.MMUTableIndex++] = writevalue;
			global.level2_base_address+=0x1000;
			global.table_entry++ ;
		}
	}  
	return 0 ;
}


//--WRITELEVEL2--------------------------------------------------------------

int WriteLevel2(void)
{
	unsigned long fields ;
	unsigned long physical ;
	unsigned long writevalue ;
	unsigned long i;
	int j,k,n;
	unsigned long IsFinePage=0;

		
	/* work out repeated data fields - note: this line would change if per-page access levels were to be supported*/
	if (global.rule.entrytype == 'T')
		fields = (global.rule.access[0]<< 4)|(global.rule.cb <<2)|0x3;
	else if (global.rule.entrytype == 'L')
		fields = (global.rule.access[3]<< 10)|(global.rule.access[2] << 8)|(global.rule.access[1] << 6)|(global.rule.access[0] << 4)|(global.rule.cb <<2)|0x1;
	else
		fields = (global.rule.access[3]<< 10)|(global.rule.access[2] << 8)|(global.rule.access[1] << 6)|(global.rule.access[0] << 4)|(global.rule.cb <<2)|0x2;

	   
	/* create entries for this descriptor */
	i = global.rule.v_base ;
	//check is belong to fine page region
	IsFinePage=CheckIsFinePage(i);
			  
	 if(IsFinePage)
		 global.level2_current_region=1;
	 else
		 global.level2_current_region=0;
					  
	 if(IsFinePage && global.level2_previous_region==0)				 
	 {
		//check 4k alignment
	 	if((global.level2_page_size & 0xfff)!=0)
		{
			//add stuff 0 to file	
			n=ALIGN(global.level2_page_size,SIZE_4K)-global.level2_page_size;
			for(k=0;k<n/4;k++)
			{
//				fwrite( &null_value, 4, 1, global.outfile );
				global.base_address[global.MMUTableIndex++] = writevalue;
			}
			global.level2_page_size+=n;					 	  
		}
	}		   	
					 	
	physical = global.rule.p_base ;

	while(i<global.rule.v_end)
	{
		if( global.rule.entrytype == 'L' )
		{
			writevalue = physical|fields ;

			if(IsFinePage)
			{ 
				for( j=64; j; j-- )
				{
//					fwrite( &writevalue, 4, 1, global.outfile );
					global.base_address[global.MMUTableIndex++] = writevalue;
					global.level2_page_size+=4;
				}
			}   
			else  
			{
				for( j=16; j; j-- )
				{
//					fwrite( &writevalue, 4, 1, global.outfile );
					global.base_address[global.MMUTableIndex++] = writevalue;
					global.level2_page_size+=4;
				}
			}
						
			physical += 0x10000;
			i += 0x10000;
		}
		else if( global.rule.entrytype == 'S' )
		{
			writevalue = physical|fields ;
		 	if(IsFinePage)
			{ 
				for( j=4; j; j-- )
				{ 
//					fwrite( &writevalue, 4, 1, global.outfile );
					global.base_address[global.MMUTableIndex++] = writevalue;
					global.level2_page_size+=4;
				}
			}
			else
			{
//				fwrite( &writevalue, 4, 1, global.outfile );
				global.base_address[global.MMUTableIndex++] = writevalue;
				global.level2_page_size+=4;
			}   
			physical += 0x1000;
			i += 0x1000;
		}
		else //tiny page
		{
			writevalue = physical|fields ;
//			fwrite( &writevalue, 4, 1, global.outfile );
			global.base_address[global.MMUTableIndex++] = writevalue;
			global.level2_page_size+=4;
			physical += 0x400;
			i += 0x400;   	
		}	
	}

	global.level2_previous_region=global.level2_current_region;
	return 0 ;
}


//--GETWORD------------------------------------------------------------------
// fetch next word, stepping over whitespace and comments
// return 0 if end-of-file

int	GetWord (char *buffer)
{
	int c;
	
	c = (int)global.MMUTableStr[global.MMUTableStrIndex++];
	
	while(c=='\t' || c==' ' || c=='/' || c=='\n')
	{
		if( c=='/') //start of comment
		{
			do
			{
				c = (int)global.MMUTableStr[global.MMUTableStrIndex++];
			} while( c!= '/' ) ;

			// get next character beyond comment
			c = (int)global.MMUTableStr[global.MMUTableStrIndex++];
		}

		while( c=='\t' || c==' ' || c == '\n') 
			c = (int)global.MMUTableStr[global.MMUTableStrIndex++];
	}

	// Check for end of file
	if( c=='\0' ) return 0;

	// Ok, should be at the start of a word
	while ( c!='\t' && c!=' ' && c!='\0' && c!= '\n')
	{
		*buffer++ = (char)c ; 
		c = (int)global.MMUTableStr[global.MMUTableStrIndex++];
	}

	//terminate word
	*buffer = '\0';
		
	return 1;
}

//--GETWORDINDEX-------------------------------------------------------------

int	  GetWordIndex (char *buffer)
{
	int index=0 ;
	
	while ( parsedata[index].index != UNRECOGNISED
			&& stricomp(parsedata[index].word,buffer) )
	{
		index++ ;
	}
		
	return index ;
}

//--ATOX---------------------------------------------------------------------

long atox( char *buffer)
{
	long v=0;
		
	while(*buffer)
	{
		v*=16;
		if(*buffer>='0' && *buffer<='9') v+= *buffer - '0';
		if(*buffer>='a' && *buffer<='f') v+= *buffer - 'a'+10;
		if(*buffer>='A' && *buffer<='F') v+= *buffer - 'A'+10;
		buffer++;
	}
	return v ;
}

//--STRICOMP-----------------------------------------------------------------
/*
		The program originally used stricmp, but this does
		not appear to be included in the ARM C library.
		
		This is not a true stricmp (or strcmpi), since only
		the "match" string is converted to upper case,
		allowing "original" to be in read-only memory.
*/

char ftoupper(char ch)
{
	if(( ch >= 'a') && (ch <= 'z'))
		return ch - 'a' + 'A';
	else
		return ch;
}

int stricomp( char *original, char *match )
{
	char *ptr = match ;

	while(*ptr)
	{
//		*ptr=toupper(*ptr) ;
		*ptr=ftoupper(*ptr) ;
		ptr++ ;
	}
		
	return strcmp(original,match) ;
}

//This code check if the address is belong to fine page region
// modify by fred chien 09/19/02
unsigned long CheckIsFinePage(unsigned long taddress)
{
	int i;
 
	for(i=0;i<Total_Fine_Pages;i++)	
	{
		if((taddress>=Fine_Page_Region[i].start)&&(taddress< Fine_Page_Region[i].end))
  			return 1;
  		else
  			continue; 	
 	}		
		
	return 0;	
}	

//this code will align the address to align
/**********************************************************************/

unsigned long ALIGN(unsigned long val, unsigned long align)
{
	/*
	 * if the value is zero, it is aligned, no matter what the size
	 */
	if (val == 0)
		return val;

	/*
	 * if the value is less than the alignment, return the alignment
	 */
	if (val < align)
		return align;

	/*
	 * finally, if there is need to move the value upwards, do so
	 */
	if ((val & ~(align - 1)) != 0)
		return (((val) + ((align) - 1)) & ~((align) - 1));
	else
		return val;
}

⌨️ 快捷键说明

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