Changes in kernel/generic/src/ddi/ddi.c [3164e3b:c0699467] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/ddi/ddi.c
r3164e3b rc0699467 45 45 #include <mm/frame.h> 46 46 #include <mm/as.h> 47 #include <mm/page.h>48 47 #include <synch/mutex.h> 49 48 #include <syscall/copy.h> … … 53 52 #include <errno.h> 54 53 #include <trace.h> 55 #include <bitops.h>56 54 57 55 /** This lock protects the parea_btree. */ … … 89 87 /** Map piece of physical memory into virtual address space of current task. 90 88 * 91 * @param phys Physical address of the starting frame. 89 * @param pf Physical address of the starting frame. 90 * @param vp Virtual address of the starting page. 92 91 * @param pages Number of pages to map. 93 92 * @param flags Address space area flags for the mapping. 94 * @param virt Virtual address of the starting page. 95 * @param bound Lowest virtual address bound. 96 * 97 * @return EOK on success. 98 * @return EPERM if the caller lacks capabilities to use this syscall. 99 * @return EBADMEM if phys is not page aligned. 100 * @return ENOENT if there is no task matching the specified ID or 101 * the physical address space is not enabled for mapping. 102 * @return ENOMEM if there was a problem in creating address space area. 103 * 104 */ 105 NO_TRACE static int physmem_map(uintptr_t phys, size_t pages, 106 unsigned int flags, uintptr_t *virt, uintptr_t bound) 93 * 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 */ 101 NO_TRACE static int ddi_physmem_map(uintptr_t pf, uintptr_t vp, size_t pages, 102 unsigned int flags) 107 103 { 108 104 ASSERT(TASK); 109 105 110 if ((phys % FRAME_SIZE) != 0) 106 if ((pf % FRAME_SIZE) != 0) 107 return EBADMEM; 108 109 if ((vp % PAGE_SIZE) != 0) 111 110 return EBADMEM; 112 111 … … 119 118 120 119 mem_backend_data_t backend_data; 121 backend_data.base = p hys;120 backend_data.base = pf; 122 121 backend_data.frames = pages; 123 122 … … 130 129 btree_node_t *nodep; 131 130 parea_t *parea = (parea_t *) btree_search(&parea_btree, 132 (btree_key_t) p hys, &nodep);131 (btree_key_t) pf, &nodep); 133 132 134 133 if ((parea != NULL) && (parea->frames >= pages)) { … … 150 149 151 150 irq_spinlock_lock(&zones.lock, true); 152 size_t znum = find_zone(ADDR2PFN(p hys), pages, 0);151 size_t znum = find_zone(ADDR2PFN(pf), pages, 0); 153 152 154 153 if (znum == (size_t) -1) { … … 166 165 } 167 166 168 if (zones.info[znum].flags & (ZONE_FIRMWARE | ZONE_RESERVED)) {169 /* 170 * Frames are part of firmware or reserved zone167 if (zones.info[znum].flags & ZONE_FIRMWARE) { 168 /* 169 * Frames are part of firmware 171 170 * -> allow mapping for privileged tasks. 172 171 */ … … 183 182 184 183 map: 185 if (!as_area_create(TASK->as, flags, FRAMES2SIZE(pages),186 AS_AREA_ATTR_NONE, &phys_backend, &backend_data , virt, bound)) {184 if (!as_area_create(TASK->as, flags, pages * PAGE_SIZE, vp, 185 AS_AREA_ATTR_NONE, &phys_backend, &backend_data)) { 187 186 /* 188 187 * The address space area was not created. … … 208 207 } 209 208 210 NO_TRACE static int physmem_unmap(uintptr_t virt)211 {212 // TODO: implement unmap213 return EOK;214 }215 216 /** Wrapper for SYS_PHYSMEM_MAP syscall.217 *218 * @param phys Physical base address to map219 * @param pages Number of pages220 * @param flags Flags of newly mapped pages221 * @param virt_ptr Destination virtual address222 * @param bound Lowest virtual address bound.223 *224 * @return 0 on success, otherwise it returns error code found in errno.h225 *226 */227 sysarg_t sys_physmem_map(uintptr_t phys, size_t pages, unsigned int flags,228 void *virt_ptr, uintptr_t bound)229 {230 uintptr_t virt = (uintptr_t) -1;231 int rc = physmem_map(ALIGN_DOWN(phys, FRAME_SIZE), pages, flags,232 &virt, bound);233 if (rc != EOK)234 return rc;235 236 rc = copy_to_uspace(virt_ptr, &virt, sizeof(virt));237 if (rc != EOK) {238 physmem_unmap((uintptr_t) virt);239 return rc;240 }241 242 return EOK;243 }244 245 sysarg_t sys_physmem_unmap(uintptr_t virt)246 {247 return physmem_unmap(virt);248 }249 250 209 /** Enable range of I/O space for task. 251 210 * … … 258 217 * 259 218 */ 260 NO_TRACE static int iospace_enable(task_id_t id, uintptr_t ioaddr, size_t size) 219 NO_TRACE static int ddi_iospace_enable(task_id_t id, uintptr_t ioaddr, 220 size_t size) 261 221 { 262 222 /* … … 283 243 /* Lock the task and release the lock protecting tasks_btree. */ 284 244 irq_spinlock_exchange(&tasks_lock, &task->lock); 245 285 246 int rc = ddi_iospace_enable_arch(task, ioaddr, size); 247 286 248 irq_spinlock_unlock(&task->lock, true); 287 249 288 250 return rc; 251 } 252 253 /** Wrapper for SYS_PHYSMEM_MAP syscall. 254 * 255 * @param phys_base Physical base address to map 256 * @param virt_base Destination virtual address 257 * @param pages Number of pages 258 * @param flags Flags of newly mapped pages 259 * 260 * @return 0 on success, otherwise it returns error code found in errno.h 261 * 262 */ 263 sysarg_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); 289 269 } 290 270 … … 303 283 return (sysarg_t) rc; 304 284 305 return (sysarg_t) iospace_enable((task_id_t) arg.task_id,285 return (sysarg_t) ddi_iospace_enable((task_id_t) arg.task_id, 306 286 (uintptr_t) arg.ioaddr, (size_t) arg.size); 307 287 } 308 288 309 sysarg_t sys_iospace_disable(ddi_ioarg_t *uspace_io_arg)310 {311 // TODO: implement312 return ENOTSUP;313 }314 315 NO_TRACE static int dmamem_map(uintptr_t virt, size_t size, unsigned int map_flags,316 unsigned int flags, void **phys)317 {318 ASSERT(TASK);319 320 // TODO: implement locking of non-anonymous mapping321 return page_find_mapping(virt, phys);322 }323 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)326 {327 ASSERT(TASK);328 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 else336 order = fnzb(pages - 1) + 1;337 338 *phys = frame_alloc_noreserve(order, 0);339 if (*phys == NULL)340 return ENOMEM;341 342 mem_backend_data_t backend_data;343 backend_data.base = (uintptr_t) *phys;344 backend_data.frames = pages;345 346 if (!as_area_create(TASK->as, map_flags, size,347 AS_AREA_ATTR_NONE, &phys_backend, &backend_data, virt, bound)) {348 frame_free_noreserve((uintptr_t) *phys);349 return ENOMEM;350 }351 352 return EOK;353 }354 355 NO_TRACE static int dmamem_unmap(uintptr_t virt, size_t size)356 {357 // TODO: implement unlocking & unmap358 return EOK;359 }360 361 NO_TRACE static int dmamem_unmap_anonymous(uintptr_t virt)362 {363 // TODO: implement unlocking & unmap364 return EOK;365 }366 367 sysarg_t sys_dmamem_map(size_t size, unsigned int map_flags, unsigned int flags,368 void *phys_ptr, void *virt_ptr, uintptr_t bound)369 {370 if ((flags & DMAMEM_FLAGS_ANONYMOUS) == 0) {371 /*372 * Non-anonymous DMA mapping373 */374 375 void *phys;376 int rc = dmamem_map((uintptr_t) virt_ptr, size, map_flags,377 flags, &phys);378 379 if (rc != EOK)380 return rc;381 382 rc = copy_to_uspace(phys_ptr, &phys, sizeof(phys));383 if (rc != EOK) {384 dmamem_unmap((uintptr_t) virt_ptr, size);385 return rc;386 }387 } else {388 /*389 * Anonymous DMA mapping390 */391 392 void *phys;393 uintptr_t virt = (uintptr_t) -1;394 int rc = dmamem_map_anonymous(size, map_flags, flags,395 &phys, &virt, bound);396 if (rc != EOK)397 return rc;398 399 rc = copy_to_uspace(phys_ptr, &phys, sizeof(phys));400 if (rc != EOK) {401 dmamem_unmap_anonymous((uintptr_t) virt);402 return rc;403 }404 405 rc = copy_to_uspace(virt_ptr, &virt, sizeof(virt));406 if (rc != EOK) {407 dmamem_unmap_anonymous((uintptr_t) virt);408 return rc;409 }410 }411 412 return EOK;413 }414 415 sysarg_t sys_dmamem_unmap(uintptr_t virt, size_t size, unsigned int flags)416 {417 if ((flags & DMAMEM_FLAGS_ANONYMOUS) == 0)418 return dmamem_unmap(virt, size);419 else420 return dmamem_unmap_anonymous(virt);421 }422 423 289 /** @} 424 290 */
Note:
See TracChangeset
for help on using the changeset viewer.