Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 | /*
* Copyright (c) 2021 Espressif Systems (Shanghai) Co., Ltd.
*
* SPDX-License-Identifier: Apache-2.0
*/
/* Include esp-idf headers first to avoid redefining BIT() macro */
#include <soc/rtc_cntl_reg.h>
#include <soc/timer_group_reg.h>
#include <soc/gpio_reg.h>
#include <soc/syscon_reg.h>
#include <soc/system_reg.h>
#include <soc/cache_memory.h>
#include "hal/soc_ll.h"
#include "esp_spi_flash.h"
#include <riscv/interrupt.h>
#include <soc/interrupt_reg.h>
#include <kernel_structs.h>
#include <string.h>
#include <toolchain/gcc.h>
#include <soc.h>
#define ESP32C3_INTC_DEFAULT_PRIO 15
extern void _PrepC(void);
extern void esprv_intc_int_set_threshold(int priority_threshold);
/*
* This is written in C rather than assembly since, during the port bring up,
* Zephyr is being booted by the Espressif bootloader. With it, the C stack
* is already set up.
*/
void __attribute__((section(".iram1"))) __start(void)
{
volatile uint32_t *wdt_rtc_protect = (uint32_t *)RTC_CNTL_WDTWPROTECT_REG;
volatile uint32_t *wdt_rtc_reg = (uint32_t *)RTC_CNTL_WDTCONFIG0_REG;
#ifdef CONFIG_RISCV_GP
/* Configure the global pointer register
* (This should be the first thing startup does, as any other piece of code could be
* relaxed by the linker to access something relative to __global_pointer$)
*/
__asm__ __volatile__(".option push\n"
".option norelax\n"
"la gp, __global_pointer$\n"
".option pop");
#endif /* CONFIG_RISCV_GP */
__asm__ __volatile__("la t0, _esp32c3_vector_table\n"
"csrw mtvec, t0\n");
/* Disable normal interrupts. */
csr_read_clear(mstatus, MSTATUS_MIE);
#if !CONFIG_BOOTLOADER_ESP_IDF
/* The watchdog timer is enabled in the 1st stage (ROM) bootloader.
* We're done booting, so disable it.
* If 2nd stage bootloader from IDF is enabled, then that will take
* care of this.
*/
volatile uint32_t *wdt_timg_protect = (uint32_t *)TIMG_WDTWPROTECT_REG(0);
volatile uint32_t *wdt_timg_reg = (uint32_t *)TIMG_WDTCONFIG0_REG(0);
*wdt_rtc_protect = RTC_CNTL_WDT_WKEY_VALUE;
*wdt_rtc_reg &= ~RTC_CNTL_WDT_FLASHBOOT_MOD_EN;
*wdt_rtc_protect = 0;
*wdt_timg_protect = TIMG_WDT_WKEY_VALUE;
*wdt_timg_reg &= ~TIMG_WDT_FLASHBOOT_MOD_EN;
*wdt_timg_protect = 0;
#endif
#if CONFIG_BOOTLOADER_ESP_IDF
/* ESP-IDF 2nd stage bootloader enables RTC WDT to check on startup sequence
* related issues in application. Hence disable that as we are about to start
* Zephyr environment.
*/
*wdt_rtc_protect = RTC_CNTL_WDT_WKEY_VALUE;
*wdt_rtc_reg &= ~RTC_CNTL_WDT_EN;
*wdt_rtc_protect = 0;
#endif
/* Configure the Cache MMU size for instruction and rodata in flash. */
extern uint32_t esp_rom_cache_set_idrom_mmu_size(uint32_t irom_size,
uint32_t drom_size);
extern int _rodata_reserved_start;
uint32_t rodata_reserved_start_align =
(uint32_t)&_rodata_reserved_start & ~(MMU_PAGE_SIZE - 1);
uint32_t cache_mmu_irom_size =
((rodata_reserved_start_align - SOC_DROM_LOW) / MMU_PAGE_SIZE) *
sizeof(uint32_t);
esp_rom_cache_set_idrom_mmu_size(cache_mmu_irom_size,
CACHE_DROM_MMU_MAX_END - cache_mmu_irom_size);
/* set global esp32c3's INTC masking level */
esprv_intc_int_set_threshold(1);
/* Enable wireless phy subsystem clock,
* This needs to be done before the kernel starts
*/
REG_CLR_BIT(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_SDIOSLAVE_EN);
SET_PERI_REG_MASK(SYSTEM_WIFI_CLK_EN_REG, SYSTEM_WIFI_CLK_EN);
/* Start Zephyr */
_PrepC();
CODE_UNREACHABLE;
}
/* Boot-time static default printk handler, possibly to be overridden later. */
int IRAM_ATTR arch_printk_char_out(int c)
{
if (c == '\n') {
esp_rom_uart_tx_one_char('\r');
}
esp_rom_uart_tx_one_char(c);
return 0;
}
void IRAM_ATTR esp_restart_noos(void)
{
/* Disable interrupts */
csr_read_clear(mstatus, MSTATUS_MIE);
/* Flush any data left in UART FIFOs */
esp_rom_uart_tx_wait_idle(0);
esp_rom_uart_tx_wait_idle(1);
esp_rom_uart_tx_wait_idle(2);
/* 2nd stage bootloader reconfigures SPI flash signals. */
/* Reset them to the defaults expected by ROM */
WRITE_PERI_REG(GPIO_FUNC0_IN_SEL_CFG_REG, 0x30);
WRITE_PERI_REG(GPIO_FUNC1_IN_SEL_CFG_REG, 0x30);
WRITE_PERI_REG(GPIO_FUNC2_IN_SEL_CFG_REG, 0x30);
WRITE_PERI_REG(GPIO_FUNC3_IN_SEL_CFG_REG, 0x30);
WRITE_PERI_REG(GPIO_FUNC4_IN_SEL_CFG_REG, 0x30);
WRITE_PERI_REG(GPIO_FUNC5_IN_SEL_CFG_REG, 0x30);
/* Reset wifi/bluetooth/ethernet/sdio (bb/mac) */
SET_PERI_REG_MASK(SYSTEM_CORE_RST_EN_REG,
SYSTEM_BB_RST | SYSTEM_FE_RST | SYSTEM_MAC_RST | SYSTEM_BT_RST |
SYSTEM_BTMAC_RST | SYSTEM_SDIO_RST | SYSTEM_EMAC_RST |
SYSTEM_MACPWR_RST | SYSTEM_RW_BTMAC_RST | SYSTEM_RW_BTLP_RST |
BLE_REG_REST_BIT | BLE_PWR_REG_REST_BIT | BLE_BB_REG_REST_BIT);
REG_WRITE(SYSTEM_CORE_RST_EN_REG, 0);
/* Reset timer/spi/uart */
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN0_REG,
SYSTEM_TIMERS_RST | SYSTEM_SPI01_RST | SYSTEM_UART_RST);
REG_WRITE(SYSTEM_PERIP_RST_EN0_REG, 0);
/* Reset dma */
SET_PERI_REG_MASK(SYSTEM_PERIP_RST_EN1_REG, SYSTEM_DMA_RST);
REG_WRITE(SYSTEM_PERIP_RST_EN1_REG, 0);
/* Reset core */
soc_ll_reset_core(0);
while (true) {
;
}
}
void sys_arch_reboot(int type)
{
esp_restart_noos();
}
void arch_irq_enable(unsigned int irq)
{
uint32_t key = irq_lock();
esprv_intc_int_set_priority(irq, ESP32C3_INTC_DEFAULT_PRIO);
esprv_intc_int_set_type(irq, 0);
esprv_intc_int_enable(1 << irq);
irq_unlock(key);
}
void arch_irq_disable(unsigned int irq)
{
esprv_intc_int_disable(1 << irq);
}
int arch_irq_is_enabled(unsigned int irq)
{
return (REG_READ(INTERRUPT_CORE0_CPU_INT_ENABLE_REG) & (1 << irq));
}
|