From 62bee620cc95f8acdff018a85a402f23b294049a Mon Sep 17 00:00:00 2001 From: Jan Pochyla Date: Tue, 7 Jan 2020 18:56:49 +0100 Subject: [PATCH 1/8] core: upgrade micropython to 1.12 --- vendor/micropython | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vendor/micropython b/vendor/micropython index 64236f551..f1b8c2460 160000 --- a/vendor/micropython +++ b/vendor/micropython @@ -1 +1 @@ -Subproject commit 64236f5518b443c3f7631a4d6b31e2c8ccc385f4 +Subproject commit f1b8c2460a76ef58aa088de872ea53edcdcc313d From 5aca68e50cf97db7b976867daed9c46ba3adc080 Mon Sep 17 00:00:00 2001 From: Jan Pochyla Date: Tue, 17 Dec 2019 19:24:08 +0100 Subject: [PATCH 2/8] core: generate moduledefs.h for micropython --- core/SConscript.firmware | 28 +++++++++++++++++++--------- core/SConscript.unix | 28 +++++++++++++++++++--------- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/core/SConscript.firmware b/core/SConscript.firmware index a58aa9af6..ae928546e 100644 --- a/core/SConscript.firmware +++ b/core/SConscript.firmware @@ -401,15 +401,6 @@ env.Replace( MPY_CROSS='vendor/micropython/mpy-cross/mpy-cross -O' + PYOPT ) -# -# Micropython version -# - -hdr_version = env.Command( - target='genhdr/mpversion.h', - source='', - action='$MAKEVERSIONHDR $TARGET', ) - # # Qstrings # @@ -428,6 +419,25 @@ qstr_generated = env.GenerateQstrDefs( env.Ignore(qstr_collected, qstr_generated) +# +# Micropython version and modules +# + +hdr_version = env.Command( + target='genhdr/mpversion.h', + source='', + action='$MAKEVERSIONHDR $TARGET', ) + +hdr_moduledefs = env.Command( + target='genhdr/moduledefs.h', + source=SOURCE_QSTR, + action='$MAKEMODULEDEFS --vpath="." $SOURCES > $TARGET', ) + +env.Ignore(hdr_moduledefs, hdr_moduledefs) +env.Ignore(hdr_moduledefs, qstr_collected) +env.Ignore(hdr_moduledefs, qstr_preprocessed) +env.Ignore(hdr_moduledefs, qstr_generated) + # # Frozen modules # diff --git a/core/SConscript.unix b/core/SConscript.unix index f3d86722a..a9286a61d 100644 --- a/core/SConscript.unix +++ b/core/SConscript.unix @@ -364,15 +364,6 @@ env.Replace( MPY_CROSS='vendor/micropython/mpy-cross/mpy-cross -O' + PYOPT ) -# -# Micropython version -# - -hdr_version = env.Command( - target='genhdr/mpversion.h', - source='', - action='$MAKEVERSIONHDR $TARGET', ) - # # Qstrings # @@ -391,6 +382,25 @@ qstr_generated = env.GenerateQstrDefs( env.Ignore(qstr_collected, qstr_generated) +# +# Micropython version and modules +# + +hdr_version = env.Command( + target='genhdr/mpversion.h', + source='', + action='$MAKEVERSIONHDR $TARGET', ) + +hdr_moduledefs = env.Command( + target='genhdr/moduledefs.h', + source=SOURCE_QSTR, + action='$MAKEMODULEDEFS --vpath="." $SOURCES > $TARGET', ) + +env.Ignore(hdr_moduledefs, hdr_moduledefs) +env.Ignore(hdr_moduledefs, qstr_collected) +env.Ignore(hdr_moduledefs, qstr_preprocessed) +env.Ignore(hdr_moduledefs, qstr_generated) + # # Frozen modules # From f52681860328ae0d8f40cdd310f21946c023d2ca Mon Sep 17 00:00:00 2001 From: Jan Pochyla Date: Tue, 7 Jan 2020 17:53:06 +0100 Subject: [PATCH 3/8] core: remove qstr blacklist As its no longer needed. Mirrors micropython change a09fd0475. --- core/site_scons/site_tools/micropython/qstrdefs.py | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/core/site_scons/site_tools/micropython/qstrdefs.py b/core/site_scons/site_tools/micropython/qstrdefs.py index 5e4e1f2bb..8560ec73b 100644 --- a/core/site_scons/site_tools/micropython/qstrdefs.py +++ b/core/site_scons/site_tools/micropython/qstrdefs.py @@ -1,17 +1,14 @@ import re import sys -QSTR_BLACKLIST = set(['NULL', 'number_of']) - def process(source, target): - re_qstr = re.compile(r'MP_QSTR_[_a-zA-Z0-9]+') + re_qstr = re.compile(r"MP_QSTR_[_a-zA-Z0-9]+") for line in source: for match in re_qstr.findall(line): - name = match.replace('MP_QSTR_', '') - if name not in QSTR_BLACKLIST: - target.write('Q(%s)\n' % name) + name = match.replace("MP_QSTR_", "") + target.write("Q(%s)\n" % name) -if __name__ == '__main__': +if __name__ == "__main__": process(sys.stdin, sys.stdout) From 6afff3cc0e9997526932dbae69c80c50e15e9f4f Mon Sep 17 00:00:00 2001 From: Jan Pochyla Date: Tue, 7 Jan 2020 17:59:22 +0100 Subject: [PATCH 4/8] core/loop: remove unused code --- core/src/trezor/loop.py | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/core/src/trezor/loop.py b/core/src/trezor/loop.py index 82aacdf32..c88909edc 100644 --- a/core/src/trezor/loop.py +++ b/core/src/trezor/loop.py @@ -9,7 +9,6 @@ See `schedule`, `run`, and syscalls `sleep`, `wait`, `signal` and `race`. import utime import utimeq -from micropython import const from trezor import io, log @@ -43,13 +42,6 @@ _paused = {} # type: Dict[int, Set[Task]] _finalizers = {} # type: Dict[int, Finalizer] if __debug__: - # for performance stats - import array - - log_delay_pos = 0 - log_delay_rb_len = const(10) - log_delay_rb = array.array("i", [0] * log_delay_rb_len) - # synthetic event queue synthetic_events = [] # type: List[Tuple[int, Any]] @@ -108,12 +100,6 @@ def run() -> None: Tasks yield back to the scheduler on any I/O, usually by calling `await` on a `Syscall`. """ - - if __debug__: - global log_delay_pos - - max_delay = const(1000000) # usec delay if queue is empty - task_entry = [0, 0, 0] # deadline, task, value msg_entry = [0, 0] # iface | flags, value while _queue or _paused: @@ -121,13 +107,9 @@ def run() -> None: if _queue: delay = utime.ticks_diff(_queue.peektime(), utime.ticks_us()) else: - delay = max_delay + delay = 1000000 # wait for 1 sec maximum if queue is empty if __debug__: - # add current delay to ring buffer for performance stats - log_delay_rb[log_delay_pos] = delay - log_delay_pos = (log_delay_pos + 1) % log_delay_rb_len - # process synthetic events if synthetic_events: iface, event = synthetic_events[0] From ecc4313a340056a9427758c6d3a0200acb3f3bc3 Mon Sep 17 00:00:00 2001 From: Jan Pochyla Date: Tue, 7 Jan 2020 18:42:23 +0100 Subject: [PATCH 5/8] core/usb: avoid naks in hid/webusb rx interfaces --- core/embed/trezorhal/usb.c | 14 ----------- core/embed/trezorhal/usb_hid-impl.h | 34 +++++++++++--------------- core/embed/trezorhal/usb_webusb-impl.h | 34 +++++++++++--------------- 3 files changed, 28 insertions(+), 54 deletions(-) diff --git a/core/embed/trezorhal/usb.c b/core/embed/trezorhal/usb.c index 9e62c73e1..0183a70ce 100644 --- a/core/embed/trezorhal/usb.c +++ b/core/embed/trezorhal/usb.c @@ -179,20 +179,6 @@ static void usb_desc_add_iface(size_t desc_len) { usb_config_desc->wTotalLength); } -static uint8_t usb_ep_set_nak(USBD_HandleTypeDef *dev, uint8_t ep_num) { - PCD_HandleTypeDef *hpcd = dev->pData; - USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; - USBx_OUTEP(ep_num)->DOEPCTL |= USB_OTG_DOEPCTL_SNAK; - return USBD_OK; -} - -static uint8_t usb_ep_clear_nak(USBD_HandleTypeDef *dev, uint8_t ep_num) { - PCD_HandleTypeDef *hpcd = dev->pData; - USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; - USBx_OUTEP(ep_num)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; - return USBD_OK; -} - /* * USB interface implementations */ diff --git a/core/embed/trezorhal/usb_hid-impl.h b/core/embed/trezorhal/usb_hid-impl.h index b893a5548..d08be2a78 100644 --- a/core/embed/trezorhal/usb_hid-impl.h +++ b/core/embed/trezorhal/usb_hid-impl.h @@ -158,20 +158,23 @@ int usb_hid_read(uint8_t iface_num, uint8_t *buf, uint32_t len) { if (iface->type != USB_IFACE_TYPE_HID) { return -2; // Invalid interface type } - usb_hid_state_t *state = &iface->hid; + volatile usb_hid_state_t *state = &iface->hid; - // Copy maximum possible amount of data and truncate the buffer length - if (len < state->last_read_len) { + // Copy maximum possible amount of data + uint32_t last_read_len = state->last_read_len; + if (len < last_read_len) { return 0; // Not enough data in the read buffer } - len = state->last_read_len; + memcpy(buf, state->rx_buffer, last_read_len); + + // Reset the length to indicate we are ready to read next packet state->last_read_len = 0; - memcpy(buf, state->rx_buffer, len); - // Clear NAK to indicate we are ready to read more data - usb_ep_clear_nak(&usb_dev_handle, state->ep_out); + // Prepare the OUT EP to receive next packet + USBD_LL_PrepareReceive(&usb_dev_handle, state->ep_out, state->rx_buffer, + state->max_packet_len); - return len; + return last_read_len; } int usb_hid_write(uint8_t iface_num, const uint8_t *buf, uint32_t len) { @@ -182,7 +185,7 @@ int usb_hid_write(uint8_t iface_num, const uint8_t *buf, uint32_t len) { if (iface->type != USB_IFACE_TYPE_HID) { return -2; // Invalid interface type } - usb_hid_state_t *state = &iface->hid; + volatile usb_hid_state_t *state = &iface->hid; if (state->ep_in_is_idle == 0) { return 0; // Last transmission is not over yet @@ -344,17 +347,8 @@ static void usb_hid_class_data_in(USBD_HandleTypeDef *dev, static void usb_hid_class_data_out(USBD_HandleTypeDef *dev, usb_hid_state_t *state, uint8_t ep_num) { if (ep_num == state->ep_out) { + // Save the report length to indicate we have read something, but don't + // schedule next reading until user reads this one state->last_read_len = USBD_LL_GetRxDataSize(dev, ep_num); - - // Prepare the OUT EP to receive next packet - // User should provide state->rx_buffer that is big enough for - // state->max_packet_len bytes - USBD_LL_PrepareReceive(dev, ep_num, state->rx_buffer, - state->max_packet_len); - - if (state->last_read_len > 0) { - // Block the OUT EP until we process received data - usb_ep_set_nak(dev, ep_num); - } } } diff --git a/core/embed/trezorhal/usb_webusb-impl.h b/core/embed/trezorhal/usb_webusb-impl.h index e50ae866d..cfc08d4fa 100644 --- a/core/embed/trezorhal/usb_webusb-impl.h +++ b/core/embed/trezorhal/usb_webusb-impl.h @@ -134,20 +134,23 @@ int usb_webusb_read(uint8_t iface_num, uint8_t *buf, uint32_t len) { if (iface->type != USB_IFACE_TYPE_WEBUSB) { return -2; // Invalid interface type } - usb_webusb_state_t *state = &iface->webusb; + volatile usb_webusb_state_t *state = &iface->webusb; - // Copy maximum possible amount of data and truncate the buffer length - if (len < state->last_read_len) { + // Copy maximum possible amount of data + uint32_t last_read_len = state->last_read_len; + if (len < last_read_len) { return 0; // Not enough data in the read buffer } - len = state->last_read_len; + memcpy(buf, state->rx_buffer, last_read_len); + + // Reset the length to indicate we are ready to read next packet state->last_read_len = 0; - memcpy(buf, state->rx_buffer, len); - // Clear NAK to indicate we are ready to read more data - usb_ep_clear_nak(&usb_dev_handle, state->ep_out); + // Prepare the OUT EP to receive next packet + USBD_LL_PrepareReceive(&usb_dev_handle, state->ep_out, state->rx_buffer, + state->max_packet_len); - return len; + return last_read_len; } int usb_webusb_write(uint8_t iface_num, const uint8_t *buf, uint32_t len) { @@ -158,7 +161,7 @@ int usb_webusb_write(uint8_t iface_num, const uint8_t *buf, uint32_t len) { if (iface->type != USB_IFACE_TYPE_WEBUSB) { return -2; // Invalid interface type } - usb_webusb_state_t *state = &iface->webusb; + volatile usb_webusb_state_t *state = &iface->webusb; state->ep_in_is_idle = 0; USBD_LL_Transmit(&usb_dev_handle, state->ep_in, UNCONST(buf), (uint16_t)len); @@ -268,17 +271,8 @@ static void usb_webusb_class_data_out(USBD_HandleTypeDef *dev, usb_webusb_state_t *state, uint8_t ep_num) { if (ep_num == state->ep_out) { + // Save the report length to indicate we have read something, but don't + // schedule next reading until user reads this one state->last_read_len = USBD_LL_GetRxDataSize(dev, ep_num); - - // Prepare the OUT EP to receive next packet - // User should provide state->rx_buffer that is big enough for - // state->max_packet_len bytes - USBD_LL_PrepareReceive(dev, ep_num, state->rx_buffer, - state->max_packet_len); - - if (state->last_read_len > 0) { - // Block the OUT EP until we process received data - usb_ep_set_nak(dev, ep_num); - } } } From 7deade5a1054808c014bde7537b770a94dfe7cbd Mon Sep 17 00:00:00 2001 From: Jan Pochyla Date: Tue, 7 Jan 2020 20:21:04 +0100 Subject: [PATCH 6/8] core/firmware: PendSV_Handler is defined in pendsv.c --- core/embed/firmware/main.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/core/embed/firmware/main.c b/core/embed/firmware/main.c index 73f63cdad..216225d32 100644 --- a/core/embed/firmware/main.c +++ b/core/embed/firmware/main.c @@ -139,8 +139,6 @@ void UsageFault_Handler(void) { error_shutdown("Internal error", "(UF)", NULL, NULL); } -void PendSV_Handler(void) { pendsv_isr_handler(); } - void SVC_C_Handler(uint32_t *stack) { uint8_t svc_number = ((uint8_t *)stack[6])[-2]; switch (svc_number) { From 87e7d43068e0b096549b4d4209cb314fdc4f7128 Mon Sep 17 00:00:00 2001 From: Jan Pochyla Date: Tue, 7 Jan 2020 20:21:34 +0100 Subject: [PATCH 7/8] core/firmware: gchelper.s moved to different directory --- core/SConscript.firmware | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/SConscript.firmware b/core/SConscript.firmware index ae928546e..367ae96b8 100644 --- a/core/SConscript.firmware +++ b/core/SConscript.firmware @@ -172,12 +172,12 @@ SOURCE_MICROPYTHON = [ 'vendor/micropython/extmod/utime_mphal.c', 'vendor/micropython/lib/embed/abort_.c', 'vendor/micropython/lib/mp-readline/readline.c', + 'vendor/micropython/lib/utils/gchelper_m3.s', 'vendor/micropython/lib/utils/interrupt_char.c', 'vendor/micropython/lib/utils/printf.c', 'vendor/micropython/lib/utils/pyexec.c', 'vendor/micropython/lib/utils/stdout_helpers.c', 'vendor/micropython/ports/stm32/gccollect.c', - 'vendor/micropython/ports/stm32/gchelper.s', 'vendor/micropython/ports/stm32/pendsv.c', 'vendor/micropython/py/argcheck.c', 'vendor/micropython/py/asmarm.c', From 655ec0a70c51cbbd4ecdf340fc3fac1ee56ec510 Mon Sep 17 00:00:00 2001 From: Jan Pochyla Date: Tue, 7 Jan 2020 20:22:07 +0100 Subject: [PATCH 8/8] core/unix: update main.c from upy 1.12 --- core/embed/unix/main.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/core/embed/unix/main.c b/core/embed/unix/main.c index 8c158f07f..c14049d26 100644 --- a/core/embed/unix/main.c +++ b/core/embed/unix/main.c @@ -141,8 +141,7 @@ STATIC int execute_from_lexer(int source_kind, const void *source, } #endif - mp_obj_t module_fun = - mp_compile(&parse_tree, source_name, emit_opt, is_repl); + mp_obj_t module_fun = mp_compile(&parse_tree, source_name, is_repl); if (!compile_only) { // execute it @@ -320,7 +319,12 @@ STATIC int usage(char **argv) { int impl_opts_cnt = 0; printf( " compile-only -- parse and compile only\n" - " emit={bytecode,native,viper} -- set the default code emitter\n"); +#if MICROPY_EMIT_NATIVE + " emit={bytecode,native,viper} -- set the default code emitter\n" +#else + " emit=bytecode -- set the default code emitter\n" +#endif + ); impl_opts_cnt++; #if MICROPY_ENABLE_GC printf( @@ -349,10 +353,12 @@ STATIC void pre_process_options(int argc, char **argv) { compile_only = true; } else if (strcmp(argv[a + 1], "emit=bytecode") == 0) { emit_opt = MP_EMIT_OPT_BYTECODE; +#if MICROPY_EMIT_NATIVE } else if (strcmp(argv[a + 1], "emit=native") == 0) { emit_opt = MP_EMIT_OPT_NATIVE_PYTHON; } else if (strcmp(argv[a + 1], "emit=viper") == 0) { emit_opt = MP_EMIT_OPT_VIPER; +#endif #if MICROPY_ENABLE_GC } else if (strncmp(argv[a + 1], "heapsize=", sizeof("heapsize=") - 1) == 0) { @@ -505,7 +511,7 @@ MP_NOINLINE int main_(int argc, char **argv) { vstr_add_strn(&vstr, p + 1, p1 - p - 1); path_items[i] = mp_obj_new_str_from_vstr(&mp_type_str, &vstr); } else { - path_items[i] = MP_OBJ_NEW_QSTR(qstr_from_strn(p, p1 - p)); + path_items[i] = mp_obj_new_str_via_qstr(p, p1 - p); } p = p1 + 1; } @@ -633,7 +639,7 @@ MP_NOINLINE int main_(int argc, char **argv) { // Set base dir of the script as first entry in sys.path char *p = strrchr(basedir, '/'); - path_items[0] = MP_OBJ_NEW_QSTR(qstr_from_strn(basedir, p - basedir)); + path_items[0] = mp_obj_new_str_via_qstr(basedir, p - basedir); free(pathbuf); set_sys_argv(argv, argc, a); @@ -652,6 +658,18 @@ MP_NOINLINE int main_(int argc, char **argv) { } } +#if MICROPY_PY_SYS_SETTRACE + MP_STATE_THREAD(prof_trace_callback) = MP_OBJ_NULL; +#endif + +#if MICROPY_PY_SYS_ATEXIT + // Beware, the sys.settrace callback should be disabled before running + // sys.atexit. + if (mp_obj_is_callable(MP_STATE_VM(sys_exitfunc))) { + mp_call_function_0(MP_STATE_VM(sys_exitfunc)); + } +#endif + #if MICROPY_PY_MICROPYTHON_MEM_INFO char *env_str_trezor_log_memory = getenv("TREZOR_LOG_MEMORY"); if (!env_str_trezor_log_memory || atoi(env_str_trezor_log_memory) == 0) {