Changeset a35b458 in mainline for kernel/generic/src/ddi/ddi.c
- Timestamp:
- 2018-03-02T20:10:49Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f1380b7
- Parents:
- 3061bc1
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:38:31)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:10:49)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/ddi/ddi.c
r3061bc1 ra35b458 79 79 { 80 80 mutex_lock(&parea_lock); 81 81 82 82 /* 83 83 * We don't check for overlaps here as the kernel is pretty sane. 84 84 */ 85 85 btree_insert(&parea_btree, (btree_key_t) parea->pbase, parea, NULL); 86 86 87 87 mutex_unlock(&parea_lock); 88 88 } … … 108 108 { 109 109 assert(TASK); 110 110 111 111 if ((phys % FRAME_SIZE) != 0) 112 112 return EBADMEM; 113 113 114 114 /* 115 115 * Unprivileged tasks are only allowed to map pareas … … 118 118 bool priv = 119 119 ((perm_get(TASK) & PERM_MEM_MANAGER) == PERM_MEM_MANAGER); 120 120 121 121 mem_backend_data_t backend_data; 122 122 backend_data.base = phys; 123 123 backend_data.frames = pages; 124 124 backend_data.anonymous = false; 125 125 126 126 /* 127 127 * Check if the memory region is explicitly enabled 128 128 * for mapping by any parea structure. 129 129 */ 130 130 131 131 mutex_lock(&parea_lock); 132 132 btree_node_t *nodep; 133 133 parea_t *parea = (parea_t *) btree_search(&parea_btree, 134 134 (btree_key_t) phys, &nodep); 135 135 136 136 if ((parea != NULL) && (parea->frames >= pages)) { 137 137 if ((!priv) && (!parea->unpriv)) { … … 139 139 return EPERM; 140 140 } 141 141 142 142 goto map; 143 143 } 144 144 145 145 parea = NULL; 146 146 mutex_unlock(&parea_lock); 147 147 148 148 /* 149 149 * Check if the memory region is part of physical 150 150 * memory generally enabled for mapping. 151 151 */ 152 152 153 153 irq_spinlock_lock(&zones.lock, true); 154 154 size_t znum = find_zone(ADDR2PFN(phys), pages, 0); 155 155 156 156 if (znum == (size_t) -1) { 157 157 /* … … 161 161 */ 162 162 irq_spinlock_unlock(&zones.lock, true); 163 163 164 164 if (!priv) 165 165 return EPERM; 166 166 167 167 goto map; 168 168 } 169 169 170 170 if (zones.info[znum].flags & (ZONE_FIRMWARE | ZONE_RESERVED)) { 171 171 /* … … 174 174 */ 175 175 irq_spinlock_unlock(&zones.lock, true); 176 176 177 177 if (!priv) 178 178 return EPERM; 179 179 180 180 goto map; 181 181 } 182 182 183 183 irq_spinlock_unlock(&zones.lock, true); 184 184 return ENOENT; 185 185 186 186 map: 187 187 if (!as_area_create(TASK->as, flags, FRAMES2SIZE(pages), … … 191 191 * We report it using ENOMEM. 192 192 */ 193 193 194 194 if (parea != NULL) 195 195 mutex_unlock(&parea_lock); 196 196 197 197 return ENOMEM; 198 198 } 199 199 200 200 /* 201 201 * Mapping is created on-demand during page fault. 202 202 */ 203 203 204 204 if (parea != NULL) { 205 205 parea->mapped = true; 206 206 mutex_unlock(&parea_lock); 207 207 } 208 208 209 209 return EOK; 210 210 } … … 235 235 if (rc != EOK) 236 236 return rc; 237 237 238 238 rc = physmem_map(ALIGN_DOWN(phys, FRAME_SIZE), pages, flags, &virt, 239 239 bound); 240 240 if (rc != EOK) 241 241 return rc; 242 242 243 243 rc = copy_to_uspace(virt_ptr, &virt, sizeof(virt)); 244 244 if (rc != EOK) { … … 246 246 return rc; 247 247 } 248 248 249 249 return EOK; 250 250 } … … 273 273 if (!(perms & PERM_IO_MANAGER)) 274 274 return EPERM; 275 275 276 276 irq_spinlock_lock(&tasks_lock, true); 277 277 278 278 task_t *task = task_find_by_id(id); 279 279 280 280 if ((!task) || (!container_check(CONTAINER, task->container))) { 281 281 /* … … 287 287 return ENOENT; 288 288 } 289 289 290 290 /* Lock the task and release the lock protecting tasks_btree. */ 291 291 irq_spinlock_exchange(&tasks_lock, &task->lock); … … 314 314 if (!(perms & PERM_IO_MANAGER)) 315 315 return EPERM; 316 316 317 317 irq_spinlock_lock(&tasks_lock, true); 318 318 319 319 task_t *task = task_find_by_id(id); 320 320 321 321 if ((!task) || (!container_check(CONTAINER, task->container))) { 322 322 /* … … 328 328 return ENOENT; 329 329 } 330 330 331 331 /* Lock the task and release the lock protecting tasks_btree. */ 332 332 irq_spinlock_exchange(&tasks_lock, &task->lock); 333 333 errno_t rc = ddi_iospace_disable_arch(task, ioaddr, size); 334 334 irq_spinlock_unlock(&task->lock, true); 335 335 336 336 return rc; 337 337 } … … 350 350 if (rc != EOK) 351 351 return (sys_errno_t) rc; 352 352 353 353 return (sys_errno_t) iospace_enable((task_id_t) arg.task_id, 354 354 (uintptr_t) arg.ioaddr, (size_t) arg.size); … … 370 370 { 371 371 assert(TASK); 372 372 373 373 // TODO: implement locking of non-anonymous mapping 374 374 return page_find_mapping(virt, phys); … … 380 380 { 381 381 assert(TASK); 382 382 383 383 size_t frames = SIZE2FRAMES(size); 384 384 if (frames == 0) … … 388 388 if (*phys == 0) 389 389 return ENOMEM; 390 390 391 391 mem_backend_data_t backend_data; 392 392 backend_data.base = *phys; 393 393 backend_data.frames = frames; 394 394 backend_data.anonymous = true; 395 395 396 396 if (!as_area_create(TASK->as, map_flags, size, 397 397 AS_AREA_ATTR_NONE, &phys_backend, &backend_data, virt, bound)) { … … 399 399 return ENOMEM; 400 400 } 401 401 402 402 return EOK; 403 403 } … … 421 421 * Non-anonymous DMA mapping 422 422 */ 423 423 424 424 uintptr_t phys; 425 425 errno_t rc = dmamem_map((uintptr_t) virt_ptr, size, map_flags, 426 426 flags, &phys); 427 427 428 428 if (rc != EOK) 429 429 return rc; 430 430 431 431 rc = copy_to_uspace(phys_ptr, &phys, sizeof(phys)); 432 432 if (rc != EOK) { … … 438 438 * Anonymous DMA mapping 439 439 */ 440 440 441 441 uintptr_t constraint; 442 442 errno_t rc = copy_from_uspace(&constraint, phys_ptr, … … 444 444 if (rc != EOK) 445 445 return rc; 446 446 447 447 uintptr_t virt; 448 448 rc = copy_from_uspace(&virt, virt_ptr, sizeof(virt)); 449 449 if (rc != EOK) 450 450 return rc; 451 451 452 452 uintptr_t phys; 453 453 rc = dmamem_map_anonymous(size, constraint, map_flags, flags, … … 455 455 if (rc != EOK) 456 456 return rc; 457 457 458 458 rc = copy_to_uspace(phys_ptr, &phys, sizeof(phys)); 459 459 if (rc != EOK) { … … 461 461 return rc; 462 462 } 463 463 464 464 rc = copy_to_uspace(virt_ptr, &virt, sizeof(virt)); 465 465 if (rc != EOK) { … … 468 468 } 469 469 } 470 470 471 471 return EOK; 472 472 }
Note:
See TracChangeset
for help on using the changeset viewer.