Merge branch 'bugfix/dualcore_startup' into 'master'

Fix dualcore startup

This MR includes:
- a workaround for a hardware bug with cache initialization
- fix of `#if CONFIG_WIFI_ENABLED` block in cpu_start.c for the case when WiFi is disabled.
- removal of miscellaneous delays in cpu_start.c

See merge request !22
This commit is contained in:
Ivan Grokhotkov 2016-08-25 11:07:21 +08:00
commit 842bc53549
2 changed files with 39 additions and 52 deletions

View file

@ -99,13 +99,18 @@ void IRAM_ATTR call_start_cpu0()
Cache_Flush(0); Cache_Flush(0);
Cache_Flush(1); Cache_Flush(1);
mmu_init(0); mmu_init(0);
REG_SET_BIT(APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR);
mmu_init(1); mmu_init(1);
REG_CLR_BIT(APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MMU_IA_CLR);
/* (above steps probably unnecessary for most serial bootloader /* (above steps probably unnecessary for most serial bootloader
usage, all that's absolutely needed is that we unmask DROM0 usage, all that's absolutely needed is that we unmask DROM0
cache on the following two lines - normal ROM boot exits with cache on the following two lines - normal ROM boot exits with
DROM0 cache unmasked, but serial bootloader exits with it DROM0 cache unmasked, but serial bootloader exits with it
masked. However can't hurt to be thorough and reset masked. However can't hurt to be thorough and reset
everything.) everything.)
The lines which manipulate DPORT_APP_CACHE_MMU_IA_CLR bit are
necessary to work around a hardware bug.
*/ */
REG_CLR_BIT(PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MASK_DROM0); REG_CLR_BIT(PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MASK_DROM0);
REG_CLR_BIT(APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MASK_DROM0); REG_CLR_BIT(APP_CACHE_CTRL1_REG, DPORT_APP_CACHE_MASK_DROM0);

View file

