Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/ddi.c

    rb5c2f56 r8cd680c  
    4242#include <ddi.h>
    4343#include <libarch/ddi.h>
     44#include <device/hw_res.h>
     45#include <device/hw_res_parsed.h>
     46#include <device/pio_window.h>
    4447#include <libc.h>
    4548#include <task.h>
     
    6871 * @param flags Flags for the new address space area.
    6972 * @param virt  Virtual address of the starting page.
    70  *
    71  * @return EOK on success
    72  * @return EPERM if the caller lacks the CAP_MEM_MANAGER capability
    73  * @return ENOENT if there is no task with specified ID
     73 *              If set to AS_AREA_ANY ((void *) -1), a suitable value
     74 *              is found by the kernel, otherwise the kernel tries to
     75 *              obey the desired value.
     76 *
     77 * @return EOK on success.
     78 * @return EPERM if the caller lacks the CAP_MEM_MANAGER capability.
    7479 * @return ENOMEM if there was some problem in creating
    7580 *         the address space area.
    7681 *
    7782 */
    78 int physmem_map(void *phys, size_t pages, unsigned int flags, void **virt)
     83int physmem_map(uintptr_t phys, size_t pages, unsigned int flags, void **virt)
    7984{
    8085        return __SYSCALL5(SYS_PHYSMEM_MAP, (sysarg_t) phys,
     
    8287}
    8388
     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
     104/** Lock a piece physical memory for DMA transfers.
     105 *
     106 * The mapping of the specified virtual memory address
     107 * to physical memory address is locked in order to
     108 * make it safe for DMA transferts.
     109 *
     110 * Caller of this function must have the CAP_MEM_MANAGER capability.
     111 *
     112 * @param virt      Virtual address of the memory to be locked.
     113 * @param size      Number of bytes to lock.
     114 * @param map_flags Desired virtual memory area flags.
     115 * @param flags     Flags for the physical memory address.
     116 * @param phys      Locked physical memory address.
     117 *
     118 * @return EOK on success.
     119 * @return EPERM if the caller lacks the CAP_MEM_MANAGER capability.
     120 * @return ENOMEM if there was some problem in creating
     121 *         the address space area.
     122 *
     123 */
    84124int dmamem_map(void *virt, size_t size, unsigned int map_flags,
    85     unsigned int flags, void **phys)
     125    unsigned int flags, uintptr_t *phys)
    86126{
    87127        return (int) __SYSCALL6(SYS_DMAMEM_MAP, (sysarg_t) size,
     
    90130}
    91131
    92 int dmamem_map_anonymous(size_t size, unsigned int map_flags,
    93     unsigned int flags, void **phys, void **virt)
    94 {
     132/** Map a piece of physical memory suitable for DMA transfers.
     133 *
     134 * Caller of this function must have the CAP_MEM_MANAGER capability.
     135 *
     136 * @param size       Number of bytes to map.
     137 * @param constraint Bit mask defining the contraint on the physical
     138 *                   address to be mapped.
     139 * @param map_flags  Desired virtual memory area flags.
     140 * @param flags      Flags for the physical memory address.
     141 * @param virt       Virtual address of the starting page.
     142 *                   If set to AS_AREA_ANY ((void *) -1), a suitable value
     143 *                   is found by the kernel, otherwise the kernel tries to
     144 *                   obey the desired value.
     145 *
     146 * @return EOK on success.
     147 * @return EPERM if the caller lacks the CAP_MEM_MANAGER capability.
     148 * @return ENOMEM if there was some problem in creating
     149 *         the address space area.
     150 *
     151 */
     152int dmamem_map_anonymous(size_t size, uintptr_t constraint,
     153    unsigned int map_flags, unsigned int flags, uintptr_t *phys, void **virt)
     154{
     155        *phys = constraint;
     156       
    95157        return (int) __SYSCALL6(SYS_DMAMEM_MAP, (sysarg_t) size,
    96158            (sysarg_t) map_flags, (sysarg_t) flags | DMAMEM_FLAGS_ANONYMOUS,
     
    132194       
    133195        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);
     220}
     221
     222/** Enable PIO for specified address range.
     223 *
     224 * @param range I/O range to be enable.
     225 * @param virt  Virtual address for application's PIO operations.
     226 */
     227int pio_enable_range(addr_range_t *range, void **virt)
     228{
     229        return pio_enable(RNGABSPTR(*range), RNGSZ(*range), virt);
     230}
     231
     232/** Enable PIO for specified HW resource wrt. to the PIO window.
     233 *
     234 * @param win      PIO window. May be NULL if the resources are known to be
     235 *                 absolute.
     236 * @param res      Resources specifying the I/O range wrt. to the PIO window.
     237 * @param virt     Virtual address for application's PIO operations.
     238 *
     239 * @return EOK on success.
     240 * @return Negative error code on failure.
     241 *
     242 */
     243int pio_enable_resource(pio_window_t *win, hw_resource_t *res, void **virt)
     244{
     245        uintptr_t addr;
     246        size_t size;
     247
     248        switch (res->type) {
     249        case IO_RANGE:
     250                addr = res->res.io_range.address;
     251                if (res->res.io_range.relative) {
     252                        if (!win)
     253                                return EINVAL;
     254                        addr += win->io.base;
     255                }
     256                size = res->res.io_range.size;
     257                break;
     258        case MEM_RANGE:
     259                addr = res->res.mem_range.address;
     260                if (res->res.mem_range.relative) {
     261                        if (!win)
     262                                return EINVAL;
     263                        addr += win->mem.base;
     264                }
     265                size = res->res.mem_range.size;
     266                break;
     267        default:
     268                return EINVAL;
     269        }
     270
     271        return pio_enable((void *) addr, size, virt);   
    134272}
    135273
     
    158296        if (!virt)
    159297                return EINVAL;
    160 
    161         void *phys_frame =
    162             (void *) ALIGN_DOWN((uintptr_t) pio_addr, PAGE_SIZE);
    163         size_t offset = pio_addr - phys_frame;
     298       
     299        uintptr_t phys_frame =
     300            ALIGN_DOWN((uintptr_t) pio_addr, PAGE_SIZE);
     301        size_t offset = (uintptr_t) pio_addr - phys_frame;
    164302        size_t pages = SIZE2PAGES(offset + size);
    165303       
    166         void *virt_page;
     304        void *virt_page = AS_AREA_ANY;
    167305        int rc = physmem_map(phys_frame, pages,
    168306            AS_AREA_READ | AS_AREA_WRITE, &virt_page);
     
    174312}
    175313
     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
    176334void pio_write_8(ioport8_t *reg, uint8_t val)
    177335{
     
    213371}
    214372
    215 /** Register IRQ notification.
    216  *
    217  * @param inr    IRQ number.
    218  * @param devno  Device number of the device generating inr.
    219  * @param method Use this method for notifying me.
    220  * @param ucode  Top-half pseudocode handler.
    221  *
    222  * @return Value returned by the kernel.
    223  *
    224  */
    225 int irq_register(int inr, int devno, int method, irq_code_t *ucode)
    226 {
    227         return __SYSCALL4(SYS_IRQ_REGISTER, inr, devno, method,
    228             (sysarg_t) ucode);
    229 }
    230 
    231 /** Unregister IRQ notification.
    232  *
    233  * @param inr   IRQ number.
    234  * @param devno Device number of the device generating inr.
    235  *
    236  * @return Value returned by the kernel.
    237  *
    238  */
    239 int irq_unregister(int inr, int devno)
    240 {
    241         return __SYSCALL2(SYS_IRQ_UNREGISTER, inr, devno);
    242 }
    243 
    244373/** @}
    245374 */
Note: See TracChangeset for help on using the changeset viewer.