1
0
mirror of https://github.com/trezor/trezor-firmware.git synced 2024-11-22 07:28:10 +00:00
trezor-firmware/setup.c
2017-12-12 12:51:08 +01:00

131 lines
4.9 KiB
C

/*
* This file is part of the TREZOR project, https://trezor.io/
*
* Copyright (C) 2014 Pavol Rusnak <stick@satoshilabs.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/cm3/scb.h>
#include <libopencm3/stm32/rcc.h>
#include <libopencm3/stm32/gpio.h>
#include <libopencm3/stm32/spi.h>
#include <libopencm3/stm32/f2/rng.h>
#include "rng.h"
#include "layout.h"
#include "util.h"
uint32_t __stack_chk_guard;
void __attribute__((noreturn)) __stack_chk_fail(void)
{
layoutDialog(&bmp_icon_error, NULL, NULL, NULL, "Stack smashing", "detected.", NULL, "Please unplug", "the device.", NULL);
for (;;) {} // loop forever
}
void nmi_handler(void)
{
// Clock Security System triggered NMI
if ((RCC_CIR & RCC_CIR_CSSF) != 0) {
layoutDialog(&bmp_icon_error, NULL, NULL, NULL, "Clock instability", "detected.", NULL, "Please unplug", "the device.", NULL);
for (;;) {} // loop forever
}
}
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
struct rcc_clock_scale clock = rcc_hse_8mhz_3v3[RCC_CLOCK_3V3_120MHZ];
rcc_clock_setup_hse_3v3(&clock);
// enable GPIO clock - A (oled), B(oled), C (buttons)
rcc_periph_clock_enable(RCC_GPIOA);
rcc_periph_clock_enable(RCC_GPIOB);
rcc_periph_clock_enable(RCC_GPIOC);
// enable SPI clock
rcc_periph_clock_enable(RCC_SPI1);
// enable RNG
rcc_periph_clock_enable(RCC_RNG);
RNG_CR |= RNG_CR_RNGEN;
// to be extra careful and heed the STM32F205xx Reference manual, Section 20.3.1
// we don't use the first random number generated after setting the RNGEN bit in setup
random32();
// enable CSS (Clock Security System)
RCC_CR |= RCC_CR_CSSON;
// set GPIO for buttons
gpio_mode_setup(GPIOC, GPIO_MODE_INPUT, GPIO_PUPD_PULLUP, GPIO2 | GPIO5);
// set GPIO for OLED display
gpio_mode_setup(GPIOA, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO4);
gpio_mode_setup(GPIOB, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, GPIO0 | GPIO1);
// enable SPI 1 for OLED display
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO5 | GPIO7);
gpio_set_af(GPIOA, GPIO_AF5, GPIO5 | GPIO7);
// spi_disable_crc(SPI1);
spi_init_master(SPI1, SPI_CR1_BAUDRATE_FPCLK_DIV_8, SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE, SPI_CR1_CPHA_CLK_TRANSITION_1, SPI_CR1_DFF_8BIT, SPI_CR1_MSBFIRST);
spi_enable_ss_output(SPI1);
// spi_enable_software_slave_management(SPI1);
// spi_set_nss_high(SPI1);
// spi_clear_mode_fault(SPI1);
spi_enable(SPI1);
// enable OTG_FS
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO10);
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_NONE, GPIO11 | GPIO12);
gpio_set_af(GPIOA, GPIO_AF10, GPIO10 | GPIO11 | GPIO12);
// enable OTG FS clock
rcc_periph_clock_enable(RCC_OTGFS);
// clear USB OTG_FS peripheral dedicated RAM
memset_reg((void *) 0x50020000, (void *) 0x50020500, 0);
}
void setupApp(void)
{
// for completeness, disable RNG peripheral interrupts for old bootloaders that had
// enabled them in RNG control register (the RNG interrupt was never enabled in the NVIC)
RNG_CR &= ~RNG_CR_IE;
// the static variables in random32 are separate between the bootloader and firmware.
// therefore, they need to be initialized here so that we can be sure to avoid dupes.
// this is to try to comply with STM32F205xx Reference manual - Section 20.3.1:
// "Each subsequent generated random number has to be compared with the previously generated
// number. The test fails if any two compared numbers are equal (continuous random number generator test)."
random32();
// enable CSS (Clock Security System)
RCC_CR |= RCC_CR_CSSON;
// hotfix for old bootloader
gpio_mode_setup(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_NONE, GPIO9);
spi_init_master(SPI1, SPI_CR1_BAUDRATE_FPCLK_DIV_8, SPI_CR1_CPOL_CLK_TO_0_WHEN_IDLE, SPI_CR1_CPHA_CLK_TRANSITION_1, SPI_CR1_DFF_8BIT, SPI_CR1_MSBFIRST);
gpio_mode_setup(GPIOA, GPIO_MODE_AF, GPIO_PUPD_PULLUP, GPIO10);
gpio_set_af(GPIOA, GPIO_AF10, GPIO10);
}