@@ -699,6 +699,99 @@ STATIC mp_obj_t esp_esf_free_bufs(mp_obj_t idx_in) {
699699}
700700STATIC MP_DEFINE_CONST_FUN_OBJ_1 (esp_esf_free_bufs_obj , esp_esf_free_bufs );
701701
702+ #if MICROPY_EMIT_XTENSA
703+
704+ // We provide here a way of committing executable data to a region from
705+ // which it can be executed by the CPU. There are 2 such writable regions:
706+ // - iram1, which may have some space left at the end of it
707+ // - memory-mapped flash rom
708+ //
709+ // By default the iram1 region (the space at the end of it) is used. The
710+ // user can select iram1 or a section of flash by calling the
711+ // esp.set_native_code_location() function; see below. If flash is selected
712+ // then it is erased as needed.
713+
714+ #define IRAM1_END (0x40108000)
715+ #define FLASH_START (0x40200000)
716+ #define FLASH_END (0x40300000)
717+ #define FLASH_SEC_SIZE (4096)
718+
719+ #define ESP_NATIVE_CODE_IRAM1 (0)
720+ #define ESP_NATIVE_CODE_FLASH (1)
721+
722+ extern uint32_t _lit4_end ;
723+ STATIC uint32_t esp_native_code_location ;
724+ STATIC uint32_t esp_native_code_start ;
725+ STATIC uint32_t esp_native_code_end ;
726+ STATIC uint32_t esp_native_code_cur ;
727+ STATIC uint32_t esp_native_code_erased ;
728+
729+ void esp_native_code_init (void ) {
730+ esp_native_code_location = ESP_NATIVE_CODE_IRAM1 ;
731+ esp_native_code_start = (uint32_t )& _lit4_end ;
732+ esp_native_code_end = IRAM1_END ;
733+ esp_native_code_cur = esp_native_code_start ;
734+ esp_native_code_erased = 0 ;
735+ }
736+
737+ void * esp_native_code_commit (void * buf , size_t len ) {
738+ //printf("COMMIT(buf=%p, len=%u, start=%08x, cur=%08x, end=%08x, erased=%08x)\n", buf, len, esp_native_code_start, esp_native_code_cur, esp_native_code_end, esp_native_code_erased);
739+
740+ len = (len + 3 ) & ~3 ;
741+ if (esp_native_code_cur + len > esp_native_code_end ) {
742+ nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_MemoryError ,
743+ "memory allocation failed, allocating %u bytes for native code" , (uint )len ));
744+ }
745+
746+ void * dest ;
747+ if (esp_native_code_location == ESP_NATIVE_CODE_IRAM1 ) {
748+ dest = (void * )esp_native_code_cur ;
749+ memcpy (dest , buf , len );
750+ } else {
751+ SpiFlashOpResult res ;
752+ while (esp_native_code_erased < esp_native_code_cur + len ) {
753+ res = spi_flash_erase_sector (esp_native_code_erased / FLASH_SEC_SIZE );
754+ if (res != SPI_FLASH_RESULT_OK ) {
755+ break ;
756+ }
757+ esp_native_code_erased += FLASH_SEC_SIZE ;
758+ }
759+ if (res == SPI_FLASH_RESULT_OK ) {
760+ res = spi_flash_write (esp_native_code_cur , buf , len );
761+ }
762+ if (res != SPI_FLASH_RESULT_OK ) {
763+ mp_raise_OSError (res == SPI_FLASH_RESULT_TIMEOUT ? MP_ETIMEDOUT : MP_EIO );
764+ }
765+ dest = (void * )(FLASH_START + esp_native_code_cur );
766+ }
767+
768+ esp_native_code_cur += len ;
769+
770+ return dest ;
771+ }
772+
773+ STATIC mp_obj_t esp_set_native_code_location (mp_obj_t start_in , mp_obj_t len_in ) {
774+ if (start_in == mp_const_none && len_in == mp_const_none ) {
775+ // use end of iram1 region
776+ esp_native_code_init ();
777+ } else {
778+ // use flash; input params are byte offsets from start of flash
779+ esp_native_code_location = ESP_NATIVE_CODE_FLASH ;
780+ esp_native_code_start = mp_obj_get_int (start_in );
781+ esp_native_code_end = esp_native_code_start + mp_obj_get_int (len_in );
782+ esp_native_code_cur = esp_native_code_start ;
783+ esp_native_code_erased = esp_native_code_start ;
784+ // memory-mapped flash is limited in extents to 1MByte
785+ if (esp_native_code_end > FLASH_END - FLASH_START ) {
786+ mp_raise_ValueError ("flash location must be below 1MByte" );
787+ }
788+ }
789+ return mp_const_none ;
790+ }
791+ STATIC MP_DEFINE_CONST_FUN_OBJ_2 (esp_set_native_code_location_obj , esp_set_native_code_location );
792+
793+ #endif
794+
702795STATIC const mp_map_elem_t esp_module_globals_table [] = {
703796 { MP_OBJ_NEW_QSTR (MP_QSTR___name__ ), MP_OBJ_NEW_QSTR (MP_QSTR_esp ) },
704797
@@ -729,6 +822,9 @@ STATIC const mp_map_elem_t esp_module_globals_table[] = {
729822 { MP_OBJ_NEW_QSTR (MP_QSTR_malloc ), (mp_obj_t )& esp_malloc_obj },
730823 { MP_OBJ_NEW_QSTR (MP_QSTR_free ), (mp_obj_t )& esp_free_obj },
731824 { MP_OBJ_NEW_QSTR (MP_QSTR_esf_free_bufs ), (mp_obj_t )& esp_esf_free_bufs_obj },
825+ #if MICROPY_EMIT_XTENSA
826+ { MP_OBJ_NEW_QSTR (MP_QSTR_set_native_code_location ), (mp_obj_t )& esp_set_native_code_location_obj },
827+ #endif
732828
733829#if MODESP_INCLUDE_CONSTANTS
734830 { MP_OBJ_NEW_QSTR (MP_QSTR_SLEEP_NONE ),
0 commit comments