]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/ia32/vm.cpp
df03955e6e0b636fefd8b7d14c4e1b8e4ee3229a
[l4.git] / kernel / fiasco / src / kern / ia32 / vm.cpp
1 INTERFACE:
2
3 #include "task.h"
4
5 class Vm : public Task
6 {
7 public:
8   ~Vm() {}
9
10   void invoke(L4_obj_ref obj, Mword rights, Syscall_frame *f, Utcb *utcb) = 0;
11
12   enum Operation
13   {
14     Vm_run_op = Task::Vm_ops + 0,
15   };
16 };
17
18 // ------------------------------------------------------------------------
19 IMPLEMENTATION:
20
21 #include "cpu.h"
22
23 class Mem_space_vm : public Mem_space
24 {
25 public:
26   Mem_space_vm(Ram_quota *q) : Mem_space(q, false) {}
27   virtual Page_number map_max_address() const
28   { return Page_number::create(1UL << (MWORD_BITS - Page_shift)); }
29 };
30
31 struct Vm_space_factory
32 {
33   /** Create a usual Mem_space object. */
34   template< typename A1 >
35   static void create(Mem_space *v, A1 a1)
36   { new (v) Mem_space_vm(a1); }
37
38   template< typename S >
39   static void create(S *v)
40   { new (v) S(); }
41 };
42
43
44 PUBLIC
45 Vm::Vm(Ram_quota *q)
46   : Task(Vm_space_factory(), q, L4_fpage(0))
47 {
48 }
49
50 PUBLIC static
51 template< typename VM >
52 slab_cache_anon *
53 Vm::allocator()
54 {
55   static slab_cache_anon *slabs = new Kmem_slab_simple (sizeof (VM),
56                                                         sizeof (Mword),
57                                                         "Vm");
58   return slabs;
59 }
60
61 PUBLIC static
62 int
63 Vm::getpage(Utcb *utcb, L4_msg_tag tag, void **addr)
64 {
65   L4_snd_item_iter item(utcb, tag.words());
66
67   if (EXPECT_FALSE(!tag.items() || !item.next()))
68     return -L4_err::EInval;
69
70   L4_fpage page(item.get()->d);
71
72   if (EXPECT_FALSE(   !page.is_mempage()
73                    || page.order() < 12))
74     return -L4_err::EInval;
75
76   unsigned int page_attribs;
77   Mem_space::Phys_addr phys;
78   Mem_space::Size size;
79
80   if (EXPECT_FALSE(!current()->space()->mem_space()
81                         ->v_lookup(Virt_addr(page.mem_address()),
82                                    &phys, &size, &page_attribs)))
83     return -L4_err::EInval;
84
85   *addr = (void *)Virt_addr(page.mem_address()).value();
86
87   return 0;
88 }
89
90 PUBLIC
91 template< typename Vm_impl >
92 void
93 Vm::vm_invoke(L4_obj_ref obj, Mword rights, Syscall_frame *f, Utcb *utcb)
94 {
95   if (EXPECT_FALSE(f->tag().proto() != L4_msg_tag::Label_task))
96     {
97       f->tag(commit_result(-L4_err::EBadproto));
98       return;
99     }
100
101   switch (utcb->values[0])
102     {
103     case Vm_run_op:
104       f->tag(static_cast<Vm_impl *>(this)->sys_vm_run(f, utcb));
105       return;
106     default:
107       Task::invoke(obj, rights, f, utcb);
108       return;
109     }
110 }
111
112
113 // ------------------------------------------------------------------------
114 IMPLEMENTATION [ia32]:
115
116 PROTECTED static inline
117 bool
118 Vm::is_64bit()
119 { return false; }
120
121 // ------------------------------------------------------------------------
122 IMPLEMENTATION [amd64]:
123
124 PROTECTED static inline
125 bool
126 Vm::is_64bit()
127 { return true; }