//------------------------------------------------------------------------- //------------------------------------------------------------------------- void PUT32 ( unsigned int, unsigned int ); unsigned int GET32 ( unsigned int ); extern void uart_init ( void ); extern void hexstring ( unsigned int d ); extern void hexstrings ( unsigned int d ); extern void start_l1cache ( void ); extern void stop_l1cache ( void ); extern void start_mmu ( unsigned int, unsigned int ); extern unsigned int LDREX ( unsigned int, unsigned int ); extern unsigned int STREX ( unsigned int, unsigned int, unsigned int ); extern unsigned int EXTEST ( unsigned int, unsigned int, unsigned int ); //Need a top level entry for every 1MB section, 20 bits. //memory base addresses 0x100000, 0x200000, 0x300000, etc. //making a one to one virtual to physical map //virtual 0x20201234 -> 0x20201234 physical // //bits 31:20 of the virtual address index into the top level table //1<<((31-20)+1) 4096 entries. 0x1000 32 bit entries, 0x4000 bytes. // //Bits 31:10 of the top level table point at the course page table //bits 19:12 of the address index into this table. //1<<((19-12)+1) 256 entries, 0x100 entries 0x400 bytes per entry // //Using a course entry // //the hardware looks in the first table and gets an entry. Bits in the //entry determine what kind it is, course, section, super section, //just using course here as it doesnt save any space using the others. //You can put the coarse entry anywhere. Going to pack it in next to //the top level table. going to limit the size of the table so only //so many entries will be allowed // //Using small pages (4096 byte) // //bits 31:12 of the small page descriptor in the course table are the //physical address in memory. bits 11:0 of the physical address come //from the virtual address. #define MMUTABLEBASE 0x00100000 #define MMUTABLESIZE (0x8000) #define MMUTABLEMASK ((MMUTABLESIZE-1)>>2) #define TOP_LEVEL_WORDS (1<<((31-20)+1)) #define COARSE_TABLE_WORDS (1<<((19-12)+1)) #define SMALL_TABLE_WORDS (1<<((11-0)+1)) unsigned int nextfree; //------------------------------------------------------------------- unsigned int next_coarse_offset ( unsigned int x ) { unsigned int mask; mask=(~0)<<(10-2); mask=~mask; while(x&mask) x++; //lazy brute force return(x); } //------------------------------------------------------------------- unsigned int add_one ( unsigned int add, unsigned int flags ) { unsigned int ra; unsigned int rb; unsigned int rc; //bits 31:20 index into the top level table ra=add>>20; rc=MMUTABLEBASE+(ra<<2); rb=GET32(rc); if(rb) { //printf("Address %08X already allocated\n",add); hexstring(add); hexstring(rc); hexstring(rb); hexstring(0xBADADD); return(1); } add=ra<<20; rb=next_coarse_offset(nextfree); rc=rb+COARSE_TABLE_WORDS; if(rc>=MMUTABLESIZE) { //printf("Not enough room\n"); hexstring(0xBAD); return(1); } nextfree=rc; //use course page table pointer on top level table PUT32(MMUTABLEBASE+(ra<<2),(MMUTABLEBASE+(rb<<2))|0x00000001); //fill in the course page table. with small entries for(ra=0;ra