diff options
Diffstat (limited to 'kernel/lib/mmu.c')
-rw-r--r-- | kernel/lib/mmu.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/kernel/lib/mmu.c b/kernel/lib/mmu.c new file mode 100644 index 0000000..e9dda7a --- /dev/null +++ b/kernel/lib/mmu.c @@ -0,0 +1,33 @@ +#include <lib/mmu.h> + +#define CACHABLE 0x08 +#define BUFFERABLE 0x04 +#define NO_PERMISSIONS_REQUIRED 0b11 << 10 +#define MMU_TABLE_BASE 0x00004000 + +void mmu_start(unsigned long base, unsigned long flags); + +void mmu_section(unsigned long virtual, unsigned long physical, unsigned long flags) +{ + unsigned long offset = virtual >> 20; + unsigned long* entry = (unsigned long*)(MMU_TABLE_BASE | (offset << 2)); + unsigned long physval = (physical & 0xFFF00000) | (flags & 0x7FFC) | 0x00C02; + *entry = physval; +} + +extern unsigned long __bss_end; +void mmu_init(void) +{ + for (unsigned long addr = 0x00000000;; addr += 0x00100000) { + if (addr < (unsigned long)&__bss_end + 0x00100000) { + mmu_section(addr, addr, CACHABLE | BUFFERABLE); + } else { + mmu_section(addr, addr, NO_PERMISSIONS_REQUIRED); + } + if (addr == 0x02000000) + mmu_section(addr, addr, CACHABLE | BUFFERABLE | NO_PERMISSIONS_REQUIRED); + if (addr == 0xFFF00000) + break; + } + mmu_start(MMU_TABLE_BASE,0x00000001|0x1000|0x0004); +} |