You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by an...@apache.org on 2020/11/25 12:07:57 UTC
[mynewt-core] branch master updated (60361f2 -> 5f5cb2b)
This is an automated email from the ASF dual-hosted git repository.
andk pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git.
from 60361f2 nucleo: Add missing BUTTON_1 definitions
new c4c5236 hw/mcu/dialog: Add support for Micro Trace Buffer (MTB)
new 592f61e hw/mcu/dialog: Fix msplim handling
new 6533786 hw/mcu/dialog: Add helpers to control MTB
new d2109a9 kernel/os/arch: Stop M33-MTB on exception
new 5f5cb2b hw/scripts: Add GDB script to handle MTB
The 5 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
.../src/arch/cortex_m33/gcc_startup_da1469x.S | 27 +++
hw/mcu/dialog/da1469x/da1469x.ld | 9 +-
hw/mcu/dialog/da1469x/include/mcu/cortex_m33.h | 15 ++
.../src/arch/cortex_m33/da1469x_m33_sleep.S | 25 +++
hw/mcu/dialog/da1469x/src/hal_system_start.c | 6 +-
hw/mcu/dialog/da1469x/src/system_da1469x.c | 5 +
hw/mcu/dialog/da1469x/syscfg.yml | 13 ++
hw/scripts/micro-trace-buffer.py | 227 +++++++++++++++++++++
kernel/os/src/arch/cortex_m33/os_fault.c | 17 ++
9 files changed, 342 insertions(+), 2 deletions(-)
create mode 100644 hw/scripts/micro-trace-buffer.py
[mynewt-core] 03/05: hw/mcu/dialog: Add helpers to control MTB
Posted by an...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
andk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
commit 65337861c0c2ac57ca8550ee1adb39bac7690965
Author: Andrzej Kaczmarek <an...@codecoup.pl>
AuthorDate: Sat Nov 21 01:39:02 2020 +0100
hw/mcu/dialog: Add helpers to control MTB
These helpers allow to enable/disable MTB tracing from code. It may be
useful to start tracing for interesting pieces of code, or temporarily
disable for uniteresting pieces of code to spare buffer space (e.g.
on some long loops that create a lot of branches).
---
hw/mcu/dialog/da1469x/include/mcu/cortex_m33.h | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/hw/mcu/dialog/da1469x/include/mcu/cortex_m33.h b/hw/mcu/dialog/da1469x/include/mcu/cortex_m33.h
index c981e63..297facd 100644
--- a/hw/mcu/dialog/da1469x/include/mcu/cortex_m33.h
+++ b/hw/mcu/dialog/da1469x/include/mcu/cortex_m33.h
@@ -35,6 +35,21 @@ hal_debug_break(void)
__BKPT(1);
}
+static inline void
+mcu_mtb_enable(void)
+{
+ *(uint32_t *)0xe0043004 |= (1 << 31);
+ __DSB();
+ __ISB();
+}
+
+static inline void
+mcu_mtb_disable(void)
+{
+ __ISB();
+ *(uint32_t *)0xe0043004 &= ~(1 << 31);
+}
+
#ifdef __cplusplus
}
#endif
[mynewt-core] 02/05: hw/mcu/dialog: Fix msplim handling
Posted by an...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
andk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
commit 592f61efd0762e63f59dec3a6d0755bee052e33a
Author: Andrzej Kaczmarek <an...@codecoup.pl>
AuthorDate: Sat Nov 21 01:34:29 2020 +0100
hw/mcu/dialog: Fix msplim handling
We have stack checking enabled by default and it can be triggered if
app has different stack location than bootloader or, in case of RAM
app, different than current app.
To avoid this we should reset MSPLIM before jumping from bootloader
to app and also when starting RAM app.
---
.../dialog_da1469x-dk-pro/src/arch/cortex_m33/gcc_startup_da1469x.S | 5 +++++
hw/mcu/dialog/da1469x/src/hal_system_start.c | 6 +++++-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/hw/bsp/dialog_da1469x-dk-pro/src/arch/cortex_m33/gcc_startup_da1469x.S b/hw/bsp/dialog_da1469x-dk-pro/src/arch/cortex_m33/gcc_startup_da1469x.S
index d173f79..c5e1281 100644
--- a/hw/bsp/dialog_da1469x-dk-pro/src/arch/cortex_m33/gcc_startup_da1469x.S
+++ b/hw/bsp/dialog_da1469x-dk-pro/src/arch/cortex_m33/gcc_startup_da1469x.S
@@ -157,6 +157,11 @@ wakeup_handler:
.globl Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
+#if MYNEWT_VAL(RAM_RESIDENT)
+ mov r0, #0
+ msr msplim, r0
+#endif
+
#if MYNEWT_VAL(MCU_MTB_ENABLE)
mov r2, #0
ldr r1, =MTB_POSITION_REG
diff --git a/hw/mcu/dialog/da1469x/src/hal_system_start.c b/hw/mcu/dialog/da1469x/src/hal_system_start.c
index 62f00fe..2445f9c 100644
--- a/hw/mcu/dialog/da1469x/src/hal_system_start.c
+++ b/hw/mcu/dialog/da1469x/src/hal_system_start.c
@@ -47,12 +47,16 @@ hal_system_start(void *img_start)
img_data = (uint32_t *)img_data_addr;
asm volatile (".syntax unified \n"
+ /* Reset MSPLIM */
+ " mov r0, #0 \n"
+ " msr msplim, r0 \n"
/* 1st word is stack pointer */
" msr msp, %0 \n"
/* 2nd word is a reset handler (image entry) */
" bx %1 \n"
: /* no output */
- : "r" (img_data[0]), "r" (img_data[1]));
+ : "r" (img_data[0]), "r" (img_data[1])
+ : "r0");
}
void
[mynewt-core] 05/05: hw/scripts: Add GDB script to handle MTB
Posted by an...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
andk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
commit 5f5cb2bfd6c4d9f4bdd18f566c380cf4f0164b1b
Author: Andrzej Kaczmarek <an...@codecoup.pl>
AuthorDate: Mon Nov 23 17:46:18 2020 +0100
hw/scripts: Add GDB script to handle MTB
This adds script for GDB to easily analyze Micro Trace Buffer (MTB)
contents. A new "mtb" command is available in GDB:
- "mtb base" -> set base address for MTB, default is 0xe0043000 (CM33)
- "mtb enable" -> enables MTB (has to be already configured!)
- "mtb disable" -> disables MTB
- "mtb decode" -> decodes current MTB contents; it prints complete
disassembled trace along with source code if proper
symbol file is loaded and sources are available
- "mtb colors <on/off>" -> enables/disables colors in decoder output,
disabled by default and requires colorama
module
As a convenient shortcut, plain "mtb" command defaults to "mtb decode".
That means if MCU has MTB already configured and enabled, it's enough
to just issue that command to get valid output.
---
hw/scripts/micro-trace-buffer.py | 227 +++++++++++++++++++++++++++++++++++++++
1 file changed, 227 insertions(+)
diff --git a/hw/scripts/micro-trace-buffer.py b/hw/scripts/micro-trace-buffer.py
new file mode 100644
index 0000000..80df78e
--- /dev/null
+++ b/hw/scripts/micro-trace-buffer.py
@@ -0,0 +1,227 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you 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.
+
+try:
+ import colorama
+except ImportError:
+ pass
+import re
+
+
+class MicroTraceBuffer(gdb.Command):
+ _arch = None
+ _file = None
+ _func = None
+ _line = None
+ _src_file = None
+ _src_lines = None
+
+ _mtb_base_addr = 0xe0043000
+
+ _colorize = False
+ _colors = {}
+
+ def __init__(self):
+ super(MicroTraceBuffer, self).__init__("mtb", gdb.COMMAND_STATUS, gdb.COMPLETE_NONE)
+ if colorama:
+ self._colors = {"A": colorama.Fore.BLUE,
+ "D": colorama.Fore.RESET,
+ "E": colorama.Fore.GREEN,
+ "F": colorama.Fore.YELLOW,
+ "L": colorama.Fore.RESET,
+ "S": colorama.Fore.RESET,
+ "X": colorama.Fore.RED}
+
+ def _print(self, s: str):
+ def repl(m):
+ if m.group(1) in self._colors:
+ return self._colors[m.group(1)]
+ else:
+ return colorama.Fore.RESET
+
+ if not colorama or not self._colorize:
+ s = re.sub(r"~([A-Z])~", "", s)
+ else:
+ s = re.sub(r"~([A-Z])~", repl, s) + colorama.Style.RESET_ALL
+ print(s)
+
+ def _get_src(self, file, line):
+ if file != self._src_file:
+ self._src_file = file
+ try:
+ f = open(file, "r")
+ self._src_lines = f.readlines()
+ except OSError:
+ self._src_lines = None
+
+ if not self._src_lines:
+ return "<not found>"
+
+ src = self._src_lines[line - 1].strip()
+ return src
+
+ def _describe_instr(self, addr: int, asm: str):
+ blk = gdb.block_for_pc(addr)
+ while blk and not blk.function:
+ blk = blk.superblock
+ func = str(blk.function) if blk else "<unknown>"
+
+ pcl = gdb.find_pc_line(addr)
+ file = pcl.symtab.filename if pcl.symtab else "<unknown>"
+ line = pcl.line
+
+ if (self._file != file) or (self._func != func):
+ self._file = file
+ self._func = func
+ self._print(f"~F~{func} ~R~@ ~E~{file}")
+
+ if self._line != line:
+ self._line = line
+ if pcl.symtab:
+ fname = pcl.symtab.fullname()
+ src = self._get_src(fname, line)
+ self._print(f"~L~{line}\t~S~{src}")
+
+ self._print(f" ~A~0x{addr:08x}: ~D~{asm}")
+
+ def _disassemble(self, start: int, end: int):
+ disasm = self._arch.disassemble(start, end)
+ for instr in disasm:
+ addr = instr["addr"]
+ asm = instr["asm"].expandtabs(8)
+ self._describe_instr(addr, asm)
+ print()
+
+ def _cmd_decode(self):
+ print(f"NOTE: using 0x{self._mtb_base_addr:08x} as MTB base address")
+ print()
+
+ u32_ptr_t = gdb.lookup_type("uint32_t").pointer()
+ mtb_reg_pos = int(gdb.Value(self._mtb_base_addr).cast(u32_ptr_t).dereference())
+ mtb_reg_master = int(gdb.Value(self._mtb_base_addr + 0x04).cast(u32_ptr_t).dereference())
+ mtb_reg_base = int(gdb.Value(self._mtb_base_addr + 0x0c).cast(u32_ptr_t).dereference())
+
+ # size of trace buffer
+ mtb_size = 1 << ((mtb_reg_master & 0x1f) + 4)
+
+ # check buffer position
+ mtb_wrap = bool(mtb_reg_pos & 0x04)
+ mtb_reg_pos = mtb_reg_pos & 0xfffffff8
+
+ # if pointer already wrapped, we start at current entry and process complete buffer,
+ # otherwise we start at beginning and process up to current entry
+ mtb_size = mtb_size if mtb_wrap else mtb_reg_pos
+ mtb_reg_pos = mtb_reg_pos if mtb_wrap else 0
+
+ # use current frame to get architecture for later disassembling
+ self._arch = gdb.newest_frame().architecture()
+
+ mtb_pkt_dst = None
+
+ for pos in range(0, mtb_size, 8):
+ exec_begin = mtb_pkt_dst
+
+ mtb_pkt = mtb_reg_base + (mtb_reg_pos + pos) % mtb_size
+ mtb_pkt_src = int(gdb.Value(mtb_pkt).cast(u32_ptr_t).dereference())
+ mtb_pkt_dst = int(gdb.Value(mtb_pkt + 4).cast(u32_ptr_t).dereference())
+
+ bit_a = mtb_pkt_src & 1
+ bit_s = mtb_pkt_dst & 1
+
+ mtb_pkt_src = mtb_pkt_src & 0xfffffffe
+ mtb_pkt_dst = mtb_pkt_dst & 0xfffffffe
+
+ # print(f"pkt> 0x{mtb_pkt_src:08x} -> 0x{mtb_pkt_dst:08x} A:{bit_a} S:{bit_s}")
+
+ exec_end = mtb_pkt_src
+
+ # exception entry/exit events are handled separately
+ if bit_a != 0:
+ if mtb_pkt_src & 0xff000000 == 0xff000000:
+ self._print(f"~X~Exception return (LR: 0x{mtb_pkt_src:08x}, "
+ f"ret address: 0x{mtb_pkt_dst:08x})")
+ else:
+ self._print(f"~X~Exception entry (ret address: 0x{mtb_pkt_src:08x})")
+ print()
+ continue
+
+ # on 1st entry in trace buffer, disassemble source of the branch
+ if exec_begin is None:
+ self._disassemble(mtb_pkt_src, mtb_pkt_src)
+ continue
+
+ # on 1st entry after MTB was enabled, disasssemble source of the branch
+ if bit_s != 0:
+ self._disassemble(mtb_pkt_src, mtb_pkt_src)
+ continue
+
+ # print(f"exe> 0x{exec_begin:08x} -> 0x{exec_end:08x}")
+
+ self._disassemble(exec_begin, exec_end)
+
+ # disassemble target of last branch
+ self._disassemble(mtb_pkt_dst, mtb_pkt_dst)
+
+ def _cmd_colors(self, args):
+ for arg in args:
+ if arg == "on":
+ self._colorize = True
+ elif arg == "off":
+ self._colorize = False
+ else:
+ # TODO: handle colors configuration
+ pass
+
+ def _cmd_enable(self):
+ u32_ptr_t = gdb.lookup_type("uint32_t").pointer()
+ addr = self._mtb_base_addr + 0x04
+ mtb_reg_master = int(gdb.Value(addr).cast(u32_ptr_t).dereference())
+ mtb_reg_master = mtb_reg_master | 0x80000000
+ gdb.execute(f"set *0x{addr:08x} = 0x{mtb_reg_master:08x}")
+
+ def _cmd_disable(self):
+ u32_ptr_t = gdb.lookup_type("uint32_t").pointer()
+ addr = self._mtb_base_addr + 0x04
+ mtb_reg_master = int(gdb.Value(addr).cast(u32_ptr_t).dereference())
+ mtb_reg_master = mtb_reg_master & 0x7fffffff
+ gdb.execute(f"set *0x{addr:08x} = 0x{mtb_reg_master:08x}")
+
+ def _cmd_base(self, arg):
+ try:
+ addr = int(arg, 0)
+ self._mtb_base_addr = addr
+ print(f"MTB base address set to 0x{self._mtb_base_addr:08x}")
+ except ValueError:
+ print(f"Invalid value for MTB base address")
+
+ def invoke(self, arg: str, from_tty: bool):
+ args = arg.split(" ")
+ if len(args[0]) == 0 or args[0] == "decode":
+ self._cmd_decode()
+ elif args[0] == "colors":
+ self._cmd_colors(args[1:])
+ elif args[0] == "enable":
+ self._cmd_enable()
+ elif args[0] == "disable":
+ self._cmd_disable()
+ elif args[0] == "base":
+ self._cmd_base(args[1])
+ else:
+ print("wut?")
+
+
+MicroTraceBuffer()
[mynewt-core] 04/05: kernel/os/arch: Stop M33-MTB on exception
Posted by an...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
andk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
commit d2109a94881c93186732c39672b2659bd9bf930b
Author: Andrzej Kaczmarek <an...@codecoup.pl>
AuthorDate: Sat Nov 21 01:40:52 2020 +0100
kernel/os/arch: Stop M33-MTB on exception
If MTB is enabled, we should better stop it in exception handler so
we do not overwrite potentially interesting trace data with not so
interesting trace data for exception handler.
We also need to check if MTB is available on given MCU since this is
optional feature for Cortex-M33.
---
kernel/os/src/arch/cortex_m33/os_fault.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/kernel/os/src/arch/cortex_m33/os_fault.c b/kernel/os/src/arch/cortex_m33/os_fault.c
index 5c45da9..c4d7cbc 100644
--- a/kernel/os/src/arch/cortex_m33/os_fault.c
+++ b/kernel/os/src/arch/cortex_m33/os_fault.c
@@ -163,6 +163,23 @@ os_default_irq(struct trap_frame *tf)
uint32_t orig_sp;
#endif
+ /* Stop MTB if implemented so interrupt handler execution is not recorded */
+ asm volatile (".syntax unified \n"
+ " ldr r1, =0xe00ff000 \n"
+ " ldr r2, [r1, #0x1c] \n"
+ " tst r2, #1 \n"
+ " beq 1f \n"
+ " bic r2, #0x00ff \n"
+ " bic r2, #0x0f00 \n"
+ " add r1, r2 \n"
+ " ldr r2, [r1, #4] \n"
+ " bic r2, #0x80000000 \n"
+ " str r2, [r1, #4] \n"
+ " 1: \n"
+ :
+ :
+ : "r1", "r2");
+
console_blocking_mode();
console_printf("Unhandled interrupt (%ld), exception sp 0x%08lx\n",
SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk, (uint32_t)tf->ef);
[mynewt-core] 01/05: hw/mcu/dialog: Add support for Micro Trace
Buffer (MTB)
Posted by an...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
andk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
commit c4c5236fd867ed2fadd509be9127d637604ecfa0
Author: Andrzej Kaczmarek <an...@codecoup.pl>
AuthorDate: Sat Nov 21 01:27:53 2020 +0100
hw/mcu/dialog: Add support for Micro Trace Buffer (MTB)
This adds support for Micro Trace Buffer (MTB) which allows to store
trace information of executed instructions in dedicated RAM area.
Stored data can be then used to recreate exact program flow.
MTB support is enabled by "MCU_MTB_ENABLE: 1". This will configure
MTB on boot, enable code which persists MTB registers state in deep
sleep and also reserves last 8KB of RAM for trace buffer.
Additionally, by setting "MCU_MTB_AUTO_START: 1", MTB is enabled on
boot.
Note that enabling MTB changes main stack location since it cannot be
placed at the end of RAM anymore since that area (8KB) is used by MTB.
Make sure to rebuild flash loader, bootloader and app with new code as
otherwise jumping from bootloader to app or from app to flash loader
will fail.
---
.../src/arch/cortex_m33/gcc_startup_da1469x.S | 22 +++++++++++++++++++
hw/mcu/dialog/da1469x/da1469x.ld | 9 +++++++-
.../src/arch/cortex_m33/da1469x_m33_sleep.S | 25 ++++++++++++++++++++++
hw/mcu/dialog/da1469x/src/system_da1469x.c | 5 +++++
hw/mcu/dialog/da1469x/syscfg.yml | 13 +++++++++++
5 files changed, 73 insertions(+), 1 deletion(-)
diff --git a/hw/bsp/dialog_da1469x-dk-pro/src/arch/cortex_m33/gcc_startup_da1469x.S b/hw/bsp/dialog_da1469x-dk-pro/src/arch/cortex_m33/gcc_startup_da1469x.S
index 616f319..d173f79 100644
--- a/hw/bsp/dialog_da1469x-dk-pro/src/arch/cortex_m33/gcc_startup_da1469x.S
+++ b/hw/bsp/dialog_da1469x-dk-pro/src/arch/cortex_m33/gcc_startup_da1469x.S
@@ -32,6 +32,9 @@
.equ SYS_CTRL_REG, 0x50000024
.equ CACHE_FLASH_REG, 0x100C0040
.equ RESET_STAT_REG, 0x500000BC
+ .equ MTB_POSITION_REG, 0xE0043000
+ .equ MTB_MASTER_REG, 0xE0043004
+ .equ MTB_FLOW_REG, 0xE0043008
.globl __StackTop
.globl __StackLimit
@@ -154,6 +157,25 @@ wakeup_handler:
.globl Reset_Handler
.type Reset_Handler, %function
Reset_Handler:
+#if MYNEWT_VAL(MCU_MTB_ENABLE)
+ mov r2, #0
+ ldr r1, =MTB_POSITION_REG
+ str r2, [r1]
+ ldr r1, =MTB_FLOW_REG
+ str r2, [r1]
+ ldr r1, =MTB_MASTER_REG
+#if MYNEWT_VAL(MCU_MTB_AUTO_START)
+ ldr r2, =0x80000009
+#else
+ ldr r2, =0x00000009
+#endif
+ str r2, [r1]
+#else
+ ldr r1, =MTB_MASTER_REG
+ mov r2, #0
+ str r2, [r1]
+#endif
+
/* Make sure interrupt vector is remapped at 0x0 */
ldr r1, =SYS_CTRL_REG
ldrh r2, [r1, #0]
diff --git a/hw/mcu/dialog/da1469x/da1469x.ld b/hw/mcu/dialog/da1469x/da1469x.ld
index d76ef05..f6714d9 100644
--- a/hw/mcu/dialog/da1469x/da1469x.ld
+++ b/hw/mcu/dialog/da1469x/da1469x.ld
@@ -210,11 +210,18 @@ SECTIONS
*(.stack*)
} > RAM
+ /* Dummy section to calculate whether we need to move stack out of MTB
+ * buffer or not. */
+ .mtb (NOLOAD) :
+ {
+ KEEP(*(.mtb));
+ }
+
_ram_start = ORIGIN(RAM);
/* Set stack top to end of RAM, and stack limit move down by
* size of stack_dummy section */
- __StackTop = ORIGIN(RAM) + LENGTH(RAM);
+ __StackTop = ORIGIN(RAM) + LENGTH(RAM) - SIZEOF(.mtb);
__StackLimit = __StackTop - SIZEOF(.stack_dummy);
PROVIDE(__stack = __StackTop);
diff --git a/hw/mcu/dialog/da1469x/src/arch/cortex_m33/da1469x_m33_sleep.S b/hw/mcu/dialog/da1469x/src/arch/cortex_m33/da1469x_m33_sleep.S
index df0d75e..d380465 100644
--- a/hw/mcu/dialog/da1469x/src/arch/cortex_m33/da1469x_m33_sleep.S
+++ b/hw/mcu/dialog/da1469x/src/arch/cortex_m33/da1469x_m33_sleep.S
@@ -46,6 +46,10 @@ da1469x_m33_sleep_state:
.saved_fpu:
.space 8 /* FPCCR, FPDSCR */
#endif
+#if MYNEWT_VAL(MCU_MTB_ENABLE)
+.saved_mtb:
+ .space 12 /* POSITION, MASTER, FLOW */
+#endif
.size da1469x_m33_sleep_state, . - da1469x_m33_sleep_state
@@ -64,6 +68,9 @@ da1469x_m33_sleep_state:
.equ QSPIC_CTRLBUS_OFFSET, 0x000
.equ QSPIC_CTRLMOD_OFFSET, 0x004
.equ QSPIC_WRITEDATA_OFFSET, 0x018
+ .equ MTB_POSITION_REG, 0xE0043000
+ .equ MTB_MASTER_REG, 0xE0043004
+ .equ MTB_FLOW_REG, 0xE0043008
.equ SCB_CPACR_MASK, 0x00F00000 /* CP10 and CP11 */
.equ SCB_SHCSR_MASK, 0x000F0000 /* xxxFAULTENA */
@@ -114,6 +121,13 @@ da1469x_m33_sleep:
stmia r3!, {r4-r5}
#endif
+#if MYNEWT_VAL(MCU_MTB_ENABLE)
+/* Save MTB state */
+ ldr r0, =MTB_POSITION_REG
+ ldm r0, {r4-r6}
+ stmia r3!, {r4-r6}
+#endif
+
/* Clear RESET_STAT_REG so wakeup handler can detect wakeup from deep sleep */
ldr r0, =RESET_STAT_REG
movs r3, #0
@@ -231,6 +245,17 @@ da1469x_m33_wakeup:
str r5, [r0, #(FPU_FPDSCR_OFFSET)]
#endif
+#if MYNEWT_VAL(MCU_MTB_ENABLE)
+/* Restore MTB state */
+ ldmia r3!, {r4-r6}
+ ldr r0, =MTB_POSITION_REG
+ str r4, [r0]
+ ldr r0, =MTB_FLOW_REG
+ str r6, [r0]
+ ldr r0, =MTB_MASTER_REG
+ str r5, [r0]
+#endif
+
/* Restore MSP, PSP and CONTROL */
ldr r3, =.saved_msp
ldmia r3!, {r0-r2}
diff --git a/hw/mcu/dialog/da1469x/src/system_da1469x.c b/hw/mcu/dialog/da1469x/src/system_da1469x.c
index 5539fd0..9d1e8f6 100644
--- a/hw/mcu/dialog/da1469x/src/system_da1469x.c
+++ b/hw/mcu/dialog/da1469x/src/system_da1469x.c
@@ -38,6 +38,11 @@
extern uint8_t __StackLimit;
+#if MYNEWT_VAL(MCU_MTB_ENABLE)
+/* Dummy symbol to reserve 8KB of RAM for MTB */
+uint32_t __attribute__((section(".mtb"))) mtb_dummy[2048];
+#endif
+
void
SystemInit(void)
{
diff --git a/hw/mcu/dialog/da1469x/syscfg.yml b/hw/mcu/dialog/da1469x/syscfg.yml
index 0671504..9369cf9 100644
--- a/hw/mcu/dialog/da1469x/syscfg.yml
+++ b/hw/mcu/dialog/da1469x/syscfg.yml
@@ -86,6 +86,19 @@ syscfg.defs:
general usage.
value: 0
+ MCU_MTB_ENABLE:
+ description: >
+ Enable support for Micro Trace Buffer (MTB).
+ This will reserve RAM space for MTB buffer, configure
+ MTB on boot and properly store/restore MTB registers
+ state during deep sleep to allow continuous trace.
+ value: 0
+ MCU_MTB_AUTO_START:
+ description: >
+ Auto start MTB trace on boot. If disabled, MTB can be
+ still enabled manually either via code or debugger.
+ value: 0
+
MCU_FLASH_MIN_WRITE_SIZE:
description: >
Specifies the required alignment for internal flash writes.