Changes in uspace/lib/c/generic/ddi.c [b5c2f56:8cd680c] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/ddi.c
rb5c2f56 r8cd680c 42 42 #include <ddi.h> 43 43 #include <libarch/ddi.h> 44 #include <device/hw_res.h> 45 #include <device/hw_res_parsed.h> 46 #include <device/pio_window.h> 44 47 #include <libc.h> 45 48 #include <task.h> … … 68 71 * @param flags Flags for the new address space area. 69 72 * @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. 74 79 * @return ENOMEM if there was some problem in creating 75 80 * the address space area. 76 81 * 77 82 */ 78 int physmem_map( void *phys, size_t pages, unsigned int flags, void **virt)83 int physmem_map(uintptr_t phys, size_t pages, unsigned int flags, void **virt) 79 84 { 80 85 return __SYSCALL5(SYS_PHYSMEM_MAP, (sysarg_t) phys, … … 82 87 } 83 88 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 */ 99 int 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 */ 84 124 int dmamem_map(void *virt, size_t size, unsigned int map_flags, 85 unsigned int flags, void **phys)125 unsigned int flags, uintptr_t *phys) 86 126 { 87 127 return (int) __SYSCALL6(SYS_DMAMEM_MAP, (sysarg_t) size, … … 90 130 } 91 131 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 */ 152 int 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 95 157 return (int) __SYSCALL6(SYS_DMAMEM_MAP, (sysarg_t) size, 96 158 (sysarg_t) map_flags, (sysarg_t) flags | DMAMEM_FLAGS_ANONYMOUS, … … 132 194 133 195 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 */ 211 static 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 */ 227 int 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 */ 243 int 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); 134 272 } 135 273 … … 158 296 if (!virt) 159 297 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; 164 302 size_t pages = SIZE2PAGES(offset + size); 165 303 166 void *virt_page ;304 void *virt_page = AS_AREA_ANY; 167 305 int rc = physmem_map(phys_frame, pages, 168 306 AS_AREA_READ | AS_AREA_WRITE, &virt_page); … … 174 312 } 175 313 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 */ 323 int 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 176 334 void pio_write_8(ioport8_t *reg, uint8_t val) 177 335 { … … 213 371 } 214 372 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 244 373 /** @} 245 374 */
Note:
See TracChangeset
for help on using the changeset viewer.