📄 mmugen.c
字号:
/*----------------------------------------------------------------------------
MMU table generator
[PJM] 1st August 2000
Copyright Peter Maloy, CodeSprite August 2000 www.codesprite.com
----------------------------------------------------------------------------*/
//---------------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
//---------------------------------------------------------------------------
enum validwords {
BASE_ADDRESS,
LEVEL ,
VIRTUAL ,
TO ,
PHYSICAL ,
PAGES ,
SECTION ,
NO_ACCESS ,
SVC_READWRITE,
NO_USR_WRITE,
FULL_ACCESS ,
FAULT ,
CACHEABLE ,
AND ,
BUFFERABLE ,
NOT ,
LARGEPAGES ,
SMALLPAGES ,
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; /* access types defined in the enum above */
unsigned long cb; /* cacheable & bufferable status */
}mmudata;
typedef struct
{
long index;
char *word;
}tparsedata;
struct {
FILE *rulefile ;
FILE *outfile ;
mmudata rule ;
unsigned long base_address ;
unsigned long table_entry ;
long state ;
long pagescount ;
} global ;
tparsedata parsedata[] = {
{BASE_ADDRESS ,"BASE_ADDRESS" },
{LEVEL ,"LEVEL" },
{VIRTUAL ,"VIRTUAL" },
{TO ,"TO" },
{PHYSICAL ,"PHYSICAL" },
{PAGES ,"PAGES" },
{SECTION ,"SECTION" },
{NO_ACCESS ,"NO_ACCESS" },
{SVC_READWRITE ,"SVC_READWRITE"},
{NO_USR_WRITE ,"NO_USR_WRITE" },
{FULL_ACCESS ,"FULL_ACCESS" },
{FAULT ,"FAULT" },
{CACHEABLE ,"CACHEABLE" },
{AND ,"AND" },
{BUFFERABLE ,"BUFFERABLE" },
{NOT ,"NOT" },
{LARGEPAGES ,"LARGEPAGES" },
{SMALLPAGES ,"SMALLPAGES" },
{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 );
//--MAIN---------------------------------------------------------------------
int main(int argc, char **argv)
{
if( ValidateArgs(argc, argv)) return -1;
global.state=0;
while( ParseRule() )
{
if(WriteTableEntries()==-1)
{
fclose( global.outfile );
fclose( global.rulefile );
exit(-1);
}
}
printf("MMU table generation complete\n");
fclose( global.outfile );
fclose( global.rulefile );
return 0 ;
}
//--VALIDATEARGS-------------------------------------------------------------
int ValidateArgs(int argc, char **argv)
{
printf("\nMMUgen\n");
printf("======\n");
if(argc!=3)
{
printf("Usage: MMUgen Rulefile Outputfile\n");
return -1;
}
if(NULL==(global.rulefile=fopen(argv[1],"r")))
{
printf("Couldn't open Rule file\n");
return -1;
}
if(NULL==(global.outfile=fopen(argv[2],"wb")))
{
fclose(global.rulefile);
printf("Couldn't open Output file\n");
return -1;
}
fseek(global.outfile, 0L, SEEK_SET);
return 0;
}
//--PARSERULE----------------------------------------------------------------
int ParseRule (void)
{
char buffer[20];
static int notted = 0;
long i;
while(GetWord(buffer))
{
switch( GetWordIndex(buffer) )
{
case BASE_ADDRESS:
GetWord(buffer);
global.base_address = atox(buffer);
break;
case LEVEL :
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 PAGES :
global.rule.entrytype = 'P';
global.rule.access = 0 ;
global.rule.cb = 0 ;
//completed rule, so implement it
return 1 ;
case SECTION :
global.rule.entrytype = 'S';
break ;
case NO_ACCESS :
global.rule.access = 0 ;
break ;
case SVC_READWRITE:
global.rule.access = 1 ;
break ;
case NO_USR_WRITE:
global.rule.access = 2 ;
break ;
case FULL_ACCESS :
global.rule.access = 3 ;
break ;
case FAULT :
global.rule.entrytype = 'F';
global.rule.access = 0 ;
global.rule.cb = 0 ;
//completed rule, so implement it
return 1 ;
case CACHEABLE :
if(notted)
{
global.rule.cb &= 1;
notted = 0;
}
else
{
global.rule.cb |= 2 ;
}
break ;
case AND :
/* ignore */ break;
case BUFFERABLE :
if(notted)
{
global.rule.cb &= 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -