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

📄 mmugen.c

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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>


#define TRUE	1
#define FALSE	0


enum  validwords 
{
		BASE_ADDRESS,
		LEVEL_KW,
		VIRTUAL		,
		TO			,
		PHYSICAL	,
		COARSEPAGES	,
		FINEPAGES	,
		SECTION		,
		NO_ACCESS_KW,
		SVC_READWRITE,
		NO_USR_WRITE,
		FULL_ACCESS	,
		DOMAIN		,
		FAULT		,
		CACHEABLE_KW,
		AND			,
		BUFFERABLE_KW,
		NOT			,
		LARGEPAGES	,
		SMALLPAGES	,
		TINYPAGES	,
		POSTPROCESS ,
		UNRECOGNISED
};

typedef struct
{
		unsigned long v_base;   /* first address in virtual section					 */
		unsigned long v_end;			/* last address in virtual section					  */
		unsigned long p_base;   /* corresponding physical base address		  */
		unsigned long entrytype; /* 'P' for pages, 'S' for section					  */
		unsigned long access[4];   /* access types defined in the enum above	   */		
		unsigned long domain;	/* page belong to what doamin 		*/
		unsigned long cb;			   /* cacheable & bufferable status						*/
}mmudata;

typedef struct
{
		long index;
		char *word;
}tparsedata;

struct {
	char *MMUTableStr;
	int MMUTableStrIndex;
	int MMUTableIndex;
	mmudata rule ;
	unsigned long access_index;
	unsigned long *base_address ;
	unsigned long table_entry ;
	long state ;   
	unsigned long level2_base_address;
	unsigned long level2_page_size;
	unsigned long level2_previous_region;//1:fine page 0:coarse page
	unsigned long level2_current_region; //1:fine page 0:coarse page
} global ;

#define SIZE_4K		0x1000


#define MAX_FINE_PAGE_REGION 128

typedef struct {
	unsigned long start;
	unsigned long end;	
}tFine_Page_Region;

unsigned long Total_Fine_Pages;
tFine_Page_Region Fine_Page_Region[MAX_FINE_PAGE_REGION];

tparsedata parsedata[] = {
	{BASE_ADDRESS   ,"BASE_ADDRESS" },
	{LEVEL_KW	 	,"LEVEL"		},
	{VIRTUAL		,"VIRTUAL"		},
	{TO				,"TO"			},
	{PHYSICAL		,"PHYSICAL"		},
	{COARSEPAGES	,"COARSEPAGES"	},
	{FINEPAGES		,"FINEPAGES"	},
	{SECTION		,"SECTION"		},
	{NO_ACCESS_KW	,"NO_ACCESS"	},
	{SVC_READWRITE  ,"SVC_READWRITE"},
	{NO_USR_WRITE   ,"NO_USR_WRITE" },
	{FULL_ACCESS	,"FULL_ACCESS"  },
	{DOMAIN			,"DOMAIN"		},
	{FAULT			,"FAULT"		},
	{CACHEABLE_KW	,"CACHEABLE"	},
	{AND			,"AND"			},
	{BUFFERABLE_KW	,"BUFFERABLE"   },
	{NOT			,"NOT"			},
	{LARGEPAGES		,"LARGEPAGES"   },
	{SMALLPAGES		,"SMALLPAGES"   },
	{TINYPAGES		,"TINYPAGES"	},
	{POSTPROCESS	,"POSTPROCESS"  },
	{UNRECOGNISED   ,"UNRECOGNISED" }
};


//--function prototypes------------------------------------------------------
int  ValidateArgs (int argc, char **argv);
int  ParseRule (void);
int  WriteTableEntries (void);
int  WriteLevel1(void);
int  WriteLevel2(void);
int	  GetWord (char *buffer);
int	  GetWordIndex (char *buffer);
long atox( char *buffer);
int	  stricomp( char *original, char *match );
unsigned long CheckIsFinePage(unsigned long);
unsigned long ALIGN(unsigned long val, unsigned long align);

//--MAIN---------------------------------------------------------------------
int mmugen(unsigned long *mmu_addr, char *mmutab_str)
{
	global.MMUTableStr = mmutab_str;	
	global.MMUTableStrIndex = 0;
	global.MMUTableIndex = 0;
	
	global.state=0;
	Total_Fine_Pages=0;
	global.level2_page_size=0;
	global.level2_previous_region=0;
	global.level2_current_region=0;
	
	
	while( ParseRule() )
	{
		if(WriteTableEntries()==-1)
		{
/*			printf("Write table entries fail.\n"); */
			return FALSE;
		}
	}
/*	printf("MMU table generation complete.\n");		*/
	*mmu_addr = (unsigned long)global.base_address;
		
	return TRUE ;
}

//--PARSERULE----------------------------------------------------------------