@ -64,6 +64,8 @@ void uartAttach();
void ets_set_appcpu_boot_addr(uint32_t ent); void ets_set_appcpu_boot_addr(uint32_t ent);
int ets_getAppEntry(); int ets_getAppEntry();
static bool app_cpu_started = false;
void IRAM_ATTR call_user_start_cpu0() { void IRAM_ATTR call_user_start_cpu0() {
//Kill wdt //Kill wdt
REG_CLR_BIT(0x3ff4808c, BIT(10)); //RTCCNTL+8C RTC_WDTCONFIG0 RTC_ REG_CLR_BIT(0x3ff4808c, BIT(10)); //RTCCNTL+8C RTC_WDTCONFIG0 RTC_
@ -114,53 +116,34 @@ void IRAM_ATTR call_user_start_cpu0() {
heap_alloc_caps_init(); heap_alloc_caps_init();
ets_printf("Pro cpu up.\n"); ets_printf("Pro cpu up.\n");
#ifndef CONFIG_FREERTOS_UNICORE #ifndef CONFIG_FREERTOS_UNICORE
ets_printf("Running app cpu, entry point is %p\n", call_user_start_cpu1); ets_printf("Starting app cpu, entry point is %p\n", call_user_start_cpu1);
ets_delay_us(60000);
SET_PERI_REG_MASK(APPCPU_CTRL_REG_B, DPORT_APPCPU_CLKGATE_EN); SET_PERI_REG_MASK(APPCPU_CTRL_REG_B, DPORT_APPCPU_CLKGATE_EN);
CLEAR_PERI_REG_MASK(APPCPU_CTRL_REG_C, DPORT_APPCPU_RUNSTALL);
SET_PERI_REG_MASK(APPCPU_CTRL_REG_A, DPORT_APPCPU_RESETTING); SET_PERI_REG_MASK(APPCPU_CTRL_REG_A, DPORT_APPCPU_RESETTING);
CLEAR_PERI_REG_MASK(APPCPU_CTRL_REG_A, DPORT_APPCPU_RESETTING); CLEAR_PERI_REG_MASK(APPCPU_CTRL_REG_A, DPORT_APPCPU_RESETTING);
for (int i=0; i<20; i++) ets_delay_us(40000);
ets_set_appcpu_boot_addr((uint32_t)call_user_start_cpu1); ets_set_appcpu_boot_addr((uint32_t)call_user_start_cpu1);
ets_delay_us(10000); while (!app_cpu_started) {
ets_delay_us(100);
// while (ets_getAppEntry()==(int)call_user_start_cpu1) ; }
//Because of Reasons (tm), the pro cpu cannot use the SPI flash while the app cpu is booting.
// while(((READ_PERI_REG(RTC_STORE7))&BIT(31)) == 0) ; // check APP boot complete flag
ets_delay_us(50000);
ets_delay_us(50000);
ets_printf("\n\nBack to pro cpu.\n");
#else #else
CLEAR_PERI_REG_MASK(APPCPU_CTRL_REG_B, DPORT_APPCPU_CLKGATE_EN); CLEAR_PERI_REG_MASK(APPCPU_CTRL_REG_B, DPORT_APPCPU_CLKGATE_EN);
#endif #endif
ets_printf("Pro cpu start user code\n");
user_start_cpu0(); user_start_cpu0();
} }
extern int xPortGetCoreID();
extern int _init_start; extern int _init_start;
/*
We arrive here because the pro CPU pulled us from reset. IRAM is in place, cache is still disabled, we can execute C code.
*/
void IRAM_ATTR call_user_start_cpu1() { void IRAM_ATTR call_user_start_cpu1() {
//We need to do this ASAP because otherwise the structure to catch the SYSCALL instruction, which
//we abuse to do ROM calls, won't work.
asm volatile (\ asm volatile (\
"wsr %0, vecbase\n" \ "wsr %0, vecbase\n" \
::"r"(&_init_start)); ::"r"(&_init_start));
//Enable SPI flash
// PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA3_U, FUNC_SD_DATA3_SPIWP); // swap PIN SDDATA3 from uart1 to spi, because cache need spi
ets_printf("App cpu up\n");
//Make page 0 access raise an exception //Make page 0 access raise an exception
//Also some other unused pages so we can catch weirdness //Also some other unused pages so we can catch weirdness
//ToDo: this but nicer. //ToDo: this but nicer.
@ -192,16 +175,15 @@ void IRAM_ATTR call_user_start_cpu1() {
"isync\n" \ "isync\n" \
:::"a4","a5"); :::"a4","a5");
ets_printf("App cpu up.\n");
app_cpu_started = 1;
user_start_cpu1(); user_start_cpu1();
} }
extern volatile int port_xSchedulerRunning; extern volatile int port_xSchedulerRunning;
extern int xPortStartScheduler(); extern int xPortStartScheduler();
void user_start_cpu1(void) { void user_start_cpu1(void) {
ets_printf("App cpu is running!\n");
//Wait for the freertos initialization is finished on CPU0 //Wait for the freertos initialization is finished on CPU0
while (port_xSchedulerRunning == 0) ; while (port_xSchedulerRunning == 0) ;
ets_printf("Core0 started initializing FreeRTOS. Jumping to scheduler.\n"); ets_printf("Core0 started initializing FreeRTOS. Jumping to scheduler.\n");
@ -221,11 +203,12 @@ static void do_global_ctors(void) {
void user_start_cpu0(void) { void user_start_cpu0(void) {
esp_err_t ret;
ets_setup_syscalls(); ets_setup_syscalls();
do_global_ctors(); do_global_ctors();
// TODO: consider ethernet interface
#if CONFIG_WIFI_ENABLED
#if 1 //workaround #if 1 //workaround
for (uint8_t i = 5; i < 8; i++) { for (uint8_t i = 5; i < 8; i++) {
ets_printf("erase sector %d\n", i); ets_printf("erase sector %d\n", i);
@ -233,8 +216,8 @@ void user_start_cpu0(void) {
} }
#endif #endif
ets_printf("nvs_flash_init\n"); ets_printf("nvs_flash_init\n");
ret = nvs_flash_init(5, 3); esp_err_t ret = nvs_flash_init(5, 3);
if (ESP_OK != ret) { if (ret != ESP_OK) {
ets_printf("nvs_flash_init fail, ret=%d\n", ret); ets_printf("nvs_flash_init fail, ret=%d\n", ret);
} }
@ -242,9 +225,8 @@ void user_start_cpu0(void) {
esp_event_init(NULL); esp_event_init(NULL);
// TODO: consider ethernet interface
#if CONFIG_WIFI_ENABLED
tcpip_adapter_init(); tcpip_adapter_init();
#endif #endif
#if CONFIG_WIFI_ENABLED && CONFIG_WIFI_AUTO_STARTUP #if CONFIG_WIFI_ENABLED && CONFIG_WIFI_AUTO_STARTUP