Merge in master updates

This commit is contained in:
Jeroen Domburg
2016-10-26 11:04:42 +08:00
21 changed files with 483 additions and 17 deletions

View File

@@ -8,7 +8,7 @@
# basically runs Make in the src/ directory but it needs to zero some variables
# the ESP-IDF project.mk makefile exports first, to not let them interfere.
#
ifeq ("$(IS_BOOTLOADER_BUILD)","")
ifndef IS_BOOTLOADER_BUILD
BOOTLOADER_COMPONENT_PATH := $(COMPONENT_PATH)
BOOTLOADER_BUILD_DIR=$(abspath $(BUILD_DIR_BASE)/bootloader)

View File

@@ -4,12 +4,13 @@
#
PROJECT_NAME := bootloader
COMPONENTS := esptool_py bootloader log
COMPONENTS := esptool_py bootloader log spi_flash
# The bootloader pseudo-component is also included in this build, for its Kconfig.projbuild to be included.
#
# IS_BOOTLOADER_BUILD tells the component Makefile.projbuild to be a no-op
IS_BOOTLOADER_BUILD := 1
export IS_BOOTLOADER_BUILD
#We cannot include the esp32 component directly but we need its includes.
#This is fixed by adding CFLAGS from Makefile.projbuild

View File

@@ -51,7 +51,7 @@ enum {
SPI_SPEED_20M,
SPI_SPEED_80M = 0xF
};
/*suppport flash size in esp32 */
/*supported flash sizes*/
enum {
SPI_SIZE_1MB = 0,
SPI_SIZE_2MB,

View File

@@ -58,6 +58,7 @@ void IRAM_ATTR set_cache_and_start_app(uint32_t drom_addr,
uint32_t irom_load_addr,
uint32_t irom_size,
uint32_t entry_addr);
static void update_flash_config(struct flash_hdr* pfhdr);
void IRAM_ATTR call_start_cpu0()
@@ -258,7 +259,7 @@ void bootloader_main()
memset(&bs, 0, sizeof(bs));
ESP_LOGI(TAG, "compile time " __TIME__ );
/* close watch dog here */
/* disable watch dog here */
REG_CLR_BIT( RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_FLASHBOOT_MOD_EN );
REG_CLR_BIT( TIMG_WDTCONFIG0_REG(0), TIMG_WDT_FLASHBOOT_MOD_EN );
SPIUnlock();
@@ -269,6 +270,8 @@ void bootloader_main()
print_flash_info(&fhdr);
update_flash_config(&fhdr);
if (!load_partition_table(&bs, PARTITION_ADD)) {
ESP_LOGE(TAG, "load partition table error!");
return;
@@ -364,7 +367,7 @@ void unpack_load_app(const partition_pos_t* partition)
uint32_t irom_size = 0;
/* Reload the RTC memory sections whenever a non-deepsleep reset
is occuring */
is occurring */
bool load_rtc_memory = rtc_get_reset_reason(0) != DEEPSLEEP_RESET;
ESP_LOGD(TAG, "bin_header: %u %u %u %u %08x", image_header.magic,
@@ -482,6 +485,36 @@ void IRAM_ATTR set_cache_and_start_app(
(*entry)();
}
static void update_flash_config(struct flash_hdr* pfhdr)
{
uint32_t size;
switch(pfhdr->spi_size) {
case SPI_SIZE_1MB:
size = 1;
break;
case SPI_SIZE_2MB:
size = 2;
break;
case SPI_SIZE_4MB:
size = 4;
break;
case SPI_SIZE_8MB:
size = 8;
break;
case SPI_SIZE_16MB:
size = 16;
break;
default:
size = 2;
}
Cache_Read_Disable( 0 );
// Set flash chip size
SPIParamCfg(g_rom_flashchip.deviceId, size * 0x100000, 0x10000, 0x1000, 0x100, 0xffff);
// TODO: set mode
// TODO: set frequency
Cache_Flush(0);
Cache_Read_Enable( 0 );
}
void print_flash_info(struct flash_hdr* pfhdr)
{

View File

@@ -63,10 +63,22 @@ config MEMMAP_TRACEMEM
of memory that can't be used for general purposes anymore. Disable this if you do not know
what this is.
config MEMMAP_TRACEMEM_TWOBANKS
bool "Reserve memory for tracing both pro as well as app cpu execution"
default "n"
depends on MEMMAP_TRACEMEM && MEMMAP_SMP
help
The ESP32 contains a feature which allows you to trace the execution path the processor
has taken through the program. This is stored in a chunk of 32K (16K for single-processor)
of memory that can't be used for general purposes anymore. Disable this if you do not know
what this is.
# Memory to reverse for trace, used in linker script
config TRACEMEM_RESERVE_DRAM
hex
default 0x8000 if MEMMAP_TRACEMEM
default 0x8000 if MEMMAP_TRACEMEM && MEMMAP_TRACEMEM_TWOBANKS
default 0x4000 if MEMMAP_TRACEMEM && !MEMMAP_TRACEMEM_TWOBANKS
default 0x0
config MEMMAP_SPISRAM

View File

@@ -46,6 +46,7 @@
#include "esp_brownout.h"
#include "esp_int_wdt.h"
#include "esp_task_wdt.h"
#include "trax.h"
void start_cpu0(void) __attribute__((weak, alias("start_cpu0_default")));
void start_cpu0_default(void) IRAM_ATTR;
@@ -135,6 +136,15 @@ void IRAM_ATTR call_start_cpu1()
void start_cpu0_default(void)
{
//Enable trace memory and immediately start trace.
#if CONFIG_MEMMAP_TRACEMEM
#if CONFIG_MEMMAP_TRACEMEM_TWOBANKS
trax_enable(TRAX_ENA_PRO_APP);
#else
trax_enable(TRAX_ENA_PRO);
#endif
trax_start_trace(TRAX_DOWNCOUNT_WORDS);
#endif
esp_set_cpu_freq(); // set CPU frequency configured in menuconfig
uart_div_modify(0, (APB_CLK_FREQ << 4) / 115200);
ets_setup_syscalls();
@@ -161,6 +171,9 @@ void start_cpu0_default(void)
#if !CONFIG_FREERTOS_UNICORE
void start_cpu1_default(void)
{
#if CONFIG_MEMMAP_TRACEMEM_TWOBANKS
trax_start_trace(TRAX_DOWNCOUNT_WORDS);
#endif
// Wait for FreeRTOS initialization to finish on PRO CPU
while (port_xSchedulerRunning[0] == 0) {
;

View File

@@ -186,7 +186,11 @@ void heap_alloc_caps_init() {
#endif
#if CONFIG_MEMMAP_TRACEMEM
#if CONFIG_MEMMAP_TRACEMEM_TWOBANKS
disable_mem_region((void*)0x3fff8000, (void*)0x40000000); //knock out trace mem region
#else
disable_mem_region((void*)0x3fff8000, (void*)0x3fffc000); //knock out trace mem region
#endif
#endif
#if 0

View File

@@ -218,7 +218,7 @@ void SelectSpiFunction(uint32_t ishspi);
void spi_flash_attach(uint32_t ishspi, bool legacy);
/**
* @brief SPI Read Flash status register. We use CMD 0x05.
* @brief SPI Read Flash status register. We use CMD 0x05 (RDSR).
* Please do not call this function in SDK.
*
* @param SpiFlashChip *spi : The information for Flash, which is exported from ld file.
@@ -232,7 +232,7 @@ void spi_flash_attach(uint32_t ishspi, bool legacy);
SpiFlashOpResult SPI_read_status(SpiFlashChip *spi, uint32_t *status);
/**
* @brief SPI Read Flash status register high 16 bit. We use CMD 0x35.
* @brief SPI Read Flash status register bits 8-15. We use CMD 0x35 (RDSR2).
* Please do not call this function in SDK.
*
* @param SpiFlashChip *spi : The information for Flash, which is exported from ld file.
@@ -243,7 +243,7 @@ SpiFlashOpResult SPI_read_status(SpiFlashChip *spi, uint32_t *status);
* SPI_FLASH_RESULT_ERR : read error.
* SPI_FLASH_RESULT_TIMEOUT : read timeout.
*/
SpiFlashOpResult SPI_read_status_high(SpiFlashChip *spi, uint32_t *status);
SpiFlashOpResult SPI_read_status_high(uint32_t *status);
/**
* @brief Write status to Falsh status register.
@@ -503,6 +503,12 @@ void SPI_Write_Encrypt_Disable(void);
*/
SpiFlashOpResult SPI_Encrypt_Write(uint32_t flash_addr, uint32_t *data, uint32_t len);
/** @brief Global SpiFlashChip structure used by ROM functions
*
*/
extern SpiFlashChip g_rom_flashchip;
/**
* @}
*/

View File

@@ -286,6 +286,7 @@ PROVIDE ( _global_impure_ptr = 0x3ffae0b0 );
PROVIDE ( gmtime = 0x40059848 );
PROVIDE ( gmtime_r = 0x40059868 );
PROVIDE ( g_phyFuns_instance = 0x3ffae0c4 );
PROVIDE ( g_rom_flashchip = 0x3ffae270 );
PROVIDE ( gpio_init = 0x40009c20 );
PROVIDE ( gpio_input_get = 0x40009b88 );
PROVIDE ( gpio_input_get_high = 0x40009b9c );
@@ -1584,6 +1585,8 @@ PROVIDE ( SPIEraseBlock = 0x40062c4c );
PROVIDE ( SPIEraseChip = 0x40062c14 );
PROVIDE ( SPIEraseSector = 0x40062ccc );
PROVIDE ( spi_flash_attach = 0x40062a6c );
/* NB: SPIUnlock @ 0x400628b0 has been replaced with an updated
version in the "spi_flash" component */
PROVIDE ( SPILock = 0x400628f0 );
PROVIDE ( SPIMasterReadModeCnfig = 0x40062b64 );
PROVIDE ( spi_modes = 0x3ff99270 );
@@ -1595,9 +1598,8 @@ PROVIDE ( SPIReadModeCnfig = 0x40062944 );
PROVIDE ( SPI_read_status = 0x4006226c );
/* This is static function, but can be used, not generated by script*/
PROVIDE ( SPI_read_status_high = 0x40062448 );
PROVIDE ( SPIUnlock = 0x400628b0 );
PROVIDE ( SPI_user_command_read = 0x400621b0 );
PROVIDE ( spi_w25q16 = 0x3ffae270 );
PROVIDE ( SPI_flashchip_data = 0x3ffae270 );
PROVIDE ( SPIWrite = 0x40062d50 );
/* This is static function, but can be used, not generated by script*/
PROVIDE ( SPI_write_enable = 0x40062320 );

View File

@@ -94,4 +94,31 @@ config ESPTOOLPY_FLASHFREQ
default "26m" if ESPTOOLPY_FLASHFREQ_26M
default "20m" if ESPTOOLPY_FLASHFREQ_20M
choice ESPTOOLPY_FLASHSIZE
prompt "Flash size"
default ESPTOOLPY_FLASHSIZE_2MB
help
SPI flash size, in megabytes
config ESPTOOLPY_FLASHSIZE_1MB
bool "1 MB"
config ESPTOOLPY_FLASHSIZE_2MB
bool "2 MB"
config ESPTOOLPY_FLASHSIZE_4MB
bool "4 MB"
config ESPTOOLPY_FLASHSIZE_8MB
bool "8 MB"
config ESPTOOLPY_FLASHSIZE_16MB
bool "16 MB"
endchoice
config ESPTOOLPY_FLASHSIZE
string
default "1MB" if ESPTOOLPY_FLASHSIZE_1MB
default "2MB" if ESPTOOLPY_FLASHSIZE_2MB
default "4MB" if ESPTOOLPY_FLASHSIZE_4MB
default "8MB" if ESPTOOLPY_FLASHSIZE_8MB
default "16MB" if ESPTOOLPY_FLASHSIZE_16MB
endmenu

View File

@@ -4,6 +4,7 @@ ESPPORT ?= $(CONFIG_ESPTOOLPY_PORT)
ESPBAUD ?= $(CONFIG_ESPTOOLPY_BAUD)
ESPFLASHMODE ?= $(CONFIG_ESPTOOLPY_FLASHMODE)
ESPFLASHFREQ ?= $(CONFIG_ESPTOOLPY_FLASHFREQ)
ESPFLASHSIZE ?= $(CONFIG_ESPTOOLPY_FLASHSIZE)
PYTHON ?= $(call dequote,$(CONFIG_PYTHON))
@@ -15,13 +16,15 @@ ESPTOOLPY_SRC := $(COMPONENT_PATH)/esptool/esptool.py
ESPTOOLPY := $(PYTHON) $(ESPTOOLPY_SRC) --chip esp32
ESPTOOLPY_SERIAL := $(ESPTOOLPY) --port $(ESPPORT) --baud $(ESPBAUD)
ESPTOOL_FLASH_OPTIONS := --flash_mode $(ESPFLASHMODE) --flash_freq $(ESPFLASHFREQ) --flash_size $(ESPFLASHSIZE)
# the no-stub argument is temporary until esptool.py fully supports compressed uploads
ESPTOOLPY_WRITE_FLASH=$(ESPTOOLPY_SERIAL) write_flash $(if $(CONFIG_ESPTOOLPY_COMPRESSED),-z) --flash_mode $(ESPFLASHMODE) --flash_freq $(ESPFLASHFREQ)
ESPTOOLPY_WRITE_FLASH=$(ESPTOOLPY_SERIAL) write_flash $(if $(CONFIG_ESPTOOLPY_COMPRESSED),-z) $(ESPTOOL_FLASH_OPTIONS)
ESPTOOL_ALL_FLASH_ARGS += $(CONFIG_APP_OFFSET) $(APP_BIN)
$(APP_BIN): $(APP_ELF) $(ESPTOOLPY_SRC)
$(Q) $(ESPTOOLPY) elf2image --flash_mode $(ESPFLASHMODE) --flash_freq $(ESPFLASHFREQ) -o $@ $<
$(Q) $(ESPTOOLPY) elf2image $(ESPTOOL_FLASH_OPTIONS) -o $@ $<
flash: all_binaries $(ESPTOOLPY_SRC)
@echo "Flashing binaries to serial port $(ESPPORT) (app at offset $(CONFIG_APP_OFFSET))..."

View File

@@ -3784,9 +3784,8 @@ In fact, nothing below this line has/is.
/* Gotcha (which seems to be deliberate in FreeRTOS, according to
http://www.freertos.org/FreeRTOS_Support_Forum_Archive/December_2012/freertos_PIC32_Bug_-_vTaskEnterCritical_6400806.html
) is that calling vTaskEnterCritical followed by vTaskExitCritical will leave the interrupts DISABLED! Re-enabling the
scheduler will re-enable the interrupts instead. */
) is that calling vTaskEnterCritical followed by vTaskExitCritical will leave the interrupts DISABLED when the scheduler
is not running. Re-enabling the scheduler will re-enable the interrupts instead. */
#if ( portCRITICAL_NESTING_IN_TCB == 1 )

View File

@@ -1,3 +1,8 @@
COMPONENT_ADD_INCLUDEDIRS := include
ifdef IS_BOOTLOADER_BUILD
# Bootloader needs updated SPIUnlock from this file
COMPONENT_OBJS := spi_flash_rom_patch.o
endif
include $(IDF_PATH)/make/component_common.mk

View File

@@ -0,0 +1,72 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "rom/spi_flash.h"
#include "soc/spi_reg.h"
static const uint32_t STATUS_QIE_BIT = (1 << 9); /* Quad Enable */
#define SPI_IDX 1
#define OTH_IDX 0
extern SpiFlashChip SPI_flashchip_data;
static void IRAM_ATTR Wait_SPI_Idle(void)
{
/* Wait for SPI state machine to be idle */
while((REG_READ(SPI_EXT2_REG(SPI_IDX)) & SPI_ST)) {
}
while(REG_READ(SPI_EXT2_REG(OTH_IDX)) & SPI_ST) {
}
}
/* Modified version of SPIUnlock() that replaces version in ROM.
This works around a bug where SPIUnlock sometimes reads the wrong
high status byte (RDSR2 result) and then copies it back to the
flash status, which can cause the CMP bit or Status Register
Protect bit to become set.
Like other ROM SPI functions, this function is not designed to be
called directly from an RTOS environment without taking precautions
about interrupts, CPU coordination, flash mapping. However some of
the functions in esp_spi_flash.c call it.
*/
SpiFlashOpResult IRAM_ATTR SPIUnlock(void)
{
uint32_t status;
Wait_SPI_Idle();
if (SPI_read_status_high(&status) != SPI_FLASH_RESULT_OK) {
return SPI_FLASH_RESULT_ERR;
}
/* Clear all bits except QIE, if it is set.
(This is different from ROM SPIUnlock, which keeps all bits as-is.)
*/
status &= STATUS_QIE_BIT;
Wait_SPI_Idle();
REG_WRITE(SPI_CMD_REG(SPI_IDX), SPI_FLASH_WREN);
while(REG_READ(SPI_CMD_REG(SPI_IDX)) != 0) {
}
Wait_SPI_Idle();
SET_PERI_REG_MASK(SPI_CTRL_REG(SPI_IDX), SPI_WRSR_2B);
if (SPI_write_status(&SPI_flashchip_data, status) != SPI_FLASH_RESULT_OK) {
return SPI_FLASH_RESULT_ERR;
}
return SPI_FLASH_RESULT_OK;
}

View File

@@ -0,0 +1,5 @@
#
# Component Makefile
#
include $(IDF_PATH)/make/component_common.mk

View File

@@ -0,0 +1,32 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdint.h>
#include "eri.h"
uint32_t eri_read(int addr) {
uint32_t ret;
asm(
"RER %0,%1"
:"=r"(ret):"r"(addr)
);
return ret;
}
void eri_write(int addr, uint32_t data) {
asm volatile (
"WER %0,%1"
::"r"(data),"r"(addr)
);
}

View File

@@ -0,0 +1,31 @@
#ifndef ERI_H
#define ERI_H
#include <stdint.h>
/*
The ERI is a bus internal to each Xtensa core. It connects, amongst others, to the debug interface, where it
allows reading/writing the same registers as available over JTAG.
*/
/**
* @brief Perform an ERI read
* @param addr : ERI register to read from
*
* @return Value read
*/
uint32_t eri_read(int addr);
/**
* @brief Perform an ERI write
* @param addr : ERI register to write to
* @param data : Value to write
*
* @return Value read
*/
void eri_write(int addr, uint32_t data);
#endif

View File

@@ -0,0 +1,62 @@
#include "soc/dport_reg.h"
#include "sdkconfig.h"
#include "esp_err.h"
#include "eri.h"
#include "xtensa-debug-module.h"
typedef enum {
TRAX_DOWNCOUNT_WORDS,
TRAX_DOWNCOUNT_INSTRUCTIONS
} trax_downcount_unit_t;
typedef enum {
TRAX_ENA_NONE = 0,
TRAX_ENA_PRO,
TRAX_ENA_APP,
TRAX_ENA_PRO_APP,
TRAX_ENA_PRO_APP_SWAP
} trax_ena_select_t;
/**
* @brief Enable the trax memory blocks to be used as Trax memory.
*
* @param pro_cpu_enable : true if Trax needs to be enabled for the pro CPU
* @param app_cpu_enable : true if Trax needs to be enabled for the pro CPU
* @param swap_regions : Normally, the pro CPU writes to Trax mem block 0 while
* the app cpu writes to block 1. Setting this to true
* inverts this.
*
* @return esp_err_t. Fails with ESP_ERR_NO_MEM if Trax enable is requested for 2 CPUs
* but memmap only has room for 1, or if Trax memmap is disabled
* entirely.
*/
int trax_enable(trax_ena_select_t ena);
/**
* @brief Start a Trax trace on the current CPU
*
* @param units_until_stop : Set the units of the delay that gets passed to
* trax_trigger_traceend_after_delay. One of TRAX_DOWNCOUNT_WORDS
* or TRAX_DOWNCOUNT_INSTRUCTIONS.
*
* @return esp_err_t. Fails with ESP_ERR_NO_MEM if Trax is disabled.
*/
int trax_start_trace(trax_downcount_unit_t units_until_stop);
/**
* @brief Trigger a Trax trace stop after the indicated delay. If this is called
* before and the previous delay hasn't ended yet, this will overwrite
* that delay with the new value. The delay will always start at the time
* the function is called.
*
* @param delay : The delay to stop the trace in, in the unit indicated to
* trax_start_trace. Note: the trace memory has 4K words available.
*
* @return esp_err_t
*/
int trax_trigger_traceend_after_delay(int delay);

View File

@@ -0,0 +1,75 @@
#ifndef XTENSA_DEBUG_MODULE_H
#define XTENSA_DEBUG_MODULE_H
/*
ERI registers / OCD offsets and field definitions
*/
#define ERI_DEBUG_OFFSET 0x100000
#define ERI_TRAX_OFFSET (ERI_DEBUG_OFFSET+0)
#define ERI_PERFMON_OFFSET (ERI_DEBUG_OFFSET+0x1000)
#define ERI_OCDREG_OFFSET (ERI_DEBUG_OFFSET+0x2000)
#define ERI_MISCDBG_OFFSET (ERI_DEBUG_OFFSET+0x3000)
#define ERI_CORESIGHT_OFFSET (ERI_DEBUG_OFFSET+0x3F00)
#define ERI_TRAX_TRAXID (ERI_TRAX_OFFSET+0x00)
#define ERI_TRAX_TRAXCTRL (ERI_TRAX_OFFSET+0x04)
#define ERI_TRAX_TRAXSTAT (ERI_TRAX_OFFSET+0x08)
#define ERI_TRAX_TRAXDATA (ERI_TRAX_OFFSET+0x0C)
#define ERI_TRAX_TRAXADDR (ERI_TRAX_OFFSET+0x10)
#define ERI_TRAX_TRIGGERPC (ERI_TRAX_OFFSET+0x14)
#define ERI_TRAX_PCMATCHCTRL (ERI_TRAX_OFFSET+0x18)
#define ERI_TRAX_DELAYCNT (ERI_TRAX_OFFSET+0x1C)
#define ERI_TRAX_MEMADDRSTART (ERI_TRAX_OFFSET+0x20)
#define ERI_TRAX_MEMADDREND (ERI_TRAX_OFFSET+0x24)
#define TRAXCTRL_TREN (1<<0) //Trace enable. Tracing starts on 0->1
#define TRAXCTRL_TRSTP (1<<1) //Trace Stop. Make 1 to stop trace.
#define TRAXCTRL_PCMEN (1<<2) //PC match enable
#define TRAXCTRL_PTIEN (1<<4) //Processor-trigger enable
#define TRAXCTRL_CTIEN (1<<5) //Cross-trigger enable
#define TRAXCTRL_TMEN (1<<7) //Tracemem Enable. Always set.
#define TRAXCTRL_CNTU (1<<9) //Post-stop-trigger countdown units; selects when DelayCount-- happens.
//0 - every 32-bit word written to tracemem, 1 - every cpu instruction
#define TRAXCTRL_TSEN (1<<11) //Undocumented/deprecated?
#define TRAXCTRL_SMPER_SHIFT 12 //Send sync every 2^(9-smper) messages. 7=reserved, 0=no sync msg
#define TRAXCTRL_SMPER_MASK 0x7 //Synchronization message period
#define TRAXCTRL_PTOWT (1<<16) //Processor Trigger Out (OCD halt) enabled when stop triggered
#define TRAXCTRL_PTOWS (1<<17) //Processor Trigger Out (OCD halt) enabled when trace stop completes
#define TRAXCTRL_CTOWT (1<<20) //Cross-trigger Out enabled when stop triggered
#define TRAXCTRL_CTOWS (1<<21) //Cross-trigger Out enabled when trace stop completes
#define TRAXCTRL_ITCTO (1<<22) //Integration mode: cross-trigger output
#define TRAXCTRL_ITCTIA (1<<23) //Integration mode: cross-trigger ack
#define TRAXCTRL_ITATV (1<<24) //replaces ATID when in integration mode: ATVALID output
#define TRAXCTRL_ATID_MASK 0x7F //ARB source ID
#define TRAXCTRL_ATID_SHIFT 24
#define TRAXCTRL_ATEN (1<<31) //ATB interface enable
#define TRAXSTAT_TRACT (1<<0) //Trace active flag.
#define TRAXSTAT_TRIG (1<<1) //Trace stop trigger. Clears on TREN 1->0
#define TRAXSTAT_PCMTG (1<<2) //Stop trigger caused by PC match. Clears on TREN 1->0
#define TRAXSTAT_PJTR (1<<3) //JTAG transaction result. 1=err in preceding jtag transaction.
#define TRAXSTAT_PTITG (1<<4) //Stop trigger caused by Processor Trigger Input. Clears on TREN 1->0
#define TRAXSTAT_CTITG (1<<5) //Stop trigger caused by Cross-Trigger Input. Clears on TREN 1->0
#define TRAXSTAT_MEMSZ_SHIFT 8 //Traceram size inducator. Usable trace ram is 2^MEMSZ bytes.
#define TRAXSTAT_MEMSZ_MASK 0x1F
#define TRAXSTAT_PTO (1<<16) //Processor Trigger Output: current value
#define TRAXSTAT_CTO (1<<17) //Cross-Trigger Output: current value
#define TRAXSTAT_ITCTOA (1<<22) //Cross-Trigger Out Ack: current value
#define TRAXSTAT_ITCTI (1<<23) //Cross-Trigger Input: current value
#define TRAXSTAT_ITATR (1<<24) //ATREADY Input: current value
#define TRAXADDR_TADDR_SHIFT 0 //Trax memory address, in 32-bit words.
#define TRAXADDR_TADDR_MASK 0x1FFFFF //Actually is only as big as the trace buffer size max addr.
#define TRAXADDR_TWRAP_SHIFT 21 //Amount of times TADDR has overflown
#define TRAXADDR_TWRAP_MASK 0x3FF
#define TRAXADDR_TWSAT (1<<31) //1 if TWRAP has overflown, clear by disabling tren.
#define PCMATCHCTRL_PCML_SHIFT 0 //Amount of lower bits to ignore in pc trigger register
#define PCMATCHCTRL_PCML_MASK 0x1F
#define PCMATCHCTRL_PCMS (1<<31) //PC Match Sense, 0 - match when procs PC is in-range, 1 - match when
//out-of-range
#endif

View File

@@ -0,0 +1,84 @@
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include <stdio.h>
#include "soc/dport_reg.h"
#include "sdkconfig.h"
#include "esp_err.h"
#include "eri.h"
#include "xtensa-debug-module.h"
#include "trax.h"
#include "esp_log.h"
#define TRACEMEM_MUX_PROBLK0_APPBLK1 0
#define TRACEMEM_MUX_BLK0_ONLY 1
#define TRACEMEM_MUX_BLK1_ONLY 2
#define TRACEMEM_MUX_PROBLK1_APPBLK0 3
static const char* TAG = "trax";
int trax_enable(trax_ena_select_t which)
{
#if !CONFIG_MEMMAP_TRACEMEM
ESP_LOGE(TAG, "Trax_enable called, but trax is disabled in menuconfig!");
return ESP_ERR_NO_MEM;
#endif
#if !CONFIG_MEMMAP_TRACEMEM_TWOBANKS
if (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP) return ESP_ERR_NO_MEM;
#endif
if (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP) {
WRITE_PERI_REG(DPORT_TRACEMEM_MUX_MODE_REG, (which == TRAX_ENA_PRO_APP_SWAP)?TRACEMEM_MUX_PROBLK1_APPBLK0:TRACEMEM_MUX_PROBLK0_APPBLK1);
} else {
WRITE_PERI_REG(DPORT_TRACEMEM_MUX_MODE_REG, TRACEMEM_MUX_BLK0_ONLY);
}
WRITE_PERI_REG(DPORT_PRO_TRACEMEM_ENA_REG, (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP || which == TRAX_ENA_PRO));
WRITE_PERI_REG(DPORT_APP_TRACEMEM_ENA_REG, (which == TRAX_ENA_PRO_APP || which == TRAX_ENA_PRO_APP_SWAP || which == TRAX_ENA_APP));
return ESP_OK;
}
int trax_start_trace(trax_downcount_unit_t units_until_stop)
{
#if !CONFIG_MEMMAP_TRACEMEM
ESP_LOGE(TAG, "Trax_start_trace called, but trax is disabled in menuconfig!");
return ESP_ERR_NO_MEM;
#endif
uint32_t v;
if (eri_read(ERI_TRAX_TRAXSTAT)&TRAXSTAT_TRACT) {
ESP_LOGI(TAG, "Stopping active trace first.");
//Trace is active. Stop trace.
eri_write(ERI_TRAX_DELAYCNT, 0);
eri_write(ERI_TRAX_TRAXCTRL, eri_read(ERI_TRAX_TRAXCTRL)|TRAXCTRL_TRSTP);
//ToDo: This will probably trigger a trace done interrupt. ToDo: Fix, but how? -JD
eri_write(ERI_TRAX_TRAXCTRL, 0);
}
eri_write(ERI_TRAX_PCMATCHCTRL, 31); //do not stop at any pc match
v=TRAXCTRL_TREN | TRAXCTRL_TMEN | TRAXCTRL_PTOWS | (1<<TRAXCTRL_SMPER_SHIFT);
if (units_until_stop == TRAX_DOWNCOUNT_INSTRUCTIONS) v|=TRAXCTRL_CNTU;
//Enable trace. This trace has no stop condition and will just keep on running.
eri_write(ERI_TRAX_TRAXCTRL, v);
return ESP_OK;
}
int trax_trigger_traceend_after_delay(int delay)
{
#if !CONFIG_MEMMAP_TRACEMEM
ESP_LOGE(TAG, "Trax_trigger_traceend_after_delay called, but trax is disabled in menuconfig!");
return ESP_ERR_NO_MEM;
#endif
eri_write(ERI_TRAX_DELAYCNT, delay);
eri_write(ERI_TRAX_TRAXCTRL, eri_read(ERI_TRAX_TRAXCTRL)|TRAXCTRL_TRSTP);
return ESP_OK;
}