mirror of
https://github.com/trezor/trezor-firmware.git
synced 2025-02-16 01:22:02 +00:00
emulator: Initial commit
This commit is contained in:
parent
7c630141d4
commit
ba5b44d0c5
1
.gitignore
vendored
1
.gitignore
vendored
@ -6,6 +6,7 @@ build/
|
||||
*.bin
|
||||
*.elf
|
||||
*.hex
|
||||
*.img
|
||||
*.list
|
||||
*.srec
|
||||
*.log
|
||||
|
11
Makefile
11
Makefile
@ -1,13 +1,24 @@
|
||||
ifneq ($(EMULATOR),1)
|
||||
OBJS += startup.o
|
||||
endif
|
||||
|
||||
OBJS += buttons.o
|
||||
OBJS += layout.o
|
||||
OBJS += oled.o
|
||||
OBJS += rng.o
|
||||
OBJS += serialno.o
|
||||
|
||||
ifneq ($(EMULATOR),1)
|
||||
OBJS += setup.o
|
||||
endif
|
||||
|
||||
OBJS += util.o
|
||||
OBJS += memory.o
|
||||
|
||||
ifneq ($(EMULATOR),1)
|
||||
OBJS += timer.o
|
||||
endif
|
||||
|
||||
OBJS += gen/bitmaps.o
|
||||
OBJS += gen/fonts.o
|
||||
|
||||
|
@ -1,6 +1,18 @@
|
||||
TOP_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
|
||||
TOOLCHAIN_DIR ?= $(TOP_DIR)vendor/libopencm3
|
||||
|
||||
ifeq ($(EMULATOR),1)
|
||||
CC = gcc
|
||||
LD = gcc
|
||||
OBJCOPY = objcopy
|
||||
OBJDUMP = objdump
|
||||
AR = ar
|
||||
AS = as
|
||||
|
||||
OPTFLAGS ?= -O3
|
||||
DBGFLAGS ?= -g3
|
||||
CPUFLAGS ?= -m32
|
||||
else
|
||||
PREFIX ?= arm-none-eabi-
|
||||
CC = $(PREFIX)gcc
|
||||
LD = $(PREFIX)gcc
|
||||
@ -15,6 +27,7 @@ OPTFLAGS ?= -O3
|
||||
DBGFLAGS ?= -g -DNDEBUG
|
||||
CPUFLAGS ?= -mcpu=cortex-m3 -mthumb
|
||||
FPUFLAGS ?= -msoft-float
|
||||
endif
|
||||
|
||||
CFLAGS += $(OPTFLAGS) \
|
||||
$(DBGFLAGS) \
|
||||
@ -55,6 +68,28 @@ CFLAGS += $(OPTFLAGS) \
|
||||
-I$(TOP_DIR)vendor/trezor-crypto/ed25519-donna \
|
||||
-I$(TOP_DIR)vendor/trezor-qrenc
|
||||
|
||||
ifeq ($(EMULATOR),1)
|
||||
CFLAGS += -DEMULATOR=1
|
||||
|
||||
ifeq ($(HEADLESS),1)
|
||||
CFLAGS += -DHEADLESS=1
|
||||
else
|
||||
CFLAGS += -DHEADLESS=0
|
||||
|
||||
CFLAGS += $(shell pkg-config --cflags sdl2)
|
||||
LDLIBS += $(shell pkg-config --libs sdl2)
|
||||
endif
|
||||
|
||||
CFLAGS += -include $(TOP_DIR)emulator/emulator.h
|
||||
CFLAGS += -include stdio.h
|
||||
|
||||
LDFLAGS += -L$(TOP_DIR) \
|
||||
-L$(TOP_DIR)emulator \
|
||||
$(CPUFLAGS)
|
||||
|
||||
LDLIBS += -ltrezor -lemulator
|
||||
LIBDEPS += $(TOP_DIR)/libtrezor.a $(TOP_DIR)emulator/libemulator.a
|
||||
else
|
||||
ifdef APPVER
|
||||
CFLAGS += -DAPPVER=$(APPVER)
|
||||
LDSCRIPT = $(TOP_DIR)/memory_app_$(APPVER).ld
|
||||
@ -62,17 +97,7 @@ else
|
||||
LDSCRIPT = $(TOP_DIR)/memory.ld
|
||||
endif
|
||||
|
||||
ifeq ($(MEMORY_PROTECT), 0)
|
||||
CFLAGS += -DMEMORY_PROTECT=0
|
||||
else
|
||||
CFLAGS += -DMEMORY_PROTECT=1
|
||||
endif
|
||||
|
||||
ifeq ($(DEBUG_RNG), 1)
|
||||
CFLAGS += -DDEBUG_RNG=1
|
||||
else
|
||||
CFLAGS += -DDEBUG_RNG=0
|
||||
endif
|
||||
CFLAGS += -DEMULATOR=0
|
||||
|
||||
LDFLAGS += --static \
|
||||
-Wl,--start-group \
|
||||
@ -93,6 +118,19 @@ LIBDEPS += $(TOP_DIR)/libtrezor.a
|
||||
|
||||
LDLIBS += -lopencm3_stm32f2
|
||||
LIBDEPS += $(TOOLCHAIN_DIR)/lib/libopencm3_stm32f2.a
|
||||
endif
|
||||
|
||||
ifeq ($(MEMORY_PROTECT), 0)
|
||||
CFLAGS += -DMEMORY_PROTECT=0
|
||||
else
|
||||
CFLAGS += -DMEMORY_PROTECT=1
|
||||
endif
|
||||
|
||||
ifeq ($(DEBUG_RNG), 1)
|
||||
CFLAGS += -DDEBUG_RNG=1
|
||||
else
|
||||
CFLAGS += -DDEBUG_RNG=0
|
||||
endif
|
||||
|
||||
all: $(NAME).bin
|
||||
|
||||
|
@ -21,12 +21,18 @@
|
||||
|
||||
struct buttonState button;
|
||||
|
||||
#if !EMULATOR
|
||||
uint16_t buttonRead(void) {
|
||||
return gpio_port_read(BTN_PORT);
|
||||
}
|
||||
#endif
|
||||
|
||||
void buttonUpdate()
|
||||
{
|
||||
uint16_t state;
|
||||
static uint16_t last_state = BTN_PIN_YES | BTN_PIN_NO;
|
||||
|
||||
state = gpio_port_read(BTN_PORT);
|
||||
state = buttonRead();
|
||||
|
||||
if ((state & BTN_PIN_YES) == 0) { // Yes button is down
|
||||
if ((last_state & BTN_PIN_YES) == 0) { // last Yes was down
|
||||
|
@ -32,6 +32,7 @@ struct buttonState {
|
||||
|
||||
extern struct buttonState button;
|
||||
|
||||
uint16_t buttonRead(void);
|
||||
void buttonUpdate(void);
|
||||
|
||||
#ifndef BTN_PORT
|
||||
|
15
emulator/Makefile
Normal file
15
emulator/Makefile
Normal file
@ -0,0 +1,15 @@
|
||||
OBJS += setup.o
|
||||
|
||||
OBJS += buttons.o
|
||||
OBJS += flash.o
|
||||
OBJS += oled.o
|
||||
OBJS += rng.o
|
||||
OBJS += timer.o
|
||||
OBJS += udp.o
|
||||
|
||||
OBJS += strl.o
|
||||
|
||||
libemulator.a: $(OBJS)
|
||||
$(AR) rcs $@ $(OBJS)
|
||||
|
||||
include ../Makefile.include
|
40
emulator/buttons.c
Normal file
40
emulator/buttons.c
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* This file is part of the TREZOR project, https://trezor.io/
|
||||
*
|
||||
* Copyright (C) 2017 Saleem Rashid <trezor@saleemrashid.com>
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "buttons.h"
|
||||
|
||||
#if !HEADLESS
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
|
||||
uint16_t buttonRead(void) {
|
||||
uint16_t state = 0;
|
||||
|
||||
#if !HEADLESS
|
||||
const uint8_t *scancodes = SDL_GetKeyboardState(NULL);
|
||||
if (scancodes[SDL_SCANCODE_LEFT]) {
|
||||
state |= BTN_PIN_NO;
|
||||
}
|
||||
if (scancodes[SDL_SCANCODE_RIGHT]) {
|
||||
state |= BTN_PIN_YES;
|
||||
}
|
||||
#endif
|
||||
|
||||
return ~state;
|
||||
}
|
40
emulator/emulator.h
Normal file
40
emulator/emulator.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* This file is part of the TREZOR project, https://trezor.io/
|
||||
*
|
||||
* Copyright (C) 2017 Saleem Rashid <trezor@saleemrashid.com>
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __EMULATOR_H__
|
||||
#define __EMULATOR_H__
|
||||
|
||||
#if EMULATOR
|
||||
|
||||
#include "strl.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
extern void *emulator_flash_base;
|
||||
|
||||
void emulatorPoll(void);
|
||||
void emulatorRandom(void *buffer, size_t size);
|
||||
|
||||
void emulatorSocketInit(void);
|
||||
size_t emulatorSocketRead(void *buffer, size_t size);
|
||||
size_t emulatorSocketWrite(const void *buffer, size_t size);
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
114
emulator/flash.c
Normal file
114
emulator/flash.c
Normal file
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* This file is part of the TREZOR project, https://trezor.io/
|
||||
*
|
||||
* Copyright (C) 2017 Saleem Rashid <trezor@saleemrashid.com>
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <libopencm3/stm32/flash.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "memory.h"
|
||||
|
||||
void flash_lock(void) {}
|
||||
void flash_unlock(void) {}
|
||||
|
||||
void flash_clear_status_flags(void) {}
|
||||
|
||||
void flash_lock_option_bytes(void) {}
|
||||
void flash_unlock_option_bytes(void) {}
|
||||
|
||||
void flash_program_option_bytes(uint32_t data) {
|
||||
(void) data;
|
||||
}
|
||||
|
||||
static ssize_t sector_to_offset(uint8_t sector) {
|
||||
switch (sector) {
|
||||
case 0:
|
||||
return 0x0;
|
||||
case 1:
|
||||
return 0x4000;
|
||||
case 2:
|
||||
return 0x8000;
|
||||
case 3:
|
||||
return 0xC000;
|
||||
case 4:
|
||||
return 0x10000;
|
||||
case 5:
|
||||
return 0x20000;
|
||||
case 6:
|
||||
return 0x40000;
|
||||
case 7:
|
||||
return 0x60000;
|
||||
case 8:
|
||||
return 0x80000;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static void *sector_to_address(uint8_t sector) {
|
||||
ssize_t offset = sector_to_offset(sector);
|
||||
if (offset < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (void *) (FLASH_ORIGIN + offset);
|
||||
}
|
||||
|
||||
static ssize_t sector_to_size(uint8_t sector) {
|
||||
ssize_t start = sector_to_offset(sector);
|
||||
if (start < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ssize_t end = sector_to_offset(sector + 1);
|
||||
if (end < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return end - start;
|
||||
}
|
||||
|
||||
void flash_erase_sector(uint8_t sector, uint32_t program_size) {
|
||||
(void) program_size;
|
||||
|
||||
void *address = sector_to_address(sector);
|
||||
if (address == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
ssize_t size = sector_to_size(sector);
|
||||
if (size < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
memset(address, 0xFF, size);
|
||||
}
|
||||
|
||||
void flash_erase_all_sectors(uint32_t program_size) {
|
||||
(void) program_size;
|
||||
|
||||
memset(emulator_flash_base, 0xFF, FLASH_TOTAL_SIZE);
|
||||
}
|
||||
|
||||
void flash_program_word(uint32_t address, uint32_t data) {
|
||||
MMIO32(address) = data;
|
||||
}
|
||||
|
||||
void flash_program_byte(uint32_t address, uint8_t data) {
|
||||
MMIO8(address) = data;
|
||||
}
|
90
emulator/oled.c
Normal file
90
emulator/oled.c
Normal file
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* This file is part of the TREZOR project, https://trezor.io/
|
||||
*
|
||||
* Copyright (C) 2017 Saleem Rashid <trezor@saleemrashid.com>
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "oled.h"
|
||||
|
||||
#if HEADLESS
|
||||
|
||||
void oledInit(void) {}
|
||||
void oledRefresh(void) {}
|
||||
void emulatorPoll(void) {}
|
||||
|
||||
#else
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
static SDL_Renderer *renderer = NULL;
|
||||
static SDL_Texture *texture = NULL;
|
||||
|
||||
void oledInit(void) {
|
||||
if (SDL_Init(SDL_INIT_VIDEO) != 0) {
|
||||
fprintf(stderr, "Failed to initialize SDL: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
atexit(SDL_Quit);
|
||||
|
||||
SDL_Window *window = SDL_CreateWindow("TREZOR", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, OLED_WIDTH, OLED_HEIGHT, 0);
|
||||
if (window == NULL) {
|
||||
fprintf(stderr, "Failed to create window: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
|
||||
if (!renderer) {
|
||||
fprintf(stderr, "Failed to create renderer: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STREAMING, OLED_WIDTH, OLED_HEIGHT);
|
||||
|
||||
oledClear();
|
||||
oledRefresh();
|
||||
}
|
||||
|
||||
void oledRefresh(void) {
|
||||
const uint8_t *buffer = oledGetBuffer();
|
||||
|
||||
static uint32_t data[OLED_HEIGHT][OLED_WIDTH];
|
||||
|
||||
for (size_t i = 0; i < OLED_BUFSIZE; i++) {
|
||||
int x = (OLED_BUFSIZE - 1 - i) % OLED_WIDTH;
|
||||
int y = (OLED_BUFSIZE - 1 - i) / OLED_WIDTH * 8 + 7;
|
||||
|
||||
for (uint8_t shift = 0; shift < 8; shift++, y--) {
|
||||
bool set = (buffer[i] >> shift) & 1;
|
||||
data[y][x] = set ? 0xFFFFFFFF : 0xFF000000;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_UpdateTexture(texture, NULL, data, OLED_WIDTH * sizeof(uint32_t));
|
||||
SDL_RenderCopy(renderer, texture, NULL, NULL);
|
||||
SDL_RenderPresent(renderer);
|
||||
}
|
||||
|
||||
void emulatorPoll(void) {
|
||||
SDL_Event event;
|
||||
|
||||
if (SDL_PollEvent(&event)) {
|
||||
if (event.type == SDL_QUIT) {
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
32
emulator/rng.c
Normal file
32
emulator/rng.c
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* This file is part of the TREZOR project, https://trezor.io/
|
||||
*
|
||||
* Copyright (C) 2017 Saleem Rashid <trezor@saleemrashid.com>
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "rng.h"
|
||||
|
||||
uint32_t random32(void) {
|
||||
static uint32_t last = 0;
|
||||
uint32_t new;
|
||||
|
||||
do {
|
||||
emulatorRandom(&new, sizeof(new));
|
||||
} while (last == new);
|
||||
|
||||
last = new;
|
||||
return new;
|
||||
}
|
95
emulator/setup.c
Normal file
95
emulator/setup.c
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* This file is part of the TREZOR project, https://trezor.io/
|
||||
*
|
||||
* Copyright (C) 2017 Saleem Rashid <trezor@saleemrashid.com>
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <libopencm3/stm32/flash.h>
|
||||
|
||||
#include "memory.h"
|
||||
#include "oled.h"
|
||||
#include "rng.h"
|
||||
#include "setup.h"
|
||||
#include "timer.h"
|
||||
|
||||
#define EMULATOR_FLASH_FILE "emulator.img"
|
||||
|
||||
void *emulator_flash_base = NULL;
|
||||
|
||||
uint32_t __stack_chk_guard;
|
||||
|
||||
static int urandom = -1;
|
||||
|
||||
static void setup_urandom(void);
|
||||
static void setup_flash(void);
|
||||
|
||||
void setup(void) {
|
||||
setup_urandom();
|
||||
setup_flash();
|
||||
}
|
||||
|
||||
void emulatorRandom(void *buffer, size_t size) {
|
||||
ssize_t n = read(urandom, buffer, size);
|
||||
if (n < 0 || ((size_t) n) != size) {
|
||||
perror("Failed to read /dev/urandom");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void setup_urandom(void) {
|
||||
urandom = open("/dev/urandom", O_RDONLY);
|
||||
if (urandom < 0) {
|
||||
perror("Failed to open /dev/urandom");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static void setup_flash(void) {
|
||||
int fd = open(EMULATOR_FLASH_FILE, O_RDWR | O_SYNC | O_CREAT, 0644);
|
||||
if (fd < 0) {
|
||||
perror("Failed to open flash emulation file");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
off_t length = lseek(fd, 0, SEEK_END);
|
||||
if (length < 0) {
|
||||
perror("Failed to read length of flash emulation file");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
emulator_flash_base = mmap(NULL, FLASH_TOTAL_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||
if (emulator_flash_base == MAP_FAILED) {
|
||||
perror("Failed to map flash emulation file");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (length < FLASH_TOTAL_SIZE) {
|
||||
if (ftruncate(fd, FLASH_TOTAL_SIZE) != 0) {
|
||||
perror("Failed to initialize flash emulation file");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Initialize the flash */
|
||||
flash_erase_all_sectors(FLASH_CR_PROGRAM_X32);
|
||||
}
|
||||
}
|
45
emulator/strl.c
Normal file
45
emulator/strl.c
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* This file is part of the TREZOR project, https://trezor.io/
|
||||
*
|
||||
* Copyright (C) 2017 Saleem Rashid <trezor@saleemrashid.com>
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "strl.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
size_t strlcpy(char *dst, const char *src, size_t size) {
|
||||
if (size == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < size - 1; i++) {
|
||||
dst[i] = src[i];
|
||||
|
||||
if (src[i] == '\0') {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
dst[size - 1] = '\0';
|
||||
return size - 2;
|
||||
}
|
||||
|
||||
size_t strlcat(char *dst, const char *src, size_t size) {
|
||||
size_t n = strnlen(dst, size);
|
||||
|
||||
return n + strlcpy(&dst[n], src, size - n);
|
||||
}
|
28
emulator/strl.h
Normal file
28
emulator/strl.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* This file is part of the TREZOR project, https://trezor.io/
|
||||
*
|
||||
* Copyright (C) 2017 Saleem Rashid <trezor@saleemrashid.com>
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __STRL_H__
|
||||
#define __STRL_H__
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
size_t strlcpy(char *dst, const char *src, size_t size);
|
||||
size_t strlcat(char *dst, const char *src, size_t size);
|
||||
|
||||
#endif
|
32
emulator/timer.c
Normal file
32
emulator/timer.c
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* This file is part of the TREZOR project, https://trezor.io/
|
||||
*
|
||||
* Copyright (C) 2017 Saleem Rashid <trezor@saleemrashid.com>
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include "timer.h"
|
||||
|
||||
void timer_init(void) {}
|
||||
|
||||
uint32_t timer_ms(void) {
|
||||
struct timespec t;
|
||||
clock_gettime(CLOCK_MONOTONIC, &t);
|
||||
|
||||
uint32_t msec = t.tv_sec * 1000 + (t.tv_nsec / 1000000);
|
||||
return msec;
|
||||
}
|
85
emulator/udp.c
Normal file
85
emulator/udp.c
Normal file
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* This file is part of the TREZOR project, https://trezor.io/
|
||||
*
|
||||
* Copyright (C) 2017 Saleem Rashid <trezor@saleemrashid.com>
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#define TREZOR_UDP_PORT 21324
|
||||
|
||||
static int fd = -1;
|
||||
static struct sockaddr_in from;
|
||||
static socklen_t fromlen;
|
||||
|
||||
void emulatorSocketInit(void) {
|
||||
fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||
if (fd < 0) {
|
||||
perror("Failed to create socket");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fromlen = 0;
|
||||
|
||||
struct sockaddr_in addr;
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons(TREZOR_UDP_PORT);
|
||||
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
|
||||
|
||||
if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) != 0) {
|
||||
perror("Failed to bind socket");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
size_t emulatorSocketRead(void *buffer, size_t size) {
|
||||
fromlen = sizeof(from);
|
||||
ssize_t n = recvfrom(fd, buffer, size, MSG_DONTWAIT, (struct sockaddr *) &from, &fromlen);
|
||||
|
||||
if (n < 0) {
|
||||
if (errno != EAGAIN && errno != EWOULDBLOCK) {
|
||||
perror("Failed to read socket");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char msg_ping[] = { 'P', 'I', 'N', 'G', 'P', 'I', 'N', 'G' };
|
||||
static const char msg_pong[] = { 'P', 'O', 'N', 'G', 'P', 'O', 'N', 'G' };
|
||||
|
||||
if (n == sizeof(msg_ping) && memcmp(buffer, msg_ping, sizeof(msg_ping)) == 0) {
|
||||
emulatorSocketWrite(msg_pong, sizeof(msg_pong));
|
||||
return 0;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
size_t emulatorSocketWrite(const void *buffer, size_t size) {
|
||||
if (fromlen > 0) {
|
||||
ssize_t n = sendto(fd, buffer, size, MSG_DONTWAIT, (const struct sockaddr *) &from, fromlen);
|
||||
if (n < 0 || ((size_t) n) != size) {
|
||||
perror("Failed to write socket");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
@ -7,7 +7,12 @@ endif
|
||||
|
||||
NAME = trezor
|
||||
|
||||
ifeq ($(EMULATOR),1)
|
||||
OBJS += udp.o
|
||||
else
|
||||
OBJS += usb.o
|
||||
endif
|
||||
|
||||
OBJS += u2f.o
|
||||
OBJS += messages.o
|
||||
OBJS += storage.o
|
||||
|
@ -47,7 +47,11 @@ void debugLog(int level, const char *bucket, const char *text)
|
||||
{
|
||||
(void)level;
|
||||
(void)bucket;
|
||||
#if EMULATOR
|
||||
puts(text);
|
||||
#else
|
||||
oledDebug(text);
|
||||
#endif
|
||||
}
|
||||
|
||||
char *debugInt(const uint32_t i)
|
||||
|
@ -234,6 +234,7 @@ void fsm_msgGetFeatures(GetFeatures *msg)
|
||||
}
|
||||
|
||||
_Static_assert(pb_arraysize(Features, coins) >= COINS_COUNT, "Features.coins max_count not large enough");
|
||||
|
||||
resp->coins_count = COINS_COUNT;
|
||||
for (int i = 0; i < COINS_COUNT; i++) {
|
||||
if (coins[i].coin_name) {
|
||||
|
@ -121,7 +121,7 @@ void layoutHome(void)
|
||||
oledRefresh();
|
||||
|
||||
// Reset lock screen timeout
|
||||
system_millis_lock_start = system_millis;
|
||||
system_millis_lock_start = timer_ms();
|
||||
}
|
||||
|
||||
void layoutConfirmOutput(const CoinInfo *coin, const TxOutputType *out)
|
||||
|
@ -48,7 +48,12 @@ const pb_field_t *MessageFields(char type, char dir, uint16_t msg_id)
|
||||
{
|
||||
const struct MessagesMap_t *m = MessagesMap;
|
||||
while (m->type) {
|
||||
#if EMULATOR
|
||||
(void) type;
|
||||
if (dir == m->dir && msg_id == m->msg_id) {
|
||||
#else
|
||||
if (type == m->type && dir == m->dir && msg_id == m->msg_id) {
|
||||
#endif
|
||||
return m->fields;
|
||||
}
|
||||
m++;
|
||||
@ -60,7 +65,12 @@ void MessageProcessFunc(char type, char dir, uint16_t msg_id, void *ptr)
|
||||
{
|
||||
const struct MessagesMap_t *m = MessagesMap;
|
||||
while (m->type) {
|
||||
#if EMULATOR
|
||||
(void) type;
|
||||
if (dir == m->dir && msg_id == m->msg_id) {
|
||||
#else
|
||||
if (type == m->type && dir == m->dir && msg_id == m->msg_id) {
|
||||
#endif
|
||||
m->process_func(ptr);
|
||||
return;
|
||||
}
|
||||
|
@ -505,7 +505,7 @@ static bool signing_check_input(TxInputType *txinput) {
|
||||
tx_sequence_hash(&hashers[1], txinput);
|
||||
// hash prevout and script type to check it later (relevant for fee computation)
|
||||
tx_prevout_hash(&hashers[2], txinput);
|
||||
hasher_Update(&hashers[2], &txinput->script_type, sizeof(&txinput->script_type));
|
||||
hasher_Update(&hashers[2], (const uint8_t *) &txinput->script_type, sizeof(&txinput->script_type));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -962,7 +962,7 @@ void signing_txack(TransactionType *tx)
|
||||
}
|
||||
// check prevouts and script type
|
||||
tx_prevout_hash(&hashers[0], tx->inputs);
|
||||
hasher_Update(&hashers[0], &tx->inputs[0].script_type, sizeof(&tx->inputs[0].script_type));
|
||||
hasher_Update(&hashers[0], (const uint8_t *) &tx->inputs[0].script_type, sizeof(&tx->inputs[0].script_type));
|
||||
if (idx2 == idx1) {
|
||||
if (!compile_input_script_sig(&tx->inputs[0])) {
|
||||
fsm_sendFailure(FailureType_Failure_ProcessError, _("Failed to compile input"));
|
||||
|
@ -55,7 +55,13 @@ _Static_assert(((uint32_t)&storageUpdate & 3) == 0, "storage unaligned");
|
||||
_Static_assert((sizeof(storageUpdate) & 3) == 0, "storage unaligned");
|
||||
|
||||
#define STORAGE_ROM ((const Storage *)(FLASH_STORAGE_START + sizeof(storage_magic) + sizeof(storage_uuid)))
|
||||
|
||||
#if EMULATOR
|
||||
// TODO: Fix this for emulator
|
||||
#define storageRom STORAGE_ROM
|
||||
#else
|
||||
const Storage *storageRom = STORAGE_ROM;
|
||||
#endif
|
||||
|
||||
char storage_uuid_str[25];
|
||||
|
||||
@ -92,7 +98,10 @@ be added to the storage u2f_counter to get the real counter value.
|
||||
#define FLASH_STORAGE_U2FAREA_LEN (0x100)
|
||||
#define FLASH_STORAGE_REALLEN (sizeof(storage_magic) + sizeof(storage_uuid) + sizeof(Storage))
|
||||
|
||||
#if !EMULATOR
|
||||
// TODO: Fix this for emulator
|
||||
_Static_assert(FLASH_STORAGE_START + FLASH_STORAGE_REALLEN <= FLASH_STORAGE_PINAREA, "Storage struct is too large for TREZOR flash");
|
||||
#endif
|
||||
|
||||
/* Current u2f offset, i.e. u2f counter is
|
||||
* storage.u2f_counter + storage_u2f_offset.
|
||||
@ -119,10 +128,12 @@ void storage_show_error(void)
|
||||
|
||||
void storage_check_flash_errors(void)
|
||||
{
|
||||
#if !EMULATOR
|
||||
// flash operation failed
|
||||
if (FLASH_SR & (FLASH_SR_PGAERR | FLASH_SR_PGPERR | FLASH_SR_PGSERR | FLASH_SR_WRPERR)) {
|
||||
storage_show_error();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool storage_from_flash(void)
|
||||
@ -197,7 +208,10 @@ bool storage_from_flash(void)
|
||||
flash_erase_sector(FLASH_META_SECTOR_LAST, FLASH_CR_PROGRAM_X32);
|
||||
flash_program_word(FLASH_STORAGE_PINAREA, 0xffffffff << pinctr);
|
||||
// erase storageRom.has_pin_failed_attempts and storageRom.pin_failed_attempts
|
||||
#if !EMULATOR
|
||||
// TODO: Fix this for emulator
|
||||
_Static_assert(((uint32_t)&STORAGE_ROM->pin_failed_attempts & 3) == 0, "storage.pin_failed_attempts unaligned");
|
||||
#endif
|
||||
flash_program_byte((uint32_t)&storageRom->has_pin_failed_attempts, 0);
|
||||
flash_program_word((uint32_t)&storageRom->pin_failed_attempts, 0);
|
||||
flash_lock();
|
||||
|
@ -32,6 +32,9 @@
|
||||
#include "gettext.h"
|
||||
#include "fastflash.h"
|
||||
|
||||
/* Screen timeout */
|
||||
uint32_t system_millis_lock_start;
|
||||
|
||||
void check_lock_screen(void)
|
||||
{
|
||||
buttonUpdate();
|
||||
@ -73,7 +76,7 @@ void check_lock_screen(void)
|
||||
|
||||
// if homescreen is shown for longer than 10 minutes, lock too
|
||||
if (layoutLast == layoutHome) {
|
||||
if ((system_millis - system_millis_lock_start) >= 600000) {
|
||||
if ((timer_ms() - system_millis_lock_start) >= 600000) {
|
||||
// lock the screen
|
||||
session_clear(true);
|
||||
layoutScreensaver();
|
||||
|
@ -20,6 +20,8 @@
|
||||
#ifndef __TREZOR_H__
|
||||
#define __TREZOR_H__
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define VERSION_MAJOR 1
|
||||
#define VERSION_MINOR 6
|
||||
#define VERSION_PATCH 0
|
||||
@ -35,4 +37,7 @@
|
||||
#define DEBUG_LOG 0
|
||||
#endif
|
||||
|
||||
/* Screen timeout */
|
||||
extern uint32_t system_millis_lock_start;
|
||||
|
||||
#endif
|
||||
|
70
firmware/udp.c
Normal file
70
firmware/udp.c
Normal file
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* This file is part of the TREZOR project, https://trezor.io/
|
||||
*
|
||||
* Copyright (C) 2017 Saleem Rashid <trezor@saleemrashid.com>
|
||||
*
|
||||
* This library is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "usb.h"
|
||||
|
||||
#include "messages.h"
|
||||
#include "timer.h"
|
||||
|
||||
static volatile char tiny = 0;
|
||||
|
||||
void usbInit(void) {
|
||||
emulatorSocketInit();
|
||||
}
|
||||
|
||||
void usbPoll(void) {
|
||||
emulatorPoll();
|
||||
|
||||
static uint8_t buffer[64];
|
||||
if (emulatorSocketRead(buffer, sizeof(buffer)) > 0) {
|
||||
if (!tiny) {
|
||||
msg_read(buffer, sizeof(buffer));
|
||||
} else {
|
||||
msg_read_tiny(buffer, sizeof(buffer));
|
||||
}
|
||||
}
|
||||
|
||||
const uint8_t *data = msg_out_data();
|
||||
|
||||
#if DEBUG_LINK
|
||||
if (data == NULL) {
|
||||
data = msg_debug_out_data();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (data != NULL) {
|
||||
emulatorSocketWrite(data, 64);
|
||||
}
|
||||
}
|
||||
|
||||
char usbTiny(char set) {
|
||||
char old = tiny;
|
||||
tiny = set;
|
||||
return old;
|
||||
}
|
||||
|
||||
void usbSleep(uint32_t millis) {
|
||||
uint32_t start = timer_ms();
|
||||
|
||||
while ((timer_ms() - start) < millis) {
|
||||
usbPoll();
|
||||
}
|
||||
}
|
@ -446,9 +446,9 @@ char usbTiny(char set)
|
||||
|
||||
void usbSleep(uint32_t millis)
|
||||
{
|
||||
uint32_t start = system_millis;
|
||||
uint32_t start = timer_ms();
|
||||
|
||||
while ((system_millis - start) < millis) {
|
||||
while ((timer_ms() - start) < millis) {
|
||||
usbd_poll(usbd_dev);
|
||||
}
|
||||
}
|
||||
|
4
memory.h
4
memory.h
@ -62,7 +62,11 @@
|
||||
|
||||
*/
|
||||
|
||||
#if EMULATOR
|
||||
#define FLASH_ORIGIN ((uint32_t) emulator_flash_base)
|
||||
#else
|
||||
#define FLASH_ORIGIN (0x08000000)
|
||||
#endif
|
||||
|
||||
#define FLASH_TOTAL_SIZE (512 * 1024)
|
||||
|
||||
|
10
oled.c
10
oled.c
@ -105,10 +105,11 @@ void oledInvertPixel(int x, int y)
|
||||
_oledbuffer[OLED_OFFSET(x, y)] ^= OLED_MASK(x, y);
|
||||
}
|
||||
|
||||
#if !EMULATOR
|
||||
/*
|
||||
* Send a block of data via the SPI bus.
|
||||
*/
|
||||
inline void SPISend(uint32_t base, uint8_t *data, int len)
|
||||
static inline void SPISend(uint32_t base, const uint8_t *data, int len)
|
||||
{
|
||||
delay(1);
|
||||
for (int i = 0; i < len; i++) {
|
||||
@ -123,7 +124,7 @@ inline void SPISend(uint32_t base, uint8_t *data, int len)
|
||||
*/
|
||||
void oledInit()
|
||||
{
|
||||
static uint8_t s[25] = {
|
||||
static const uint8_t s[25] = {
|
||||
OLED_DISPLAYOFF,
|
||||
OLED_SETDISPLAYCLOCKDIV,
|
||||
0x80,
|
||||
@ -169,6 +170,7 @@ void oledInit()
|
||||
oledClear();
|
||||
oledRefresh();
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Clears the display buffer (sets all pixels to black)
|
||||
@ -184,9 +186,10 @@ void oledClear()
|
||||
* make the change visible. All other operations only change the buffer
|
||||
* not the content of the display.
|
||||
*/
|
||||
#if !EMULATOR
|
||||
void oledRefresh()
|
||||
{
|
||||
static uint8_t s[3] = {OLED_SETLOWCOLUMN | 0x00, OLED_SETHIGHCOLUMN | 0x00, OLED_SETSTARTLINE | 0x00};
|
||||
static const uint8_t s[3] = {OLED_SETLOWCOLUMN | 0x00, OLED_SETHIGHCOLUMN | 0x00, OLED_SETSTARTLINE | 0x00};
|
||||
|
||||
// draw triangle in upper right corner
|
||||
if (is_debug_link) {
|
||||
@ -216,6 +219,7 @@ void oledRefresh()
|
||||
oledInvertPixel(OLED_WIDTH - 1, 4);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
const uint8_t *oledGetBuffer()
|
||||
{
|
||||
|
2
rng.c
2
rng.c
@ -23,6 +23,7 @@
|
||||
|
||||
#include "rng.h"
|
||||
|
||||
#if !EMULATOR
|
||||
uint32_t random32(void)
|
||||
{
|
||||
static uint32_t last = 0, new = 0;
|
||||
@ -34,6 +35,7 @@ uint32_t random32(void)
|
||||
last = new;
|
||||
return new;
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t random_uniform(uint32_t n)
|
||||
{
|
||||
|
3
timer.c
3
timer.c
@ -27,9 +27,6 @@
|
||||
/* 1 tick = 1 ms */
|
||||
volatile uint32_t system_millis;
|
||||
|
||||
/* Screen timeout */
|
||||
uint32_t system_millis_lock_start;
|
||||
|
||||
/*
|
||||
* Initialise the Cortex-M3 SysTick timer
|
||||
*/
|
||||
|
17
timer.h
17
timer.h
@ -22,12 +22,17 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/* 1 tick = 1 ms */
|
||||
extern volatile uint32_t system_millis;
|
||||
|
||||
/* Screen timeout */
|
||||
extern uint32_t system_millis_lock_start;
|
||||
|
||||
void timer_init(void);
|
||||
|
||||
#if EMULATOR
|
||||
uint32_t timer_ms(void);
|
||||
#else
|
||||
static inline uint32_t timer_ms(void) {
|
||||
/* 1 tick = 1 ms */
|
||||
extern volatile uint32_t system_millis;
|
||||
|
||||
return system_millis;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
6
util.c
6
util.c
@ -17,7 +17,6 @@
|
||||
* along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <libopencm3/cm3/scb.h>
|
||||
#include "util.h"
|
||||
|
||||
inline void delay(uint32_t wait)
|
||||
@ -72,8 +71,3 @@ void __attribute__((noreturn)) system_halt(void)
|
||||
{
|
||||
for (;;) {} // loop forever
|
||||
}
|
||||
|
||||
void __attribute__((noreturn)) system_reset(void)
|
||||
{
|
||||
scb_reset_system();
|
||||
}
|
||||
|
6
util.h
6
util.h
@ -22,8 +22,10 @@
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if !EMULATOR
|
||||
#include <libopencm3/cm3/scb.h>
|
||||
#include <libopencm3/cm3/vector.h>
|
||||
#endif
|
||||
|
||||
// Statement expressions make these macros side-effect safe
|
||||
#define MIN(a, b) ({ typeof(a) _a = (a); typeof(b) _b = (b); _a < _b ? _a : _b; })
|
||||
@ -42,9 +44,8 @@ uint32_t readprotobufint(uint8_t **ptr);
|
||||
|
||||
// halt execution (or do an endless loop)
|
||||
void __attribute__((noreturn)) system_halt(void);
|
||||
// reset system
|
||||
void __attribute__((noreturn)) system_reset(void);
|
||||
|
||||
#if !EMULATOR
|
||||
// defined in memory.ld
|
||||
extern uint8_t _ram_start[], _ram_end[];
|
||||
|
||||
@ -65,5 +66,6 @@ static inline void __attribute__((noreturn)) load_vector_table(const vector_tabl
|
||||
// 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