int ParseRule (void)
{
	char buffer[20];
	static int	   notted = 0;

	while(GetWord(buffer))
	{
		switch( GetWordIndex(buffer) )
		{
			case BASE_ADDRESS:
				GetWord(buffer);
				global.base_address = (unsigned long *)atox(buffer);
				global.level2_base_address=((unsigned long)global.base_address)+0x4000;
				break;
			case LEVEL_KW:
				GetWord(buffer);
				global.state = atoi(buffer);
				/* check table_entry is a sensible value */
				if(global.table_entry != 0 && global.table_entry != 0x1000)
				{
					printf("Table data error - at end of Level 1, the table was %08lx bytes long (should be 0x4000)\n",global.table_entry<<2);
				}
				break;

			case VIRTUAL	 :
				GetWord(buffer);
				global.rule.v_base =  atox(buffer);
				break;

			case TO				  :
				GetWord(buffer);
				global.rule.v_end =  atox(buffer);
				break;

			case PHYSICAL	:
				GetWord(buffer) ;
				global.rule.p_base =  atox(buffer);
				break;

			case COARSEPAGES			   :
				global.rule.entrytype = 'C';
				global.access_index=0;
				global.rule.access[0] = 0 ;
				global.rule.access[1] = 0 ;
				global.rule.access[2] = 0 ;
				global.rule.access[3] = 0 ;
				global.rule.cb = 0 ;
				//completed rule, so implement it
				return 1 ;
						
			 case FINEPAGES			   :
				global.rule.entrytype = 'I';
				global.access_index=0;
				global.rule.access[0] = 0 ;
				global.rule.access[1] = 0 ;
				global.rule.access[2] = 0 ;
				global.rule.access[3] = 0 ;
				global.rule.cb = 0 ;
				Fine_Page_Region[Total_Fine_Pages].start=global.rule.v_base;
				Fine_Page_Region[Total_Fine_Pages].end=global.rule.v_end ;
				Total_Fine_Pages++;
				//completed rule, so implement it
				return 1 ;
						
			case SECTION	 :
				global.access_index=0;
				global.rule.entrytype = 'S';
				break ;
						
			case NO_ACCESS_KW:
										
				global.rule.access[global.access_index] = 0 ;
				global.access_index++;
				break ;

			case SVC_READWRITE:
				global.rule.access[global.access_index] = 1 ;
				global.access_index++;
				break ;

			case NO_USR_WRITE:
				global.rule.access[global.access_index] = 2 ;
				global.access_index++;
				break ;

			case FULL_ACCESS :
				global.rule.access[global.access_index] = 3 ;
				global.access_index++;
				break ;
			case DOMAIN		:
				GetWord(buffer);
				global.rule.domain=atox(buffer);
				break;

			case FAULT			   :
				global.rule.entrytype = 'F';
				global.access_index=0;
				global.rule.access[0] = 0 ;
				global.rule.access[1] = 0 ;
				global.rule.access[2] = 0 ;
				global.rule.access[3] = 0 ;
				global.rule.cb = 0 ;
				//completed rule, so implement it
				return 1 ;

			case CACHEABLE_KW:
				if(notted)
				{
					global.rule.cb &= 1;
					notted = 0;
				}
				else
				{
					global.rule.cb |= 2 ;
				}
				break ;
			case AND				 :
				/* ignore */ 
				break;
			case BUFFERABLE_KW:
				if(notted)
				{
					global.rule.cb &= 2;
					notted=0;
				}
				else
				{
					global.rule.cb |= 1 ;
				}
				//completed rule, so implement it
				return 1 ;

			case NOT				 :
				notted=1;
				break;

			case LARGEPAGES  :
				global.access_index=0;
				global.rule.entrytype = 'L';
				break ;
			case SMALLPAGES  :
				global.access_index=0;
				global.rule.entrytype = 'S';
				break ;
			case TINYPAGES  :
				global.access_index=0;
				global.rule.entrytype = 'T';
				break ;				
			case POSTPROCESS :
#if 0	//ted		
				GetWord(buffer); //skip ENTRY
				GetWord(buffer); //get address
				fseek( global.outfile, atox(buffer) ,SEEK_SET );
				GetWord(buffer); //skip EQUALS
				GetWord(buffer); //get value
				i = atox(buffer);
				fwrite( &i, 4, 1, global.outfile );
#endif				
				break ;

			case UNRECOGNISED:
				printf("Unrecognised word '%s'\n",buffer);
		}
	}

	// must have hit end of rule file without finding the end of a rule
	return 0;

}


//--WRITETABLEENTRIES--------------------------------------------------------

int WriteTableEntries (void)
{
	switch( global.state )
	{
		case 1: return WriteLevel1();
		case 2: return WriteLevel2();
		default: printf("MMU page table level not set\n");
				 return -1;
	}
}

⌨️ 快捷键说明

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