usb.patch, with conflicts and some warnings fixed
[pintos-anon] / src / threads / pte.h
1 #ifndef THREADS_PTE_H
2 #define THREADS_PTE_H
3
4 #include "threads/vaddr.h"
5
6 /* Functions and macros for working with x86 hardware page
7    tables.
8
9    See vaddr.h for more generic functions and macros for virtual
10    addresses.
11    
12    Virtual addresses are structured as follows:
13
14     31                  22 21                  12 11                   0
15    +----------------------+----------------------+----------------------+
16    | Page Directory Index |   Page Table Index   |    Page Offset       |
17    +----------------------+----------------------+----------------------+
18 */
19
20 /* Page table index (bits 12:21). */
21 #define PTSHIFT PGBITS                     /* First page table bit. */
22 #define PTBITS  10                         /* Number of page table bits. */
23 #define PTSPAN  (1 << PTBITS << PGBITS)    /* Bytes covered by a page table. */
24 #define PTMASK  BITMASK(PTSHIFT, PTBITS)   /* Page table bits (12:21). */
25
26 /* Page directory index (bits 22:31). */
27 #define PDSHIFT (PTSHIFT + PTBITS)         /* First page directory bit. */
28 #define PDBITS  10                         /* Number of page dir bits. */
29 #define PDMASK  BITMASK(PDSHIFT, PDBITS)   /* Page directory bits (22:31). */
30
31 /* memory dedicated to PCI - make sure this is 4MB aligned */
32 #define PCI_ADDR_ZONE_BEGIN     0xe0000000
33 #define PCI_ADDR_ZONE_END       0xe0800000
34 #define PCI_ADDR_ZONE_PDES      2
35 #define PCI_ADDR_ZONE_PAGES     (PCI_ADDR_ZONE_END-PCI_ADDR_ZONE_BEGIN)/PGSIZE
36
37
38
39 /* Obtains page table index from a virtual address. */
40 static inline unsigned pt_no (const void *va) {
41   return ((uintptr_t) va & PTMASK) >> PTSHIFT;
42 }
43
44 /* Obtains page directory index from a virtual address. */
45 static inline uintptr_t pd_no (const void *va) {
46   return (uintptr_t) va >> PDSHIFT;
47 }
48
49 /* Page directory and page table entries.
50
51    For more information see the section on page tables in the
52    Pintos reference guide chapter, or [IA32-v3a] 3.7.6
53    "Page-Directory and Page-Table Entries".
54
55    PDEs and PTEs share a common format:
56
57    31                                 12 11                     0
58    +------------------------------------+------------------------+
59    |         Physical Address           |         Flags          |
60    +------------------------------------+------------------------+
61
62    In a PDE, the physical address points to a page table.
63    In a PTE, the physical address points to a data or code page.
64    The important flags are listed below.
65    When a PDE or PTE is not "present", the other flags are
66    ignored.
67    A PDE or PTE that is initialized to 0 will be interpreted as
68    "not present", which is just fine. */
69 #define PTE_FLAGS 0x00000fff    /* Flag bits. */
70 #define PTE_ADDR  0xfffff000    /* Address bits. */
71 #define PTE_AVL   0x00000e00    /* Bits available for OS use. */
72 #define PTE_P 0x1               /* 1=present, 0=not present. */
73 #define PTE_W 0x2               /* 1=read/write, 0=read-only. */
74 #define PTE_U 0x4               /* 1=user/kernel, 0=kernel only. */
75 #define PTE_WT (1 << 3)         /* 1=write-through, 0=write-back */
76 #define PTE_CD (1 << 4)         /* 1=cache disabled, 0=cache enabled. */
77 #define PTE_A 0x20              /* 1=accessed, 0=not acccessed. */
78 #define PTE_D 0x40              /* 1=dirty, 0=not dirty (PTEs only). */
79 #define PTE_G (1 << 8)          /* 1=global page, do not flush */
80
81 /* Returns a PDE that points to page table PT. */
82 static inline uint32_t pde_create_user (uint32_t *pt) {
83   ASSERT (pg_ofs (pt) == 0);
84   return vtop (pt) | PTE_U | PTE_P | PTE_W;
85 }
86
87 /* Returns a PDE that points to page table PT. */
88 static inline uint32_t pde_create_kernel (uint32_t *pt) {
89   ASSERT (pg_ofs (pt) == 0);
90   return vtop (pt) | PTE_P | PTE_W | PTE_G;
91 }
92
93 /* Returns a pointer to the page table that page directory entry
94    PDE, which must "present", points to. */
95 static inline uint32_t *pde_get_pt (uint32_t pde) {
96   ASSERT (pde & PTE_P);
97   return ptov (pde & PTE_ADDR);
98 }
99
100 /* Returns a PTE that points to PAGE.
101    The PTE's page is readable.
102    If WRITABLE is true then it will be writable as well.
103    The page will be usable only by ring 0 code (the kernel). */
104 static inline uint32_t pte_create_kernel (void *page, bool writable) {
105   ASSERT (pg_ofs (page) == 0);
106   return vtop (page) | PTE_P | (writable ? PTE_W : 0) | PTE_G;
107 }
108
109 /* Returns a PTE that points to PAGE.
110    The PTE's page is readable.
111    If WRITABLE is true then it will be writable as well.
112    The page will be usable by both user and kernel code. */
113 static inline uint32_t pte_create_user (void *page, bool writable) {
114   ASSERT (pg_ofs (page) == 0);
115   return vtop (page) | PTE_P | (writable ? PTE_W : 0) | PTE_U;
116 }
117
118 /* Returns a pointer to the page that page table entry PTE points
119    to. */
120 static inline void *pte_get_page (uint32_t pte) {
121   return ptov (pte & PTE_ADDR);
122 }
123
124 #endif /* threads/pte.h */
125