2 * Copyright (c) 2001-2004 Jakub Jermar
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 /** @addtogroup genericmm
38 /** Address space area flags. */
39 #define AS_AREA_READ 1
40 #define AS_AREA_WRITE 2
41 #define AS_AREA_EXEC 4
42 #define AS_AREA_CACHEABLE 8
46 #include <arch/mm/page.h>
47 #include <arch/mm/as.h>
48 #include <arch/mm/asid.h>
49 #include <arch/types.h>
50 #include <synch/spinlock.h>
51 #include <synch/mutex.h>
53 #include <adt/btree.h>
57 * Defined to be true if user address space and kernel address space shadow each
60 #define KERNEL_ADDRESS_SPACE_SHADOWED KERNEL_ADDRESS_SPACE_SHADOWED_ARCH
62 #define KERNEL_ADDRESS_SPACE_START KERNEL_ADDRESS_SPACE_START_ARCH
63 #define KERNEL_ADDRESS_SPACE_END KERNEL_ADDRESS_SPACE_END_ARCH
64 #define USER_ADDRESS_SPACE_START USER_ADDRESS_SPACE_START_ARCH
65 #define USER_ADDRESS_SPACE_END USER_ADDRESS_SPACE_END_ARCH
67 #define USTACK_ADDRESS USTACK_ADDRESS_ARCH
69 /** Kernel address space. */
70 #define FLAG_AS_KERNEL (1 << 0)
72 /* Address space area attributes. */
73 #define AS_AREA_ATTR_NONE 0
74 #define AS_AREA_ATTR_PARTIAL 1 /**< Not fully initialized area. */
76 /** The page fault was not resolved by as_page_fault(). */
78 /** The page fault was resolved by as_page_fault(). */
80 /** The page fault was caused by memcpy_from_uspace() or memcpy_to_uspace(). */
83 /** Address space structure.
85 * as_t contains the list of as_areas of userspace accessible
86 * pages for one or more tasks. Ranges of kernel memory pages are not
87 * supposed to figure in the list as they are shared by all tasks and
88 * set up during system initialization.
91 /** Protected by asidlock. */
92 link_t inactive_as_with_asid_link
;
96 /** Number of references (i.e tasks that reference this as). */
99 /** Number of processors on wich is this address space active. */
100 count_t cpu_refcount
;
102 /** B+tree of address space areas. */
103 btree_t as_area_btree
;
106 * Address space identifier.
107 * Constant on architectures that do not support ASIDs.
111 /** Non-generic content. */
112 as_genarch_t genarch
;
114 /** Architecture specific content. */
119 pte_t
*(* page_table_create
)(int flags
);
120 void (* page_table_destroy
)(pte_t
*page_table
);
121 void (* page_table_lock
)(as_t
*as
, bool lock
);
122 void (* page_table_unlock
)(as_t
*as
, bool unlock
);
126 * This structure contains information associated with the shared address space
130 /** This lock must be acquired only when the as_area lock is held. */
132 /** This structure can be deallocated if refcount drops to 0. */
135 * B+tree containing complete map of anonymous pages of the shared area.
140 /** Page fault access type. */
149 /** Backend data stored in address space area. */
150 typedef union mem_backend_data
{
151 struct { /**< elf_backend members */
153 elf_segment_header_t
*segment
;
155 struct { /**< phys_backend members */
159 } mem_backend_data_t
;
161 /** Address space area structure.
163 * Each as_area_t structure describes one contiguous area of virtual memory.
164 * In the future, it should not be difficult to support shared areas.
168 /** Containing address space. */
170 /** Flags related to the memory represented by the address space area. */
172 /** Attributes related to the address space area itself. */
174 /** Size of this area in multiples of PAGE_SIZE. */
176 /** Base address of this area. */
178 /** Map of used space. */
182 * If the address space area has been shared, this pointer will reference
183 * the share info structure.
185 share_info_t
*sh_info
;
187 /** Memory backend backing this address space area. */
188 struct mem_backend
*backend
;
190 /** Data to be used by the backend. */
191 mem_backend_data_t backend_data
;
194 /** Address space area backend structure. */
195 typedef struct mem_backend
{
196 int (* page_fault
)(as_area_t
*area
, uintptr_t addr
, pf_access_t access
);
197 void (* frame_free
)(as_area_t
*area
, uintptr_t page
, uintptr_t frame
);
198 void (* share
)(as_area_t
*area
);
201 extern as_t
*AS_KERNEL
;
202 extern as_operations_t
*as_operations
;
204 SPINLOCK_EXTERN(inactive_as_with_asid_lock
);
205 extern link_t inactive_as_with_asid_head
;
207 extern void as_init(void);
209 extern as_t
*as_create(int flags
);
210 extern void as_destroy(as_t
*as
);
211 extern void as_switch(as_t
*old_as
, as_t
*new_as
);
212 extern int as_page_fault(uintptr_t page
, pf_access_t access
, istate_t
*istate
);
214 extern as_area_t
*as_area_create(as_t
*as
, int flags
, size_t size
,
215 uintptr_t base
, int attrs
, mem_backend_t
*backend
,
216 mem_backend_data_t
*backend_data
);
217 extern int as_area_destroy(as_t
*as
, uintptr_t address
);
218 extern int as_area_resize(as_t
*as
, uintptr_t address
, size_t size
, int flags
);
219 int as_area_share(as_t
*src_as
, uintptr_t src_base
, size_t acc_size
,
220 as_t
*dst_as
, uintptr_t dst_base
, int dst_flags_mask
);
222 extern int as_area_get_flags(as_area_t
*area
);
223 extern bool as_area_check_access(as_area_t
*area
, pf_access_t access
);
224 extern size_t as_get_size(uintptr_t base
);
225 extern int used_space_insert(as_area_t
*a
, uintptr_t page
, count_t count
);
226 extern int used_space_remove(as_area_t
*a
, uintptr_t page
, count_t count
);
229 /* Interface to be implemented by architectures. */
230 #ifndef as_constructor_arch
231 extern int as_constructor_arch(as_t
*as
, int flags
);
232 #endif /* !def as_constructor_arch */
233 #ifndef as_destructor_arch
234 extern int as_destructor_arch(as_t
*as
);
235 #endif /* !def as_destructor_arch */
236 #ifndef as_create_arch
237 extern int as_create_arch(as_t
*as
, int flags
);
238 #endif /* !def as_create_arch */
239 #ifndef as_install_arch
240 extern void as_install_arch(as_t
*as
);
241 #endif /* !def as_install_arch */
242 #ifndef as_deinstall_arch
243 extern void as_deinstall_arch(as_t
*as
);
244 #endif /* !def as_deinstall_arch */
246 /* Backend declarations and functions. */
247 extern mem_backend_t anon_backend
;
248 extern mem_backend_t elf_backend
;
249 extern mem_backend_t phys_backend
;
251 extern int elf_load(elf_header_t
*header
, as_t
*as
);
253 /* Address space area related syscalls. */
254 extern unative_t
sys_as_area_create(uintptr_t address
, size_t size
, int flags
);
255 extern unative_t
sys_as_area_resize(uintptr_t address
, size_t size
, int flags
);
256 extern unative_t
sys_as_area_destroy(uintptr_t address
);
258 /* Introspection functions. */
259 extern void as_print(as_t
*as
);