| 574 | } |
| 575 | |
| 576 | int _mm_aspace_map(rt_aspace_t aspace, rt_varea_t *pvarea, void **addr, |
| 577 | rt_size_t length, rt_size_t attr, mm_flag_t flags, |
| 578 | rt_mem_obj_t mem_obj, rt_size_t offset) |
| 579 | { |
| 580 | int err = RT_EOK; |
| 581 | rt_varea_t varea; |
| 582 | struct _mapping_property prop = INIT_PROP(mem_obj, offset, flags, attr); |
| 583 | |
| 584 | WR_LOCK(aspace); |
| 585 | |
| 586 | /** |
| 587 | * @brief .prefer & .map_size are scratched from varea which setup by caller |
| 588 | * .limit_start & .limit_range_size have default to be in range of aspace |
| 589 | * .flags is from parameter, and will be fill in varea if install successfully |
| 590 | */ |
| 591 | struct rt_mm_va_hint hint = {.prefer = *addr, |
| 592 | .map_size = length, |
| 593 | .limit_start = aspace->start, |
| 594 | .limit_range_size = aspace->size, |
| 595 | .flags = flags}; |
| 596 | |
| 597 | if (mem_obj->hint_free) |
| 598 | { |
| 599 | /* mem object can control mapping range and so by modifing hint */ |
| 600 | mem_obj->hint_free(&hint); |
| 601 | } |
| 602 | |
| 603 | /* try to allocate a virtual address region for varea */ |
| 604 | err = _varea_install(aspace, pvarea, &hint, &prop, addr); |
| 605 | |
| 606 | if (err == RT_EOK) |
| 607 | { |
| 608 | varea = *pvarea; |
| 609 | if (MMF_TEST_CNTL(flags, MMF_PREFETCH)) |
| 610 | { |
| 611 | /* do the MMU & TLB business */ |
| 612 | err = _do_prefetch(aspace, varea, varea->start, varea->size); |
| 613 | if (err) |
| 614 | { |
| 615 | LOG_I("%s: failed to prefetch page into varea(%s)", |
| 616 | __func__, VAREA_NAME(varea)); |
| 617 | |
| 618 | /* restore data structure and MMU */ |
| 619 | _varea_uninstall_locked(varea); |
| 620 | if (!(varea->flag & MMF_STATIC_ALLOC)) |
| 621 | rt_free(varea); |
| 622 | } |
| 623 | } |
| 624 | } |
| 625 | |
| 626 | WR_UNLOCK(aspace); |
| 627 | |
| 628 | return err; |
| 629 | } |
| 630 | |
| 631 | static rt_varea_t _varea_create(void *start, rt_size_t size) |
| 632 | { |
no test coverage detected