Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

pagemap.h

Go to the documentation of this file.
00001 // See the end of this file for license information.
00002 
00003 #ifndef TORSION_PAGE_H
00004 #define TORSION_PAGE_H
00005 
00006 #include "irq.h"
00007 #include "hash.h"
00008 #include "array.h"
00009 #include "types.h"
00010 #include "addrmap.h"
00011 #include "critical.h"
00012 #include "slaballoc.h"
00013 
00014 class Page_map;
00015 extern Page_map page_map;
00016 
00017 const unsigned VIRTUAL_MEMORY_END = ~0;
00018 
00020 
00021 class Mapping_cache_info {
00022 public:
00023   unsigned ref_count;     
00024   unsigned last_mapped_time;    
00025   void* virtual_page;     
00026   void* physical_page;      
00027 
00029   inline void
00030   init(void* virtual_page = NULL, void* physical_page = NULL) {
00031     ref_count = 0;
00032     last_mapped_time = 0;
00033     this->virtual_page = virtual_page;
00034     this->physical_page = physical_page;
00035   }
00036 };
00037 
00039 
00040 class Page_map : public Address_map {
00041 protected:
00042   void* direct_mapped_end;    
00043   unsigned* temp_mapping_cache;   
00044   unsigned* first_free_temp_mapping;  
00045   static const Size MAPPING_CACHE_PAGE_COUNT = 1024;
00047   Mapping_cache_info mapping_cache_usage[MAPPING_CACHE_PAGE_COUNT];
00049   Hash_table<void*, Mapping_cache_info*> mapping_cache_mappings;
00051   Hash_node<void*, Mapping_cache_info*> mapping_nodes[MAPPING_CACHE_PAGE_COUNT];
00052   Int_handler handler;      
00053 
00059   Hash_table<void*, void*> dirty_pages[2];
00060   int dirty_pages_index;    
00061 
00064   Slab_allocator dirty_pages_nodes[2];
00065   
00066 public:
00067   static const unsigned PTE_USER = 0x4;
00068   static const unsigned PTE_ACCESSED = 0x20;
00069   static const unsigned PTE_PAGE_FRAME_ADDRESS = 0xfffff000;
00071   static const unsigned DIRTY_PAGE_COPIED = 1;
00072   static const unsigned CR0_PAGING = (1 << 31);
00074   static const unsigned CR0_RESPECT_READONLY = (1 << 16);
00075 
00077   void
00078   init(unsigned& last_available_address);
00079 
00085   void map_page(void* virtual_page, void* physical_page);
00086 
00094   unsigned*
00095   map_temp_page(unsigned* physical_page);
00096 
00101   void
00102   unmap_temp_page(unsigned* virtual_page);
00103 
00105   void
00106   unmap_page(void* virtual_page);
00107 
00110   static inline unsigned*
00111   table_entry_to_phys(unsigned page_entry) {
00112     return (unsigned*)(page_entry & PTE_PAGE_FRAME_ADDRESS);
00113   }
00114 
00118   inline Hash_table<void*, void*>&
00119   get_dirty_pages() {
00120     return dirty_pages[dirty_pages_index];
00121   }
00122   
00126   inline Hash_table<void*, void*>&
00127   get_dirty_pages_next() {
00128     // 1 - dirty_pages_index, so as to get whichever of the two indices
00129     // (0 and 1) that dirty_pages_index isn't
00130     return dirty_pages[1 - dirty_pages_index];
00131   }
00132 
00138   inline void
00139   switch_dirty_pages_hashes() {
00140     // each time this function is called, dirty_pages_index switches between
00141     // 0 and 1
00142     dirty_pages_index = 1 - dirty_pages_index;    
00143   }
00144 
00146   void
00147   free_dirty_pages_next();
00148 
00150   bool
00151   handle_page_fault();
00152 
00154   inline void*
00155   virtual_to_physical_page(void* virtual_addr) {
00156     return table_entry_to_phys(get_table_entry(virtual_addr));
00157   }
00158 
00160   inline bool
00161   is_dirty(void* virtual_addr) {
00162     if (dirty_pages_index == -1)
00163       return false;
00164 
00165     return dirty_pages[dirty_pages_index].has_key(virtual_addr);
00166   }
00167 
00176   void
00177   add_dirty_page(void* dirty_page, void* physical_page = NULL, int index = -1);
00178 
00180   void
00181   print();
00182 };
00183 
00185 inline bool
00186 page_fault_handler();
00187 
00188 // TODO:
00189 // upon evicting a page to disk (swapping):
00190 // log the page to disk
00191 // (note that if the page to swap is copy-on-write, maybe log the original
00192 //  instead of the copy so as to ensure snapshot consistency?)
00193 // unset dirty bit in pte
00194 // add the page to the block map (in memory)
00195 
00196 // Page table entry for virtual page in memory:
00197 // 
00198 //  31                                   12     9 8 7 6 5 4 3 2 1 0
00199 // +---------------------------------------------------------------+
00200 // |                                       |                  U R  |
00201 // |       page frame address 31..12       |0 0 0 X X D A X X / / P|
00202 // |                                       |                  S W  |
00203 // +---------------------------------------------------------------+
00204 //
00205 //   P : present = 1
00206 // R/W : read/write
00207 // U/S : user/supervisor = 0
00208 //   D : dirty
00209 //   X : Intel reserved
00210 //   0 : unused
00211 //
00212 // Page table entry for unused virtual page:
00213 // 
00214 //  31                                                            0
00215 // +---------------------------------------------------------------+
00216 // |                                                               |
00217 // |0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0|
00218 // |                                                               |
00219 // +---------------------------------------------------------------+
00220 
00221 #endif
00222 
00223 /* Torsion Operating System, Copyright (C) 2000-2004 Dan Helfman
00224  *
00225  * This program is free software; you can redistribute it and/or modify it
00226  * under the terms of the GNU General Public License as published by the
00227  * Free Software Foundation; either version 2 of the License, or (at your
00228  * option) any later version.
00229  * 
00230  * This program is distributed in the hope that it will be useful, but
00231  * WITHOUT ANY WARRANTY; without even the implied warranty of
00232  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00233  * General Public License for more details (in the COPYING file).
00234  * 
00235  * You should have received a copy of the GNU General Public License along
00236  * with this program; if not, write to the Free Software Foundation, Inc.,
00237  * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00238  */

Torsion Operating System, Copyright (C) 2000-2004 Dan Helfman