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