]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/paging.cpp
a482d9c6e6ecdc858bfb07e5d2f404c9e3daffca
[l4.git] / kernel / fiasco / src / kern / paging.cpp
1 INTERFACE:
2
3 #include "types.h"
4
5 namespace Page {
6   
7   /* These things must be defined in arch part in
8      the most efficent way according to the architecture.
9   
10   typedef int Attribs;
11
12   enum Attribs_enum {
13     USER_NO  = xxx, ///< User No access
14     USER_RO  = xxx, ///< User Read only
15     USER_RW  = xxx, ///< User Read/Write
16     USER_RX  = xxx, ///< User Read/Execute
17     USER_XO  = xxx, ///< User Execute only
18     USER_RWX = xxx, ///< User Read/Write/Execute
19
20     NONCACHEABLE = xxx, ///< Caching is off
21     CACHEABLE    = xxx, ///< Cahe is enabled
22   };
23      
24   
25   */
26
27
28 };
29
30 EXTENSION class PF {
31 public:
32   static Mword is_translation_error( Mword error );
33   static Mword is_usermode_error( Mword error );
34   static Mword is_read_error( Mword error );
35   static Mword addr_to_msgword0( Address pfa, Mword error );
36   static Mword pc_to_msgword1( Address pc, Mword error );
37 };
38
39
40 class Pdir_alloc_null
41 {
42 public:
43   Pdir_alloc_null() {}
44   void *alloc(unsigned long) const { return 0; }
45   void free(void *, unsigned long) const {}
46   bool valid() const { return false; }
47 };
48
49 template<typename ALLOC>
50 class Pdir_alloc_simple
51 {
52 public:
53   Pdir_alloc_simple(ALLOC *a = 0) : _a(a) {}
54
55   void *alloc(unsigned long size) const
56   { return _a->unaligned_alloc(size); }
57
58   void free(void *block, unsigned long size) const
59   { return _a->unaligned_free(size, block); }
60
61   bool valid() const { return _a; }
62
63 private:
64   ALLOC *_a;
65 };
66
67
68 class Pdir : public Ptab::Base<Pte_base, Ptab_traits_vpn, Ptab_va_vpn >
69 {
70 public:
71   enum { Super_level = Pte_base::Super_level };
72
73 private:
74   static bool       _have_superpages;
75   static unsigned   _super_level;
76 };
77
78 IMPLEMENTATION:
79 //---------------------------------------------------------------------------
80
81 bool Pdir::_have_superpages;
82 unsigned  Pdir::_super_level;
83
84 template<typename ALLOC>
85 inline Pdir_alloc_simple<ALLOC> pdir_alloc(ALLOC *a)
86 { return Pdir_alloc_simple<ALLOC>(a); }
87
88 PUBLIC static inline
89 void
90 Pdir::have_superpages(bool yes)
91 {
92   _have_superpages = yes;
93   _super_level = yes ? Super_level : (Super_level + 1);
94 }
95
96 PUBLIC static inline
97 unsigned
98 Pdir::super_level()
99 { return _super_level; }
100
101
102 IMPLEMENT inline NEEDS[PF::is_usermode_error]
103 Mword PF::pc_to_msgword1(Address pc, Mword error)
104 {
105   return is_usermode_error(error) ? pc : (Mword)-1;
106 }
107
108 //---------------------------------------------------------------------------
109 IMPLEMENTATION[!ppc32]:
110
111 PUBLIC
112 Address
113 Pdir::virt_to_phys(Address virt) const
114 {
115   Iter i = walk(Virt_addr(virt));
116   if (!i.e->valid())
117     return ~0;
118
119   return i.e->addr() | (virt & ~(~0UL << i.shift()));
120 }
121
122 //---------------------------------------------------------------------------
123 IMPLEMENTATION[ppc32]:
124
125 PUBLIC
126 Address
127 Pdir::virt_to_phys(Address virt) const
128 {
129   Iter i = walk(Virt_addr(virt));
130
131   if (!i.e->valid())
132     return ~0UL;
133
134   Address phys;
135   Pte_htab::pte_lookup(i.e, &phys);
136   return phys | (virt & ~(~0UL << i.shift()));
137 }