📄 mmugen.c
字号:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <ctype.h>#define TRUE 1#define FALSE 0enum 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 128typedef 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 + -