]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/arm/vmem_alloc-arch.cpp
d7fdb5208f4e21509775ec7dfad40389f2c0aac0
[l4.git] / kernel / fiasco / src / kern / arm / vmem_alloc-arch.cpp
1 //---------------------------------------------------------------------------
2 IMPLEMENTATION [arm]:
3
4 #include "mem.h"
5 #include "pagetable.h"
6 #include "kmem_space.h"
7 #include "mapped_alloc.h"
8 #include "config.h"
9 #include "panic.h"
10 #include "kdb_ke.h"
11 #include "mem_unit.h"
12 #include "ram_quota.h"
13 #include "static_init.h"
14
15 #include <cstdio>
16 #include <cassert>
17 #include <cstring>
18
19
20 IMPLEMENT
21 void Vmem_alloc::init()
22 {
23   // Allocate a generic zero page
24   printf("Vmem_alloc::init()\n");
25
26   if(Config::VMEM_ALLOC_TEST) 
27     {
28       printf("Vmem_alloc::TEST\n");
29
30       printf("  allocate zero-filled page...");
31       void *p = page_alloc((void*)(0xefc01000), ZERO_FILL );
32       printf(" [%p] done\n",p);
33       printf("  free zero-filled page...");
34       page_free(p);
35       printf(" done\n");
36
37       printf("  allocate no-zero-filled page...");
38       p = page_alloc((void*)(0xefc02000), NO_ZERO_FILL );
39       printf(" [%p] done\n",p);
40       printf("  free no-zero-filled page...");
41       page_free(p);
42       printf(" done\n");
43     }
44 }
45
46 IMPLEMENT
47 void *Vmem_alloc::page_alloc(void *address, Zero_fill zf, unsigned mode)
48 {
49   Address page;
50   void *vpage;
51
52   vpage = Mapped_allocator::allocator()->alloc(Config::PAGE_SHIFT);
53   
54   if (EXPECT_FALSE(!vpage)) 
55     return 0;
56
57   page = Kmem_space::kdir()->walk(vpage, 0, false, 0).phys(vpage);
58   //printf("  allocated page (virt=%p, phys=%08lx\n", vpage, page);
59   Mem_unit::inv_dcache(vpage, ((char*)vpage) + Config::PAGE_SIZE);
60
61   // insert page into master page table
62   Pte pte = Kmem_space::kdir()->walk(address, Config::PAGE_SIZE, true,
63       Ram_quota::root);
64
65   unsigned long pa = Page::CACHEABLE;
66   if (mode & User)
67     pa |= Page::USER_RW;
68   else
69     pa |= Page::KERN_RW;
70
71   pte.set(page, Config::PAGE_SIZE, Mem_page_attr(pa), true);
72
73   Mem_unit::dtlb_flush(address);
74
75   if (zf == ZERO_FILL)
76     Mem::memset_mwords((unsigned long *)address, 0, Config::PAGE_SIZE >> 2);
77
78   return address;
79 }
80
81 IMPLEMENT
82 void Vmem_alloc::page_free(void *page)
83 {
84   Pte pte = Kmem_space::kdir()->walk(page, 0, false,0);
85   if (!pte.valid())
86     return;
87
88   // Invalidate the page because we remove this alias and use the
89   // mapped_allocator mapping from now on.
90   // Write back is not needed here, because we free the page.
91   Mem_unit::inv_vdcache(page, ((char*)page) + Config::PAGE_SIZE);
92
93   Address phys = pte.phys(page);
94   pte.set_invalid(0, true);
95   Mem_unit::dtlb_flush(page);
96
97   Mapped_allocator::allocator()->free_phys(Config::PAGE_SHIFT, phys);
98 }
99
100 IMPLEMENT
101 void *Vmem_alloc::page_unmap(void *page)
102 {
103   Pte pte = Kmem_space::kdir()->walk(page, 0, false,0);
104   if (!pte.valid())
105     return 0;
106
107   Mem_unit::inv_dcache(page, ((char*)page) + Config::PAGE_SIZE);
108
109   Address phys = pte.phys(page);
110   pte.set_invalid(0, true);
111   Mem_unit::dtlb_flush(page);
112
113   return (void*)Mem_layout::phys_to_pmem(phys);
114 }