pmap.h revision 1.4.4.3 1 1.4.4.3 bouyer /* $NetBSD: pmap.h,v 1.4.4.3 2001/04/23 09:41:34 bouyer Exp $ */
2 1.4.4.2 bouyer
3 1.4.4.2 bouyer /*
4 1.4.4.2 bouyer * Copyright (c) 1994,1995 Mark Brinicombe.
5 1.4.4.2 bouyer * All rights reserved.
6 1.4.4.2 bouyer *
7 1.4.4.2 bouyer * Redistribution and use in source and binary forms, with or without
8 1.4.4.2 bouyer * modification, are permitted provided that the following conditions
9 1.4.4.2 bouyer * are met:
10 1.4.4.2 bouyer * 1. Redistributions of source code must retain the above copyright
11 1.4.4.2 bouyer * notice, this list of conditions and the following disclaimer.
12 1.4.4.2 bouyer * 2. Redistributions in binary form must reproduce the above copyright
13 1.4.4.2 bouyer * notice, this list of conditions and the following disclaimer in the
14 1.4.4.2 bouyer * documentation and/or other materials provided with the distribution.
15 1.4.4.2 bouyer * 3. All advertising materials mentioning features or use of this software
16 1.4.4.2 bouyer * must display the following acknowledgement:
17 1.4.4.2 bouyer * This product includes software developed by Mark Brinicombe
18 1.4.4.2 bouyer * 4. The name of the author may not be used to endorse or promote products
19 1.4.4.2 bouyer * derived from this software without specific prior written permission.
20 1.4.4.2 bouyer *
21 1.4.4.2 bouyer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 1.4.4.2 bouyer * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23 1.4.4.2 bouyer * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24 1.4.4.2 bouyer * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25 1.4.4.2 bouyer * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26 1.4.4.2 bouyer * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 1.4.4.2 bouyer * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 1.4.4.2 bouyer * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 1.4.4.2 bouyer * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30 1.4.4.2 bouyer * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 1.4.4.2 bouyer */
32 1.4.4.2 bouyer
33 1.4.4.2 bouyer #ifndef _ARM32_PMAP_H_
34 1.4.4.2 bouyer #define _ARM32_PMAP_H_
35 1.4.4.2 bouyer
36 1.4.4.2 bouyer #include <machine/cpufunc.h>
37 1.4.4.2 bouyer #include <machine/pte.h>
38 1.4.4.2 bouyer
39 1.4.4.2 bouyer /*
40 1.4.4.2 bouyer * Data structures used by pmap
41 1.4.4.2 bouyer */
42 1.4.4.2 bouyer
43 1.4.4.2 bouyer /*
44 1.4.4.2 bouyer * Structure that describes a Level 1 page table and the flags
45 1.4.4.2 bouyer * associated with it.
46 1.4.4.2 bouyer */
47 1.4.4.2 bouyer struct l1pt {
48 1.4.4.2 bouyer SIMPLEQ_ENTRY(l1pt) pt_queue; /* Queue pointers */
49 1.4.4.2 bouyer struct pglist pt_plist; /* Allocated page list */
50 1.4.4.2 bouyer vaddr_t pt_va; /* Allocated virtual address */
51 1.4.4.2 bouyer int pt_flags; /* Flags */
52 1.4.4.2 bouyer };
53 1.4.4.2 bouyer #define PTFLAG_STATIC 1 /* Statically allocated */
54 1.4.4.2 bouyer #define PTFLAG_KPT 2 /* Kernel pt's are mapped */
55 1.4.4.2 bouyer #define PTFLAG_CLEAN 4 /* L1 is clean */
56 1.4.4.2 bouyer
57 1.4.4.2 bouyer /*
58 1.4.4.2 bouyer * The pmap structure itself.
59 1.4.4.2 bouyer */
60 1.4.4.2 bouyer struct pmap {
61 1.4.4.2 bouyer pd_entry_t *pm_pdir; /* KVA of page directory */
62 1.4.4.2 bouyer struct l1pt *pm_l1pt; /* L1 descriptor */
63 1.4.4.2 bouyer void *pm_unused1; /* Reserved for l2 map */
64 1.4.4.2 bouyer paddr_t pm_pptpt; /* PA of pt's page table */
65 1.4.4.2 bouyer vaddr_t pm_vptpt; /* VA of pt's page table */
66 1.4.4.2 bouyer short pm_dref; /* page directory ref count */
67 1.4.4.2 bouyer short pm_count; /* pmap reference count */
68 1.4.4.2 bouyer simple_lock_data_t pm_lock; /* lock on pmap */
69 1.4.4.2 bouyer struct pmap_statistics pm_stats; /* pmap statistics */
70 1.4.4.2 bouyer };
71 1.4.4.2 bouyer
72 1.4.4.2 bouyer typedef struct pmap *pmap_t;
73 1.4.4.2 bouyer
74 1.4.4.2 bouyer /*
75 1.4.4.2 bouyer * For each vm_page_t, there is a list of all currently valid virtual
76 1.4.4.2 bouyer * mappings of that page. An entry is a pv_entry_t, the list is pv_table.
77 1.4.4.2 bouyer */
78 1.4.4.2 bouyer typedef struct pv_entry {
79 1.4.4.2 bouyer struct pv_entry *pv_next; /* next pv_entry */
80 1.4.4.2 bouyer pmap_t pv_pmap; /* pmap where mapping lies */
81 1.4.4.2 bouyer vaddr_t pv_va; /* virtual address for mapping */
82 1.4.4.2 bouyer int pv_flags; /* flags */
83 1.4.4.2 bouyer } *pv_entry_t;
84 1.4.4.2 bouyer
85 1.4.4.2 bouyer /*
86 1.4.4.2 bouyer * A pv_page_info struture looks like this. It is used to contain status
87 1.4.4.2 bouyer * information for pv_entry freelists.
88 1.4.4.2 bouyer */
89 1.4.4.2 bouyer struct pv_page;
90 1.4.4.2 bouyer
91 1.4.4.2 bouyer struct pv_page_info {
92 1.4.4.2 bouyer TAILQ_ENTRY(pv_page) pgi_list;
93 1.4.4.2 bouyer struct pv_entry *pgi_freelist;
94 1.4.4.2 bouyer int pgi_nfree;
95 1.4.4.2 bouyer };
96 1.4.4.2 bouyer
97 1.4.4.2 bouyer /*
98 1.4.4.2 bouyer * A pv_page itself looks like this. pv_entries are requested from the VM a
99 1.4.4.2 bouyer * pv_page at a time.
100 1.4.4.2 bouyer *
101 1.4.4.2 bouyer * We also define a macro that states the number of pv_entries per page
102 1.4.4.2 bouyer * allocated.
103 1.4.4.2 bouyer */
104 1.4.4.2 bouyer #define NPVPPG ((NBPG - sizeof(struct pv_page_info)) / sizeof(struct pv_entry))
105 1.4.4.2 bouyer
106 1.4.4.2 bouyer struct pv_page {
107 1.4.4.2 bouyer struct pv_page_info pvp_pgi;
108 1.4.4.2 bouyer struct pv_entry pvp_pv[NPVPPG];
109 1.4.4.2 bouyer };
110 1.4.4.2 bouyer
111 1.4.4.2 bouyer /*
112 1.4.4.2 bouyer * Page hooks. I'll eliminate these sometime soon :-)
113 1.4.4.2 bouyer *
114 1.4.4.2 bouyer * For speed we store the both the virtual address and the page table
115 1.4.4.2 bouyer * entry address for each page hook.
116 1.4.4.2 bouyer */
117 1.4.4.2 bouyer typedef struct {
118 1.4.4.2 bouyer vaddr_t va;
119 1.4.4.2 bouyer pt_entry_t *pte;
120 1.4.4.2 bouyer } pagehook_t;
121 1.4.4.2 bouyer
122 1.4.4.2 bouyer /*
123 1.4.4.2 bouyer * Physical / virtual address structure. In a number of places (particularly
124 1.4.4.2 bouyer * during bootstrapping) we need to keep track of the physical and virtual
125 1.4.4.2 bouyer * addresses of various pages
126 1.4.4.2 bouyer */
127 1.4.4.2 bouyer typedef struct {
128 1.4.4.2 bouyer paddr_t pv_pa;
129 1.4.4.2 bouyer vaddr_t pv_va;
130 1.4.4.2 bouyer } pv_addr_t;
131 1.4.4.2 bouyer
132 1.4.4.2 bouyer /*
133 1.4.4.2 bouyer * _KERNEL specific macros, functions and prototypes
134 1.4.4.2 bouyer */
135 1.4.4.2 bouyer
136 1.4.4.2 bouyer #ifdef _KERNEL
137 1.4.4.2 bouyer
138 1.4.4.2 bouyer /*
139 1.4.4.2 bouyer * Commonly referenced structures
140 1.4.4.2 bouyer */
141 1.4.4.2 bouyer extern pv_entry_t pv_table; /* Phys to virt mappings, per page. */
142 1.4.4.2 bouyer extern pmap_t kernel_pmap; /* pmap pointer used for the kernel */
143 1.4.4.2 bouyer extern struct pmap kernel_pmap_store; /* kernel_pmap points to this */
144 1.4.4.2 bouyer extern int pmap_debug_level; /* Only exists if PMAP_DEBUG */
145 1.4.4.2 bouyer
146 1.4.4.2 bouyer /*
147 1.4.4.2 bouyer * Macros that we need to export
148 1.4.4.2 bouyer */
149 1.4.4.2 bouyer #define pmap_kernel() (&kernel_pmap_store)
150 1.4.4.3 bouyer #define pmap_update() /* nothing (yet) */
151 1.4.4.2 bouyer #define pmap_resident_count(pmap) ((pmap)->pm_stats.resident_count)
152 1.4.4.2 bouyer #define pmap_wired_count(pmap) ((pmap)->pm_stats.wired_count)
153 1.4.4.2 bouyer
154 1.4.4.2 bouyer #define pmap_phys_address(ppn) (arm_page_to_byte((ppn)))
155 1.4.4.2 bouyer
156 1.4.4.2 bouyer /*
157 1.4.4.2 bouyer * Functions that we need to export
158 1.4.4.2 bouyer */
159 1.4.4.2 bouyer extern boolean_t pmap_testbit __P((paddr_t, int));
160 1.4.4.2 bouyer extern void pmap_changebit __P((paddr_t, int, int));
161 1.4.4.2 bouyer extern vaddr_t pmap_map __P((vaddr_t, vaddr_t, vaddr_t, int));
162 1.4.4.2 bouyer extern void pmap_procwr __P((struct proc *, vaddr_t, int));
163 1.4.4.2 bouyer #define PMAP_NEED_PROCWR
164 1.4.4.2 bouyer
165 1.4.4.2 bouyer /*
166 1.4.4.2 bouyer * Functions we use internally
167 1.4.4.2 bouyer */
168 1.4.4.2 bouyer extern void pmap_bootstrap __P((pd_entry_t *, pv_addr_t));
169 1.4.4.2 bouyer extern void pmap_debug __P((int));
170 1.4.4.2 bouyer extern int pmap_handled_emulation __P((pmap_t, vaddr_t));
171 1.4.4.2 bouyer extern int pmap_modified_emulation __P((pmap_t, vaddr_t));
172 1.4.4.2 bouyer extern void pmap_postinit __P((void));
173 1.4.4.2 bouyer extern pt_entry_t *pmap_pte __P((pmap_t, vaddr_t));
174 1.4.4.2 bouyer
175 1.4.4.2 bouyer #endif /* _KERNEL */
176 1.4.4.2 bouyer
177 1.4.4.2 bouyer /*
178 1.4.4.2 bouyer * Useful macros and constants
179 1.4.4.2 bouyer */
180 1.4.4.2 bouyer
181 1.4.4.2 bouyer /* Virtual address to page table entry */
182 1.4.4.2 bouyer #define vtopte(va) \
183 1.4.4.2 bouyer ((pt_entry_t *)(PROCESS_PAGE_TBLS_BASE + \
184 1.4.4.2 bouyer (arm_byte_to_page((unsigned int)(va)) << 2)))
185 1.4.4.2 bouyer
186 1.4.4.2 bouyer /* Virtual address to physical address */
187 1.4.4.2 bouyer #define vtophys(va) \
188 1.4.4.2 bouyer ((*vtopte(va) & PG_FRAME) | ((unsigned int)(va) & ~PG_FRAME))
189 1.4.4.2 bouyer
190 1.4.4.2 bouyer /* L1 and L2 page table macros */
191 1.4.4.2 bouyer #define pmap_pde(m, v) (&((m)->pm_pdir[((vaddr_t)(v) >> PDSHIFT)&4095]))
192 1.4.4.2 bouyer #define pmap_pte_pa(pte) (*(pte) & PG_FRAME)
193 1.4.4.2 bouyer #define pmap_pde_v(pde) (*(pde) != 0)
194 1.4.4.2 bouyer #define pmap_pte_v(pte) (*(pte) != 0)
195 1.4.4.2 bouyer
196 1.4.4.2 bouyer /* Size of the kernel part of the L1 page table */
197 1.4.4.2 bouyer #define KERNEL_PD_SIZE \
198 1.4.4.2 bouyer (PD_SIZE - (KERNEL_SPACE_START >> PDSHIFT) * sizeof(pd_entry_t))
199 1.4.4.2 bouyer
200 1.4.4.2 bouyer #endif /* _ARM32_PMAP_H_ */
201