Back to home page

Quest Cross Reference

 
 

    


Warning, cross-references for /kernel/include/mem/virtual.h need to be fixed.

0001 /*                    The Quest Operating System
0002  *  Copyright (C) 2005-2010  Richard West, Boston University
0003  *
0004  *  This program is free software: you can redistribute it and/or modify
0005  *  it under the terms of the GNU General Public License as published by
0006  *  the Free Software Foundation, either version 3 of the License, or
0007  *  (at your option) any later version.
0008  *
0009  *  This program is distributed in the hope that it will be useful,
0010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
0011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0012  *  GNU General Public License for more details.
0013  *
0014  *  You should have received a copy of the GNU General Public License
0015  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
0016  */
0017 
0018 #ifndef _VIRTUAL_H_
0019 #define _VIRTUAL_H_
0020 #include "types.h"
0021 #include "util/cassert.h"
0022 
0023 #define PGTBL_NUM_ENTRIES 0x400
0024 #define PGDIR_NUM_ENTRIES 0x400
0025 #define PGDIR_KERNEL_BEGIN 0x300 /* where shared kernel entries begin */
0026 #define PGDIR_KERNEL_STACK 0x3FE /* per-process kernel stack is not shared */
0027 #define BIGPAGE_SIZE_BITS 22
0028 #define BIGPAGE_SIZE (1<<BIGPAGE_SIZE_BITS)
0029 #define PAGE_SIZE_BITS 12
0030 #define PAGE_SIZE (1<<PAGE_SIZE_BITS)
0031 #define FRAMENUM_TO_FRAME(x) ((frame_t) ((x) << PAGE_SIZE_BITS))
0032 #define FRAME_TO_FRAMENUM(x) ((framenum_t) ((x) >> PAGE_SIZE_BITS))
0033 #define BIGFRAMENUM_TO_FRAME(x) ((frame_t) ((x) << BIGPAGE_SIZE_BITS))
0034 #define FRAME_TO_BIGFRAMENUM(x) ((framenum_t) ((x) >> BIGPAGE_SIZE_BITS))
0035 
0036 extern void *map_virtual_page (uint32 phys_frame);
0037 extern void unmap_virtual_page (void *virt_addr);
0038 extern void *map_virtual_pages (uint32 * phys_frames, uint32 count);
0039 extern void *map_contiguous_virtual_pages (uint32 phys_frame, uint32 count);
0040 extern void unmap_virtual_pages (void *virt_addr, uint32 count);
0041 extern void *get_phys_addr (void *virt_addr);
0042 
0043 typedef union {
0044   u32 raw;
0045   struct {
0046     uint offset:PAGE_SIZE_BITS;
0047     uint pgtbl_i:(BIGPAGE_SIZE_BITS - PAGE_SIZE_BITS);
0048     uint pgdir_i:(8*sizeof (u32) - BIGPAGE_SIZE_BITS);
0049   };
0050 } linear_address_t PACKED;
0051 CASSERT (sizeof (linear_address_t) == sizeof (u32), linear_address_t);
0052 
0053 typedef union {
0054   uint32 raw;
0055   /* 4 kiB page */
0056   union {
0057     uint raw:12;
0058     struct {
0059       uint present:1;
0060       uint writeable:1;
0061       uint supervisor:1;
0062       uint write_through:1;
0063       uint cache_disabled:1;
0064       uint accessed:1;
0065       uint dirty:1;
0066       uint attribute_index:1;
0067       uint global_page:1;
0068       uint avail:3;
0069     };
0070   } flags;
0071   struct {
0072     uint __align:12;
0073     framenum_t framenum:20;
0074   };
0075 } pgtbl_entry_t PACKED;
0076 CASSERT (sizeof (pgtbl_entry_t) == sizeof (u32), pgtbl_entry_t);
0077 
0078 typedef struct {
0079   frame_t table_pa;             /* table physical address */
0080   pgtbl_entry_t *table_va;      /* table virtual address */
0081   uint8 *starting_va;           /* first virtual address */
0082 } pgtbl_t;
0083 
0084 typedef union {
0085   uint32 raw;
0086 
0087   /* 4 KiB page */
0088   union {
0089     union {
0090       uint32 raw:12;
0091       struct {
0092         uint present:1;
0093         uint writeable:1;
0094         uint supervisor:1;
0095         uint write_through:1;
0096         uint cache_disabled:1;
0097         uint accessed:1;
0098         uint avail1:1;
0099         uint page_size:1;
0100         uint global_page:1;     /* ignored */
0101         uint avail3:3;
0102       };
0103     } flags;
0104     struct {
0105       uint __align:12;
0106       framenum_t table_framenum:20;
0107     };
0108   };
0109 
0110   /* 4 MiB page */
0111   union {
0112     union {
0113       uint32 raw:22;
0114       struct {
0115         uint present:1;
0116         uint writeable:1;
0117         uint supervisor:1;
0118         uint write_through:1;
0119         uint cache_disabled:1;
0120         uint accessed:1;
0121         uint dirty:1;
0122         uint page_size:1;
0123         uint global_page:1;
0124         uint avail3:3;
0125         uint attribute_index:1;
0126         uint reserved:9;
0127       };
0128     } flags_4k;
0129     struct {
0130       uint __align_4k:22;
0131       framenum_t framenum:10;   /* 4 MiB frame number */
0132     };
0133   };
0134 } pgdir_entry_t PACKED;
0135 CASSERT (sizeof (pgdir_entry_t) == sizeof (u32), pgdir_entry_t);
0136 
0137 typedef struct {
0138   frame_t dir_pa;               /* directory physical address */
0139   pgdir_entry_t *dir_va;        /* directory virtual address */
0140 } pgdir_t;
0141 
0142 
0143 /* precondition: dir has valid VA, PA 
0144  * postcondition: return has valid VA, PA
0145  * failure result is (0, 0) */
0146 pgdir_t clone_page_directory (pgdir_t dir);
0147 /* precondition: dir PA and VA are valid, va is aligned */
0148 /* postcondition: returned frame is aligned */
0149 /* failure: -1 */
0150 frame_t pgdir_get_frame (pgdir_t dir, void *va);
0151 /* Obtains the physical address of a virtual address in the given
0152  * page directory. */
0153 /* precondition: dir PA and VA are valid */
0154 /* failure: -1 */
0155 phys_addr_t pgdir_get_phys_addr (pgdir_t dir, void *va);
0156 
0157 #endif
0158 
0159 /* 
0160  * Local Variables:
0161  * indent-tabs-mode: nil
0162  * mode: C
0163  * c-file-style: "gnu"
0164  * c-basic-offset: 2
0165  * End: 
0166  */
0167 
0168 /* vi: set et sw=2 sts=2: */