📄 mmugen.c
字号:
//--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-fileint 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/02unsigned 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 + -