Ignore:
File:
1 edited

Legend:

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

    r9d58539 r8cd680c  
    121121        backend_data.base = phys;
    122122        backend_data.frames = pages;
     123        backend_data.anonymous = false;
    123124       
    124125        /*
     
    210211NO_TRACE static int physmem_unmap(uintptr_t virt)
    211212{
    212         // TODO: implement unmap
    213         return EOK;
     213        ASSERT(TASK);
     214
     215        return as_area_destroy(TASK->as, virt);
    214216}
    215217
     
    228230    void *virt_ptr, uintptr_t bound)
    229231{
    230         uintptr_t virt = (uintptr_t) -1;
    231         int rc = physmem_map(ALIGN_DOWN(phys, FRAME_SIZE), pages, flags,
    232             &virt, bound);
     232        uintptr_t virt;
     233        int rc = copy_from_uspace(&virt, virt_ptr, sizeof(virt));
     234        if (rc != EOK)
     235                return rc;
     236       
     237        rc = physmem_map(ALIGN_DOWN(phys, FRAME_SIZE), pages, flags, &virt,
     238            bound);
    233239        if (rc != EOK)
    234240                return rc;
     
    250256/** Enable range of I/O space for task.
    251257 *
    252  * @param id Task ID of the destination task.
     258 * @param id     Task ID of the destination task.
    253259 * @param ioaddr Starting I/O address.
    254  * @param size Size of the enabled I/O space..
     260 * @param size   Size of the enabled I/O space.
    255261 *
    256262 * @return 0 on success, EPERM if the caller lacks capabilities to use this
     
    285291        int rc = ddi_iospace_enable_arch(task, ioaddr, size);
    286292        irq_spinlock_unlock(&task->lock, true);
     293
     294        return rc;
     295}
     296
     297/** Disable range of I/O space for task.
     298 *
     299 * @param id     Task ID of the destination task.
     300 * @param ioaddr Starting I/O address.
     301 * @param size   Size of the enabled I/O space.
     302 *
     303 * @return 0 on success, EPERM if the caller lacks capabilities to use this
     304 *           syscall, ENOENT if there is no task matching the specified ID.
     305 *
     306 */
     307NO_TRACE static int iospace_disable(task_id_t id, uintptr_t ioaddr, size_t size)
     308{
     309        /*
     310         * Make sure the caller is authorised to make this syscall.
     311         */
     312        cap_t caps = cap_get(TASK);
     313        if (!(caps & CAP_IO_MANAGER))
     314                return EPERM;
     315       
     316        irq_spinlock_lock(&tasks_lock, true);
     317       
     318        task_t *task = task_find_by_id(id);
     319       
     320        if ((!task) || (!container_check(CONTAINER, task->container))) {
     321                /*
     322                 * There is no task with the specified ID
     323                 * or the task belongs to a different security
     324                 * context.
     325                 */
     326                irq_spinlock_unlock(&tasks_lock, true);
     327                return ENOENT;
     328        }
     329       
     330        /* Lock the task and release the lock protecting tasks_btree. */
     331        irq_spinlock_exchange(&tasks_lock, &task->lock);
     332        int rc = ddi_iospace_disable_arch(task, ioaddr, size);
     333        irq_spinlock_unlock(&task->lock, true);
    287334       
    288335        return rc;
     
    309356sysarg_t sys_iospace_disable(ddi_ioarg_t *uspace_io_arg)
    310357{
    311         // TODO: implement
    312         return ENOTSUP;
     358        ddi_ioarg_t arg;
     359        int rc = copy_from_uspace(&arg, uspace_io_arg, sizeof(ddi_ioarg_t));
     360        if (rc != 0)
     361                return (sysarg_t) rc;
     362
     363        return (sysarg_t) iospace_disable((task_id_t) arg.task_id,
     364            (uintptr_t) arg.ioaddr, (size_t) arg.size);
    313365}
    314366
    315367NO_TRACE static int dmamem_map(uintptr_t virt, size_t size, unsigned int map_flags,
    316     unsigned int flags, void **phys)
     368    unsigned int flags, uintptr_t *phys)
    317369{
    318370        ASSERT(TASK);
     
    322374}
    323375
    324 NO_TRACE static int dmamem_map_anonymous(size_t size, unsigned int map_flags,
    325     unsigned int flags, void **phys, uintptr_t *virt, uintptr_t bound)
     376NO_TRACE static int dmamem_map_anonymous(size_t size, uintptr_t constraint,
     377    unsigned int map_flags, unsigned int flags, uintptr_t *phys,
     378    uintptr_t *virt, uintptr_t bound)
    326379{
    327380        ASSERT(TASK);
    328381       
    329         size_t pages = SIZE2FRAMES(size);
    330         uint8_t order;
    331        
    332         /* We need the 2^order >= pages */
    333         if (pages == 1)
    334                 order = 0;
    335         else
    336                 order = fnzb(pages - 1) + 1;
    337        
    338         *phys = frame_alloc_noreserve(order, 0);
    339         if (*phys == NULL)
     382        size_t frames = SIZE2FRAMES(size);
     383        *phys = frame_alloc(frames, FRAME_ATOMIC, constraint);
     384        if (*phys == 0)
    340385                return ENOMEM;
    341386       
    342387        mem_backend_data_t backend_data;
    343         backend_data.base = (uintptr_t) *phys;
    344         backend_data.frames = pages;
     388        backend_data.base = *phys;
     389        backend_data.frames = frames;
     390        backend_data.anonymous = true;
    345391       
    346392        if (!as_area_create(TASK->as, map_flags, size,
    347393            AS_AREA_ATTR_NONE, &phys_backend, &backend_data, virt, bound)) {
    348                 frame_free_noreserve((uintptr_t) *phys);
     394                frame_free(*phys, frames);
    349395                return ENOMEM;
    350396        }
     
    361407NO_TRACE static int dmamem_unmap_anonymous(uintptr_t virt)
    362408{
    363         // TODO: implement unlocking & unmap
    364         return EOK;
     409        return as_area_destroy(TASK->as, virt);
    365410}
    366411
     
    373418                 */
    374419               
    375                 void *phys;
     420                uintptr_t phys;
    376421                int rc = dmamem_map((uintptr_t) virt_ptr, size, map_flags,
    377422                    flags, &phys);
     
    390435                 */
    391436               
    392                 void *phys;
    393                 uintptr_t virt = (uintptr_t) -1;
    394                 int rc = dmamem_map_anonymous(size, map_flags, flags,
     437                uintptr_t constraint;
     438                int rc = copy_from_uspace(&constraint, phys_ptr,
     439                    sizeof(constraint));
     440                if (rc != EOK)
     441                        return rc;
     442               
     443                uintptr_t virt;
     444                rc = copy_from_uspace(&virt, virt_ptr, sizeof(virt));
     445                if (rc != EOK)
     446                        return rc;
     447               
     448                uintptr_t phys;
     449                rc = dmamem_map_anonymous(size, constraint, map_flags, flags,
    395450                    &phys, &virt, bound);
    396451                if (rc != EOK)
Note: See TracChangeset for help on using the changeset viewer.