allocate enough storage for the page table! move cache invalidating and page table...
[AROS.git] / arch / arm-raspi / kernel / mmu.c
blobdebaed48b1e1fb2cecadabb3a9b23e341f59aa8a
1 /*
2 Copyright © 2013, The AROS Development Team. All rights reserved.
3 $Id$
4 */
6 #include <inttypes.h>
7 #include <aros/kernel.h>
8 #include <aros/libcall.h>
9 #include <stddef.h>
10 #include <string.h>
12 #include <proto/exec.h>
13 #include <proto/kernel.h>
15 #include "kernel_intern.h"
16 #include "mmu.h"
18 unsigned int pagetable[4096] __attribute__ ((aligned (16384)));
19 unsigned int pagetable0[64] __attribute__ ((aligned (16384)));
21 void core_MMUUpdatePageTables(void)
23 unsigned int pt_addr = (unsigned int) &pagetable;
24 unsigned int pt0_addr = (unsigned int) &pagetable0;
26 /* Invalidate caches */
27 asm volatile("mcr p15, 0, %[r], c8, c7, 0" : : [r] "r" (0x0)); //Invalidate entire unified TLB
28 asm volatile("mcr p15, 0, %[r], c8, c6, 0" : : [r] "r" (0x0)); //Invalidate entire data TLB
29 asm volatile("mcr p15, 0, %[r], c8, c5, 0" : : [r] "r" (0x0)); //Invalidate entire instruction TLB
30 asm volatile("mcr p15, 0, %[r], c7, c5, 6" : : [r] "r" (0x0)); //Invalidate entire branch prediction array
31 asm volatile("mcr p15, 0, %[r], c7, c5, 0" : : [r] "r" (0x0)); //Invalidate icache
33 /* setup_ttbr0/1 */
34 asm volatile("mcr p15, 0, %[addr], c2, c0, 0" : : [addr] "r" (pt0_addr));
35 asm volatile("mcr p15, 0, %[addr], c2, c0, 1" : : [addr] "r" (pt_addr));
36 /* setup_ttbrc */
37 asm volatile("mcr p15, 0, %[n], c2, c0, 2" : : [n] "r" (7));
40 void core_SetupMMU(void)
42 unsigned int page;
43 register unsigned int control;
45 D(bug("[Kernel] core_SetupMMU: Creating MMU pagetable[0] entries for 4GB address space\n"));
47 for (page = 0; page < 4096; page ++)
49 unsigned int pageflags = PAGE_TRANSLATIONFAULT;
50 if (page > 64)
52 pageflags = (page << 20) | PAGE_FL_S_BIT | PAGE_SECTION;
53 #if defined(ARM_PERIIOBASE)
54 if ((page < (ARM_PERIIOBASE >> 20)) || (page > ((ARM_PERIIOBASE + ARM_PERIIOSIZE) >> 20)))
55 #endif
56 pageflags |= PAGE_C_BIT;
58 pagetable[page] = pageflags;
61 D(bug("[Kernel] core_SetupMMU: Creating MMU pagetable[1] entries for 64MB address space\n"));
62 for (page = 0; page < 64; page++)
64 pagetable0[page] = (page << 20) | PAGE_FL_S_BIT | PAGE_C_BIT | PAGE_SECTION;
67 core_MMUUpdatePageTables();
69 /* Set the domain access control to all-supervisor */
70 asm volatile("mcr p15, 0, %[r], c3, c0, 0" : : [r] "r" (~0));
72 /* Enable L1 caches (I-cache and D-cache) and MMU.*/
73 asm volatile("mrc p15, 0, %[control], c1, c0, 0" : [control] "=r" (control));
74 control |= ( ENABLE_I_CACHE | ENABLE_D_CACHE | ENABLE_MMU );
75 asm volatile ("mcr p15, 0, %[r], c7, c10, 4" : : [r] "r" (0)); /* dsb */
76 asm volatile ("mcr p15, 0, %0, c1, c0, 0" : : "r" (control) : "cc" );
77 asm volatile ("mcr p15, 0, %[r], c7, c5, 4" : : [r] "r" (0)); /* isb */
79 D(bug("[Kernel] core_SetupMMU: Done\n"));
82 void core_ProtPage(intptr_t addr, char p, char rw, char us)
84 D(bug("[Kernel] Marking page 0x%p as read-only\n", addr));
86 core_MMUUpdatePageTables();
89 void core_ProtKernelArea(intptr_t addr, intptr_t length, char p, char rw, char us)
91 D(bug("[Kernel] Protecting area 0x%p - 0x%p\n", addr, addr + length - 1));
92 while (length > 0)
94 core_ProtPage(addr, p, rw, us);
95 addr += 4096;
96 length -= 4096;