soc: esp32: Define __start as a C function

The first stage bootloader, part of the ESP32 ROM, already sets up
a stack that's sufficient to execute C programs.  So, instead of
implementing __stack() in assembly, do it in C to simplify things
slightly.

This ESP32-specific initialization will perform the following:

  - Disable the watchdog timer that's enabled by the bootloader
  - Move exception handlers to IRAM
  - Disable normal interrupts
  - Disable the second CPU
  - Zero out the BSS segment

Things that might be performed in the future include setting up the
CPU frequency, memory protection regions, and enabling the flash
cache.

Signed-off-by: Leandro Pereira <leandro.pereira@intel.com>
This commit is contained in:
Leandro Pereira 2017-06-13 10:48:38 -07:00 committed by Anas Nashif
commit 0e08b946de
6 changed files with 78 additions and 6 deletions

View file

@ -77,6 +77,14 @@ config XTENSA_RESET_VECTOR
This is always needed for the simulator. Real boards may already This is always needed for the simulator. Real boards may already
implement this in boot ROM. implement this in boot ROM.
config XTENSA_USE_CORE_CRT1
bool
prompt "Use crt1.S from core"
default y
help
SoC or boards might define their own __start by setting this setting
to false.
menu "Specific core configuration" menu "Specific core configuration"
config IRQ_OFFLOAD_INTNUM config IRQ_OFFLOAD_INTNUM

View file

@ -8,9 +8,10 @@ else
# Use our own routines implmented in assembly # Use our own routines implmented in assembly
obj-atomic=atomic.o obj-atomic=atomic.o
endif endif
obj-y = ${obj-atomic} cpu_idle.o fatal.o crt1.o \ obj-y = ${obj-atomic} cpu_idle.o fatal.o \
swap.o thread.o xt_zephyr.o xtensa_context.o xtensa_intr_asm.o \ swap.o thread.o xt_zephyr.o xtensa_context.o xtensa_intr_asm.o \
xtensa_intr.o xtensa_vectors.o irq_manage.o xtensa_intr.o xtensa_vectors.o irq_manage.o
obj-$(CONFIG_XTENSA_USE_CORE_CRT1) += crt1.o
obj-$(CONFIG_IRQ_OFFLOAD) += irq_offload.o obj-$(CONFIG_IRQ_OFFLOAD) += irq_offload.o
# Keep this last so that vague linking works # Keep this last so that vague linking works
obj-y += sw_isr_table.o obj-y += sw_isr_table.o

View file

@ -1 +1 @@
obj- = soc.o obj-y = soc.o

View file

@ -191,10 +191,6 @@ SECTIONS
*(.dynamic) *(.dynamic)
*(.gnu.version_d) *(.gnu.version_d)
. = ALIGN(4); /* this table MUST be 4-byte aligned */ . = ALIGN(4); /* this table MUST be 4-byte aligned */
_bss_table_start = ABSOLUTE(.);
LONG(_bss_start)
LONG(_bss_end)
_bss_table_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.); _rodata_end = ABSOLUTE(.);
} GROUP_LINK_IN(RAMABLE_REGION) } GROUP_LINK_IN(RAMABLE_REGION)

View file

@ -0,0 +1,65 @@
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <soc/dport_reg.h>
#include <soc/rtc_cntl_reg.h>
#include <soc/timer_group_reg.h>
#include <string.h>
#include <toolchain/gcc.h>
#include <xtensa/config/core-isa.h>
#include <xtensa/corebits.h>
#include <zephyr/types.h>
extern void _Cstart(void);
/*
* 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 u32_t *wdt_rtc_reg = (u32_t *)RTC_CNTL_WDTCONFIG0_REG;
volatile u32_t *wdt_timg_reg = (u32_t *)TIMG_WDTCONFIG0_REG(0);
volatile u32_t *app_cpu_config_reg = (u32_t *)DPORT_APPCPU_CTRL_B_REG;
extern u32_t _init_start;
extern u32_t _bss_start;
extern u32_t _bss_end;
/* Move the exception vector table to IRAM. */
__asm__ __volatile__ (
"wsr %0, vecbase"
:
: "r"(&_init_start));
/* Zero out BSS. Clobber _bss_start to avoid memset() elision. */
memset(&_bss_start, 0, (&_bss_end - &_bss_start) * sizeof(_bss_start));
__asm__ __volatile__ (
""
:
: "g"(&_bss_start)
: "memory");
/* The watchdog timer is enabled in the bootloader. We're done booting,
* so disable it.
*/
*wdt_rtc_reg &= ~RTC_CNTL_WDT_FLASHBOOT_MOD_EN;
*wdt_timg_reg &= ~TIMG_WDT_FLASHBOOT_MOD_EN;
/* Disable normal interrupts. */
__asm__ __volatile__ (
"wsr %0, PS"
:
: "r"(PS_INTLEVEL(XCHAL_EXCM_LEVEL) | PS_UM | PS_WOE));
/* Disable CPU1 while we figure out how to have SMP in Zephyr. */
*app_cpu_config_reg &= ~DPORT_APPCPU_CLKGATE_EN;
/* Start Zephyr */
_Cstart();
CODE_UNREACHABLE;
}

View file

@ -15,3 +15,5 @@ CONFIG_SERIAL=y
CONFIG_UART_CONSOLE_ON_DEV_NAME="ROMUART" CONFIG_UART_CONSOLE_ON_DEV_NAME="ROMUART"
CONFIG_UART_CONSOLE=y CONFIG_UART_CONSOLE=y
CONFIG_UART_ESP32=y CONFIG_UART_ESP32=y
CONFIG_XTENSA_USE_CORE_CRT1=n