Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 8cd680c in mainline


Ignore:
Timestamp:
2014-08-18T20:34:28Z (6 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
master
Children:
6eeb4a3
Parents:
8820544
Message:

Add pio_disable().

  • Implement *iospace_disable*().
  • Implement physmem_unmap().
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/abs32le/src/ddi/ddi.c

    r8820544 r8cd680c  
    4646}
    4747
     48/** Disable I/O space range for task.
     49 *
     50 */
     51int ddi_iospace_disable_arch(task_t *task, uintptr_t ioaddr, size_t size)
     52{
     53        return 0;
     54}
     55
    4856/** @}
    4957 */
  • kernel/arch/amd64/src/ddi/ddi.c

    r8820544 r8cd680c  
    5151 *
    5252 * @param task   Task.
    53  * @param ioaddr Startign I/O space address.
     53 * @param ioaddr Starting I/O space address.
    5454 * @param size   Size of the enabled I/O range.
    5555 *
    56  * @return 0 on success or an error code from errno.h.
     56 * @return EOK on success or an error code from errno.h.
    5757 *
    5858 */
     
    106106        task->arch.iomapver++;
    107107       
     108        return EOK;
     109}
     110
     111/** Disable I/O space range for task.
     112 *
     113 * Interrupts are disabled and task is locked.
     114 *
     115 * @param task   Task.
     116 * @param ioaddr Starting I/O space address.
     117 * @param size   Size of the enabled I/O range.
     118 *
     119 * @return EOK on success or an error code from errno.h.
     120 *
     121 */
     122int ddi_iospace_disable_arch(task_t *task, uintptr_t ioaddr, size_t size)
     123{
     124        size_t elements = ioaddr + size;
     125        if (elements > IO_PORTS)
     126                return ENOENT;
     127       
     128        if (ioaddr >= task->arch.iomap.elements)
     129                return EINVAL; 
     130
     131        if (task->arch.iomap.elements < elements)
     132                size -= elements - task->arch.iomap.elements;
     133
     134        /*
     135         * Disable the range.
     136         */
     137        bitmap_set_range(&task->arch.iomap, (size_t) ioaddr, size);
     138       
     139        /*
     140         * Increment I/O Permission bitmap generation counter.
     141         */
     142        task->arch.iomapver++;
     143       
    108144        return 0;
    109145}
  • kernel/arch/arm32/src/ddi/ddi.c

    r8820544 r8cd680c  
    5353}
    5454
     55/** Disable I/O space range for task.
     56 *
     57 * Interrupts are disabled and task is locked.
     58 *
     59 * @param task Task.
     60 * @param ioaddr Startign I/O space address.
     61 * @param size Size of the disabled I/O range.
     62 *
     63 * @return 0 on success or an error code from errno.h.
     64 */
     65int ddi_iospace_disable_arch(task_t *task, uintptr_t ioaddr, size_t size)
     66{
     67        return 0;
     68}
     69
    5570/** @}
    5671 */
  • kernel/arch/ia32/src/ddi/ddi.c

    r8820544 r8cd680c  
    5151 *
    5252 * @param task   Task.
    53  * @param ioaddr Startign I/O space address.
     53 * @param ioaddr Starting I/O space address.
    5454 * @param size   Size of the enabled I/O range.
    5555 *
     
    109109}
    110110
     111/** Disable I/O space range for task.
     112 *
     113 * Interrupts are disabled and task is locked.
     114 *
     115 * @param task   Task.
     116 * @param ioaddr Starting I/O space address.
     117 * @param size   Size of the enabled I/O range.
     118 *
     119 * @return EOK on success or an error code from errno.h.
     120 *
     121 */
     122int ddi_iospace_disable_arch(task_t *task, uintptr_t ioaddr, size_t size)
     123{
     124        size_t elements = ioaddr + size;
     125        if (elements > IO_PORTS)
     126                return ENOENT;
     127       
     128        if (ioaddr >= task->arch.iomap.elements)
     129                return EINVAL; 
     130
     131        if (task->arch.iomap.elements < elements)
     132                size -= elements - task->arch.iomap.elements;
     133
     134        /*
     135         * Disable the range.
     136         */
     137        bitmap_set_range(&task->arch.iomap, (size_t) ioaddr, size);
     138       
     139        /*
     140         * Increment I/O Permission bitmap generation counter.
     141         */
     142        task->arch.iomapver++;
     143       
     144        return 0;
     145}
     146
     147
    111148/** Install I/O Permission bitmap.
    112149 *
  • kernel/arch/ia64/src/ddi/ddi.c

    r8820544 r8cd680c  
    4747 * Interrupts are disabled and task is locked.
    4848 *
    49  * @param task          Task.
    50  * @param ioaddr        Starting I/O space address.
    51  * @param size          Size of the enabled I/O range.
     49 * @param task   Task.
     50 * @param ioaddr Starting I/O space address.
     51 * @param size   Size of the enabled I/O range.
    5252 *
    53  * @return 0 on success or an error code from errno.h.
     53 * @return EOK on success or an error code from errno.h.
    5454 */
    5555int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
     
    7272        bitmap_set_range(task->arch.iomap, iopage, size / 4);
    7373       
    74         return 0;
     74        return EOK;
     75}
     76
     77/** Disable I/O space range for task.
     78 *
     79 * Interrupts are disabled and task is locked.
     80 *
     81 * @param task   Task.
     82 * @param ioaddr Starting I/O space address.
     83 * @param size   Size of the disabled I/O range.
     84 *
     85 * @return EOK on success or an error code from errno.h.
     86 */
     87int ddi_iospace_disable_arch(task_t *task, uintptr_t ioaddr, size_t size)
     88{
     89        if (!task->arch.iomap)
     90                return EINVAL;
     91
     92        uintptr_t iopage = ioaddr / PORTS_PER_PAGE;
     93        size = ALIGN_UP(size + ioaddr - 4 * iopage, PORTS_PER_PAGE);
     94        bitmap_clear_range(task->arch.iomap, iopage, size / 4);
     95       
     96        return EOK;
    7597}
    7698
  • kernel/arch/mips32/src/ddi/ddi.c

    r8820544 r8cd680c  
    4444 * Interrupts are disabled and task is locked.
    4545 *
    46  * @param task Task.
    47  * @param ioaddr Startign I/O space address.
    48  * @param size Size of the enabled I/O range.
     46 * @param task   Task.
     47 * @param ioaddr Startinig I/O space address.
     48 * @param size   Size of the enabled I/O range.
    4949 *
    5050 * @return 0 on success or an error code from errno.h.
     
    5555}
    5656
     57/** Disable I/O space range for task.
     58 *
     59 * Interrupts are disabled and task is locked.
     60 *
     61 * @param task   Task.
     62 * @param ioaddr Starting I/O space address.
     63 * @param size   Size of the disabled I/O range.
     64 *
     65 * @return 0 on success or an error code from errno.h.
     66 */
     67int ddi_iospace_disable_arch(task_t *task, uintptr_t ioaddr, size_t size)
     68{
     69        return 0;
     70}
     71
    5772/** @}
    5873 */
  • kernel/arch/ppc32/src/ddi/ddi.c

    r8820544 r8cd680c  
    4141 * Interrupts are disabled and task is locked.
    4242 *
    43  * @param task Task.
    44  * @param ioaddr Startign I/O space address.
    45  * @param size Size of the enabled I/O range.
     43 * @param task   Task.
     44 * @param ioaddr Starting I/O space address.
     45 * @param size   Size of the enabled I/O range.
    4646 *
    4747 * @return 0 on success or an error code from errno.h.
     
    5353}
    5454
     55/** Disable I/O space range for task.
     56 *
     57 * Interrupts are disabled and task is locked.
     58 *
     59 * @param task   Task.
     60 * @param ioaddr Starting I/O space address.
     61 * @param size   Size of the disabled I/O range.
     62 *
     63 * @return 0 on success or an error code from errno.h.
     64 *
     65 */
     66int ddi_iospace_disable_arch(task_t *task, uintptr_t ioaddr, size_t size)
     67{
     68        return 0;
     69}
     70
    5571/** @}
    5672 */
  • kernel/arch/sparc32/src/ddi/ddi.c

    r8820544 r8cd680c  
    4646}
    4747
     48/** Disable I/O space range for task.
     49 *
     50 */
     51int ddi_iospace_disable_arch(task_t *task, uintptr_t ioaddr, size_t size)
     52{
     53        return 0;
     54}
     55
    4856/** @}
    4957 */
  • kernel/arch/sparc64/src/ddi/ddi.c

    r8820544 r8cd680c  
    4141 * Interrupts are disabled and task is locked.
    4242 *
    43  * @param task Task.
     43 * @param task   Task.
    4444 * @param ioaddr Starting I/O space address.
    45  * @param size Size of the enabled I/O range.
     45 * @param size   Size of the enabled I/O range.
    4646 *
    47  * @return 0 on success or an error code from errno.h.
     47 * @return EOK on success or an error code from errno.h.
    4848 */
    4949int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size)
     
    5252}
    5353
     54/** Disable I/O space range for task.
     55 *
     56 * Interrupts are disabled and task is locked.
     57 *
     58 * @param task   Task.
     59 * @param ioaddr Starting I/O space address.
     60 * @param size   Size of the disabled I/O range.
     61 *
     62 * @return EOK on success or an error code from errno.h.
     63 */
     64int ddi_iospace_disable_arch(task_t *task, uintptr_t ioaddr, size_t size)
     65{
     66        return 0;
     67}
     68
    5469/** @}
    5570 */
  • kernel/generic/include/ddi/ddi.h

    r8820544 r8cd680c  
    7070 */
    7171extern int ddi_iospace_enable_arch(task_t *, uintptr_t, size_t);
     72extern int ddi_iospace_disable_arch(task_t *, uintptr_t, size_t);
    7273
    7374#endif
  • kernel/generic/src/ddi/ddi.c

    r8820544 r8cd680c  
    211211NO_TRACE static int physmem_unmap(uintptr_t virt)
    212212{
    213         // TODO: implement unmap
    214         return EOK;
     213        ASSERT(TASK);
     214
     215        return as_area_destroy(TASK->as, virt);
    215216}
    216217
     
    255256/** Enable range of I/O space for task.
    256257 *
    257  * @param id Task ID of the destination task.
     258 * @param id     Task ID of the destination task.
    258259 * @param ioaddr Starting I/O address.
    259  * @param size Size of the enabled I/O space..
     260 * @param size   Size of the enabled I/O space.
    260261 *
    261262 * @return 0 on success, EPERM if the caller lacks capabilities to use this
     
    290291        int rc = ddi_iospace_enable_arch(task, ioaddr, size);
    291292        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);
    292334       
    293335        return rc;
     
    314356sysarg_t sys_iospace_disable(ddi_ioarg_t *uspace_io_arg)
    315357{
    316         // TODO: implement
    317         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);
    318365}
    319366
  • uspace/lib/c/generic/ddi.c

    r8820544 r8cd680c  
    8787}
    8888
     89/** Unmap a piece of physical memory to task.
     90 *
     91 * Caller of this function must have the CAP_MEM_MANAGER capability.
     92 *
     93 * @param virt Virtual address from the phys-mapped region.
     94 *
     95 * @return EOK on success.
     96 * @return EPERM if the caller lacks the CAP_MEM_MANAGER capability.
     97 *
     98 */
     99int physmem_unmap(void *virt)
     100{
     101        return __SYSCALL1(SYS_PHYSMEM_UNMAP, (sysarg_t) virt);
     102}
     103
    89104/** Lock a piece physical memory for DMA transfers.
    90105 *
     
    179194       
    180195        return __SYSCALL1(SYS_IOSPACE_ENABLE, (sysarg_t) &arg);
     196}
     197
     198/** Disable I/O space range to task.
     199 *
     200 * Caller of this function must have the IO_MEM_MANAGER capability.
     201 *
     202 * @param id     Task ID.
     203 * @param ioaddr Starting address of the I/O range.
     204 * @param size   Size of the range.
     205 *
     206 * @return EOK on success
     207 * @return EPERM if the caller lacks the CAP_IO_MANAGER capability
     208 * @return ENOENT if there is no task with specified ID
     209 *
     210 */
     211static int iospace_disable(task_id_t id, void *ioaddr, size_t size)
     212{
     213        const ddi_ioarg_t arg = {
     214                .task_id = id,
     215                .ioaddr = ioaddr,
     216                .size = size
     217        };
     218       
     219        return __SYSCALL1(SYS_IOSPACE_DISABLE, (sysarg_t) &arg);
    181220}
    182221
     
    273312}
    274313
     314/** Disable PIO for specified I/O range.
     315 *
     316 * @param virt     I/O start address.
     317 * @param size     Size of the I/O region.
     318 *
     319 * @return EOK on success.
     320 * @return Negative error code on failure.
     321 *
     322 */
     323int pio_disable(void *virt, size_t size)
     324{
     325#ifdef IO_SPACE_BOUNDARY
     326        if (virt < IO_SPACE_BOUNDARY)
     327                return iospace_disable(task_get_id(), virt, size);
     328#else
     329        (void) iospace_disable;
     330#endif
     331        return physmem_unmap(virt);
     332}
     333
    275334void pio_write_8(ioport8_t *reg, uint8_t val)
    276335{
  • uspace/lib/c/include/ddi.h

    r8820544 r8cd680c  
    5151
    5252extern int physmem_map(uintptr_t, size_t, unsigned int, void **);
     53extern int physmem_unmap(void *);
    5354
    5455extern int dmamem_map(void *, size_t, unsigned int, unsigned int, uintptr_t *);
     
    6162extern int pio_enable_resource(pio_window_t *, hw_resource_t *, void **);
    6263extern int pio_enable(void *, size_t, void **);
     64extern int pio_disable(void *, size_t);
    6365
    6466typedef void (*trace_fnc)(const volatile void *place, uint32_t val,
Note: See TracChangeset for help on using the changeset viewer.