Changeset a35b458 in mainline for kernel/generic/src/ipc/irq.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/ipc/irq.c
r3061bc1 ra35b458 85 85 for (size_t i = 0; i < rangecount; i++) 86 86 pbase[i] = ranges[i].base; 87 87 88 88 /* Map the PIO ranges into the kernel virtual address space. */ 89 89 for (size_t i = 0; i < rangecount; i++) { … … 100 100 } 101 101 } 102 102 103 103 /* Rewrite the IRQ code addresses from physical to kernel virtual. */ 104 104 for (size_t i = 0; i < cmdcount; i++) { 105 105 uintptr_t addr; 106 106 size_t size; 107 107 108 108 /* Process only commands that use an address. */ 109 109 switch (cmds[i].cmd) { … … 127 127 continue; 128 128 } 129 129 130 130 addr = (uintptr_t) cmds[i].addr; 131 131 132 132 size_t j; 133 133 for (j = 0; j < rangecount; j++) { … … 135 135 if (!iswithin(pbase[j], ranges[j].size, addr, size)) 136 136 continue; 137 137 138 138 /* Switch the command to a kernel virtual address. */ 139 139 addr -= pbase[j]; 140 140 addr += ranges[j].base; 141 141 142 142 cmds[i].addr = (void *) addr; 143 143 break; 144 144 } 145 145 146 146 if (j == rangecount) { 147 147 /* … … 154 154 } 155 155 } 156 156 157 157 free(pbase); 158 158 return EOK; … … 172 172 if (cmds[i].cmd >= CMD_LAST) 173 173 return EINVAL; 174 174 175 175 if (cmds[i].srcarg >= IPC_CALL_LEN) 176 176 return EINVAL; 177 177 178 178 if (cmds[i].dstarg >= IPC_CALL_LEN) 179 179 return EINVAL; 180 180 181 181 switch (cmds[i].cmd) { 182 182 case CMD_PREDICATE: … … 188 188 if (i + cmds[i].value > cmdcount) 189 189 return EINVAL; 190 190 191 191 break; 192 192 default: … … 194 194 } 195 195 } 196 196 197 197 return EOK; 198 198 } … … 224 224 irq_pio_range_t *ranges = NULL; 225 225 irq_cmd_t *cmds = NULL; 226 226 227 227 irq_code_t *code = malloc(sizeof(*code), 0); 228 228 errno_t rc = copy_from_uspace(code, ucode, sizeof(*code)); 229 229 if (rc != EOK) 230 230 goto error; 231 231 232 232 if ((code->rangecount > IRQ_MAX_RANGE_COUNT) || 233 233 (code->cmdcount > IRQ_MAX_PROG_SIZE)) 234 234 goto error; 235 235 236 236 ranges = malloc(sizeof(code->ranges[0]) * code->rangecount, 0); 237 237 rc = copy_from_uspace(ranges, code->ranges, … … 239 239 if (rc != EOK) 240 240 goto error; 241 241 242 242 cmds = malloc(sizeof(code->cmds[0]) * code->cmdcount, 0); 243 243 rc = copy_from_uspace(cmds, code->cmds, … … 245 245 if (rc != EOK) 246 246 goto error; 247 247 248 248 rc = code_check(cmds, code->cmdcount); 249 249 if (rc != EOK) 250 250 goto error; 251 251 252 252 rc = ranges_map_and_apply(ranges, code->rangecount, cmds, 253 253 code->cmdcount); 254 254 if (rc != EOK) 255 255 goto error; 256 256 257 257 code->ranges = ranges; 258 258 code->cmds = cmds; 259 259 260 260 return code; 261 261 262 262 error: 263 263 if (cmds) 264 264 free(cmds); 265 265 266 266 if (ranges) 267 267 free(ranges); 268 268 269 269 free(code); 270 270 return NULL; … … 275 275 irq_spinlock_lock(&irq_uspace_hash_table_lock, true); 276 276 irq_spinlock_lock(&irq->lock, false); 277 277 278 278 if (irq->notif_cfg.hashed_in) { 279 279 /* Remove the IRQ from the uspace IRQ hash table. */ … … 318 318 if ((inr < 0) || (inr > last_inr)) 319 319 return ELIMIT; 320 320 321 321 irq_code_t *code; 322 322 if (ucode) { … … 326 326 } else 327 327 code = NULL; 328 328 329 329 /* 330 330 * Allocate and populate the IRQ kernel object. … … 334 334 if (rc != EOK) 335 335 return rc; 336 336 337 337 rc = copy_to_uspace(uspace_handle, &handle, sizeof(cap_handle_t)); 338 338 if (rc != EOK) { … … 353 353 return ENOMEM; 354 354 } 355 355 356 356 irq_initialize(irq); 357 357 irq->inr = inr; … … 363 363 irq->notif_cfg.code = code; 364 364 irq->notif_cfg.counter = 0; 365 365 366 366 /* 367 367 * Insert the IRQ structure into the uspace IRQ hash table. … … 369 369 irq_spinlock_lock(&irq_uspace_hash_table_lock, true); 370 370 irq_spinlock_lock(&irq->lock, false); 371 371 372 372 irq->notif_cfg.hashed_in = true; 373 373 hash_table_insert(&irq_uspace_hash_table, &irq->link); 374 374 375 375 irq_spinlock_unlock(&irq->lock, false); 376 376 irq_spinlock_unlock(&irq_uspace_hash_table_lock, true); … … 378 378 kobject_initialize(kobject, KOBJECT_TYPE_IRQ, irq, &irq_kobject_ops); 379 379 cap_publish(TASK, handle, kobject); 380 380 381 381 return EOK; 382 382 } … … 395 395 if (!kobj) 396 396 return ENOENT; 397 397 398 398 assert(kobj->irq->notif_cfg.answerbox == box); 399 399 … … 402 402 kobject_put(kobj); 403 403 cap_free(TASK, handle); 404 404 405 405 return EOK; 406 406 } … … 419 419 list_append(&call->ab_link, &irq->notif_cfg.answerbox->irq_notifs); 420 420 irq_spinlock_unlock(&irq->notif_cfg.answerbox->irq_lock, false); 421 421 422 422 waitq_wakeup(&irq->notif_cfg.answerbox->wq, WAKEUP_FIRST); 423 423 } … … 435 435 irq_code_t *code = irq->notif_cfg.code; 436 436 uint32_t *scratch = irq->notif_cfg.scratch; 437 437 438 438 if (!irq->notif_cfg.notify) 439 439 return IRQ_DECLINE; 440 440 441 441 if (!code) 442 442 return IRQ_DECLINE; 443 443 444 444 for (size_t i = 0; i < code->cmdcount; i++) { 445 445 uintptr_t srcarg = code->cmds[i].srcarg; 446 446 uintptr_t dstarg = code->cmds[i].dstarg; 447 447 448 448 switch (code->cmds[i].cmd) { 449 449 case CMD_PIO_READ_8: … … 493 493 if (scratch[srcarg] == 0) 494 494 i += code->cmds[i].value; 495 495 496 496 break; 497 497 case CMD_ACCEPT: … … 502 502 } 503 503 } 504 504 505 505 return IRQ_DECLINE; 506 506 } … … 516 516 { 517 517 assert(irq); 518 518 519 519 assert(interrupts_disabled()); 520 520 assert(irq_spinlock_locked(&irq->lock)); 521 521 522 522 if (irq->notif_cfg.answerbox) { 523 523 call_t *call = ipc_call_alloc(FRAME_ATOMIC); 524 524 if (!call) 525 525 return; 526 526 527 527 call->flags |= IPC_CALL_NOTIF; 528 528 /* Put a counter to the message */ 529 529 call->priv = ++irq->notif_cfg.counter; 530 530 531 531 /* Set up args */ 532 532 IPC_SET_IMETHOD(call->data, irq->notif_cfg.imethod); … … 536 536 IPC_SET_ARG4(call->data, irq->notif_cfg.scratch[4]); 537 537 IPC_SET_ARG5(call->data, irq->notif_cfg.scratch[5]); 538 538 539 539 send_call(irq, call); 540 540 } … … 555 555 { 556 556 irq_spinlock_lock(&irq->lock, true); 557 557 558 558 if (irq->notif_cfg.answerbox) { 559 559 call_t *call = ipc_call_alloc(FRAME_ATOMIC); … … 562 562 return; 563 563 } 564 564 565 565 call->flags |= IPC_CALL_NOTIF; 566 566 /* Put a counter to the message */ 567 567 call->priv = ++irq->notif_cfg.counter; 568 568 569 569 IPC_SET_IMETHOD(call->data, irq->notif_cfg.imethod); 570 570 IPC_SET_ARG1(call->data, a1); … … 573 573 IPC_SET_ARG4(call->data, a4); 574 574 IPC_SET_ARG5(call->data, a5); 575 575 576 576 send_call(irq, call); 577 577 } 578 578 579 579 irq_spinlock_unlock(&irq->lock, true); 580 580 }
Note:
See TracChangeset
for help on using the changeset viewer.