Subversion Repositories HelenOS-historic

Rev

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.