00001
00002
00003 #ifndef kmem_h
00004 #define kmem_h
00005
00006 #include "initcalls.h"
00007 #include "kern_types.h"
00008 #include "kip.h"
00009 #include "mem_layout.h"
00010
00011
00012
00013
00014
00015
00016 class Pdir;
00017 class Tss;
00018
00019
00020
00021
00022
00023
00024
00030 class Kmem
00031 {
00032 friend class Jdb;
00033 friend class Jdb_dbinfo;
00034 friend class Jdb_kern_info_misc;
00035 friend class Kdb;
00036 friend class Profile;
00037 friend class Vmem_alloc;
00038
00039 private:
00040 Kmem();
00041 Kmem (const Kmem&);
00042 static Address mem_max, _himem;
00043
00044 public:
00045 enum
00046 {
00047 mem_tcbs = Mem_layout::Tcbs,
00048 mem_user_max = Mem_layout::User_max,
00049 };
00050
00051 static void init();
00052 static Mword is_kmem_page_fault(Mword pfa, Mword error);
00053 static Mword is_ipc_page_fault(Mword pfa, Mword error);
00054 static Mword is_smas_page_fault(Mword pfa);
00055 static Mword is_io_bitmap_page_fault(Mword pfa);
00056 static Address kcode_start();
00057 static Address kcode_end();
00058 static Address kmem_base();
00059 static Address virt_to_phys(const void *addr);
00060 private:
00061
00062 protected:
00063 static Pdir *kdir asm ("KMEM_KDIR");
00064
00065 private:
00066 static Address user_max();
00067 static Unsigned8 *io_bitmap_delimiter;
00068
00069 public:
00070 static inline Mword is_tcb_page_fault( Address addr, Mword );
00071
00079 static inline const Pdir* dir();
00080
00081 static inline Address get_mem_max();
00082
00083 static inline Address himem();
00084
00088 static inline Address volatile * kernel_esp();
00089
00098 static inline void * phys_to_virt(Address addr);
00099
00103 static void dir_init(Pdir *d);
00104
00108 static inline Address ipc_window(unsigned win);
00109
00110 static inline Address io_bitmap_delimiter_page();
00111
00112
00113
00114
00115
00116
00117 static void map_devpage_4k(Address phys, Address virt, bool cached, bool global, Address *offs=0);
00118
00119 private:
00121 static inline Address alloc_from_page(Address *from, Address size);
00122
00123 static FIASCO_INIT Address himem_alloc();
00124 };
00125
00126 typedef Kmem Kmem_space;
00127
00128
00129
00130
00131
00132 #include "tss.h"
00133 #include "cpu.h"
00134 #include "paging.h"
00135 #include "std_macros.h"
00136
00137
00138
00139
00140
00141
00142
00143
00144 inline Mword
00145 Kmem::is_tcb_page_fault( Address addr, Mword )
00146 {
00147 return ( addr >= Mem_layout::Tcbs
00148 && addr < Mem_layout::Tcbs
00149 + (Config::thread_block_size
00150 * Config::max_threads()) );
00151 }
00152
00153
00161 inline const Pdir* Kmem::dir() { return kdir; }
00162
00163
00164 inline Address Kmem::get_mem_max() { return mem_max; }
00165
00166 inline Address Kmem::himem() { return _himem; }
00167
00168
00173 inline Address volatile *
00174 Kmem::kernel_esp()
00175 {
00176 return reinterpret_cast<Address volatile *>(&Cpu::get_tss()->esp0);
00177 }
00178
00179
00189 inline void *
00190 Kmem::phys_to_virt(Address addr)
00191 {
00192 return reinterpret_cast<void *>(Mem_layout::phys_to_pmem(addr));
00193 }
00194
00195
00200 inline Address
00201 Kmem::ipc_window(unsigned win)
00202 {
00203 return win == 0
00204 ? Mem_layout::Ipc_window0
00205 : Mem_layout::Ipc_window1;
00206 }
00207
00208
00209
00210 inline Address
00211 Kmem::io_bitmap_delimiter_page()
00212 {
00213 return reinterpret_cast<Address>(io_bitmap_delimiter);
00214 }
00215
00216
00217
00218 inline Mword
00219 Kmem::is_io_bitmap_page_fault(Address addr)
00220 {
00221 return (addr >= Mem_layout::Io_bitmap &&
00222 addr <= Mem_layout::Io_bitmap + L4_fpage::Io_port_max / 8);
00223 }
00224
00225
00226
00227 inline Mword
00228 Kmem::is_smas_page_fault(Address addr)
00229 {
00230 return (addr >= Mem_layout::Smas_start && addr < Mem_layout::Smas_end);
00231 }
00232
00233
00234
00235 inline Mword
00236 Kmem::is_ipc_page_fault(Address addr, Mword )
00237 {
00238 return (addr >= ipc_window(0) && addr < ipc_window(1) +
00239 (Config::SUPERPAGE_SIZE << 1));
00240 }
00241
00242
00243
00244 inline Mword
00245 Kmem::is_kmem_page_fault(Address addr, Mword )
00246 {
00247 return (addr >= mem_user_max);
00248 }
00249
00250
00258 inline Address
00259 Kmem::virt_to_phys(const void *addr)
00260 {
00261 Address a = reinterpret_cast<Address>(addr);
00262
00263 if (EXPECT_TRUE (Mem_layout::in_pmem(a)))
00264 return Mem_layout::pmem_to_phys(a);
00265
00266 if (EXPECT_TRUE (Mem_layout::in_boot_state(a)))
00267 return a - Mem_layout::Boot_state_start;
00268
00269 return kdir->virt_to_phys(a);
00270 }
00271
00272
00273 inline Address Kmem::kcode_start()
00274 { return virt_to_phys (&Mem_layout::start) & Config::PAGE_MASK; }
00275
00276
00277 inline Address Kmem::kcode_end()
00278 {
00279 return (virt_to_phys (&Mem_layout::end) + Config::PAGE_SIZE)
00280 & Config::PAGE_MASK;
00281 }
00282
00283
00284 inline Address Kmem::user_max() { return (Address) -1; }
00285
00286 #endif // kmem_h