diff --git a/core/app_main.c b/core/app_main.c new file mode 100644 index 0000000..86d1cb3 --- /dev/null +++ b/core/app_main.c @@ -0,0 +1,501 @@ +/* Implementation of libmain/app_main.o from the Espressif SDK. + * + * This contains most of the startup code for the SDK/OS, some event handlers, + * etc. + * + * Part of esp-open-rtos + * Copyright (C) 2015 Superhouse Automation Pty Ltd + * BSD Licensed as described in the file LICENSE + */ + +#include +#include +#include +#include + +#include "common_macros.h" +#include "xtensa_ops.h" +#include "esp/rom.h" +#include "esp/iomux_regs.h" +#include "esp/uart_regs.h" +#include "esp/spi_regs.h" +#include "esp/dport_regs.h" +#include "esp/wdev_regs.h" +#include "os_version.h" + +#include "espressif/esp_system.h" +#include "sdk_internal.h" + +/* This is not declared in any header file (but arguably should be) */ + +void user_init(void); + +#define UART_DIVISOR 1068 // 74906 bps (yeah, I don't understand it either) +#define BOOT_INFO_SIZE 28 +//TODO: phy_info should probably be a struct (no idea about its organization, though) +#define PHY_INFO_SIZE 128 + +// These are the offsets of these values within the RTCMEM regions. It appears +// that the ROM saves them to RTCMEM before calling us, and we pull them out of +// there to display them in startup messages (not sure why it works that way). +#define RTCMEM_BACKUP_PHY_VER 31 +#define RTCMEM_SYSTEM_PP_VER 62 + +#define halt() while (1) {} + +extern uint32_t *_bss_start; +extern uint32_t *_bss_end; + +// .Ldata003 -- .irom.text+0x0 +static const uint8_t IROM default_phy_info[PHY_INFO_SIZE] = { + 0x05, 0x00, 0x04, 0x02, 0x05, 0x05, 0x05, 0x02, + 0x05, 0x00, 0x04, 0x05, 0x05, 0x04, 0x05, 0x05, + 0x04, 0xfe, 0xfd, 0xff, 0xf0, 0xf0, 0xf0, 0xe0, + 0xe0, 0xe0, 0xe1, 0x0a, 0xff, 0xff, 0xf8, 0x00, + 0xf8, 0xf8, 0x52, 0x4e, 0x4a, 0x44, 0x40, 0x38, + 0x00, 0x00, 0x01, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xe1, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x01, 0x93, 0x43, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +}; + +// user_init_flag -- .bss+0x0 +uint8_t sdk_user_init_flag; + +// info -- .bss+0x4 +struct sdk_info_st sdk_info; + +// xUserTaskHandle -- .bss+0x28 +xTaskHandle sdk_xUserTaskHandle; + +// xWatchDogTaskHandle -- .bss+0x2c +xTaskHandle sdk_xWatchDogTaskHandle; + +/* Static function prototypes */ + +static void IRAM get_otp_mac_address(uint8_t *buf); +static void IRAM set_spi0_divisor(uint32_t divisor); +static void IRAM default_putc(uint8_t c); +static void IRAM default_putc1(uint8_t c); +static void zero_bss(void); +static void init_networking(uint8_t *phy_info, uint8_t *mac_addr); +static void init_g_ic(void); +static void dump_excinfo(void); +static void user_start_phase2(void); +static void dump_flash_data(uint32_t start_addr, uint32_t length); +static void dump_flash_config_sectors(uint32_t start_addr); + +// .Lfunc001 -- .text+0x14 +static void IRAM get_otp_mac_address(uint8_t *buf) { + uint32_t otp_flags; + uint32_t otp_id0, otp_id1; + uint32_t otp_vendor_id; + + otp_flags = DPORT.OTP_CHIPID; + otp_id1 = DPORT.OTP_MAC1; + otp_id0 = DPORT.OTP_MAC0; + if (!(otp_flags & 0x8000)) { + //FIXME: do we really need this check? + printf("Firmware ONLY supports ESP8266!!!\n"); + halt(); + } + if (otp_id0 == 0 && otp_id1 == 0) { + printf("empty otp\n"); + halt(); + } + if (otp_flags & 0x1000) { + // If bit 12 is set, it indicates that the vendor portion of the MAC + // address is stored in DPORT.OTP_MAC2. + otp_vendor_id = DPORT.OTP_MAC2; + buf[0] = otp_vendor_id >> 16; + buf[1] = otp_vendor_id >> 8; + buf[2] = otp_vendor_id; + } else { + // If bit 12 is clear, there's no MAC vendor in DPORT.OTP_MAC2, so + // default to the Espressif MAC vendor prefix instead. + buf[1] = 0xfe; + buf[0] = 0x18; + buf[2] = 0x34; + } + buf[3] = otp_id1 >> 8; + buf[4] = otp_id1; + buf[5] = otp_id0 >> 24; +} + +// .Lfunc002 -- .text+0xa0 +static void IRAM set_spi0_divisor(uint32_t divisor) { + int cycle_len, half_cycle_len, clkdiv; + + if (divisor < 2) { + clkdiv = 0; + SPI(0).CTRL0 |= SPI_CTRL0_CLOCK_EQU_SYS_CLOCK; + IOMUX.CONF |= IOMUX_CONF_SPI0_CLOCK_EQU_SYS_CLOCK; + } else { + cycle_len = divisor - 1; + half_cycle_len = (divisor / 2) - 1; + clkdiv = VAL2FIELD(SPI_CTRL0_CLOCK_NUM, cycle_len) + | VAL2FIELD(SPI_CTRL0_CLOCK_HIGH, half_cycle_len) + | VAL2FIELD(SPI_CTRL0_CLOCK_LOW, cycle_len); + SPI(0).CTRL0 &= ~SPI_CTRL0_CLOCK_EQU_SYS_CLOCK; + IOMUX.CONF &= ~IOMUX_CONF_SPI0_CLOCK_EQU_SYS_CLOCK; + } + SPI(0).CTRL0 = SET_FIELD(SPI(0).CTRL0, SPI_CTRL0_CLOCK, clkdiv); +} + +// .text+0x148 +void sdk_user_fatal_exception_handler(void) { + if (!sdk_NMIIrqIsOn) { + vPortEnterCritical(); + do { + DPORT.DPORT0 &= 0xffffffe0; + } while (DPORT.DPORT0 & 0x00000001); + } + Cache_Read_Disable(); + Cache_Read_Enable(0, 0, 1); + dump_excinfo(); + while (FIELD2VAL(UART_STATUS_TXFIFO_COUNT, UART(0).STATUS)) {} + while (FIELD2VAL(UART_STATUS_TXFIFO_COUNT, UART(1).STATUS)) {} + sdk_system_restart_in_nmi(); + halt(); +} + +// .Lfunc003 -- .text+0x1d0 +static void IRAM default_putc(uint8_t c) { + while (FIELD2VAL(UART_STATUS_TXFIFO_COUNT, UART(0).STATUS) > 125) {} + UART(0).FIFO = c; +} + +// .Lfunc004 -- .text+0x1f4 +static void IRAM default_putc1(uint8_t c) { + if (c == '\n') { + default_putc('\r'); + } else if (c == '\r') { + return; + } + default_putc(c); +} + +// .text+0x258 +void IRAM sdk_user_start(void) { + uint32_t buf32[sizeof(struct sdk_g_ic_saved_st) / 4]; + uint8_t *buf8 = (uint8_t *)buf32; + uint32_t flash_speed_divisor; + uint32_t flash_sectors; + uint32_t flash_size; + int boot_slot; + uint32_t cksum_magic; + uint32_t cksum_len; + uint32_t cksum_value; + uint32_t ic_flash_addr; + + SPI(0).USER0 |= SPI_USER0_CS_SETUP; + sdk_SPIRead(0, buf32, 4); + + switch (buf8[3] & 0x0f) { + case 0xf: // 80 MHz + flash_speed_divisor = 1; + break; + case 0x0: // 40 MHz + flash_speed_divisor = 2; + break; + case 0x1: // 26 MHz + flash_speed_divisor = 3; + break; + case 0x2: // 20 MHz + flash_speed_divisor = 4; + break; + default: // Invalid -- Assume 40 MHz + flash_speed_divisor = 2; + } + switch (buf8[3] >> 4) { + case 0x0: // 4 Mbit (512 KByte) + flash_sectors = 128; + break; + case 0x1: // 2 Mbit (256 Kbyte) + flash_sectors = 64; + break; + case 0x2: // 8 Mbit (1 Mbyte) + flash_sectors = 256; + break; + case 0x3: // 16 Mbit (2 Mbyte) + flash_sectors = 512; + break; + case 0x4: // 32 Mbit (4 Mbyte) + flash_sectors = 1024; + break; + default: // Invalid -- Assume 4 Mbit (512 KByte) + flash_sectors = 128; + } + //FIXME: we should probably calculate flash_sectors by starting with flash_size and dividing by sdk_flashchip.sector_size instead of vice-versa. + flash_size = flash_sectors * 4096; + sdk_flashchip.chip_size = flash_size; + set_spi0_divisor(flash_speed_divisor); + sdk_SPIRead(flash_size - 256, buf32, BOOT_INFO_SIZE); + boot_slot = buf8[0]; + cksum_magic = buf32[1]; + cksum_len = buf32[3 + boot_slot]; + cksum_value = buf32[5 + boot_slot]; + ic_flash_addr = (flash_sectors - 2 + boot_slot) * sdk_flashchip.sector_size; + sdk_SPIRead(ic_flash_addr, buf32, sizeof(struct sdk_g_ic_saved_st)); + Cache_Read_Enable(0, 0, 1); + zero_bss(); + sdk_os_install_putc1(default_putc1); + if (cksum_magic == 0xffffffff) { + // No checksum required + } else if ((cksum_magic == 0x55aa55aa) && + (sdk_system_get_checksum(buf8, cksum_len) == cksum_value)) { + // Checksum OK + } else { + // Bad checksum or bad cksum_magic value + dump_flash_config_sectors(flash_sectors - 4); + //FIXME: should we halt here? (original SDK code doesn't) + } + memcpy(&sdk_g_ic.s, buf32, sizeof(struct sdk_g_ic_saved_st)); + + user_start_phase2(); +} + +// .text+0x3a8 +void vApplicationStackOverflowHook(xTaskHandle task, char *task_name) { + printf("\"%s\"(stack_size = %lu) overflow the heap_size.\n", task_name, uxTaskGetStackHighWaterMark(task)); +} + +// .text+0x3d8 +void vApplicationIdleHook(void) { + printf("idle %lu\n", WDEV.SYS_TIME); +} + +// .text+0x404 +void vApplicationTickHook(void) { + printf("tick %lu\n", WDEV.SYS_TIME); +} + +// .Lfunc005 -- .irom0.text+0x8 +static void zero_bss(void) { + uint32_t *addr; + + for (addr = _bss_start; addr < _bss_end; addr++) { + *addr = 0; + } +} + +// .Lfunc006 -- .irom0.text+0x70 +static void init_networking(uint8_t *phy_info, uint8_t *mac_addr) { + if (sdk_register_chipv6_phy(phy_info)) { + printf("FATAL: sdk_register_chipv6_phy failed"); + halt(); + } + sdk_uart_div_modify(0, UART_DIVISOR); + sdk_uart_div_modify(1, UART_DIVISOR); + sdk_phy_disable_agc(); + sdk_ieee80211_phy_init(sdk_g_ic.s.phy_mode); + sdk_lmacInit(); + sdk_wDev_Initialize(); + sdk_pp_attach(); + sdk_ieee80211_ifattach(sdk_g_ic, mac_addr); + _xt_isr_mask(1); + DPORT.DPORT0 = SET_FIELD(DPORT.DPORT0, DPORT_DPORT0_FIELD0, 1); + sdk_pm_attach(); + sdk_phy_enable_agc(); + sdk_cnx_attach(sdk_g_ic); + sdk_wDevEnableRx(); +} + +// .Lfunc007 -- .irom0.text+0x148 +static void init_g_ic(void) { + if (sdk_g_ic.s.wifi_mode == 0xff) { + sdk_g_ic.s.wifi_mode = 2; + } + sdk_wifi_softap_set_default_ssid(); + if (sdk_g_ic.s._unknown30d < 1 || sdk_g_ic.s._unknown30d > 14) { + sdk_g_ic.s._unknown30d = 1; + } + if (sdk_g_ic.s._unknown544 < 100 || sdk_g_ic.s._unknown544 > 60000) { + sdk_g_ic.s._unknown544 = 100; + } + if (sdk_g_ic.s._unknown30e == 1 || sdk_g_ic.s._unknown30e > 4) { + sdk_g_ic.s._unknown30e = 0; + } + bzero(sdk_g_ic.s._unknown2ac, sizeof(sdk_g_ic.s._unknown2ac)); + if (sdk_g_ic.s._unknown30f > 1) { + sdk_g_ic.s._unknown30f = 0; + } + if (sdk_g_ic.s._unknown310 > 4) { + sdk_g_ic.s._unknown310 = 4; + } + if (sdk_g_ic.s._unknown1e4._unknown1e4 == 0xffffffff) { + bzero(&sdk_g_ic.s._unknown1e4, sizeof(sdk_g_ic.s._unknown1e4)); + bzero(&sdk_g_ic.s._unknown20f, sizeof(sdk_g_ic.s._unknown20f)); + } + sdk_g_ic.s.wifi_led_enable = 0; + if (sdk_g_ic.s._unknown281 > 1) { + sdk_g_ic.s._unknown281 = 0; + } + if (sdk_g_ic.s.ap_number > 5) { + sdk_g_ic.s.ap_number = 1; + } + if (sdk_g_ic.s.phy_mode < 1 || sdk_g_ic.s.phy_mode > 3) { + sdk_g_ic.s.phy_mode = PHY_MODE_11N; + } +} + +// .Lfunc008 -- .irom0.text+0x2a0 +static void dump_excinfo(void) { + uint32_t exccause, epc1, epc2, epc3, excvaddr, depc, excsave1; + uint32_t excinfo[8]; + + RSR(exccause, exccause); + printf("Fatal exception (%d): \n", (int)exccause); + RSR(epc1, epc1); + RSR(epc2, epc2); + RSR(epc3, epc3); + RSR(excvaddr, excvaddr); + RSR(depc, depc); + RSR(excsave1, excsave1); + printf("%s=0x%08lx\n", "epc1", epc1); + printf("%s=0x%08lx\n", "epc2", epc2); + printf("%s=0x%08lx\n", "epc3", epc3); + printf("%s=0x%08lx\n", "excvaddr", excvaddr); + printf("%s=0x%08lx\n", "depc", depc); + printf("%s=0x%08lx\n", "excsave1", excsave1); + sdk_system_rtc_mem_read(0, excinfo, 32); // Why? + excinfo[0] = 2; + excinfo[1] = exccause; + excinfo[2] = epc1; + excinfo[3] = epc2; + excinfo[4] = epc3; + excinfo[5] = excvaddr; + excinfo[6] = depc; + excinfo[7] = excsave1; + sdk_system_rtc_mem_write(0, excinfo, 32); +} + +// .irom0.text+0x368 +int sdk_uart_rx_one_char(char *buf) { + if (FIELD2VAL(UART_STATUS_RXFIFO_COUNT, UART(0).STATUS)) { + *buf = UART(0).FIFO; + return 0; + } + return 1; +} + +// .irom0.text+0x398 +void sdk_wdt_init(void) { + WDT.CTRL &= ~WDT_CTRL_ENABLE; + DPORT.INT_ENABLE |= DPORT_INT_ENABLE_WDT; + WDT.REG1 = 0x0000000b; + WDT.REG2 = 0x0000000c; + WDT.CTRL |= WDT_CTRL_FLAG3 | WDT_CTRL_FLAG4 | WDT_CTRL_FLAG5; + WDT.CTRL = SET_FIELD(WDT.CTRL, WDT_CTRL_FIELD0, 0); + WDT.CTRL |= WDT_CTRL_ENABLE; + sdk_pp_soft_wdt_init(); +} + +// .irom0.text+0x474 +void sdk_user_init_task(void *params) { + int phy_ver, pp_ver; + + sdk_ets_timer_init(); + printf("\nESP-Open-SDK ver: %s compiled @ %s %s\n", OS_VERSION_STR, __DATE__, __TIME__); + phy_ver = RTCMEM_BACKUP[RTCMEM_BACKUP_PHY_VER] >> 16; + printf("phy ver: %d, ", phy_ver); + pp_ver = RTCMEM_SYSTEM[RTCMEM_SYSTEM_PP_VER]; + printf("pp ver: %d.%d\n\n", (pp_ver >> 8) & 0xff, pp_ver & 0xff); + user_init(); + sdk_user_init_flag = 1; + sdk_wifi_mode_set(sdk_g_ic.s.wifi_mode); + if (sdk_g_ic.s.wifi_mode == 1) { + sdk_wifi_station_start(); + netif_set_default(sdk_g_ic.v.station_netif_info->netif); + } + if (sdk_g_ic.s.wifi_mode == 2) { + sdk_wifi_softap_start(); + netif_set_default(sdk_g_ic.v.softap_netif_info->netif); + } + if (sdk_g_ic.s.wifi_mode == 3) { + sdk_wifi_station_start(); + sdk_wifi_softap_start(); + netif_set_default(sdk_g_ic.v.softap_netif_info->netif); + } + if (sdk_wifi_station_get_auto_connect()) { + sdk_wifi_station_connect(); + } + vTaskDelete(NULL); +} + +// .Lfunc009 -- .irom0.text+0x5b4 +static void user_start_phase2(void) { + uint8_t *buf; + uint8_t *phy_info; + + sdk_system_rtc_mem_read(0, &sdk_rst_if, sizeof(sdk_rst_if)); + if (sdk_rst_if.version > 3) { + // Bad version number. Probably garbage. + bzero(&sdk_rst_if, sizeof(sdk_rst_if)); + } + buf = malloc(sizeof(sdk_rst_if)); + bzero(buf, sizeof(sdk_rst_if)); + sdk_system_rtc_mem_write(0, buf, sizeof(sdk_rst_if)); + free(buf); + sdk_sleep_reset_analog_rtcreg_8266(); + get_otp_mac_address(sdk_info.sta_mac_addr); + sdk_wifi_softap_cacl_mac(sdk_info.softap_mac_addr, sdk_info.sta_mac_addr); + sdk_info._unknown0 = 0x0104a8c0; + sdk_info._unknown1 = 0x00ffffff; + sdk_info._unknown2 = 0x0104a8c0; + init_g_ic(); + phy_info = malloc(PHY_INFO_SIZE); + sdk_spi_flash_read(sdk_flashchip.chip_size - sdk_flashchip.sector_size * 4, (uint32_t *)phy_info, PHY_INFO_SIZE); + + // Wait for UARTs to finish sending anything in their queues. + while (FIELD2VAL(UART_STATUS_TXFIFO_COUNT, UART(0).STATUS) > 0) {} + while (FIELD2VAL(UART_STATUS_TXFIFO_COUNT, UART(1).STATUS) > 0) {} + + if (phy_info[0] != 5) { + // Bad version byte. Discard what we read and use default values + // instead. + memcpy(phy_info, default_phy_info, PHY_INFO_SIZE); + } + init_networking(phy_info, sdk_info.sta_mac_addr); + free(phy_info); + tcpip_init(NULL, NULL); + sdk_wdt_init(); + xTaskCreate(sdk_user_init_task, (signed char *)"uiT", 1024, 0, 14, sdk_xUserTaskHandle); +} + +// .Lfunc010 -- .irom0.text+0x710 +static void dump_flash_data(uint32_t start_addr, uint32_t length) { + uint8_t *buf; + int bufsize, i; + + bufsize = (length + 3) & 0xfffc; + buf = malloc(bufsize); + sdk_spi_flash_read(start_addr, (uint32_t *)buf, bufsize); + for (i = 0; i < length; ) { + printf("%02x ", buf[i]); + if ((i & 0x1f) == 0) { + printf("\n"); + } + } + printf("\n"); + free(buf); +} + +// .Lfunc011 -- .irom0.text+0x790 +static void dump_flash_config_sectors(uint32_t start_addr) { + printf("system param error\n"); + // The original code used start_addr+1, start_addr+2, etc. This is + // obviously wrong as start_addr is clearly a byte address, not a sector + // address. + dump_flash_data(start_addr + sdk_flashchip.sector_size, sizeof(struct sdk_g_ic_saved_st)); + dump_flash_data(start_addr + sdk_flashchip.sector_size * 2, sizeof(struct sdk_g_ic_saved_st)); + dump_flash_data(start_addr + sdk_flashchip.sector_size * 3, BOOT_INFO_SIZE); +} + diff --git a/core/include/esp/wdev_regs.h b/core/include/esp/wdev_regs.h new file mode 100644 index 0000000..74788ca --- /dev/null +++ b/core/include/esp/wdev_regs.h @@ -0,0 +1,30 @@ +/* esp/wdev_regs.h + * + * ESP8266 register definitions for the "wdev" region (0x3FF2xxx) + * + * Not compatible with ESP SDK register access code. + */ + +#ifndef _ESP_WDEV_REGS_H +#define _ESP_WDEV_REGS_H + +#include "esp/types.h" +#include "common_macros.h" + +#define WDEV_BASE 0x3FF20000 +#define WDEV (*(struct WDEV_REGS *)(WDEV_BASE)) + +/* Note: This memory region is not currently well understood. Pretty much all + * of the definitions here are from reverse-engineering the Espressif SDK code, + * many are just educated guesses, and almost certainly some are misleading or + * wrong. If you can improve on any of this, please contribute! + */ + +struct WDEV_REGS { + uint32_t volatile _unknown[768]; // 0x0000 - 0x0bfc + uint32_t volatile SYS_TIME; // 0x0c00 +} __attribute__ (( packed )); + +_Static_assert(sizeof(struct WDEV_REGS) == 0xc04, "WDEV_REGS is the wrong size"); + +#endif /* _ESP_WDEV_REGS_H */ diff --git a/core/include/esp/wdt_regs.h b/core/include/esp/wdt_regs.h index eb51f57..66bf1d0 100644 --- a/core/include/esp/wdt_regs.h +++ b/core/include/esp/wdt_regs.h @@ -31,6 +31,17 @@ struct WDT_REGS { _Static_assert(sizeof(struct WDT_REGS) == 0x18, "WDT_REGS is the wrong size"); +/* Details for CTRL register */ + +/* Note: these are currently just guesses based on interpretation of the startup code */ + +#define WDT_CTRL_ENABLE BIT(0) +#define WDT_CTRL_FIELD0_M 0x00000003 +#define WDT_CTRL_FIELD0_S 1 +#define WDT_CTRL_FLAG3 BIT(3) +#define WDT_CTRL_FLAG4 BIT(4) +#define WDT_CTRL_FLAG5 BIT(5) + /* Writing WDT_FEED_MAGIC to WDT.FEED register "feeds the dog" and holds off * triggering for another cycle (unconfirmed) */ #define WDT_FEED_MAGIC 0x73 diff --git a/core/include/os_version.h b/core/include/os_version.h new file mode 100644 index 0000000..86b3bd8 --- /dev/null +++ b/core/include/os_version.h @@ -0,0 +1,6 @@ +#ifndef _VERSION_H +#define _VERSION_H + +#define OS_VERSION_STR "0.0.1" + +#endif /* _VERSION_H */ diff --git a/core/include/sdk_internal.h b/core/include/sdk_internal.h new file mode 100644 index 0000000..314d2ca --- /dev/null +++ b/core/include/sdk_internal.h @@ -0,0 +1,235 @@ +#ifndef _INTERNAL_SDK_STRUCTURES_H +#define _INTERNAL_SDK_STRUCTURES_H + +#include "espressif/esp_wifi.h" +#include "espressif/spi_flash.h" +#include "lwip/netif.h" + +/////////////////////////////////////////////////////////////////////////////// +// Internal structures and data objects // +/////////////////////////////////////////////////////////////////////////////// + +// 'info' is declared in app_main.o at .bss+0x4 + +struct sdk_info_st { + uint32_t _unknown0; + uint32_t _unknown1; + uint32_t _unknown2; + uint8_t _unknown3[12]; + uint8_t softap_mac_addr[6]; + uint8_t sta_mac_addr[6]; +}; + +extern struct sdk_info_st sdk_info; + +// 'rst_if' is declared in user_interface.o at .bss+0xfc + +struct sdk_rst_if_st { + uint32_t version; + uint8_t _unknown[28]; +}; + +extern struct sdk_rst_if_st sdk_rst_if; + +// 'g_ic' is declared in libnet80211/ieee80211.o at .bss+0x0 +// See also: http://esp8266-re.foogod.com/wiki/G_ic_(IoT_RTOS_SDK_0.9.9) + +struct sdk_g_ic_netif_info { + struct netif *netif; + //TODO: rest of this structure is unknown. +}; + +// This is the portion of g_ic which is not loaded/saved to the flash ROM, and +// starts out zeroed on every boot. +struct sdk_g_ic_volatile_st { + void *_unknown0; + void *_unknown4; + + uint8_t _unknown8[8]; + + struct sdk_g_ic_netif_info *station_netif_info; + struct sdk_g_ic_netif_info *softap_netif_info; + uint8_t _unknown18; + uint32_t _unknown1c; + uint32_t _unknown20; + + uint8_t _unknown24[8]; + + uint8_t _unknown2c; + + uint8_t _unknown30[76]; + + uint8_t _unknown7c; + uint8_t _unknown7d; + uint8_t _unknown7e; + uint8_t _unknown7f; + + uint8_t _unknown80[204]; + + void *_unknown14c; + + uint8_t _unknown150[20]; + + uint32_t _unknown164; + void *_unknown168; + void *_unknown16c; + void *_unknown170; + void *_unknown174; + void *_unknown178; + + uint8_t _unknown17c[4]; + + void *_unknown180; + void *_unknown184; + struct station_info *station_info_head; + struct station_info *station_info_tail; + uint32_t _unknown190; + uint32_t _unknown194; + + uint8_t _unknown198[40]; + + void *_unknown1c0; + void *_unknown1c4; + uint32_t _unknown1c8; + + uint8_t _unknown1cc[4]; + + uint16_t _unknown1d0; + + uint8_t _unknown1d2[2]; + + uint8_t _unknown1d4; + + uint8_t _unknown1d5[3]; +}; + +struct sdk_g_ic_unk0_st { + uint32_t _unknown1e4; + uint8_t _unknown1e8[32]; +}; + +// This is the portion of g_ic which is loaded/saved to the flash ROM, and thus +// is preserved across reboots. +struct sdk_g_ic_saved_st { + uint8_t _unknown1d8; + uint8_t boot_info; + uint8_t user0_addr[3]; + uint8_t user1_addr[3]; + uint8_t wifi_mode; + uint8_t wifi_led_enable; + uint8_t wifi_led_gpio; + uint8_t _unknown1e3; + + struct sdk_g_ic_unk0_st _unknown1e4; + + uint8_t _unknown208; + uint8_t _unknown209; + uint8_t _unknown20a; + uint8_t _unknown20b; + uint8_t _unknown20c; + uint8_t _unknown20d; + uint8_t _unknown20e; + uint8_t _unknown20f[64]; + uint8_t _unknown24f; + + uint8_t _unknown250[49]; + + uint8_t _unknown281; + + uint8_t _unknown282[6]; + + uint32_t _unknown288; + uint8_t _unknown28c; + + uint8_t _unknown290[28]; + + uint8_t _unknown2ac[64]; + uint8_t _unknonwn2ec; + + uint8_t _unknown2ed[32]; + + uint8_t _unknown30d; + uint8_t _unknown30e; + uint8_t _unknown30f; + uint8_t _unknown310; + + uint8_t _unknown311[3]; + + uint8_t ap_number; + uint8_t current_ap_id; + + uint8_t _unknown316[502]; + + uint32_t _unknown50c; + uint16_t _unknown510; + uint16_t _unknown512; + uint16_t _unknown514; + + uint8_t _unknown516[2]; + + uint8_t auto_connect; + + uint8_t _unknown519[3]; + + enum sdk_phy_mode phy_mode; + + uint8_t _unknown520[36]; + + uint16_t _unknown544; + + uint8_t _unknown546[2]; +}; + +struct sdk_g_ic_st { + struct sdk_g_ic_volatile_st v; // 0x0 - 0x1d8 + struct sdk_g_ic_saved_st s; // 0x1d8 - 0x548 +}; + +extern struct sdk_g_ic_st sdk_g_ic; + +/////////////////////////////////////////////////////////////////////////////// +// The above structures all refer to data regions outside our control, and a +// simple mistake/misunderstanding editing things here can completely screw up +// how we access them, so do some basic sanity checks to make sure that they +// appear to match up correctly with the actual data structures other parts of +// the SDK are expecting. +/////////////////////////////////////////////////////////////////////////////// + +_Static_assert(sizeof(struct sdk_info_st) == 0x24, "info_st is the wrong size!"); +_Static_assert(sizeof(struct sdk_rst_if_st) == 0x20, "sdk_rst_if_st is the wrong size!"); +_Static_assert(sizeof(struct sdk_g_ic_volatile_st) == 0x1d8, "sdk_g_ic_volatile_st is the wrong size!"); +_Static_assert(sizeof(struct sdk_g_ic_saved_st) == 0x370, "sdk_g_ic_saved_st is the wrong size!"); +_Static_assert(sizeof(struct sdk_g_ic_st) == 0x548, "sdk_g_ic_st is the wrong size!"); + +/////////////////////////////////////////////////////////////////////////////// +// Function Prototypes // +/////////////////////////////////////////////////////////////////////////////// + +sdk_SpiFlashOpResult sdk_SPIRead(uint32_t src_addr, uint32_t *des_addr, uint32_t size); +sdk_SpiFlashOpResult sdk_SPIWrite(uint32_t des_addr, uint32_t *src_addr, uint32_t size); +void sdk_cnx_attach(struct sdk_g_ic_st); +void sdk_ets_timer_init(void); +void sdk_ieee80211_ifattach(struct sdk_g_ic_st, uint8_t *); +void sdk_ieee80211_phy_init(enum sdk_phy_mode); +void sdk_lmacInit(void); +void sdk_os_install_putc1( void (*func)(uint8_t) ); +void sdk_phy_disable_agc(void); +void sdk_phy_enable_agc(void); +void sdk_pm_attach(void); +void sdk_pp_attach(void); +void sdk_pp_soft_wdt_init(void); +int sdk_register_chipv6_phy(uint8_t *); +void sdk_sleep_reset_analog_rtcreg_8266(void); +uint32_t sdk_system_get_checksum(uint8_t *, uint32_t); +void sdk_system_restart_in_nmi(void); +void sdk_wDevEnableRx(void); +void sdk_wDev_Initialize(void); +void sdk_wifi_mode_set(uint8_t); +void sdk_wifi_softap_cacl_mac(uint8_t *, uint8_t *); +void sdk_wifi_softap_set_default_ssid(void); +void sdk_wifi_softap_start(void); +void sdk_wifi_station_connect(void); +bool sdk_wifi_station_get_auto_connect(void); +void sdk_wifi_station_start(void); + +#endif /* _INTERNAL_SDK_STRUCTURES_H */ diff --git a/core/include/xtensa_ops.h b/core/include/xtensa_ops.h new file mode 100644 index 0000000..49d1fbe --- /dev/null +++ b/core/include/xtensa_ops.h @@ -0,0 +1,21 @@ +/** xtensa_ops.h + * + * Special macros/etc which deal with Xtensa-specific architecture/CPU + * considerations. + * + * Part of esp-open-rtos + * Copyright (C) 2015 Superhouse Automation Pty Ltd + * BSD Licensed as described in the file LICENSE + */ + +#ifndef _XTENSA_OPS_H +#define _XTENSA_OPS_H + +// GCC macros for reading, writing, and exchanging Xtensa processor special +// registers: + +#define RSR(var, reg) asm volatile ("rsr %0, " #reg : "=r" (var)); +#define WSR(var, reg) asm volatile ("wsr %0, " #reg : : "r" (var)); +#define XSR(var, reg) asm volatile ("xsr %0, " #reg : "+r" (var)); + +#endif /* _XTENSA_OPS_H */ diff --git a/lib/libmain.remove b/lib/libmain.remove index ae569f8..35145b3 100644 --- a/lib/libmain.remove +++ b/lib/libmain.remove @@ -2,3 +2,4 @@ printf-stdarg.o libc.o xtensa_vectors.o +app_main.o