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
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"
config IRQ_OFFLOAD_INTNUM

View file

@ -8,9 +8,10 @@ else
# Use our own routines implmented in assembly
obj-atomic=atomic.o
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 \
xtensa_intr.o xtensa_vectors.o irq_manage.o
obj-$(CONFIG_XTENSA_USE_CORE_CRT1) += crt1.o
obj-$(CONFIG_IRQ_OFFLOAD) += irq_offload.o
# Keep this last so that vague linking works
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)
*(.gnu.version_d)
. = 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(.);
} 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=y
CONFIG_UART_ESP32=y
CONFIG_XTENSA_USE_CORE_CRT1=n