mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-11-22 15:38:11 +00:00
startup: use custom reset_handler
+ group confidential data in one place + zero all SRAM where needed
This commit is contained in:
parent
a01ba51a2a
commit
98e617d874
1
Makefile
1
Makefile
@ -1,3 +1,4 @@
|
|||||||
|
OBJS += startup.o
|
||||||
OBJS += buttons.o
|
OBJS += buttons.o
|
||||||
OBJS += layout.o
|
OBJS += layout.o
|
||||||
OBJS += oled.o
|
OBJS += oled.o
|
||||||
|
@ -7,11 +7,14 @@ LD = $(PREFIX)gcc
|
|||||||
OBJCOPY = $(PREFIX)objcopy
|
OBJCOPY = $(PREFIX)objcopy
|
||||||
OBJDUMP = $(PREFIX)objdump
|
OBJDUMP = $(PREFIX)objdump
|
||||||
AR = $(PREFIX)ar
|
AR = $(PREFIX)ar
|
||||||
|
AS = $(PREFIX)as
|
||||||
FLASH = st-flash
|
FLASH = st-flash
|
||||||
OPENOCD = openocd
|
OPENOCD = openocd
|
||||||
|
|
||||||
OPTFLAGS ?= -O3
|
OPTFLAGS ?= -O3
|
||||||
DBGFLAGS ?= -g -DNDEBUG
|
DBGFLAGS ?= -g -DNDEBUG
|
||||||
|
CPUFLAGS ?= -mcpu=cortex-m3 -mthumb
|
||||||
|
FPUFLAGS ?= -msoft-float
|
||||||
|
|
||||||
CFLAGS += $(OPTFLAGS) \
|
CFLAGS += $(OPTFLAGS) \
|
||||||
$(DBGFLAGS) \
|
$(DBGFLAGS) \
|
||||||
@ -40,10 +43,10 @@ CFLAGS += $(OPTFLAGS) \
|
|||||||
-ffunction-sections \
|
-ffunction-sections \
|
||||||
-fdata-sections \
|
-fdata-sections \
|
||||||
-fstack-protector-all \
|
-fstack-protector-all \
|
||||||
-mcpu=cortex-m3 \
|
$(CPUFLAGS) \
|
||||||
-mthumb \
|
$(FPUFLAGS) \
|
||||||
-msoft-float \
|
|
||||||
-DSTM32F2 \
|
-DSTM32F2 \
|
||||||
|
-DCONFIDENTIAL='__attribute__((section("confidential")))' \
|
||||||
-I$(TOOLCHAIN_DIR)/include \
|
-I$(TOOLCHAIN_DIR)/include \
|
||||||
-I$(TOP_DIR) \
|
-I$(TOP_DIR) \
|
||||||
-I$(TOP_DIR)gen \
|
-I$(TOP_DIR)gen \
|
||||||
@ -83,9 +86,8 @@ LDFLAGS += --static \
|
|||||||
-T$(LDSCRIPT) \
|
-T$(LDSCRIPT) \
|
||||||
-nostartfiles \
|
-nostartfiles \
|
||||||
-Wl,--gc-sections \
|
-Wl,--gc-sections \
|
||||||
-mcpu=cortex-m3 \
|
$(CPUFLAGS) \
|
||||||
-mthumb \
|
$(FPUFLAGS)
|
||||||
-msoft-float
|
|
||||||
|
|
||||||
all: $(NAME).bin
|
all: $(NAME).bin
|
||||||
|
|
||||||
@ -128,6 +130,9 @@ $(NAME).list: $(NAME).elf
|
|||||||
$(NAME).elf: $(OBJS) $(LDSCRIPT) $(TOOLCHAIN_DIR)/lib/libopencm3_stm32f2.a $(TOP_DIR)/libtrezor.a
|
$(NAME).elf: $(OBJS) $(LDSCRIPT) $(TOOLCHAIN_DIR)/lib/libopencm3_stm32f2.a $(TOP_DIR)/libtrezor.a
|
||||||
$(LD) -o $(NAME).elf $(OBJS) -ltrezor -lopencm3_stm32f2 $(LDFLAGS)
|
$(LD) -o $(NAME).elf $(OBJS) -ltrezor -lopencm3_stm32f2 $(LDFLAGS)
|
||||||
|
|
||||||
|
%.o: %.s Makefile
|
||||||
|
$(AS) $(CPUFLAGS) -o $@ $<
|
||||||
|
|
||||||
%.o: %.c Makefile
|
%.o: %.c Makefile
|
||||||
$(CC) $(CFLAGS) -MMD -o $@ -c $<
|
$(CC) $(CFLAGS) -MMD -o $@ -c $<
|
||||||
|
|
||||||
|
@ -78,6 +78,9 @@ void show_unofficial_warning(const uint8_t *hash)
|
|||||||
|
|
||||||
void __attribute__((noreturn)) load_app(void)
|
void __attribute__((noreturn)) load_app(void)
|
||||||
{
|
{
|
||||||
|
// zero out SRAM
|
||||||
|
memset_reg(_ram_start, _ram_end, 0);
|
||||||
|
|
||||||
load_vector_table((const vector_table_t *) FLASH_APP_START);
|
load_vector_table((const vector_table_t *) FLASH_APP_START);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,14 +22,14 @@
|
|||||||
|
|
||||||
#define VERSION_MAJOR 1
|
#define VERSION_MAJOR 1
|
||||||
#define VERSION_MINOR 3
|
#define VERSION_MINOR 3
|
||||||
#define VERSION_PATCH 2
|
#define VERSION_PATCH 3
|
||||||
|
|
||||||
#define STR(X) #X
|
#define STR(X) #X
|
||||||
#define VERSTR(X) STR(X)
|
#define VERSTR(X) STR(X)
|
||||||
|
|
||||||
#define VERSION_MAJOR_CHAR "\x01"
|
#define VERSION_MAJOR_CHAR "\x01"
|
||||||
#define VERSION_MINOR_CHAR "\x03"
|
#define VERSION_MINOR_CHAR "\x03"
|
||||||
#define VERSION_PATCH_CHAR "\x02"
|
#define VERSION_PATCH_CHAR "\x03"
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
ifeq ($(FASTFLASH),1)
|
APPVER = 1.0.0
|
||||||
APPVER = 2.0.0
|
|
||||||
|
|
||||||
|
ifeq ($(FASTFLASH),1)
|
||||||
OBJS += fastflash.o
|
OBJS += fastflash.o
|
||||||
OBJS += bootloader.o
|
OBJS += bootloader.o
|
||||||
else
|
|
||||||
APPVER = 1.0.0
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
NAME = trezor
|
NAME = trezor
|
||||||
@ -93,6 +91,7 @@ CFLAGS += -DUSE_ETHEREUM=1
|
|||||||
|
|
||||||
bootloader.o: ../fastflash/bootloader.bin
|
bootloader.o: ../fastflash/bootloader.bin
|
||||||
$(OBJCOPY) -I binary -O elf32-littlearm -B arm \
|
$(OBJCOPY) -I binary -O elf32-littlearm -B arm \
|
||||||
|
--redefine-sym _binary_$(shell echo -n "$<" | tr -c "[:alnum:]" "_")_start=__bootloader_start__ \
|
||||||
--redefine-sym _binary_$(shell echo -n "$<" | tr -c "[:alnum:]" "_")_size=__bootloader_size__ \
|
--redefine-sym _binary_$(shell echo -n "$<" | tr -c "[:alnum:]" "_")_size=__bootloader_size__ \
|
||||||
--rename-section .data=.bootloader \
|
--rename-section .data=.rodata \
|
||||||
$< $@
|
$< $@
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
static bool ethereum_signing = false;
|
static bool ethereum_signing = false;
|
||||||
static uint32_t data_total, data_left;
|
static uint32_t data_total, data_left;
|
||||||
static EthereumTxRequest msg_tx_request;
|
static EthereumTxRequest msg_tx_request;
|
||||||
static uint8_t privkey[32];
|
static CONFIDENTIAL uint8_t privkey[32];
|
||||||
static uint8_t chain_id;
|
static uint8_t chain_id;
|
||||||
struct SHA3_CTX keccak_ctx;
|
struct SHA3_CTX keccak_ctx;
|
||||||
|
|
||||||
|
@ -24,16 +24,18 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
extern uint8_t __bootloader_loadaddr__[];
|
#define bootloader_vec ((vector_table_t *) 0x20000000)
|
||||||
extern uint8_t __bootloader_runaddr__[];
|
|
||||||
extern uint8_t __bootloader_size__[];
|
|
||||||
|
|
||||||
void load_bootloader(void)
|
|
||||||
{
|
|
||||||
memcpy(__bootloader_runaddr__, __bootloader_loadaddr__, (size_t) __bootloader_size__);
|
|
||||||
}
|
|
||||||
|
|
||||||
void __attribute__((noreturn)) run_bootloader(void)
|
void __attribute__((noreturn)) run_bootloader(void)
|
||||||
{
|
{
|
||||||
load_vector_table((const vector_table_t *) __bootloader_runaddr__);
|
extern uint8_t __bootloader_start__[];
|
||||||
|
extern uint8_t __bootloader_size__[];
|
||||||
|
|
||||||
|
// zero out SRAM
|
||||||
|
memset_reg(_ram_start, _ram_end, 0);
|
||||||
|
|
||||||
|
// copy bootloader
|
||||||
|
memcpy(bootloader_vec, __bootloader_start__, (size_t) __bootloader_size__);
|
||||||
|
|
||||||
|
load_vector_table(bootloader_vec);
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
#ifndef __FASTFLASH_H__
|
#ifndef __FASTFLASH_H__
|
||||||
#define __FASTFLASH_H__
|
#define __FASTFLASH_H__
|
||||||
|
|
||||||
void load_bootloader(void);
|
|
||||||
void __attribute__((noreturn)) run_bootloader(void);
|
void __attribute__((noreturn)) run_bootloader(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -177,7 +177,7 @@ const CoinType *fsm_getCoin(bool has_name, const char *name)
|
|||||||
|
|
||||||
HDNode *fsm_getDerivedNode(const char *curve, uint32_t *address_n, size_t address_n_count)
|
HDNode *fsm_getDerivedNode(const char *curve, uint32_t *address_n, size_t address_n_count)
|
||||||
{
|
{
|
||||||
static HDNode node;
|
static CONFIDENTIAL HDNode node;
|
||||||
if (!storage_getRootNode(&node, curve, true)) {
|
if (!storage_getRootNode(&node, curve, true)) {
|
||||||
fsm_sendFailure(FailureType_Failure_NotInitialized, _("Device not initialized or passphrase request cancelled or unsupported curve"));
|
fsm_sendFailure(FailureType_Failure_NotInitialized, _("Device not initialized or passphrase request cancelled or unsupported curve"));
|
||||||
layoutHome();
|
layoutHome();
|
||||||
|
@ -32,7 +32,7 @@ static uint32_t inputs_count;
|
|||||||
static uint32_t outputs_count;
|
static uint32_t outputs_count;
|
||||||
static const CoinType *coin;
|
static const CoinType *coin;
|
||||||
static const HDNode *root;
|
static const HDNode *root;
|
||||||
static HDNode node;
|
static CONFIDENTIAL HDNode node;
|
||||||
static bool signing = false;
|
static bool signing = false;
|
||||||
enum {
|
enum {
|
||||||
STAGE_REQUEST_1_INPUT,
|
STAGE_REQUEST_1_INPUT,
|
||||||
@ -54,7 +54,8 @@ static TxInputType input;
|
|||||||
static TxOutputBinType bin_output;
|
static TxOutputBinType bin_output;
|
||||||
static TxStruct to, tp, ti;
|
static TxStruct to, tp, ti;
|
||||||
static SHA256_CTX hashers[3];
|
static SHA256_CTX hashers[3];
|
||||||
static uint8_t privkey[32], pubkey[33], sig[64];
|
static uint8_t CONFIDENTIAL privkey[32];
|
||||||
|
static uint8_t pubkey[33], sig[64];
|
||||||
static uint8_t hash_prevouts[32], hash_sequence[32],hash_outputs[32];
|
static uint8_t hash_prevouts[32], hash_sequence[32],hash_outputs[32];
|
||||||
static uint8_t hash_check[32];
|
static uint8_t hash_check[32];
|
||||||
static uint64_t to_spend, authorized_amount, spending, change_spend;
|
static uint64_t to_spend, authorized_amount, spending, change_spend;
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#include "gettext.h"
|
#include "gettext.h"
|
||||||
|
|
||||||
Storage storage;
|
Storage CONFIDENTIAL storage;
|
||||||
|
|
||||||
uint32_t storage_uuid[12/sizeof(uint32_t)];
|
uint32_t storage_uuid[12/sizeof(uint32_t)];
|
||||||
char storage_uuid_str[25];
|
char storage_uuid_str[25];
|
||||||
@ -95,12 +95,12 @@ static const uint32_t storage_magic = 0x726f7473; // 'stor' as uint32_t
|
|||||||
|
|
||||||
static bool sessionSeedCached, sessionSeedUsesPassphrase;
|
static bool sessionSeedCached, sessionSeedUsesPassphrase;
|
||||||
|
|
||||||
static uint8_t sessionSeed[64];
|
static uint8_t CONFIDENTIAL sessionSeed[64];
|
||||||
|
|
||||||
static bool sessionPinCached;
|
static bool sessionPinCached;
|
||||||
|
|
||||||
static bool sessionPassphraseCached;
|
static bool sessionPassphraseCached;
|
||||||
static char sessionPassphrase[51];
|
static char CONFIDENTIAL sessionPassphrase[51];
|
||||||
|
|
||||||
#define STORAGE_VERSION 8
|
#define STORAGE_VERSION 8
|
||||||
|
|
||||||
|
@ -152,7 +152,7 @@ int compile_output(const CoinType *coin, const HDNode *root, TxOutputType *in, T
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (in->address_n_count > 0) {
|
if (in->address_n_count > 0) {
|
||||||
HDNode node;
|
static CONFIDENTIAL HDNode node;
|
||||||
InputScriptType input_script_type;
|
InputScriptType input_script_type;
|
||||||
|
|
||||||
switch (in->script_type) {
|
switch (in->script_type) {
|
||||||
|
@ -95,7 +95,6 @@ int main(void)
|
|||||||
#if FASTFLASH
|
#if FASTFLASH
|
||||||
uint16_t state = gpio_port_read(BTN_PORT);
|
uint16_t state = gpio_port_read(BTN_PORT);
|
||||||
if ((state & BTN_PIN_NO) == 0) {
|
if ((state & BTN_PIN_NO) == 0) {
|
||||||
load_bootloader();
|
|
||||||
run_bootloader();
|
run_bootloader();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -450,7 +450,7 @@ void getReadableAppId(const uint8_t appid[U2F_APPID_SIZE], const char **appname,
|
|||||||
|
|
||||||
const HDNode *getDerivedNode(uint32_t *address_n, size_t address_n_count)
|
const HDNode *getDerivedNode(uint32_t *address_n, size_t address_n_count)
|
||||||
{
|
{
|
||||||
static HDNode node;
|
static CONFIDENTIAL HDNode node;
|
||||||
if (!storage_getRootNode(&node, NIST256P1_NAME, false)) {
|
if (!storage_getRootNode(&node, NIST256P1_NAME, false)) {
|
||||||
layoutHome();
|
layoutHome();
|
||||||
debugLog(0, "", "ERR: Device not init");
|
debugLog(0, "", "ERR: Device not init");
|
||||||
|
13
memory.ld
13
memory.ld
@ -6,4 +6,17 @@ MEMORY
|
|||||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.confidential (NOLOAD) : {
|
||||||
|
*(confidential)
|
||||||
|
ASSERT ((SIZEOF(.confidential) <= 32K), "Error: Confidential section too big!");
|
||||||
|
} >ram
|
||||||
|
}
|
||||||
|
|
||||||
INCLUDE libopencm3_stm32f2.ld
|
INCLUDE libopencm3_stm32f2.ld
|
||||||
|
|
||||||
|
_ram_start = ORIGIN(ram);
|
||||||
|
_ram_end = ORIGIN(ram) + LENGTH(ram);
|
||||||
|
|
||||||
|
_data_size = SIZEOF(.data);
|
||||||
|
@ -6,4 +6,17 @@ MEMORY
|
|||||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
|
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 128K
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.confidential (NOLOAD) : {
|
||||||
|
*(confidential)
|
||||||
|
ASSERT ((SIZEOF(.confidential) <= 32K), "Error: Confidential section too big!");
|
||||||
|
} >ram
|
||||||
|
}
|
||||||
|
|
||||||
INCLUDE libopencm3_stm32f2.ld
|
INCLUDE libopencm3_stm32f2.ld
|
||||||
|
|
||||||
|
_ram_start = ORIGIN(ram);
|
||||||
|
_ram_end = ORIGIN(ram) + LENGTH(ram);
|
||||||
|
|
||||||
|
_data_size = SIZEOF(.data);
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
/* STM32F205RE - 512K Flash, 128K RAM */
|
|
||||||
/* program starts at 0x08010000 */
|
|
||||||
MEMORY
|
|
||||||
{
|
|
||||||
rom (rx) : ORIGIN = 0x08010000, LENGTH = 512K - 64K
|
|
||||||
bootloader (rx) : ORIGIN = 0x20000000, LENGTH = 32K
|
|
||||||
ram (rwx) : ORIGIN = 0x20000000 + LENGTH(bootloader),
|
|
||||||
LENGTH = 128K - LENGTH(bootloader)
|
|
||||||
}
|
|
||||||
|
|
||||||
INCLUDE libopencm3_stm32f2.ld
|
|
||||||
|
|
||||||
SECTIONS
|
|
||||||
{
|
|
||||||
.bootloader : {
|
|
||||||
__bootloader_runaddr__ = .;
|
|
||||||
KEEP (*(.bootloader*))
|
|
||||||
} >bootloader AT >rom
|
|
||||||
|
|
||||||
__bootloader_loadaddr__ = LOADADDR(.bootloader);
|
|
||||||
}
|
|
@ -6,4 +6,17 @@ MEMORY
|
|||||||
LENGTH = 128K - LENGTH(rom)
|
LENGTH = 128K - LENGTH(rom)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.confidential (NOLOAD) : {
|
||||||
|
*(confidential)
|
||||||
|
ASSERT ((SIZEOF(.confidential) <= 32K), "Error: Confidential section too big!");
|
||||||
|
} >ram
|
||||||
|
}
|
||||||
|
|
||||||
INCLUDE libopencm3_stm32f2.ld
|
INCLUDE libopencm3_stm32f2.ld
|
||||||
|
|
||||||
|
_ram_start = ORIGIN(ram);
|
||||||
|
_ram_end = ORIGIN(ram) + LENGTH(ram);
|
||||||
|
|
||||||
|
_data_size = SIZEOF(.data);
|
||||||
|
9
setup.c
9
setup.c
@ -17,6 +17,7 @@
|
|||||||
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <libopencm3/cm3/scb.h>
|
||||||
#include <libopencm3/stm32/rcc.h>
|
#include <libopencm3/stm32/rcc.h>
|
||||||
#include <libopencm3/stm32/gpio.h>
|
#include <libopencm3/stm32/gpio.h>
|
||||||
#include <libopencm3/stm32/spi.h>
|
#include <libopencm3/stm32/spi.h>
|
||||||
@ -44,6 +45,14 @@ void nmi_handler(void)
|
|||||||
|
|
||||||
void setup(void)
|
void setup(void)
|
||||||
{
|
{
|
||||||
|
// set SCB_CCR STKALIGN bit to make sure 8-byte stack alignment on exception entry is in effect.
|
||||||
|
// This is not strictly necessary for the current TREZOR system.
|
||||||
|
// This is here to comply with guidance from section 3.3.3 "Binary compatibility with other Cortex processors"
|
||||||
|
// of the ARM Cortex-M3 Processor Technical Reference Manual.
|
||||||
|
// According to section 4.4.2 and 4.4.7 of the "STM32F10xxx/20xxx/21xxx/L1xxxx Cortex-M3 programming manual",
|
||||||
|
// STM32F2 series MCUs are r2p0 and always have this bit set on reset already.
|
||||||
|
SCB_CCR |= SCB_CCR_STKALIGN;
|
||||||
|
|
||||||
// setup clock
|
// setup clock
|
||||||
struct rcc_clock_scale clock = rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_120MHZ];
|
struct rcc_clock_scale clock = rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_120MHZ];
|
||||||
rcc_clock_setup_hse_3v3(&clock);
|
rcc_clock_setup_hse_3v3(&clock);
|
||||||
|
39
startup.s
Normal file
39
startup.s
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
.syntax unified
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
|
.global memset_reg
|
||||||
|
.type memset_reg, STT_FUNC
|
||||||
|
memset_reg:
|
||||||
|
// call with the following (note that the arguments are not validated prior to use):
|
||||||
|
// r0 - address of first word to write (inclusive)
|
||||||
|
// r1 - address of first word following the address in r0 to NOT write (exclusive)
|
||||||
|
// r2 - word value to be written
|
||||||
|
// both addresses in r0 and r1 needs to be divisible by 4!
|
||||||
|
.L_loop_begin:
|
||||||
|
str r2, [r0], 4 // store the word in r2 to the address in r0, post-indexed
|
||||||
|
cmp r0, r1
|
||||||
|
bne .L_loop_begin
|
||||||
|
bx lr
|
||||||
|
|
||||||
|
.global reset_handler
|
||||||
|
.type reset_handler, STT_FUNC
|
||||||
|
reset_handler:
|
||||||
|
ldr r0, =_ram_start // r0 - point to beginning of SRAM
|
||||||
|
ldr r1, =_ram_end // r1 - point to byte after the end of SRAM
|
||||||
|
ldr r2, =0 // r2 - the byte-sized value to be written
|
||||||
|
bl memset_reg
|
||||||
|
|
||||||
|
// copy .data section from flash to SRAM
|
||||||
|
ldr r0, =_data // dst addr
|
||||||
|
ldr r1, =_data_loadaddr // src addr
|
||||||
|
ldr r2, =_data_size // length in bytes
|
||||||
|
bl memcpy
|
||||||
|
|
||||||
|
// enter the application code
|
||||||
|
bl main
|
||||||
|
|
||||||
|
// loop forever if the application code returns
|
||||||
|
b .
|
||||||
|
|
||||||
|
.end
|
25
util.h
25
util.h
@ -41,18 +41,25 @@ void __attribute__((noreturn)) system_halt(void);
|
|||||||
// reset system
|
// reset system
|
||||||
void __attribute__((noreturn)) system_reset(void);
|
void __attribute__((noreturn)) system_reset(void);
|
||||||
|
|
||||||
static inline void __attribute__((noreturn)) load_vector_table(const vector_table_t *vector_table) {
|
// defined in memory.ld
|
||||||
// Relocate vector table
|
extern uint8_t _ram_start[], _ram_end[];
|
||||||
SCB_VTOR = (uint32_t) vector_table;
|
|
||||||
|
|
||||||
// Set stack pointer
|
// defined in startup.s
|
||||||
__asm__ volatile("msr msp, %0" :: "r" (vector_table->initial_sp_value));
|
extern void memset_reg(void *start, void *stop, uint32_t val);
|
||||||
|
|
||||||
// Jump to address
|
static inline void __attribute__((noreturn)) load_vector_table(const vector_table_t *vector_table)
|
||||||
vector_table->reset();
|
{
|
||||||
|
// Relocate vector table
|
||||||
|
SCB_VTOR = (uint32_t)vector_table;
|
||||||
|
|
||||||
// Prevent compiler from generating stack protector code (which causes CPU fault because the stack is moved)
|
// Set stack pointer
|
||||||
for (;;);
|
__asm__ volatile("msr msp, %0" :: "r" (vector_table->initial_sp_value));
|
||||||
|
|
||||||
|
// Jump to address
|
||||||
|
vector_table->reset();
|
||||||
|
|
||||||
|
// Prevent compiler from generating stack protector code (which causes CPU fault because the stack is moved)
|
||||||
|
for (;;);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user