From 8a636bd9cfc82d6f2181f206b33904a3ad592683 Mon Sep 17 00:00:00 2001 From: cepetr Date: Thu, 10 Apr 2025 17:57:49 +0200 Subject: [PATCH] fix(core): make mod_trezorio_poll return False only on timeout [no changelog] --- core/embed/projects/kernel/main.c | 2 +- .../sys/syscall/stm32/syscall_dispatch.c | 4 +- core/embed/sys/syscall/stm32/syscall_stubs.c | 4 +- .../sys/syscall/stm32/syscall_verifiers.c | 4 +- .../sys/syscall/stm32/syscall_verifiers.h | 2 +- core/embed/sys/task/inc/sys/sysevent.h | 4 +- core/embed/sys/task/sysevent.c | 4 +- .../upymod/modtrezorio/modtrezorio-poll.h | 197 +++++++++--------- 8 files changed, 113 insertions(+), 108 deletions(-) diff --git a/core/embed/projects/kernel/main.c b/core/embed/projects/kernel/main.c index 227734382d..0a5dbb8f87 100644 --- a/core/embed/projects/kernel/main.c +++ b/core/embed/projects/kernel/main.c @@ -186,7 +186,7 @@ static void kernel_loop(applet_t *coreapp) { sysevents_t awaited = {0}; sysevents_t signalled = {0}; - sysevents_poll(&awaited, &signalled, 100); + sysevents_poll(&awaited, &signalled, ticks_timeout(100)); } while (applet_is_alive(coreapp)); } diff --git a/core/embed/sys/syscall/stm32/syscall_dispatch.c b/core/embed/sys/syscall/stm32/syscall_dispatch.c index 26492f4aa0..7f38d0b7e9 100644 --- a/core/embed/sys/syscall/stm32/syscall_dispatch.c +++ b/core/embed/sys/syscall/stm32/syscall_dispatch.c @@ -157,9 +157,9 @@ __attribute((no_stack_protector)) void syscall_handler(uint32_t *args, case SYSCALL_SYSEVENTS_POLL: { const sysevents_t *awaited = (sysevents_t *)args[0]; sysevents_t *signalled = (sysevents_t *)args[1]; - uint32_t timeout = args[2]; + uint32_t deadline = args[2]; if (!g_in_app_callback) { - sysevents_poll__verified(awaited, signalled, timeout); + sysevents_poll__verified(awaited, signalled, deadline); } } break; diff --git a/core/embed/sys/syscall/stm32/syscall_stubs.c b/core/embed/sys/syscall/stm32/syscall_stubs.c index 95d2920a21..bd43f460b3 100644 --- a/core/embed/sys/syscall/stm32/syscall_stubs.c +++ b/core/embed/sys/syscall/stm32/syscall_stubs.c @@ -77,8 +77,8 @@ uint64_t systick_us_to_cycles(uint64_t us) { #include void sysevents_poll(const sysevents_t *awaited, sysevents_t *signalled, - uint32_t timeout) { - syscall_invoke3((uint32_t)awaited, (uint32_t)signalled, timeout, + uint32_t deadline) { + syscall_invoke3((uint32_t)awaited, (uint32_t)signalled, deadline, SYSCALL_SYSEVENTS_POLL); } diff --git a/core/embed/sys/syscall/stm32/syscall_verifiers.c b/core/embed/sys/syscall/stm32/syscall_verifiers.c index 784f36fe3c..53c724828c 100644 --- a/core/embed/sys/syscall/stm32/syscall_verifiers.c +++ b/core/embed/sys/syscall/stm32/syscall_verifiers.c @@ -46,7 +46,7 @@ // --------------------------------------------------------------------- void sysevents_poll__verified(const sysevents_t *awaited, - sysevents_t *signalled, uint32_t timeout) { + sysevents_t *signalled, uint32_t deadline) { if (!probe_read_access(awaited, sizeof(*awaited))) { goto access_violation; } @@ -55,7 +55,7 @@ void sysevents_poll__verified(const sysevents_t *awaited, goto access_violation; } - sysevents_poll(awaited, signalled, timeout); + sysevents_poll(awaited, signalled, deadline); return; access_violation: diff --git a/core/embed/sys/syscall/stm32/syscall_verifiers.h b/core/embed/sys/syscall/stm32/syscall_verifiers.h index b61ecf7058..6d53d7a979 100644 --- a/core/embed/sys/syscall/stm32/syscall_verifiers.h +++ b/core/embed/sys/syscall/stm32/syscall_verifiers.h @@ -25,7 +25,7 @@ #include void sysevents_poll__verified(const sysevents_t *awaited, - sysevents_t *signalled, uint32_t timeout); + sysevents_t *signalled, uint32_t deadline); // --------------------------------------------------------------------- #include diff --git a/core/embed/sys/task/inc/sys/sysevent.h b/core/embed/sys/task/inc/sys/sysevent.h index 3632d4db6e..e99bc1415d 100644 --- a/core/embed/sys/task/inc/sys/sysevent.h +++ b/core/embed/sys/task/inc/sys/sysevent.h @@ -46,11 +46,11 @@ typedef struct { } sysevents_t; // sys_events_t // Polls for the specified events. The function blocks until at least -// one event is signaled or the timeout (in milliseconds) expires. +// one event is signaled or deadline expires. // // Multiple events may be signaled simultaneously. // // Returns the events that were signaled. If the timeout expires, both // fields in the result are set to 0. void sysevents_poll(const sysevents_t* awaited, sysevents_t* signalled, - uint32_t timeout); + uint32_t deadline); diff --git a/core/embed/sys/task/sysevent.c b/core/embed/sys/task/sysevent.c index 49e2501169..b79eec43ec 100644 --- a/core/embed/sys/task/sysevent.c +++ b/core/embed/sys/task/sysevent.c @@ -157,7 +157,7 @@ static inline void insert_poller(sysevent_dispatcher_t *dispatcher, } void sysevents_poll(const sysevents_t *awaited, sysevents_t *signalled, - uint32_t timeout) { + uint32_t deadline) { sysevent_dispatcher_t *dispatcher = &g_sysevent_dispatcher; memset(signalled, 0, sizeof(*signalled)); @@ -177,7 +177,7 @@ void sysevents_poll(const sysevents_t *awaited, sysevents_t *signalled, dispatcher->pollers[prio].task = systask_active(); dispatcher->pollers[prio].awaited = awaited; dispatcher->pollers[prio].signalled = signalled; - dispatcher->pollers[prio].deadline = ticks_timeout(timeout); + dispatcher->pollers[prio].deadline = deadline; if (active_task != kernel_task) { systask_yield_to(kernel_task); diff --git a/core/embed/upymod/modtrezorio/modtrezorio-poll.h b/core/embed/upymod/modtrezorio/modtrezorio-poll.h index 7b6dee283a..69f9d4b2f4 100644 --- a/core/embed/upymod/modtrezorio/modtrezorio-poll.h +++ b/core/embed/upymod/modtrezorio/modtrezorio-poll.h @@ -115,121 +115,126 @@ STATIC mp_obj_t mod_trezorio_poll(mp_obj_t ifaces, mp_obj_t list_ref, // just coerce it to an uint. Deliberately assigning *get_int* to *uint_t* // will give us C's wrapping unsigned overflow behavior, and the `deadline` // result will come out correct. - const mp_uint_t timeout = MAX(trezor_obj_get_int(timeout_ms), 0); - sysevents_t signalled = {0}; + const mp_uint_t deadline = ticks_timeout(trezor_obj_get_int(timeout_ms)); - sysevents_poll(&awaited, &signalled, timeout); + for (;;) { + sysevents_t signalled = {0}; + sysevents_poll(&awaited, &signalled, deadline); + + if (signalled.read_ready == 0 && signalled.write_ready == 0) { + return mp_const_false; + } #ifdef USE_TOUCH - if (signalled.read_ready & (1 << SYSHANDLE_TOUCH)) { - const uint32_t evt = touch_get_event(); - if (evt != 0) { - // ignore TOUCH_MOVE events if they are too frequent - if ((evt & TOUCH_MOVE) == 0 || - (hal_ticks_ms() - last_touch_sample_time > 10)) { - last_touch_sample_time = hal_ticks_ms(); + if (signalled.read_ready & (1 << SYSHANDLE_TOUCH)) { + const uint32_t evt = touch_get_event(); + if (evt != 0) { + // ignore TOUCH_MOVE events if they are too frequent + if ((evt & TOUCH_MOVE) == 0 || + (hal_ticks_ms() - last_touch_sample_time > 10)) { + last_touch_sample_time = hal_ticks_ms(); - mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(3, NULL)); - const uint32_t etype = (evt >> 24) & 0xFFU; // event type - const uint32_t ex = (evt >> 12) & 0xFFFU; // x position - const uint32_t ey = evt & 0xFFFU; // y position - uint32_t exr; // rotated x position - uint32_t eyr; // rotated y position - switch (display_get_orientation()) { - case 90: - exr = ey; - eyr = DISPLAY_RESX - ex; - break; - case 180: - exr = DISPLAY_RESX - ex; - eyr = DISPLAY_RESY - ey; - break; - case 270: - exr = DISPLAY_RESY - ey; - eyr = ex; - break; - default: - exr = ex; - eyr = ey; - break; + mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(3, NULL)); + const uint32_t etype = (evt >> 24) & 0xFFU; // event type + const uint32_t ex = (evt >> 12) & 0xFFFU; // x position + const uint32_t ey = evt & 0xFFFU; // y position + uint32_t exr; // rotated x position + uint32_t eyr; // rotated y position + switch (display_get_orientation()) { + case 90: + exr = ey; + eyr = DISPLAY_RESX - ex; + break; + case 180: + exr = DISPLAY_RESX - ex; + eyr = DISPLAY_RESY - ey; + break; + case 270: + exr = DISPLAY_RESY - ey; + eyr = ex; + break; + default: + exr = ex; + eyr = ey; + break; + } + tuple->items[0] = MP_OBJ_NEW_SMALL_INT(etype); + tuple->items[1] = MP_OBJ_NEW_SMALL_INT(exr); + tuple->items[2] = MP_OBJ_NEW_SMALL_INT(eyr); + ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_TOUCH); + ret->items[1] = MP_OBJ_FROM_PTR(tuple); + return mp_const_true; + } + } + } +#endif + +#ifdef USE_BUTTON + if (signalled.read_ready & (1 << SYSHANDLE_BUTTON)) { + button_event_t btn_event = {0}; + if (button_get_event(&btn_event)) { + mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL)); + uint32_t etype = btn_event.event_type; + uint32_t en = btn_event.button; + if (display_get_orientation() == 180) { + en = (en == BTN_LEFT) ? BTN_RIGHT : BTN_LEFT; } tuple->items[0] = MP_OBJ_NEW_SMALL_INT(etype); - tuple->items[1] = MP_OBJ_NEW_SMALL_INT(exr); - tuple->items[2] = MP_OBJ_NEW_SMALL_INT(eyr); - ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_TOUCH); + tuple->items[1] = MP_OBJ_NEW_SMALL_INT(en); + ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_BUTTON); ret->items[1] = MP_OBJ_FROM_PTR(tuple); return mp_const_true; } } - } -#endif - -#ifdef USE_BUTTON - if (signalled.read_ready & (1 << SYSHANDLE_BUTTON)) { - button_event_t btn_event = {0}; - if (button_get_event(&btn_event)) { - mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL)); - uint32_t etype = btn_event.event_type; - uint32_t en = btn_event.button; - if (display_get_orientation() == 180) { - en = (en == BTN_LEFT) ? BTN_RIGHT : BTN_LEFT; - } - tuple->items[0] = MP_OBJ_NEW_SMALL_INT(etype); - tuple->items[1] = MP_OBJ_NEW_SMALL_INT(en); - ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_BUTTON); - ret->items[1] = MP_OBJ_FROM_PTR(tuple); - return mp_const_true; - } - } #endif #ifdef USE_BLE - if (signalled.read_ready & (1 << SYSHANDLE_BLE_IFACE_0)) { - ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_BLE_IFACE_0); - ret->items[1] = MP_OBJ_NEW_SMALL_INT(BLE_RX_PACKET_SIZE); - return mp_const_true; - } - - if (signalled.write_ready & (1 << SYSHANDLE_BLE_IFACE_0)) { - ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_BLE_IFACE_0 | POLL_WRITE); - ret->items[1] = mp_const_none; - return mp_const_true; - } - - if (signalled.read_ready & (1 << SYSHANDLE_BLE)) { - ble_event_t event = {0}; - if (ble_get_event(&event)) { - mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL)); - tuple->items[0] = MP_OBJ_NEW_SMALL_INT(event.type); - tuple->items[1] = parse_ble_event_data(&event); - ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_BLE); - ret->items[1] = MP_OBJ_FROM_PTR(tuple); - return mp_const_true; - } - } -#endif - - if (signalled.read_ready & (1 << SYSHANDLE_USB)) { - usb_event_t event = usb_get_event(); - ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_USB); - ret->items[1] = MP_OBJ_NEW_SMALL_INT((int32_t)event); - return mp_const_true; - } - - for (syshandle_t h = SYSHANDLE_USB_IFACE_0; h <= SYSHANDLE_USB_IFACE_7; h++) { - if (signalled.read_ready & (1 << h)) { - ret->items[0] = MP_OBJ_NEW_SMALL_INT(h); - ret->items[1] = MP_OBJ_NEW_SMALL_INT(USB_PACKET_LEN); + if (signalled.read_ready & (1 << SYSHANDLE_BLE_IFACE_0)) { + ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_BLE_IFACE_0); + ret->items[1] = MP_OBJ_NEW_SMALL_INT(BLE_RX_PACKET_SIZE); return mp_const_true; } - if (signalled.write_ready & (1 << h)) { - ret->items[0] = MP_OBJ_NEW_SMALL_INT(h | POLL_WRITE); + if (signalled.write_ready & (1 << SYSHANDLE_BLE_IFACE_0)) { + ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_BLE_IFACE_0 | POLL_WRITE); ret->items[1] = mp_const_none; return mp_const_true; } - } - return mp_const_false; + if (signalled.read_ready & (1 << SYSHANDLE_BLE)) { + ble_event_t event = {0}; + if (ble_get_event(&event)) { + mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(mp_obj_new_tuple(2, NULL)); + tuple->items[0] = MP_OBJ_NEW_SMALL_INT(event.type); + tuple->items[1] = parse_ble_event_data(&event); + ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_BLE); + ret->items[1] = MP_OBJ_FROM_PTR(tuple); + return mp_const_true; + } + } +#endif + + if (signalled.read_ready & (1 << SYSHANDLE_USB)) { + usb_event_t event = usb_get_event(); + ret->items[0] = MP_OBJ_NEW_SMALL_INT(SYSHANDLE_USB); + ret->items[1] = MP_OBJ_NEW_SMALL_INT((int32_t)event); + return mp_const_true; + } + + for (syshandle_t h = SYSHANDLE_USB_IFACE_0; h <= SYSHANDLE_USB_IFACE_7; + h++) { + if (signalled.read_ready & (1 << h)) { + ret->items[0] = MP_OBJ_NEW_SMALL_INT(h); + ret->items[1] = MP_OBJ_NEW_SMALL_INT(USB_PACKET_LEN); + return mp_const_true; + } + + if (signalled.write_ready & (1 << h)) { + ret->items[0] = MP_OBJ_NEW_SMALL_INT(h | POLL_WRITE); + ret->items[1] = mp_const_none; + return mp_const_true; + } + } + } } STATIC MP_DEFINE_CONST_FUN_OBJ_3(mod_trezorio_poll_obj, mod_trezorio_poll);