00001 #ifndef THREADS_VADDR_H 00002 //107597904289 00003 #define THREADS_VADDR_H 00004 00005 #include <debug.h> 00006 #include <stdint.h> 00007 #include <stdbool.h> 00008 00009 #include "threads/loader.h" 00010 00011 /* Functions and macros for working with virtual addresses. 00012 00013 See pte.h for functions and macros specifically for x86 00014 hardware page tables. */ 00015 00016 #define BITMASK(SHIFT, CNT) (((1ul << (CNT)) - 1) << (SHIFT)) 00017 00018 /* Page offset (bits 0:12). */ 00019 #define PGSHIFT 0 /* Index of first offset bit. */ 00020 #define PGBITS 12 /* Number of offset bits. */ 00021 #define PGSIZE (1 << PGBITS) /* Bytes in a page. */ 00022 #define PGMASK BITMASK(PGSHIFT, PGBITS) /* Page offset bits (0:12). */ 00023 00024 /* Offset within a page. */ 00025 static inline unsigned pg_ofs (const void *va) { 00026 return (uintptr_t) va & PGMASK; 00027 } 00028 00029 /* Virtual page number. */ 00030 static inline uintptr_t pg_no (const void *va) { 00031 return (uintptr_t) va >> PGBITS; 00032 } 00033 00034 /* Round up to nearest page boundary. */ 00035 static inline void *pg_round_up (const void *va) { 00036 return (void *) (((uintptr_t) va + PGSIZE - 1) & ~PGMASK); 00037 } 00038 00039 /* Round down to nearest page boundary. */ 00040 static inline void *pg_round_down (const void *va) { 00041 return (void *) ((uintptr_t) va & ~PGMASK); 00042 } 00043 00044 /* Base address of the 1:1 physical-to-virtual mapping. Physical 00045 memory is mapped starting at this virtual address. Thus, 00046 physical address 0 is accessible at PHYS_BASE, physical 00047 address address 0x1234 at (uint8_t *) PHYS_BASE + 0x1234, and 00048 so on. 00049 00050 This address also marks the end of user programs' address 00051 space. Up to this point in memory, user programs are allowed 00052 to map whatever they like. At this point and above, the 00053 virtual address space belongs to the kernel. */ 00054 #define PHYS_BASE ((void *) LOADER_PHYS_BASE) 00055 00056 /* Returns true if VADDR is a user virtual address. */ 00057 static inline bool 00058 is_user_vaddr (const void *vaddr) 00059 { 00060 return vaddr < PHYS_BASE; 00061 } 00062 00063 /* Returns true if VADDR is a kernel virtual address. */ 00064 static inline bool 00065 is_kernel_vaddr (const void *vaddr) 00066 { 00067 return vaddr >= PHYS_BASE; 00068 } 00069 00070 /* Returns kernel virtual address at which physical address PADDR 00071 is mapped. */ 00072 static inline void * 00073 ptov (uintptr_t paddr) 00074 { 00075 ASSERT ((void *) paddr < PHYS_BASE); 00076 00077 return (void *) (paddr + PHYS_BASE); 00078 } 00079 00080 /* Returns physical address at which kernel virtual address VADDR 00081 is mapped. */ 00082 static inline uintptr_t 00083 vtop (const void *vaddr) 00084 { 00085 ASSERT (is_kernel_vaddr (vaddr)); 00086 00087 return (uintptr_t) vaddr - (uintptr_t) PHYS_BASE; 00088 } 00089 00090 #endif /* threads/vaddr.h */