📄 mmugen.c
字号:
#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 + -