Rev 1288 | Rev 1309 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1288 | Rev 1306 | ||
---|---|---|---|
Line 192... | Line 192... | ||
192 | * @param as Address space. |
192 | * @param as Address space. |
193 | * @param address Virtual address belonging to the area to be changed. Must be page-aligned. |
193 | * @param address Virtual address belonging to the area to be changed. Must be page-aligned. |
194 | * @param size New size of the virtual memory block starting at address. |
194 | * @param size New size of the virtual memory block starting at address. |
195 | * @param flags Flags influencing the remap operation. Currently unused. |
195 | * @param flags Flags influencing the remap operation. Currently unused. |
196 | * |
196 | * |
197 | * @return address on success, (__address) -1 otherwise. |
197 | * @return Zero on success or a value from @ref errno.h otherwise. |
198 | */ |
198 | */ |
199 | __address as_area_resize(as_t *as, __address address, size_t size, int flags) |
199 | int as_area_resize(as_t *as, __address address, size_t size, int flags) |
200 | { |
200 | { |
201 | as_area_t *area = NULL; |
201 | as_area_t *area; |
202 | ipl_t ipl; |
202 | ipl_t ipl; |
203 | size_t pages; |
203 | size_t pages; |
204 | 204 | ||
205 | ipl = interrupts_disable(); |
205 | ipl = interrupts_disable(); |
206 | spinlock_lock(&as->lock); |
206 | spinlock_lock(&as->lock); |
Line 210... | Line 210... | ||
210 | */ |
210 | */ |
211 | area = find_area_and_lock(as, address); |
211 | area = find_area_and_lock(as, address); |
212 | if (!area) { |
212 | if (!area) { |
213 | spinlock_unlock(&as->lock); |
213 | spinlock_unlock(&as->lock); |
214 | interrupts_restore(ipl); |
214 | interrupts_restore(ipl); |
215 | return (__address) -1; |
215 | return ENOENT; |
216 | } |
216 | } |
217 | 217 | ||
218 | if (area->flags & AS_AREA_DEVICE) { |
218 | if (area->flags & AS_AREA_DEVICE) { |
219 | /* |
219 | /* |
220 | * Remapping of address space areas associated |
220 | * Remapping of address space areas associated |
221 | * with memory mapped devices is not supported. |
221 | * with memory mapped devices is not supported. |
222 | */ |
222 | */ |
223 | spinlock_unlock(&area->lock); |
223 | spinlock_unlock(&area->lock); |
224 | spinlock_unlock(&as->lock); |
224 | spinlock_unlock(&as->lock); |
225 | interrupts_restore(ipl); |
225 | interrupts_restore(ipl); |
226 | return (__address) -1; |
226 | return ENOTSUP; |
227 | } |
227 | } |
228 | 228 | ||
229 | pages = SIZE2FRAMES((address - area->base) + size); |
229 | pages = SIZE2FRAMES((address - area->base) + size); |
230 | if (!pages) { |
230 | if (!pages) { |
231 | /* |
231 | /* |
232 | * Zero size address space areas are not allowed. |
232 | * Zero size address space areas are not allowed. |
233 | */ |
233 | */ |
234 | spinlock_unlock(&area->lock); |
234 | spinlock_unlock(&area->lock); |
235 | spinlock_unlock(&as->lock); |
235 | spinlock_unlock(&as->lock); |
236 | interrupts_restore(ipl); |
236 | interrupts_restore(ipl); |
237 | return (__address) -1; |
237 | return EPERM; |
238 | } |
238 | } |
239 | 239 | ||
240 | if (pages < area->pages) { |
240 | if (pages < area->pages) { |
241 | int i; |
241 | int i; |
242 | 242 | ||
Line 279... | Line 279... | ||
279 | */ |
279 | */ |
280 | if (!check_area_conflicts(as, address, pages * PAGE_SIZE, area)) { |
280 | if (!check_area_conflicts(as, address, pages * PAGE_SIZE, area)) { |
281 | spinlock_unlock(&area->lock); |
281 | spinlock_unlock(&area->lock); |
282 | spinlock_unlock(&as->lock); |
282 | spinlock_unlock(&as->lock); |
283 | interrupts_restore(ipl); |
283 | interrupts_restore(ipl); |
284 | return (__address) -1; |
284 | return EADDRNOTAVAIL; |
285 | } |
285 | } |
286 | } |
286 | } |
287 | 287 | ||
288 | area->pages = pages; |
288 | area->pages = pages; |
289 | 289 | ||
290 | spinlock_unlock(&area->lock); |
290 | spinlock_unlock(&area->lock); |
291 | spinlock_unlock(&as->lock); |
291 | spinlock_unlock(&as->lock); |
292 | interrupts_restore(ipl); |
292 | interrupts_restore(ipl); |
293 | 293 | ||
- | 294 | return 0; |
|
- | 295 | } |
|
- | 296 | ||
- | 297 | /** Destroy address space area. |
|
- | 298 | * |
|
- | 299 | * @param as Address space. |
|
- | 300 | * @param address Address withing the area to be deleted. |
|
- | 301 | * |
|
- | 302 | * @return Zero on success or a value from @ref errno.h on failure. |
|
- | 303 | */ |
|
- | 304 | int as_area_destroy(as_t *as, __address address) |
|
- | 305 | { |
|
- | 306 | as_area_t *area; |
|
- | 307 | __address base; |
|
- | 308 | ipl_t ipl; |
|
- | 309 | int i; |
|
- | 310 | ||
- | 311 | ipl = interrupts_disable(); |
|
- | 312 | spinlock_lock(&as->lock); |
|
- | 313 | ||
- | 314 | area = find_area_and_lock(as, address); |
|
- | 315 | if (!area) { |
|
- | 316 | spinlock_unlock(&as->lock); |
|
- | 317 | interrupts_restore(ipl); |
|
294 | return address; |
318 | return ENOENT; |
- | 319 | } |
|
- | 320 | ||
- | 321 | base = area->base; |
|
- | 322 | for (i = 0; i < area->pages; i++) { |
|
- | 323 | pte_t *pte; |
|
- | 324 | ||
- | 325 | /* |
|
- | 326 | * Releasing physical memory. |
|
- | 327 | * Areas mapping memory-mapped devices are treated differently than |
|
- | 328 | * areas backing frame_alloc()'ed memory. |
|
- | 329 | */ |
|
- | 330 | page_table_lock(as, false); |
|
- | 331 | pte = page_mapping_find(as, area->base + i*PAGE_SIZE); |
|
- | 332 | if (pte && PTE_VALID(pte)) { |
|
- | 333 | ASSERT(PTE_PRESENT(pte)); |
|
- | 334 | page_mapping_remove(as, area->base + i*PAGE_SIZE); |
|
- | 335 | if (area->flags & AS_AREA_DEVICE) { |
|
- | 336 | __address frame; |
|
- | 337 | frame = PTE_GET_FRAME(pte); |
|
- | 338 | frame_free(ADDR2PFN(frame)); |
|
- | 339 | } |
|
- | 340 | page_table_unlock(as, false); |
|
- | 341 | } else { |
|
- | 342 | page_table_unlock(as, false); |
|
- | 343 | } |
|
- | 344 | } |
|
- | 345 | /* |
|
- | 346 | * Invalidate TLB's. |
|
- | 347 | */ |
|
- | 348 | tlb_shootdown_start(TLB_INVL_PAGES, AS->asid, area->base, area->pages); |
|
- | 349 | tlb_invalidate_pages(AS->asid, area->base, area->pages); |
|
- | 350 | tlb_shootdown_finalize(); |
|
- | 351 | ||
- | 352 | spinlock_unlock(&area->lock); |
|
- | 353 | ||
- | 354 | /* |
|
- | 355 | * Remove the empty area from address space. |
|
- | 356 | */ |
|
- | 357 | btree_remove(&AS->as_area_btree, base, NULL); |
|
- | 358 | ||
- | 359 | spinlock_unlock(&AS->lock); |
|
- | 360 | interrupts_restore(ipl); |
|
- | 361 | return 0; |
|
295 | } |
362 | } |
296 | 363 | ||
297 | /** Send address space area to another task. |
364 | /** Send address space area to another task. |
298 | * |
365 | * |
299 | * Address space area is sent to the specified task. |
366 | * Address space area is sent to the specified task. |
Line 305... | Line 372... | ||
305 | * space area and any associated mapping is preserved. |
372 | * space area and any associated mapping is preserved. |
306 | * |
373 | * |
307 | * @param dst_id Task ID of the accepting task. |
374 | * @param dst_id Task ID of the accepting task. |
308 | * @param src_base Base address of the source address space area. |
375 | * @param src_base Base address of the source address space area. |
309 | * |
376 | * |
310 | * @return 0 on success or ENOENT if there is no such task or |
377 | * @return Zero on success or ENOENT if there is no such task or |
311 | * if there is no such address space area, |
378 | * if there is no such address space area, |
312 | * EPERM if there was a problem in accepting the area or |
379 | * EPERM if there was a problem in accepting the area or |
313 | * ENOMEM if there was a problem in allocating destination |
380 | * ENOMEM if there was a problem in allocating destination |
314 | * address space area. |
381 | * address space area. |
315 | */ |
382 | */ |
Line 889... | Line 956... | ||
889 | } |
956 | } |
890 | 957 | ||
891 | /** Wrapper for as_area_resize. */ |
958 | /** Wrapper for as_area_resize. */ |
892 | __native sys_as_area_resize(__address address, size_t size, int flags) |
959 | __native sys_as_area_resize(__address address, size_t size, int flags) |
893 | { |
960 | { |
894 | return as_area_resize(AS, address, size, 0); |
961 | return (__native) as_area_resize(AS, address, size, 0); |
- | 962 | } |
|
- | 963 | ||
- | 964 | /** Wrapper for as_area_destroy. */ |
|
- | 965 | __native sys_as_area_destroy(__address address) |
|
- | 966 | { |
|
- | 967 | return (__native) as_area_destroy(AS, address); |
|
895 | } |
968 | } |
896 | 969 | ||
897 | /** Prepare task for accepting address space area from another task. |
970 | /** Prepare task for accepting address space area from another task. |
898 | * |
971 | * |
899 | * @param uspace_accept_arg Accept structure passed from userspace. |
972 | * @param uspace_accept_arg Accept structure passed from userspace. |