]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/paging.cpp
update
[l4.git] / kernel / fiasco / src / kern / paging.cpp
1 INTERFACE:
2
3 #include "types.h"
4 #include "l4_msg_item.h"
5
6 EXTENSION class Page
7 {
8 public:
9
10   /* These things must be defined in arch part in
11      the most efficent way according to the architecture.
12
13   typedef int Attribs;
14
15   enum Attribs_enum {
16     USER_NO  = xxx, ///< User No access
17     USER_RO  = xxx, ///< User Read only
18     USER_RW  = xxx, ///< User Read/Write
19     USER_RX  = xxx, ///< User Read/Execute
20     USER_XO  = xxx, ///< User Execute only
21     USER_RWX = xxx, ///< User Read/Write/Execute
22
23     NONCACHEABLE = xxx, ///< Caching is off
24     CACHEABLE    = xxx, ///< Cahe is enabled
25   };
26
27   */
28   typedef L4_msg_item::Memory_type Type;
29
30   struct Kern
31   : cxx::int_type_base<unsigned char, Kern>,
32     cxx::int_bit_ops<Kern>,
33     cxx::int_null_chk<Kern>
34   {
35     Kern() = default;
36     explicit Kern(Value v) : cxx::int_type_base<unsigned char, Kern>(v) {}
37
38     static Kern Global() { return Kern(1); }
39   };
40
41   typedef L4_fpage::Rights Rights;
42
43   struct Attr
44   {
45     Rights rights;
46     Type type;
47     Kern kern;
48
49     Attr() = default;
50     explicit Attr(Rights r, Type t = Type::Normal(), Kern k = Kern(0))
51     : rights(r), type(t), kern(k) {}
52
53     Attr apply(Attr o) const
54     {
55       Attr n = *this;
56       n.rights &= o.rights;
57       if ((o.type & Type::Set()) == Type::Set())
58         n.type = o.type & ~Type::Set();
59       return n;
60     }
61   };
62 };
63
64 EXTENSION class PF {
65 public:
66   static Mword is_translation_error( Mword error );
67   static Mword is_usermode_error( Mword error );
68   static Mword is_read_error( Mword error );
69   static Mword addr_to_msgword0( Address pfa, Mword error );
70   static Mword pc_to_msgword1( Address pc, Mword error );
71 };
72
73
74 class Pdir_alloc_null
75 {
76 public:
77   Pdir_alloc_null() {}
78   void *alloc(unsigned long) const { return 0; }
79   void free(void *, unsigned long) const {}
80   bool valid() const { return false; }
81 };
82
83 template<typename ALLOC>
84 class Pdir_alloc_simple
85 {
86 public:
87   Pdir_alloc_simple(ALLOC *a = 0) : _a(a) {}
88
89   void *alloc(unsigned long size) const
90   { return _a->unaligned_alloc(size); }
91
92   void free(void *block, unsigned long size) const
93   { return _a->unaligned_free(size, block); }
94
95   bool valid() const { return _a; }
96
97   Phys_mem_addr::Value
98   to_phys(void *v) const { return _a->to_phys(v); }
99
100 private:
101   ALLOC *_a;
102 };
103
104
105 class Pdir
106 : public Ptab::Base<Pte_ptr, Ptab_traits_vpn, Ptab_va_vpn >
107 {
108 public:
109   enum { Super_level = Pte_ptr::Super_level };
110 };
111
112 IMPLEMENTATION:
113 //---------------------------------------------------------------------------
114
115 template<typename ALLOC>
116 inline Pdir_alloc_simple<ALLOC> pdir_alloc(ALLOC *a)
117 { return Pdir_alloc_simple<ALLOC>(a); }
118
119 IMPLEMENT inline NEEDS[PF::is_usermode_error]
120 Mword PF::pc_to_msgword1(Address pc, Mword error)
121 {
122   return is_usermode_error(error) ? pc : (Mword)-1;
123 }
124
125 //---------------------------------------------------------------------------
126 IMPLEMENTATION[!ppc32]:
127
128 PUBLIC
129 Address
130 Pdir::virt_to_phys(Address virt) const
131 {
132   Virt_addr va(virt);
133   auto i = walk(va);
134   if (!i.is_valid())
135     return ~0;
136
137   return i.page_addr() | cxx::get_lsb(virt, i.page_order());
138 }
139
140 //---------------------------------------------------------------------------
141 IMPLEMENTATION[ppc32]:
142
143 PUBLIC
144 Address
145 Pdir::virt_to_phys(Address virt) const
146 {
147   auto i = walk(Virt_addr(virt));
148
149   //if (!i.is_valid())
150     return ~0UL;
151
152 #ifdef FIX_THIS
153   Address phys;
154   Pte_htab::pte_lookup(i.e, &phys);
155   return phys | (virt & ~(~0UL << i.page_order()));
156 #endif
157 }