Changes in / [1a9174e:d3b2ffa] in mainline
- Files:
-
- 1 added
- 23 edited
Legend:
- Unmodified
- Added
- Removed
-
HelenOS.config
r1a9174e rd3b2ffa 494 494 495 495 % Support for NS16550 controller (kernel console) 496 ! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=serial|CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&(PLATFORM=ia32|PLATFORM=amd64)] CONFIG_NS16550_KCON ( n/y)496 ! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=serial|CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&(PLATFORM=ia32|PLATFORM=amd64)] CONFIG_NS16550_KCON (y/n) 497 497 498 498 % Use NS16550 controller as serial input (kernel console) -
kernel/generic/include/synch/waitq.h
r1a9174e rd3b2ffa 82 82 extern void _waitq_wakeup_unsafe(waitq_t *, wakeup_mode_t); 83 83 extern void waitq_interrupt_sleep(struct thread *); 84 extern void waitq_unsleep(waitq_t *);85 84 extern int waitq_count_get(waitq_t *); 86 85 extern void waitq_count_set(waitq_t *, int val); -
kernel/generic/src/ipc/ipc.c
r1a9174e rd3b2ffa 550 550 errno_t rc; 551 551 552 restart:553 552 rc = waitq_sleep_timeout(&box->wq, usec, flags, NULL); 554 553 if (rc != EOK) … … 590 589 list_append(&request->ab_link, &box->dispatched_calls); 591 590 } else { 592 /* This can happen regularly after ipc_cleanup */ 591 /* 592 * This can happen regularly after ipc_cleanup, or in 593 * response to ipc_poke(). Let the caller sort out the wakeup. 594 */ 593 595 irq_spinlock_unlock(&box->lock, true); 594 goto restart;596 return NULL; 595 597 } 596 598 -
kernel/generic/src/ipc/sysipc.c
r1a9174e rd3b2ffa 856 856 sys_errno_t sys_ipc_poke(void) 857 857 { 858 waitq_ unsleep(&TASK->answerbox.wq);858 waitq_wakeup(&TASK->answerbox.wq, WAKEUP_FIRST); 859 859 return EOK; 860 860 } -
kernel/generic/src/synch/waitq.c
r1a9174e rd3b2ffa 190 190 if (do_wakeup) 191 191 thread_ready(thread); 192 }193 194 /** Interrupt the first thread sleeping in the wait queue.195 *196 * Note that the caller somehow needs to know that the thread to be interrupted197 * is sleeping interruptibly.198 *199 * @param wq Pointer to wait queue.200 *201 */202 void waitq_unsleep(waitq_t *wq)203 {204 irq_spinlock_lock(&wq->lock, true);205 206 if (!list_empty(&wq->sleepers)) {207 thread_t *thread = list_get_instance(list_first(&wq->sleepers),208 thread_t, wq_link);209 210 irq_spinlock_lock(&thread->lock, false);211 212 assert(thread->sleep_interruptible);213 214 if ((thread->timeout_pending) &&215 (timeout_unregister(&thread->sleep_timeout)))216 thread->timeout_pending = false;217 218 list_remove(&thread->wq_link);219 thread->saved_context = thread->sleep_interruption_context;220 thread->sleep_queue = NULL;221 222 irq_spinlock_unlock(&thread->lock, false);223 thread_ready(thread);224 }225 226 irq_spinlock_unlock(&wq->lock, true);227 192 } 228 193 -
tools/ew.py
r1a9174e rd3b2ffa 217 217 cmdline += ' -nographic' 218 218 219 if ((not is_override('nographic')) and not is_override('noserial')): 220 cmdline += ' -serial stdio' 221 219 222 if (is_override('bigmem')): 220 223 cmdline += ' -m 4G' … … 343 346 print("-notablet\tDisable USB tablet (use only relative-position PS/2 mouse instead), if applicable.") 344 347 print("-nographic\tDisable graphical output. Serial port output must be enabled for this to be useful.") 348 print("-noserial\tDisable serial port output in the terminal.") 345 349 print("-bigmem\tSets maximum RAM size to 4GB.") 346 350 … … 401 405 elif sys.argv[i] == '-bigmem': 402 406 overrides['bigmem'] = True 407 elif sys.argv[i] == '-noserial': 408 overrides['noserial'] = True 403 409 elif sys.argv[i] == '-qemu_path' and i < len(sys.argv) - 1: 404 410 expect_qemu = True -
uspace/app/stats/stats.c
r1a9174e rd3b2ffa 38 38 #include <stdio.h> 39 39 #include <task.h> 40 #include <thread.h>41 40 #include <stats.h> 42 41 #include <errno.h> -
uspace/app/top/top.c
r1a9174e rd3b2ffa 39 39 #include <stdlib.h> 40 40 #include <task.h> 41 #include <thread.h>42 41 #include <sys/time.h> 43 42 #include <errno.h> -
uspace/drv/bus/usb/xhci/endpoint.c
r1a9174e rd3b2ffa 102 102 if (dev->speed >= USB_SPEED_HIGH || 103 103 ep->transfer_type != USB_TRANSFER_INTERRUPT) { 104 105 // XXX: According to the spec, the interval should be 106 // from [1, 16]. However, in QEMU, we get 0 here 107 // (a QEMU bug?). 108 if (xhci_ep->interval == 0) 109 xhci_ep->interval = 8; 110 104 111 xhci_ep->interval = 1 << (xhci_ep->interval - 1); 105 112 } -
uspace/drv/nic/virtio-net/virtio-net.c
r1a9174e rd3b2ffa 70 70 }; 71 71 72 /** Allocate DMA buffers73 *74 * @param buffers[in] Number of buffers to allocate.75 * @param size[in] Size of each buffer.76 * @param write[in] True if the buffers are writable by the driver, false77 * otherwise.78 * @param buf[out] Output array holding virtual addresses of the allocated79 * buffers.80 * @param buf_p[out] Output array holding physical addresses of the allocated81 * buffers.82 *83 * The buffers can be deallocated by virtio_net_teardown_bufs().84 *85 * @return EOK on success or error code.86 */87 static errno_t virtio_net_setup_bufs(unsigned int buffers, size_t size,88 bool write, void *buf[], uintptr_t buf_p[])89 {90 /*91 * Allocate all buffers at once in one large chunk.92 */93 void *virt = AS_AREA_ANY;94 uintptr_t phys;95 errno_t rc = dmamem_map_anonymous(buffers * size, 0,96 write ? AS_AREA_WRITE : AS_AREA_READ, 0, &phys, &virt);97 if (rc != EOK)98 return rc;99 100 ddf_msg(LVL_NOTE, "DMA buffers: %p-%p", virt, virt + buffers * size);101 102 /*103 * Calculate addresses of the individual buffers for easy access.104 */105 for (unsigned i = 0; i < buffers; i++) {106 buf[i] = virt + i * size;107 buf_p[i] = phys + i * size;108 }109 110 return EOK;111 }112 113 /** Deallocate DMA buffers114 *115 * @param buf[in] Array holding the virtual addresses of the DMA buffers116 * previously allocated by virtio_net_setup_bufs().117 */118 static void virtio_net_teardown_bufs(void *buf[])119 {120 if (buf[0]) {121 dmamem_unmap_anonymous(buf[0]);122 buf[0] = NULL;123 }124 }125 126 /** Create free descriptor list from the unused VIRTIO descriptors127 *128 * @param vdev[in] VIRTIO device for which the free list will be created.129 * @param num[in] Index of the virtqueue for which the free list will be130 * created.131 * @param size[in] Number of descriptors on the free list. The free list will132 * contain descriptors starting from 0 to \a size - 1.133 * @param head[out] Variable that will hold the VIRTIO descriptor at the head134 * of the free list.135 */136 static void virtio_net_create_desc_free_list(virtio_dev_t *vdev, uint16_t num,137 uint16_t size, uint16_t *head)138 {139 for (unsigned i = 0; i < size; i++) {140 virtio_virtq_desc_set(vdev, num, i, 0, 0,141 VIRTQ_DESC_F_NEXT, (i + 1 == size) ? -1U : i + 1);142 }143 *head = 0;144 }145 146 /** Allocate a descriptor from the free list147 *148 * @param vdev[in] VIRTIO device with the free list.149 * @param num[in] Index of the virtqueue with free list.150 * @param head[in,out] Head of the free list.151 *152 * @return Allocated descriptor or 0xFFFF if the list is empty.153 */154 static uint16_t virtio_net_alloc_desc(virtio_dev_t *vdev, uint16_t num,155 uint16_t *head)156 {157 virtq_t *q = &vdev->queues[num];158 fibril_mutex_lock(&q->lock);159 uint16_t descno = *head;160 if (descno != (uint16_t) -1U)161 *head = virtio_virtq_desc_get_next(vdev, num, descno);162 fibril_mutex_unlock(&q->lock);163 return descno;164 }165 166 /** Free a descriptor into the free list167 *168 * @param vdev[in] VIRTIO device with the free list.169 * @param num[in] Index of the virtqueue with free list.170 * @param head[in,out] Head of the free list.171 * @param descno[in] The freed descriptor.172 */173 static void virtio_net_free_desc(virtio_dev_t *vdev, uint16_t num,174 uint16_t *head, uint16_t descno)175 {176 virtq_t *q = &vdev->queues[num];177 fibril_mutex_lock(&q->lock);178 virtio_virtq_desc_set(vdev, num, descno, 0, 0, VIRTQ_DESC_F_NEXT,179 *head);180 *head = descno;181 fibril_mutex_unlock(&q->lock);182 }183 184 72 static void virtio_net_irq_handler(ipc_call_t *icall, ddf_dev_t *dev) 185 73 { … … 214 102 215 103 while (virtio_virtq_consume_used(vdev, TX_QUEUE_1, &descno, &len)) { 216 virtio_ net_free_desc(vdev, TX_QUEUE_1,217 &virtio_net->tx_free_head,descno);104 virtio_free_desc(vdev, TX_QUEUE_1, &virtio_net->tx_free_head, 105 descno); 218 106 } 219 107 while (virtio_virtq_consume_used(vdev, CT_QUEUE_1, &descno, &len)) { 220 virtio_ net_free_desc(vdev, CT_QUEUE_1,221 &virtio_net->ct_free_head,descno);108 virtio_free_desc(vdev, CT_QUEUE_1, &virtio_net->ct_free_head, 109 descno); 222 110 } 223 111 } … … 345 233 * Setup DMA buffers 346 234 */ 347 rc = virtio_ net_setup_bufs(RX_BUFFERS, RX_BUF_SIZE, false,235 rc = virtio_setup_dma_bufs(RX_BUFFERS, RX_BUF_SIZE, false, 348 236 virtio_net->rx_buf, virtio_net->rx_buf_p); 349 237 if (rc != EOK) 350 238 goto fail; 351 rc = virtio_ net_setup_bufs(TX_BUFFERS, TX_BUF_SIZE, true,239 rc = virtio_setup_dma_bufs(TX_BUFFERS, TX_BUF_SIZE, true, 352 240 virtio_net->tx_buf, virtio_net->tx_buf_p); 353 241 if (rc != EOK) 354 242 goto fail; 355 rc = virtio_ net_setup_bufs(CT_BUFFERS, CT_BUF_SIZE, true,243 rc = virtio_setup_dma_bufs(CT_BUFFERS, CT_BUF_SIZE, true, 356 244 virtio_net->ct_buf, virtio_net->ct_buf_p); 357 245 if (rc != EOK) … … 379 267 * Put all TX and CT buffers on a free list 380 268 */ 381 virtio_ net_create_desc_free_list(vdev, TX_QUEUE_1, TX_BUFFERS,269 virtio_create_desc_free_list(vdev, TX_QUEUE_1, TX_BUFFERS, 382 270 &virtio_net->tx_free_head); 383 virtio_ net_create_desc_free_list(vdev, CT_QUEUE_1, CT_BUFFERS,271 virtio_create_desc_free_list(vdev, CT_QUEUE_1, CT_BUFFERS, 384 272 &virtio_net->ct_free_head); 385 273 … … 414 302 415 303 fail: 416 virtio_ net_teardown_bufs(virtio_net->rx_buf);417 virtio_ net_teardown_bufs(virtio_net->tx_buf);418 virtio_ net_teardown_bufs(virtio_net->ct_buf);304 virtio_teardown_dma_bufs(virtio_net->rx_buf); 305 virtio_teardown_dma_bufs(virtio_net->tx_buf); 306 virtio_teardown_dma_bufs(virtio_net->ct_buf); 419 307 420 308 virtio_device_setup_fail(vdev); … … 428 316 virtio_net_t *virtio_net = (virtio_net_t *) nic_get_specific(nic); 429 317 430 virtio_ net_teardown_bufs(virtio_net->rx_buf);431 virtio_ net_teardown_bufs(virtio_net->tx_buf);432 virtio_ net_teardown_bufs(virtio_net->ct_buf);318 virtio_teardown_dma_bufs(virtio_net->rx_buf); 319 virtio_teardown_dma_bufs(virtio_net->tx_buf); 320 virtio_teardown_dma_bufs(virtio_net->ct_buf); 433 321 434 322 virtio_device_setup_fail(&virtio_net->virtio_dev); … … 446 334 } 447 335 448 uint16_t descno = virtio_ net_alloc_desc(vdev, TX_QUEUE_1,336 uint16_t descno = virtio_alloc_desc(vdev, TX_QUEUE_1, 449 337 &virtio_net->tx_free_head); 450 338 if (descno == (uint16_t) -1U) { -
uspace/lib/c/generic/async/ports.c
r1a9174e rd3b2ffa 35 35 #include <ipc/irq.h> 36 36 #include <ipc/event.h> 37 #include <futex.h>38 37 #include <fibril.h> 39 38 #include <adt/hash_table.h> -
uspace/lib/c/generic/async/server.c
r1a9174e rd3b2ffa 122 122 #include "../private/fibril.h" 123 123 124 #define DPRINTF(...) ((void) 0) 125 124 126 /** Async framework global futex */ 125 127 futex_t async_futex = FUTEX_INITIALIZER; … … 132 134 link_t link; 133 135 134 cap_call_handle_t chandle;135 136 ipc_call_t call; 136 137 } msg_t; … … 164 165 list_t msg_queue; 165 166 166 /** Identification of the opening call. */167 cap_call_handle_t chandle;168 169 167 /** Call data of the opening call. */ 170 168 ipc_call_t call; … … 179 177 void *data; 180 178 } connection_t; 179 180 /* Member of notification_t::msg_list. */ 181 typedef struct { 182 link_t link; 183 ipc_call_t calldata; 184 } notification_msg_t; 181 185 182 186 /* Notification data */ … … 197 201 void *arg; 198 202 199 /** Data of the most recent notification. */ 200 ipc_call_t calldata; 201 202 /** 203 * How many notifications with this `imethod` arrived since it was last 204 * handled. If `count` > 1, `calldata` only holds the data for the most 205 * recent such notification, all the older data being lost. 206 * 207 * `async_spawn_notification_handler()` can be used to increase the 208 * number of notifications that can be processed simultaneously, 209 * reducing the likelihood of losing them when the handler blocks. 210 */ 211 long count; 203 /** List of arrived notifications. */ 204 list_t msg_list; 212 205 } notification_t; 213 206 … … 249 242 static LIST_INITIALIZE(notification_queue); 250 243 static FIBRIL_SEMAPHORE_INITIALIZE(notification_semaphore, 0); 244 245 static LIST_INITIALIZE(notification_freelist); 246 static long notification_freelist_total = 0; 247 static long notification_freelist_used = 0; 251 248 252 249 static sysarg_t notification_avail = 0; … … 412 409 client_t *client = async_client_get(fibril_connection->in_task_id, true); 413 410 if (!client) { 414 ipc_answer_0(fibril_connection->c handle, ENOMEM);411 ipc_answer_0(fibril_connection->call.cap_handle, ENOMEM); 415 412 return 0; 416 413 } … … 421 418 * Call the connection handler function. 422 419 */ 423 fibril_connection->handler(fibril_connection->c handle,420 fibril_connection->handler(fibril_connection->call.cap_handle, 424 421 &fibril_connection->call, fibril_connection->data); 425 422 … … 448 445 449 446 list_remove(&msg->link); 450 ipc_answer_0(msg->c handle, EHANGUP);447 ipc_answer_0(msg->call.cap_handle, EHANGUP); 451 448 free(msg); 452 449 } … … 471 468 * @param in_task_id Identification of the incoming connection. 472 469 * @param in_phone_hash Identification of the incoming connection. 473 * @param chandle Handle of the opening IPC_M_CONNECT_ME_TO call. 474 * If chandle is CAP_NIL, the connection was opened by 475 * accepting the IPC_M_CONNECT_TO_ME call and this 476 * function is called directly by the server. 477 * @param call Call data of the opening call. 470 * @param call Call data of the opening call. If call is NULL, 471 * the connection was opened by accepting the 472 * IPC_M_CONNECT_TO_ME call and this function is 473 * called directly by the server. 478 474 * @param handler Connection handler. 479 475 * @param data Client argument to pass to the connection handler. … … 483 479 */ 484 480 static fid_t async_new_connection(task_id_t in_task_id, sysarg_t in_phone_hash, 485 cap_call_handle_t chandle, ipc_call_t *call, async_port_handler_t handler, 486 void *data) 481 ipc_call_t *call, async_port_handler_t handler, void *data) 487 482 { 488 483 connection_t *conn = malloc(sizeof(*conn)); 489 484 if (!conn) { 490 if (c handle != CAP_NIL)491 ipc_answer_0(c handle, ENOMEM);485 if (call) 486 ipc_answer_0(call->cap_handle, ENOMEM); 492 487 493 488 return (uintptr_t) NULL; … … 497 492 conn->in_phone_hash = in_phone_hash; 498 493 list_initialize(&conn->msg_queue); 499 conn->chandle = chandle;500 494 conn->close_chandle = CAP_NIL; 501 495 conn->handler = handler; … … 504 498 if (call) 505 499 conn->call = *call; 500 else 501 conn->call.cap_handle = CAP_NIL; 506 502 507 503 /* We will activate the fibril ASAP */ … … 512 508 free(conn); 513 509 514 if (c handle != CAP_NIL)515 ipc_answer_0(c handle, ENOMEM);510 if (call) 511 ipc_answer_0(call->cap_handle, ENOMEM); 516 512 517 513 return (uintptr_t) NULL; … … 568 564 sysarg_t phone_hash = IPC_GET_ARG5(answer); 569 565 fid_t fid = async_new_connection(answer.in_task_id, phone_hash, 570 CAP_NIL,NULL, handler, data);566 NULL, handler, data); 571 567 if (fid == (uintptr_t) NULL) 572 568 return ENOMEM; … … 637 633 * timeouts are unregistered. 638 634 * 639 * @param chandle Handle of the incoming call. 640 * @param call Data of the incoming call. 635 * @param call Data of the incoming call. 641 636 * 642 637 * @return False if the call doesn't match any connection. … … 644 639 * 645 640 */ 646 static bool route_call( cap_call_handle_t chandle,ipc_call_t *call)641 static bool route_call(ipc_call_t *call) 647 642 { 648 643 assert(call); … … 667 662 } 668 663 669 msg->chandle = chandle;670 664 msg->call = *call; 671 665 list_append(&msg->link, &conn->msg_queue); 672 666 673 667 if (IPC_GET_IMETHOD(*call) == IPC_M_PHONE_HUNGUP) 674 conn->close_chandle = c handle;668 conn->close_chandle = call->cap_handle; 675 669 676 670 /* If the connection fibril is waiting for an event, activate it */ … … 709 703 notification_t *notification = list_get_instance( 710 704 list_first(¬ification_queue), notification_t, qlink); 711 list_remove(¬ification->qlink);712 705 713 706 async_notification_handler_t handler = notification->handler; 714 707 void *arg = notification->arg; 715 ipc_call_t calldata = notification->calldata; 716 long count = notification->count; 717 718 notification->count = 0; 708 709 notification_msg_t *m = list_pop(¬ification->msg_list, 710 notification_msg_t, link); 711 assert(m); 712 ipc_call_t calldata = m->calldata; 713 714 notification_freelist_used--; 715 716 if (notification_freelist_total > 64 && 717 notification_freelist_total > 2 * notification_freelist_used) { 718 /* Going to free the structure if we have too much. */ 719 notification_freelist_total--; 720 } else { 721 /* Otherwise add to freelist. */ 722 list_append(&m->link, ¬ification_freelist); 723 m = NULL; 724 } 725 726 if (list_empty(¬ification->msg_list)) 727 list_remove(¬ification->qlink); 719 728 720 729 futex_unlock(¬ification_futex); 721 722 // FIXME: Pass count to the handler. It might be important.723 (void) count;724 730 725 731 if (handler) 726 732 handler(&calldata, arg); 733 734 free(m); 727 735 } 728 736 … … 760 768 futex_lock(¬ification_futex); 761 769 770 notification_msg_t *m = list_pop(¬ification_freelist, 771 notification_msg_t, link); 772 773 if (!m) { 774 futex_unlock(¬ification_futex); 775 m = malloc(sizeof(notification_msg_t)); 776 if (!m) { 777 DPRINTF("Out of memory.\n"); 778 abort(); 779 } 780 781 futex_lock(¬ification_futex); 782 notification_freelist_total++; 783 } 784 762 785 ht_link_t *link = hash_table_find(¬ification_hash_table, 763 786 &IPC_GET_IMETHOD(*call)); … … 765 788 /* Invalid notification. */ 766 789 // TODO: Make sure this can't happen and turn it into assert. 790 notification_freelist_total--; 767 791 futex_unlock(¬ification_futex); 792 free(m); 768 793 return; 769 794 } … … 772 797 hash_table_get_inst(link, notification_t, htlink); 773 798 774 notification->count++; 775 notification->calldata = *call; 776 777 if (link_in_use(¬ification->qlink)) { 778 /* Notification already queued. */ 779 futex_unlock(¬ification_futex); 780 return; 781 } 782 783 list_append(¬ification->qlink, ¬ification_queue); 799 notification_freelist_used++; 800 m->calldata = *call; 801 list_append(&m->link, ¬ification->msg_list); 802 803 if (!link_in_use(¬ification->qlink)) 804 list_append(¬ification->qlink, ¬ification_queue); 805 784 806 futex_unlock(¬ification_futex); 785 807 … … 802 824 notification->handler = handler; 803 825 notification->arg = arg; 826 827 list_initialize(¬ification->msg_list); 804 828 805 829 fid_t fib = 0; … … 1011 1035 list_remove(&msg->link); 1012 1036 1013 cap_call_handle_t chandle = msg->c handle;1037 cap_call_handle_t chandle = msg->call.cap_handle; 1014 1038 *call = msg->call; 1015 1039 free(msg); … … 1058 1082 * Otherwise the call is routed to its connection fibril. 1059 1083 * 1060 * @param chandle Handle of the incoming call. 1061 * @param call Data of the incoming call. 1062 * 1063 */ 1064 static void handle_call(cap_call_handle_t chandle, ipc_call_t *call) 1084 * @param call Data of the incoming call. 1085 * 1086 */ 1087 static void handle_call(ipc_call_t *call) 1065 1088 { 1066 1089 assert(call); … … 1069 1092 return; 1070 1093 1071 if (c handle == CAP_NIL) {1094 if (call->cap_handle == CAP_NIL) { 1072 1095 if (call->flags & IPC_CALL_NOTIF) { 1073 1096 /* Kernel notification */ … … 1087 1110 async_get_port_handler(iface, 0, &data); 1088 1111 1089 async_new_connection(call->in_task_id, in_phone_hash, c handle,1090 call,handler, data);1112 async_new_connection(call->in_task_id, in_phone_hash, call, 1113 handler, data); 1091 1114 return; 1092 1115 } 1093 1116 1094 1117 /* Try to route the call through the connection hash table */ 1095 if (route_call(c handle, call))1118 if (route_call(call)) 1096 1119 return; 1097 1120 1098 1121 /* Unknown call from unknown phone - hang it up */ 1099 ipc_answer_0(c handle, EHANGUP);1122 ipc_answer_0(call->cap_handle, EHANGUP); 1100 1123 } 1101 1124 … … 1178 1201 1179 1202 assert(rc == EOK); 1180 handle_call( call.cap_handle,&call);1203 handle_call(&call); 1181 1204 } 1182 1205 … … 1847 1870 } 1848 1871 1849 _ Noreturn void async_manager(void)1872 __noreturn void async_manager(void) 1850 1873 { 1851 1874 futex_lock(&async_futex); -
uspace/lib/c/generic/fibril_synch.c
r1a9174e rd3b2ffa 44 44 #include <stdlib.h> 45 45 #include <stdio.h> 46 #include <io/kio.h> 47 46 48 #include "private/async.h" 47 49 #include "private/fibril.h" 50 51 static fibril_local bool deadlocked = false; 48 52 49 53 static void optimize_execution_power(void) … … 62 66 { 63 67 fibril_t *f = (fibril_t *) fibril_get_id(); 68 69 if (deadlocked) { 70 kio_printf("Deadlock detected while printing deadlock. Aborting.\n"); 71 abort(); 72 } 73 deadlocked = true; 64 74 65 75 printf("Deadlock detected.\n"); -
uspace/lib/c/generic/ubsan.c
r1a9174e rd3b2ffa 98 98 #endif 99 99 void __ubsan_handle_nonnull_return(struct nonnull_return_data *data); 100 void __ubsan_handle_builtin_unreachable(struct unreachable_data *data); 100 101 101 102 static void print_loc(const char *func, struct source_location *loc) … … 107 108 f += sizeof(func_prefix); 108 109 109 PRINTF(" Undefined behavior %s at %s:%" PRIu32 " col %" PRIu32 "\n",110 PRINTF("####### Undefined behavior %s at %s:%" PRIu32 " col %" PRIu32 "\n", 110 111 f, loc->file_name, loc->line, loc->column); 111 112 } … … 115 116 { 116 117 print_loc(__func__, &data->loc); 118 PRINTF("Type: %s, alignment: %lu, type_check_kind: %hhu\n", 119 data->type->type_name, data->alignment, data->type_check_kind); 117 120 ubsan_panic(); 118 121 } … … 219 222 ubsan_panic(); 220 223 } 224 225 void __ubsan_handle_builtin_unreachable(struct unreachable_data *data) 226 { 227 print_loc(__func__, &data->loc); 228 ubsan_panic(); 229 } 230 -
uspace/lib/c/include/async.h
r1a9174e rd3b2ffa 51 51 #include <abi/cap.h> 52 52 53 #include <_bits/__noreturn.h> 54 53 55 typedef sysarg_t aid_t; 54 56 typedef sysarg_t port_id_t; … … 108 110 typedef struct async_exch async_exch_t; 109 111 110 extern _ Noreturn void async_manager(void);112 extern __noreturn void async_manager(void); 111 113 112 114 #define async_get_call(data) \ -
uspace/lib/c/include/futex.h
r1a9174e rd3b2ffa 45 45 atomic_t val; 46 46 #ifdef CONFIG_DEBUG_FUTEX 47 _Atomicvoid *owner;47 void *owner; 48 48 #endif 49 49 } futex_t; -
uspace/lib/c/include/setjmp.h
r1a9174e rd3b2ffa 35 35 36 36 #include <libarch/fibril_context.h> 37 #include <_bits/__noreturn.h> 37 38 38 39 typedef context_t jmp_buf[1]; 39 40 40 41 extern int __setjmp(jmp_buf) __attribute__((returns_twice)); 41 extern _ Noreturn void __longjmp(jmp_buf, int);42 extern __noreturn void __longjmp(jmp_buf, int); 42 43 43 44 #define setjmp __setjmp 44 extern _ Noreturn void longjmp(jmp_buf, int);45 extern __noreturn void longjmp(jmp_buf, int); 45 46 46 47 #endif -
uspace/lib/drv/generic/remote_usb.c
r1a9174e rd3b2ffa 77 77 return EBADMEM; 78 78 79 usb_device_desc_t tmp_desc;79 sysarg_t address, depth, speed, handle, iface; 80 80 81 81 const errno_t ret = async_req_1_5(exch, DEV_IFACE_ID(USB_DEV_IFACE), 82 IPC_M_USB_GET_MY_DESCRIPTION, 83 (sysarg_t *) &tmp_desc.address, 84 (sysarg_t *) &tmp_desc.depth, 85 (sysarg_t *) &tmp_desc.speed, 86 &tmp_desc.handle, 87 (sysarg_t *) &tmp_desc.iface); 88 if (ret == EOK && desc) 89 *desc = tmp_desc; 82 IPC_M_USB_GET_MY_DESCRIPTION, &address, &depth, &speed, &handle, 83 &iface); 84 if (ret == EOK && desc) { 85 *desc = (usb_device_desc_t) { 86 .address = address, 87 .depth = depth, 88 .speed = speed, 89 .handle = handle, 90 .iface = iface, 91 }; 92 } 93 90 94 return ret; 91 95 } -
uspace/lib/softfloat/common.c
r1a9174e rd3b2ffa 252 252 int j; 253 253 for (j = 0; j < 32; j += 8) { 254 if (i & (0xFF << (24 - j))) {254 if (i & (0xFFu << (24 - j))) { 255 255 return (j + count_zeroes8(i >> (24 - j))); 256 256 } -
uspace/lib/usb/include/usb/request.h
r1a9174e rd3b2ffa 75 75 #define USB_SETUP_PACKET_SIZE 8 76 76 77 /** Device request setup packet.78 * The setup packet describes the request.79 */80 typedef struct {81 /** Request type.82 * The type combines transfer direction, request type and83 * intended recipient.84 */85 uint8_t request_type;86 77 #define SETUP_REQUEST_TYPE_DEVICE_TO_HOST (1 << 7) 87 78 #define SETUP_REQUEST_TYPE_HOST_TO_DEVICE (0 << 7) … … 94 85 (uint8_t)(((type & 0x3) << 5) | (recipient & 0x1f)) 95 86 96 /** Request identification. */ 97 uint8_t request; 98 /** Main parameter to the request. */ 99 union __attribute__((packed)) { 100 uint16_t value; 101 /* FIXME: add #ifdefs according to host endianness */ 102 struct __attribute__((packed)) { 103 uint8_t value_low; 104 uint8_t value_high; 87 /** Device request setup packet. 88 * The setup packet describes the request. 89 */ 90 typedef union { 91 struct __attribute__((packed)) { 92 /** Request type. 93 * The type combines transfer direction, request type and 94 * intended recipient. 95 */ 96 uint8_t request_type; 97 98 /** Request identification. */ 99 uint8_t request; 100 /** Main parameter to the request. */ 101 union __attribute__((packed)) { 102 uint16_t value; 103 /* FIXME: add #ifdefs according to host endianness */ 104 struct __attribute__((packed)) { 105 uint8_t value_low; 106 uint8_t value_high; 107 }; 105 108 }; 109 /** Auxiliary parameter to the request. 110 * Typically, it is offset to something. 111 */ 112 uint16_t index; 113 /** Length of extra data. */ 114 uint16_t length; 106 115 }; 107 /** Auxiliary parameter to the request. 108 * Typically, it is offset to something. 109 */ 110 uint16_t index; 111 /** Length of extra data. */ 112 uint16_t length; 116 uint64_t raw; 113 117 } __attribute__((packed)) usb_device_request_setup_packet_t; 114 118 -
uspace/lib/usbhost/src/usb2_bus.c
r1a9174e rd3b2ffa 142 142 usb_log_debug("Device(%d): Setting USB address.", address); 143 143 err = bus_device_send_batch_sync(dev, usb2_default_target, USB_DIRECTION_OUT, 144 NULL, 0, *(uint64_t *)&set_address, "set address", NULL);144 NULL, 0, set_address.raw, "set address", NULL); 145 145 if (err) { 146 146 usb_log_error("Device(%d): Failed to set new address: %s.", -
uspace/lib/virtio/virtio-pci.h
r1a9174e rd3b2ffa 181 181 } virtio_dev_t; 182 182 183 extern errno_t virtio_setup_dma_bufs(unsigned int, size_t, bool, void *[], 184 uintptr_t []); 185 extern void virtio_teardown_dma_bufs(void *[]); 186 183 187 extern void virtio_virtq_desc_set(virtio_dev_t *vdev, uint16_t, uint16_t, 184 188 uint64_t, uint32_t, uint16_t, uint16_t); … … 186 190 uint16_t); 187 191 192 extern void virtio_create_desc_free_list(virtio_dev_t *, uint16_t, uint16_t, 193 uint16_t *); 194 extern uint16_t virtio_alloc_desc(virtio_dev_t *, uint16_t, uint16_t *); 195 extern void virtio_free_desc(virtio_dev_t *, uint16_t, uint16_t *, uint16_t); 196 188 197 extern void virtio_virtq_produce_available(virtio_dev_t *, uint16_t, uint16_t); 189 198 extern bool virtio_virtq_consume_used(virtio_dev_t *, uint16_t, uint16_t *, -
uspace/lib/virtio/virtio.c
r1a9174e rd3b2ffa 39 39 #include <libarch/barrier.h> 40 40 41 /** Allocate DMA buffers 42 * 43 * @param buffers[in] Number of buffers to allocate. 44 * @param size[in] Size of each buffer. 45 * @param write[in] True if the buffers are writable by the driver, false 46 * otherwise. 47 * @param buf[out] Output array holding virtual addresses of the allocated 48 * buffers. 49 * @param buf_p[out] Output array holding physical addresses of the allocated 50 * buffers. 51 * 52 * The buffers can be deallocated by virtio_net_teardown_bufs(). 53 * 54 * @return EOK on success or error code. 55 */ 56 errno_t virtio_setup_dma_bufs(unsigned int buffers, size_t size, 57 bool write, void *buf[], uintptr_t buf_p[]) 58 { 59 /* 60 * Allocate all buffers at once in one large chunk. 61 */ 62 void *virt = AS_AREA_ANY; 63 uintptr_t phys; 64 errno_t rc = dmamem_map_anonymous(buffers * size, 0, 65 write ? AS_AREA_WRITE : AS_AREA_READ, 0, &phys, &virt); 66 if (rc != EOK) 67 return rc; 68 69 ddf_msg(LVL_NOTE, "DMA buffers: %p-%p", virt, virt + buffers * size); 70 71 /* 72 * Calculate addresses of the individual buffers for easy access. 73 */ 74 for (unsigned i = 0; i < buffers; i++) { 75 buf[i] = virt + i * size; 76 buf_p[i] = phys + i * size; 77 } 78 79 return EOK; 80 } 81 82 /** Deallocate DMA buffers 83 * 84 * @param buf[in] Array holding the virtual addresses of the DMA buffers 85 * previously allocated by virtio_net_setup_bufs(). 86 */ 87 extern void virtio_teardown_dma_bufs(void *buf[]) 88 { 89 if (buf[0]) { 90 dmamem_unmap_anonymous(buf[0]); 91 buf[0] = NULL; 92 } 93 } 94 41 95 void virtio_virtq_desc_set(virtio_dev_t *vdev, uint16_t num, uint16_t descno, 42 96 uint64_t addr, uint32_t len, uint16_t flags, uint16_t next) … … 57 111 return pio_read_le16(&d->next); 58 112 } 113 114 /** Create free descriptor list from the unused VIRTIO descriptors 115 * 116 * @param vdev[in] VIRTIO device for which the free list will be created. 117 * @param num[in] Index of the virtqueue for which the free list will be 118 * created. 119 * @param size[in] Number of descriptors on the free list. The free list will 120 * contain descriptors starting from 0 to \a size - 1. 121 * @param head[out] Variable that will hold the VIRTIO descriptor at the head 122 * of the free list. 123 */ 124 void virtio_create_desc_free_list(virtio_dev_t *vdev, uint16_t num, 125 uint16_t size, uint16_t *head) 126 { 127 for (unsigned i = 0; i < size; i++) { 128 virtio_virtq_desc_set(vdev, num, i, 0, 0, 129 VIRTQ_DESC_F_NEXT, (i + 1 == size) ? -1U : i + 1); 130 } 131 *head = 0; 132 } 133 134 /** Allocate a descriptor from the free list 135 * 136 * @param vdev[in] VIRTIO device with the free list. 137 * @param num[in] Index of the virtqueue with free list. 138 * @param head[in,out] Head of the free list. 139 * 140 * @return Allocated descriptor or 0xFFFF if the list is empty. 141 */ 142 uint16_t virtio_alloc_desc(virtio_dev_t *vdev, uint16_t num, uint16_t *head) 143 { 144 virtq_t *q = &vdev->queues[num]; 145 fibril_mutex_lock(&q->lock); 146 uint16_t descno = *head; 147 if (descno != (uint16_t) -1U) 148 *head = virtio_virtq_desc_get_next(vdev, num, descno); 149 fibril_mutex_unlock(&q->lock); 150 return descno; 151 } 152 153 /** Free a descriptor into the free list 154 * 155 * @param vdev[in] VIRTIO device with the free list. 156 * @param num[in] Index of the virtqueue with free list. 157 * @param head[in,out] Head of the free list. 158 * @param descno[in] The freed descriptor. 159 */ 160 void virtio_free_desc(virtio_dev_t *vdev, uint16_t num, uint16_t *head, 161 uint16_t descno) 162 { 163 virtq_t *q = &vdev->queues[num]; 164 fibril_mutex_lock(&q->lock); 165 virtio_virtq_desc_set(vdev, num, descno, 0, 0, VIRTQ_DESC_F_NEXT, 166 *head); 167 *head = descno; 168 fibril_mutex_unlock(&q->lock); 169 } 170 59 171 60 172 void virtio_virtq_produce_available(virtio_dev_t *vdev, uint16_t num,
Note:
See TracChangeset
for help on using the changeset viewer.