github.com/tinygo-org/tinygo@v0.31.3-0.20240404173401-90b0bf646c27/src/device/esp/esp32c3.S (about)

     1  // This is a very minimal bootloader for the ESP32-C3. It only initializes the
     2  // flash and then continues with the generic RISC-V initialization code, which
     3  // in turn will call runtime.main.
     4  // It is written in assembly (and not in a higher level language) to make sure
     5  // it is entirely loaded into IRAM and doesn't accidentally call functions
     6  // stored in IROM.
     7  //
     8  // For reference, here is a nice introduction into RISC-V assembly:
     9  // https://www.imperialviolet.org/2016/12/31/riscv.html
    10  
    11  .section .init
    12  .global call_start_cpu0
    13  .type call_start_cpu0,@function
    14  call_start_cpu0:
    15      // At this point:
    16      // - The ROM bootloader is finished and has jumped to here.
    17      // - We're running from IRAM: both IRAM and DRAM segments have been loaded
    18      //   by the ROM bootloader.
    19      // - We have a usable stack (but not the one we would like to use).
    20      // - No flash mappings (MMU) are set up yet.
    21  
    22      // Reset MMU, see bootloader_reset_mmu in the ESP-IDF.
    23      call Cache_Suspend_ICache
    24      mv s0, a0 // autoload value
    25      call Cache_Invalidate_ICache_All
    26      call Cache_MMU_Init
    27  
    28      // Set up DROM from flash.
    29      // Somehow, this also sets up IROM from flash. Not sure why, but it avoids
    30      // the need for another such call.
    31      // C equivalent:
    32      //   Cache_Dbus_MMU_Set(MMU_ACCESS_FLASH, 0x3C00_0000, 0, 64, 128, 0)
    33      li a0, 0              // ext_ram: MMU_ACCESS_FLASH
    34      li a1, 0x3C000000     // vaddr: address in the data bus
    35      li a2, 0              // paddr: physical address in the flash chip
    36      li a3, 64             // psize: always 64 (kilobytes)
    37      li a4, 128            // num: pages to be set (8192K / 64K = 128)
    38      li a5, 0              // fixed
    39      call Cache_Dbus_MMU_Set
    40  
    41      // Enable the flash cache.
    42      mv a0, s0 // restore autoload value from Cache_Suspend_ICache call
    43      call Cache_Resume_ICache
    44  
    45      // Jump to generic RISC-V initialization, which initializes the stack
    46      // pointer and globals register. It should not return.
    47      // (It appears that the linker relaxes this jump and instead inserts the
    48      // _start function right after here).
    49      j _start
    50  
    51  .section .text.exception_vectors
    52  .global _vector_table
    53  .type _vector_table,@function
    54  
    55  _vector_table:
    56  
    57      .option push
    58      .option norvc
    59  
    60      .rept 32
    61      j handleInterruptASM            /* interrupt handler */
    62      .endr
    63  
    64      .option pop
    65  
    66  .size _vector_table, .-_vector_table
    67