Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/ddi/ddi.c

    rc6ae4c2 rc0699467  
    4545#include <mm/frame.h>
    4646#include <mm/as.h>
    47 #include <mm/page.h>
    4847#include <synch/mutex.h>
    4948#include <syscall/copy.h>
     
    5352#include <errno.h>
    5453#include <trace.h>
    55 #include <bitops.h>
    5654
    5755/** This lock protects the parea_btree. */
     
    8987/** Map piece of physical memory into virtual address space of current task.
    9088 *
    91  * @param phys  Physical address of the starting frame.
    92  * @param virt  Virtual address of the starting page.
     89 * @param p  Physical address of the starting frame.
     90 * @param v  Virtual address of the starting page.
    9391 * @param pages Number of pages to map.
    9492 * @param flags Address space area flags for the mapping.
    9593 *
    96  * @return EOK on success.
    97  * @return EPERM if the caller lacks capabilities to use this syscall.
    98  * @return EBADMEM if phys or virt is not page aligned.
    99  * @return ENOENT if there is no task matching the specified ID or
    100  *         the physical address space is not enabled for mapping.
    101  * @return ENOMEM if there was a problem in creating address space area.
    102  *
    103  */
    104 NO_TRACE static int ddi_physmem_map(uintptr_t phys, uintptr_t virt, size_t pages,
     94 * @return 0 on success, EPERM if the caller lacks capabilities to use this
     95 *         syscall, EBADMEM if pf or vf is not page aligned, ENOENT if there
     96 *         is no task matching the specified ID or the physical address space
     97 *         is not enabled for mapping and ENOMEM if there was a problem in
     98 *         creating address space area.
     99 *
     100 */
     101NO_TRACE static int ddi_physmem_map(uintptr_t pf, uintptr_t vp, size_t pages,
    105102    unsigned int flags)
    106103{
    107104        ASSERT(TASK);
    108105       
    109         if ((phys % FRAME_SIZE) != 0)
     106        if ((pf % FRAME_SIZE) != 0)
    110107                return EBADMEM;
    111108       
    112         if ((virt % PAGE_SIZE) != 0)
     109        if ((vp % PAGE_SIZE) != 0)
    113110                return EBADMEM;
    114111       
     
    121118       
    122119        mem_backend_data_t backend_data;
    123         backend_data.base = phys;
     120        backend_data.base = pf;
    124121        backend_data.frames = pages;
    125122       
     
    132129        btree_node_t *nodep;
    133130        parea_t *parea = (parea_t *) btree_search(&parea_btree,
    134             (btree_key_t) phys, &nodep);
     131            (btree_key_t) pf, &nodep);
    135132       
    136133        if ((parea != NULL) && (parea->frames >= pages)) {
     
    152149       
    153150        irq_spinlock_lock(&zones.lock, true);
    154         size_t znum = find_zone(ADDR2PFN(phys), pages, 0);
     151        size_t znum = find_zone(ADDR2PFN(pf), pages, 0);
    155152       
    156153        if (znum == (size_t) -1) {
     
    185182       
    186183map:
    187         if (!as_area_create(TASK->as, flags, FRAMES2SIZE(pages), virt,
     184        if (!as_area_create(TASK->as, flags, pages * PAGE_SIZE, vp,
    188185            AS_AREA_ATTR_NONE, &phys_backend, &backend_data)) {
    189186                /*
     
    256253/** Wrapper for SYS_PHYSMEM_MAP syscall.
    257254 *
    258  * @param phys  Physical base address to map
    259  * @param virt  Destination virtual address
     255 * @param phys_base Physical base address to map
     256 * @param virt_base Destination virtual address
    260257 * @param pages Number of pages
    261258 * @param flags Flags of newly mapped pages
     
    264261 *
    265262 */
    266 sysarg_t sys_physmem_map(uintptr_t phys, uintptr_t virt,
    267     size_t pages, unsigned int flags)
    268 {
    269         return (sysarg_t)
    270             ddi_physmem_map(ALIGN_DOWN(phys, FRAME_SIZE),
    271             ALIGN_DOWN(virt, PAGE_SIZE), pages, flags);
     263sysarg_t sys_physmem_map(sysarg_t phys_base, sysarg_t virt_base,
     264    sysarg_t pages, sysarg_t flags)
     265{
     266        return (sysarg_t) ddi_physmem_map(ALIGN_DOWN((uintptr_t) phys_base,
     267            FRAME_SIZE), ALIGN_DOWN((uintptr_t) virt_base, PAGE_SIZE),
     268            (size_t) pages, (int) flags);
    272269}
    273270
     
    290287}
    291288
    292 NO_TRACE static int dmamem_map(uintptr_t virt, size_t size,
    293     unsigned int map_flags, unsigned int flags, void **phys)
    294 {
    295         ASSERT(TASK);
    296        
    297         if ((flags & DMAMEM_FLAGS_ANONYMOUS) == 0) {
    298                 // TODO: implement locking of non-anonymous mapping
    299                 return page_find_mapping(virt, phys);
    300         } else {
    301                 // TODO: implement locking
    302                
    303                 if ((virt % PAGE_SIZE) != 0)
    304                         return EBADMEM;
    305                
    306                 size_t pages = SIZE2FRAMES(size);
    307                 uint8_t order;
    308                
    309                 /* We need the 2^order >= pages */
    310                 if (pages == 1)
    311                         order = 0;
    312                 else
    313                         order = fnzb(pages - 1) + 1;
    314                
    315                 *phys = frame_alloc_noreserve(order, 0);
    316                 if (*phys == NULL)
    317                         return ENOMEM;
    318                
    319                 mem_backend_data_t backend_data;
    320                 backend_data.base = (uintptr_t) *phys;
    321                 backend_data.frames = pages;
    322                
    323                 if (!as_area_create(TASK->as, map_flags, size, virt,
    324                     AS_AREA_ATTR_NONE, &phys_backend, &backend_data)) {
    325                         frame_free_noreserve((uintptr_t) *phys);
    326                         return ENOMEM;
    327                 }
    328                
    329                 return EOK;
    330         }
    331 }
    332 
    333 NO_TRACE static int dmamem_unmap(uintptr_t virt, size_t size,
    334     unsigned int flags)
    335 {
    336         // TODO: implement unlocking & unmap
    337         return EOK;
    338 }
    339 
    340 sysarg_t sys_dmamem_map(uintptr_t virt, size_t size, unsigned int map_flags,
    341     unsigned int flags, void *phys_ptr)
    342 {
    343         void *phys;
    344         int rc = dmamem_map(virt, size, map_flags, flags, &phys);
    345         if (rc != EOK)
    346                 return rc;
    347        
    348         rc = copy_to_uspace(phys_ptr, &phys, sizeof(phys));
    349         if (rc != EOK) {
    350                 dmamem_unmap(virt, size, flags);
    351                 return rc;
    352         }
    353        
    354         return EOK;
    355 }
    356 
    357 sysarg_t sys_dmamem_unmap(uintptr_t virt, size_t size, unsigned int flags)
    358 {
    359         return dmamem_unmap(virt, size, flags);
    360 }
    361 
    362289/** @}
    363290 */
Note: See TracChangeset for help on using the changeset viewer.