]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/arm/kmem_alloc-arm.cpp
8d3bd29032ac2ccab04f3c5ba2243c39e728eaf8
[l4.git] / kernel / fiasco / src / kern / arm / kmem_alloc-arm.cpp
1 IMPLEMENTATION [arm]:
2
3 #include "mem_unit.h"
4 #include "kmem_space.h"
5 #include "pagetable.h"
6 #include "ram_quota.h"
7
8
9 PRIVATE //inline
10 bool
11 Kmem_alloc::map_pmem(unsigned long phy, unsigned long size)
12 {
13   static unsigned long next_map = Mem_layout::Map_base + (4 << 20);
14   size = Mem_layout::round_superpage(size + (phy & ~Config::SUPERPAGE_MASK));
15   phy = Mem_layout::trunc_superpage(phy);
16
17   if (next_map + size > Mem_layout::Map_end)
18     return false;
19
20   for (unsigned long i = 0; i <size; i+=Config::SUPERPAGE_SIZE)
21     {
22       Pte pte = Kmem_space::kdir()->walk((char*)next_map+i,
23           Config::SUPERPAGE_SIZE, false, Ptab::Null_alloc(),
24           Kmem_space::kdir());
25       pte.set(phy+i, Config::SUPERPAGE_SIZE, 
26           Mem_page_attr(Page::KERN_RW | Page::CACHEABLE),
27           true);
28
29     }
30   Mem_layout::add_pmem(phy, next_map, size);
31   next_map += size;
32   return true;
33 }
34
35 IMPLEMENT
36 Kmem_alloc::Kmem_alloc()
37 {
38   // The -Wframe-larger-than= warning for this function is known and
39   // no problem, because the function runs only on our boot stack.
40   Mword alloc_size = Config::KMEM_SIZE;
41   a->init(Mem_layout::Map_base);
42   Mem_region_map<64> map;
43   unsigned long available_size = create_free_map(Kip::k(), &map);
44
45   // sanity check whether the KIP has been filled out, number is arbitrary
46   if (available_size < (1 << 18))
47     panic("Kmem_alloc: No kernel memory available (%ld)\n",
48           available_size);
49
50   for (int i = map.length() - 1; i >= 0 && alloc_size > 0; --i)
51     {
52       Mem_region f = map[i];
53       if (f.size() > alloc_size)
54         f.start += (f.size() - alloc_size);
55
56       Kip::k()->add_mem_region(Mem_desc(f.start, f.end,
57             Mem_desc::Reserved));
58       //printf("ALLOC1: [%08lx; %08lx] sz=%ld\n", f.start, f.end, f.size());
59       if (Mem_layout::phys_to_pmem(f.start) == ~0UL)
60         if (!map_pmem(f.start, f.size()))
61           panic("Kmem_alloc: cannot map physical memory %p\n", (void*)f.start);
62       a->add_mem((void*)Mem_layout::phys_to_pmem(f.start), f.size());
63       alloc_size -= f.size();
64     }
65
66   if (alloc_size)
67     WARNX(Warning, "Kmem_alloc: cannot allocate sufficient kernel memory\n");
68 }
69
70 //----------------------------------------------------------------------------
71 IMPLEMENTATION [arm && debug]:
72
73 #include <cstdio>
74
75 #include "kip_init.h"
76 #include "panic.h"
77
78 PUBLIC
79 void Kmem_alloc::debug_dump()
80 {
81   a->dump();
82
83   unsigned long free = a->avail();
84   printf("Used %ldKB out of %dKB of Kmem\n",
85          (Config::KMEM_SIZE - free + 1023)/1024,
86          (Config::KMEM_SIZE        + 1023)/1024);
87 }