runs
This commit is contained in:
parent
37e4af5451
commit
2ce4b88980
@ -50,6 +50,8 @@ BL_FLASH_BASE = 0x08000000
|
||||
BL_FLASH_SIZE = 0xe000
|
||||
BL_FLASH_LAST = 0x0800e000
|
||||
|
||||
MPY_FLASH_BASE = 0x08010000
|
||||
|
||||
# Final 8k bytes of flash reserved for secret data (not code)
|
||||
# - must be page-aligned, contains pairing secret
|
||||
BL_NVROM_BASE = 0x0800e000 # = BL_FLASH_LAST
|
||||
@ -100,6 +102,7 @@ LDFLAGS += -Wl,-Map=$(TARGET_NAME).map
|
||||
|
||||
ASFLAGS += -Wa,--defsym,BL_FLASH_BASE=$(BL_FLASH_BASE) -Wa,--defsym,BL_FLASH_SIZE=$(BL_FLASH_SIZE)
|
||||
ASFLAGS += -Wa,--defsym,BL_SRAM_BASE=$(BL_SRAM_BASE) -Wa,--defsym,BL_SRAM_SIZE=$(BL_SRAM_SIZE)
|
||||
ASFLAGS += -Wa,--defsym,MPY_FLASH_BASE=$(MPY_FLASH_BASE)
|
||||
|
||||
|
||||
TARGET_ELF = $(TARGET_NAME).elf
|
||||
@ -152,8 +155,11 @@ dfu-slow: $(TARGET_NAME).dfu
|
||||
dfu-util -d 0483:df11 -a 0 -D $<
|
||||
|
||||
dfu: $(TARGET_NAME).dfu
|
||||
echo 'dfu' | nc localhost 4444
|
||||
$(PYTHON_DO_DFU) -u $<
|
||||
|
||||
up: dfu
|
||||
|
||||
# upload current production version (or latest release version anyway)
|
||||
latest:
|
||||
$(PYTHON_DO_DFU) -u `ls -t1 releases/*/bootloader.dfu | head -1`
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
*/
|
||||
#include "basics.h"
|
||||
#include "ae.h"
|
||||
#include "clocks.h"
|
||||
#include "rng.h"
|
||||
#include "delay.h"
|
||||
#include "faster_sha256.h"
|
||||
@ -12,6 +13,7 @@
|
||||
#include "stm32l4xx_hal.h"
|
||||
#include "ae_config.h"
|
||||
#include "oled.h"
|
||||
#include "console.h"
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
@ -24,6 +26,11 @@
|
||||
# define ERR(msg)
|
||||
# define ERRV(val, msg)
|
||||
#endif
|
||||
#if 0
|
||||
// affects timing
|
||||
# define ERR(msg) puts(msg)
|
||||
# define ERRV(val, msg) do { puts2(msg); puts2(": "); puthex2(val); putchar('\n'); } while(0)
|
||||
#endif
|
||||
|
||||
// Must be exactly 32 chars:
|
||||
static const char *copyright_msg = "Copyright 2018- by Coinkite Inc.";
|
||||
@ -367,7 +374,13 @@ ae_setup(void)
|
||||
MY_UART->RTOR = 24; // timeout in bit periods: 3 chars or so
|
||||
MY_UART->CR2 = USART_CR2_RTOEN; // rx timeout enable
|
||||
MY_UART->CR3 = USART_CR3_HDSEL | USART_CR3_ONEBIT;
|
||||
MY_UART->BRR = 0x0000015b; // 230400 bps
|
||||
#if HCLK_FREQUENCY == 80000000
|
||||
MY_UART->BRR = 0x0000015b; // 230400 bps @ 80 Mhz SYSCLK
|
||||
#elif HCLK_FREQUENCY == 120000000
|
||||
MY_UART->BRR = 521; // 230400 bps @ 120 Mhz SYSCLK
|
||||
#else
|
||||
# error "needs math"
|
||||
#endif
|
||||
|
||||
// clear rx timeout flag
|
||||
MY_UART->ICR = USART_ICR_RTOCF;
|
||||
@ -375,7 +388,7 @@ ae_setup(void)
|
||||
// finally enable UART
|
||||
MY_UART->CR1 |= USART_CR1_UE;
|
||||
|
||||
// configure pin A0 to be AF8_UART4, PULL_NONE
|
||||
// configure pin A0 to be AFx_UARTy, PULL_NONE
|
||||
gpio_setup();
|
||||
|
||||
// mark it as ready
|
||||
|
||||
@ -31,18 +31,34 @@
|
||||
#include "stm32l4xx_hal.h"
|
||||
|
||||
// HSE is used and is 8MHz
|
||||
// - not doing a complete setup here, but enough
|
||||
// - expect mainline code to refine this more
|
||||
// - doing a complete setup here, and not changing in MicroPython anymore
|
||||
// - this chip is well made and can handle later changes to clocks
|
||||
// - lots of internal RC osc we can use as well... HSI, MSI and HSI48
|
||||
|
||||
#define CKCC_CLK_PLLN (40)
|
||||
#define CKCC_CLK_PLLM (2)
|
||||
#define CKCC_CLK_PLLR (2)
|
||||
#define CKCC_CLK_PLLP (7)
|
||||
#define CKCC_CLK_PLLQ (4)
|
||||
#if HCLK_FREQUENCY == 80000000
|
||||
// To get 80Mhz for SYSCLK...
|
||||
// 8Mhz (HSE) => /2 (M) *40 (N) /2 (R) => 80Mhz
|
||||
|
||||
// expected value of HAL_RCC_GetHCLKFreq(): 80Mhz
|
||||
#define HCLK_FREQUENCY 80000000
|
||||
# define CKCC_CLK_PLLM (2)
|
||||
# define CKCC_CLK_PLLN (40)
|
||||
# define CKCC_CLK_PLLR (2)
|
||||
# define CKCC_CLK_PLLP (7)
|
||||
# define CKCC_CLK_PLLQ (4)
|
||||
#endif
|
||||
|
||||
|
||||
#if HCLK_FREQUENCY == 120000000
|
||||
// For for 120Mhz SYSCLK...
|
||||
// 8Mhz (HSE) => /2 (M) *60 (N) /2 (R) => 120Mhz
|
||||
// R output => main sysclk (target 120)
|
||||
// Q output => should be 48Mhz for RNG and OCTOSPI maybe
|
||||
|
||||
# define CKCC_CLK_PLLM (2)
|
||||
# define CKCC_CLK_PLLN (60)
|
||||
# define CKCC_CLK_PLLR (2)
|
||||
# define CKCC_CLK_PLLP (7)
|
||||
# define CKCC_CLK_PLLQ (5)
|
||||
#endif
|
||||
|
||||
// systick_setup()
|
||||
//
|
||||
@ -64,6 +80,9 @@ clocks_setup(void)
|
||||
RCC_ClkInitTypeDef RCC_ClkInitStruct;
|
||||
RCC_OscInitTypeDef RCC_OscInitStruct;
|
||||
|
||||
// setup power supplies
|
||||
HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST);
|
||||
|
||||
// Configure LSE Drive Capability
|
||||
__HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
|
||||
|
||||
@ -95,7 +114,7 @@ clocks_setup(void)
|
||||
|
||||
HAL_RCC_OscConfig(&RCC_OscInitStruct);
|
||||
|
||||
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4);
|
||||
HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5);
|
||||
|
||||
// DIS-able MSI-Hardware auto calibration mode with LSE
|
||||
CLEAR_BIT(RCC->CR, RCC_CR_MSIPLLEN);
|
||||
@ -112,7 +131,7 @@ clocks_setup(void)
|
||||
PeriphClkInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI1;
|
||||
PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLLSAI1;
|
||||
PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLLSAI1;
|
||||
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
|
||||
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; // XXX wrong?
|
||||
PeriphClkInitStruct.RngClockSelection = RCC_RNGCLKSOURCE_PLLSAI1;
|
||||
|
||||
PeriphClkInitStruct.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_HSE;
|
||||
@ -128,10 +147,17 @@ clocks_setup(void)
|
||||
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
|
||||
|
||||
__HAL_RCC_RTC_ENABLE();
|
||||
__HAL_RCC_HASH_CLK_ENABLE();
|
||||
__HAL_RCC_HASH_CLK_ENABLE(); // for SHA256
|
||||
__HAL_RCC_SPI1_CLK_ENABLE(); // for OLED
|
||||
__HAL_RCC_SPI2_CLK_ENABLE(); // for SPI flash
|
||||
//__HAL_RCC_DMA1_CLK_ENABLE(); // for SPI from mpy
|
||||
//__HAL_RCC_DMA2_CLK_ENABLE(); // might not need
|
||||
__HAL_RCC_DMAMUX1_CLK_ENABLE(); // because code missing in mpy?
|
||||
|
||||
// setup SYSTICK, but we don't have the irq hooked up and not using HAL
|
||||
// but we use it in polling mode for delay_ms()
|
||||
systick_setup();
|
||||
|
||||
}
|
||||
|
||||
// EOF
|
||||
|
||||
@ -3,6 +3,8 @@
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#define HCLK_FREQUENCY 120000000
|
||||
|
||||
// call once at startup
|
||||
void clocks_setup(void);
|
||||
|
||||
|
||||
@ -212,6 +212,16 @@ hex_dump(const void *d, int len)
|
||||
#define USART_TEACK_REACK_TIMEOUT 1000U /*!< USART TX or RX enable acknowledge time-out value */
|
||||
#define USART_DUMMY_DATA ((uint16_t) 0xFFFF) /*!< USART transmitted dummy data */
|
||||
|
||||
// WaitOnFlag()
|
||||
//
|
||||
static void
|
||||
WaitOnFlag(uint32_t Flag, FlagStatus Status)
|
||||
{
|
||||
while((((MY_UART->ISR & Flag) == Flag) ? SET : RESET) == Status) {
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Handle USART Communication Timeout.
|
||||
* @param husart USART handle.
|
||||
@ -481,6 +491,30 @@ HAL_StatusTypeDef HAL_USART_Init(USART_HandleTypeDef *husart)
|
||||
*/
|
||||
HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxData, uint16_t Size, uint32_t Timeout)
|
||||
{
|
||||
while(Size > 0U) {
|
||||
while(!(MY_UART->ISR & UART_FLAG_TXE)) {
|
||||
// wait to be able send
|
||||
}
|
||||
|
||||
MY_UART->TDR = *pTxData;
|
||||
pTxData++;
|
||||
Size --;
|
||||
}
|
||||
|
||||
while(!(MY_UART->ISR & UART_FLAG_TC)) {
|
||||
// wait for final byte to be sent
|
||||
}
|
||||
|
||||
// Clear Transmission Complete Flag
|
||||
MY_UART->ICR = USART_CLEAR_TCF;
|
||||
|
||||
// Clear overrun flag and discard the received data
|
||||
MY_UART->ICR = USART_CLEAR_OREF;
|
||||
MY_UART->RQR = USART_RXDATA_FLUSH_REQUEST;
|
||||
MY_UART->RQR = USART_TXDATA_FLUSH_REQUEST;
|
||||
|
||||
return HAL_OK;
|
||||
#if 0
|
||||
uint8_t *ptxdata8bits;
|
||||
uint16_t *ptxdata16bits;
|
||||
uint32_t tickstart;
|
||||
@ -562,6 +596,7 @@ HAL_StatusTypeDef HAL_USART_Transmit(USART_HandleTypeDef *husart, uint8_t *pTxDa
|
||||
{
|
||||
return HAL_BUSY;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -40,16 +40,19 @@ good_addr(const uint8_t *b, int minlen, int len, bool readonly)
|
||||
{
|
||||
uint32_t x = (uint32_t)b;
|
||||
|
||||
// XXX needs changes for mk4
|
||||
|
||||
if(minlen) {
|
||||
if(!b) return EFAULT; // gave no buffer
|
||||
if(len < minlen) return ERANGE; // too small
|
||||
}
|
||||
|
||||
// mk4 is different
|
||||
STATIC_ASSERT(SRAM1_BASE == BL_SRAM_BASE);
|
||||
|
||||
if((x >= SRAM1_BASE) && ((x-SRAM1_BASE) < SRAM1_SIZE_MAX)) {
|
||||
// inside SRAM1, okay
|
||||
const uint32_t sram_start = BL_SRAM_BASE + BL_SRAM_SIZE;
|
||||
const uint32_t sram_end = SRAM3_BASE + SRAM3_SIZE;
|
||||
|
||||
if((x >= sram_start) && ((x+len) <= sram_end)) {
|
||||
// inside the 3 SRAM areas
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -97,7 +100,7 @@ firewall_dispatch(int method_num, uint8_t *buf_io, int len_in,
|
||||
|
||||
int rv = 0;
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
// TODO: re-enable this; causing crash now.
|
||||
// in case the caller didn't already, but would just lead to a crash anyway
|
||||
__disable_irq();
|
||||
@ -169,17 +172,21 @@ firewall_dispatch(int method_num, uint8_t *buf_io, int len_in,
|
||||
rv = EPERM;
|
||||
goto fail;
|
||||
}
|
||||
puts("Die: DFU");
|
||||
scr = screen_dfu;
|
||||
break;
|
||||
case 1:
|
||||
// in case some way for Micropython to detect it.
|
||||
scr = screen_downgrade;
|
||||
puts("Die: Downgrade");
|
||||
break;
|
||||
case 2:
|
||||
scr = screen_blankish;
|
||||
puts("Die: Blankish");
|
||||
break;
|
||||
case 3:
|
||||
scr = screen_brick;
|
||||
puts("Die: Brick");
|
||||
secure = true; // no point going into DFU, if even possible
|
||||
break;
|
||||
}
|
||||
@ -188,6 +195,7 @@ firewall_dispatch(int method_num, uint8_t *buf_io, int len_in,
|
||||
oled_show(scr);
|
||||
|
||||
wipe_all_sram();
|
||||
psram_wipe();
|
||||
|
||||
if(secure) {
|
||||
// just die with that message shown; can't start DFU
|
||||
@ -232,6 +240,8 @@ firewall_dispatch(int method_num, uint8_t *buf_io, int len_in,
|
||||
// NOT-REACHED (but ok if it does)
|
||||
}
|
||||
|
||||
psram_wipe();
|
||||
|
||||
// wait for an interrupt which will never happen (ie. sleep)
|
||||
LOCKUP_FOREVER()
|
||||
break;
|
||||
|
||||
@ -50,7 +50,7 @@ firewall_setup(void)
|
||||
uint32_t start = (uint32_t)&firewall_starts;
|
||||
uint32_t len = BL_FLASH_SIZE - (start - BL_FLASH_BASE);
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
ASSERT(start);
|
||||
ASSERT(!(start & 0xff));
|
||||
ASSERT(len>256);
|
||||
@ -65,14 +65,13 @@ firewall_setup(void)
|
||||
// - many of the bits in these registers are not-implemented and are forced to zero
|
||||
// - that prevents the firewall being used for things like protecting OTP area
|
||||
// - (Mk1-3) volatile data is SRAM1 only, so doesn't help us, since we're using SRAM2
|
||||
// - (Mk4) we are in SRAM1, so we could protect all our RAM ... but errata 2.4.2 fucks that
|
||||
// - on-chip DFU will erase up to start (0x300), which borks the reset vector
|
||||
// but sensitive stuff is still there (which would allow bypass)
|
||||
// - so it's important to enable option bytes to set write-protect on entire bootloader
|
||||
// - to disable debug and complete protection, must enable write-protect "level 2"
|
||||
//
|
||||
|
||||
// XXX TODO: protect part SRAM1 for us to use?
|
||||
|
||||
FIREWALL_InitTypeDef init = {
|
||||
.CodeSegmentStartAddress = start,
|
||||
.CodeSegmentLength = len,
|
||||
|
||||
@ -25,11 +25,14 @@ gpio_setup(void)
|
||||
// - try not to limit PCB changes for future revs; leave unused unchanged.
|
||||
// - oled_setup() uses pins on PA4 thru PA8
|
||||
|
||||
// enable clock to that part of chip
|
||||
// enable clock to GPIO's ... we will be using them all at some point
|
||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
||||
__HAL_RCC_GPIOE_CLK_ENABLE();
|
||||
|
||||
{ // Onewire bus pins used for ATECC508A comms
|
||||
{ // Onewire bus pins used for ATECC608 comms
|
||||
GPIO_InitTypeDef setup = {
|
||||
.Pin = ONEWIRE_PIN,
|
||||
.Mode = GPIO_MODE_AF_OD,
|
||||
@ -45,8 +48,11 @@ gpio_setup(void)
|
||||
HAL_GPIO_Init(ONEWIRE_PORT, &setup);
|
||||
}
|
||||
|
||||
// debug console: USART1 = PA9=Tx & PA10=Rx
|
||||
{ GPIO_InitTypeDef setup = {
|
||||
// Bugfix: re-init of console port pins seems to wreck
|
||||
// the mpy uart code, so avoid after first time.
|
||||
if(USART1->BRR == 0) {
|
||||
// debug console: USART1 = PA9=Tx & PA10=Rx
|
||||
GPIO_InitTypeDef setup = {
|
||||
.Pin = GPIO_PIN_9,
|
||||
.Mode = GPIO_MODE_AF_PP,
|
||||
.Pull = GPIO_NOPULL,
|
||||
@ -70,9 +76,30 @@ gpio_setup(void)
|
||||
};
|
||||
HAL_GPIO_Init(GPIOC, &setup);
|
||||
|
||||
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, 1); // turn on
|
||||
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, 0); // turn LED off
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
// TEST CODE -- keep
|
||||
// enable MCO=PA8 for clock watching. Conflicts w/ OLED normal use.
|
||||
GPIO_InitTypeDef mco_setup = {
|
||||
.Pin = GPIO_PIN_8,
|
||||
.Mode = GPIO_MODE_AF_PP,
|
||||
.Pull = GPIO_NOPULL,
|
||||
.Speed = GPIO_SPEED_FREQ_VERY_HIGH,
|
||||
.Alternate = GPIO_AF0_MCO,
|
||||
};
|
||||
HAL_GPIO_Init(GPIOA, &mco_setup);
|
||||
|
||||
// select a signal to view here.
|
||||
// RCC_MCO1SOURCE_SYSCLK => 120Mhz (correct)
|
||||
// RCC_MCO1SOURCE_PLLCLK (PLL R output) => (same os SYSCLK)
|
||||
// RCC_MCO1SOURCE_HSI48 => 48Mhz
|
||||
// RCC_MCO1SOURCE_HSE => 8Mhz (correct)
|
||||
__HAL_RCC_MCO1_CONFIG(RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1);
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||
|
||||
@ -94,4 +121,5 @@ gpio_setup(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// EOF
|
||||
|
||||
@ -34,6 +34,7 @@ uint32_t HAL_PWREx_GetVoltageRange(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
// NOTE: this is expected value for this project.
|
||||
return PWR_REGULATOR_VOLTAGE_SCALE1_BOOST;
|
||||
}
|
||||
#else
|
||||
@ -42,4 +43,140 @@ uint32_t HAL_PWREx_GetVoltageRange(void)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @brief Configure the main internal regulator output voltage.
|
||||
* @param VoltageScaling specifies the regulator output voltage to achieve
|
||||
* a tradeoff between performance and power consumption.
|
||||
* This parameter can be one of the following values:
|
||||
@if STM32L4S9xx
|
||||
* @arg @ref PWR_REGULATOR_VOLTAGE_SCALE1_BOOST when available, Regulator voltage output range 1 boost mode,
|
||||
* typical output voltage at 1.2 V,
|
||||
* system frequency up to 120 MHz.
|
||||
@endif
|
||||
* @arg @ref PWR_REGULATOR_VOLTAGE_SCALE1 Regulator voltage output range 1 mode,
|
||||
* typical output voltage at 1.2 V,
|
||||
* system frequency up to 80 MHz.
|
||||
* @arg @ref PWR_REGULATOR_VOLTAGE_SCALE2 Regulator voltage output range 2 mode,
|
||||
* typical output voltage at 1.0 V,
|
||||
* system frequency up to 26 MHz.
|
||||
* @note When moving from Range 1 to Range 2, the system frequency must be decreased to
|
||||
* a value below 26 MHz before calling HAL_PWREx_ControlVoltageScaling() API.
|
||||
* When moving from Range 2 to Range 1, the system frequency can be increased to
|
||||
* a value up to 80 MHz after calling HAL_PWREx_ControlVoltageScaling() API. For
|
||||
* some devices, the system frequency can be increased up to 120 MHz.
|
||||
* @note When moving from Range 2 to Range 1, the API waits for VOSF flag to be
|
||||
* cleared before returning the status. If the flag is not cleared within
|
||||
* 50 microseconds, HAL_TIMEOUT status is reported.
|
||||
* @retval HAL Status
|
||||
*/
|
||||
#define PWR_FLAG_SETTING_DELAY_US 50UL /*!< Time out value for REGLPF and VOSF flags setting */
|
||||
HAL_StatusTypeDef HAL_PWREx_ControlVoltageScaling(uint32_t VoltageScaling)
|
||||
{
|
||||
uint32_t wait_loop_index;
|
||||
|
||||
assert_param(IS_PWR_VOLTAGE_SCALING_RANGE(VoltageScaling));
|
||||
|
||||
#if defined(PWR_CR5_R1MODE)
|
||||
if (VoltageScaling == PWR_REGULATOR_VOLTAGE_SCALE1_BOOST)
|
||||
{
|
||||
/* If current range is range 2 */
|
||||
if (READ_BIT(PWR->CR1, PWR_CR1_VOS) == PWR_REGULATOR_VOLTAGE_SCALE2)
|
||||
{
|
||||
/* Make sure Range 1 Boost is enabled */
|
||||
CLEAR_BIT(PWR->CR5, PWR_CR5_R1MODE);
|
||||
|
||||
/* Set Range 1 */
|
||||
MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE1);
|
||||
|
||||
/* Wait until VOSF is cleared */
|
||||
wait_loop_index = ((PWR_FLAG_SETTING_DELAY_US * SystemCoreClock) / 1000000U) + 1;
|
||||
while ((HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF)) && (wait_loop_index != 0U))
|
||||
{
|
||||
wait_loop_index--;
|
||||
}
|
||||
if (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF))
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
/* If current range is range 1 normal or boost mode */
|
||||
else
|
||||
{
|
||||
/* Enable Range 1 Boost (no issue if bit already reset) */
|
||||
CLEAR_BIT(PWR->CR5, PWR_CR5_R1MODE);
|
||||
}
|
||||
}
|
||||
else if (VoltageScaling == PWR_REGULATOR_VOLTAGE_SCALE1)
|
||||
{
|
||||
/* If current range is range 2 */
|
||||
if (READ_BIT(PWR->CR1, PWR_CR1_VOS) == PWR_REGULATOR_VOLTAGE_SCALE2)
|
||||
{
|
||||
/* Make sure Range 1 Boost is disabled */
|
||||
SET_BIT(PWR->CR5, PWR_CR5_R1MODE);
|
||||
|
||||
/* Set Range 1 */
|
||||
MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE1);
|
||||
|
||||
/* Wait until VOSF is cleared */
|
||||
wait_loop_index = ((PWR_FLAG_SETTING_DELAY_US * SystemCoreClock) / 1000000U) + 1;
|
||||
while ((HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF)) && (wait_loop_index != 0U))
|
||||
{
|
||||
wait_loop_index--;
|
||||
}
|
||||
if (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF))
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
/* If current range is range 1 normal or boost mode */
|
||||
else
|
||||
{
|
||||
/* Disable Range 1 Boost (no issue if bit already set) */
|
||||
SET_BIT(PWR->CR5, PWR_CR5_R1MODE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set Range 2 */
|
||||
MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE2);
|
||||
/* No need to wait for VOSF to be cleared for this transition */
|
||||
/* PWR_CR5_R1MODE bit setting has no effect in Range 2 */
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
/* If Set Range 1 */
|
||||
if (VoltageScaling == PWR_REGULATOR_VOLTAGE_SCALE1)
|
||||
{
|
||||
if (READ_BIT(PWR->CR1, PWR_CR1_VOS) != PWR_REGULATOR_VOLTAGE_SCALE1)
|
||||
{
|
||||
/* Set Range 1 */
|
||||
MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE1);
|
||||
|
||||
/* Wait until VOSF is cleared */
|
||||
wait_loop_index = ((PWR_FLAG_SETTING_DELAY_US * SystemCoreClock) / 1000000U) + 1U;
|
||||
while ((HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF)) && (wait_loop_index != 0U))
|
||||
{
|
||||
wait_loop_index--;
|
||||
}
|
||||
if (HAL_IS_BIT_SET(PWR->SR2, PWR_SR2_VOSF))
|
||||
{
|
||||
return HAL_TIMEOUT;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (READ_BIT(PWR->CR1, PWR_CR1_VOS) != PWR_REGULATOR_VOLTAGE_SCALE2)
|
||||
{
|
||||
/* Set Range 2 */
|
||||
MODIFY_REG(PWR->CR1, PWR_CR1_VOS, PWR_REGULATOR_VOLTAGE_SCALE2);
|
||||
/* No need to wait for VOSF to be cleared for this transition */
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return HAL_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -50,8 +50,8 @@ reboot_seed_setup(void)
|
||||
|
||||
// can only do this once, and might be done already
|
||||
if(SYSCFG->SWPR != (1<<31)) {
|
||||
ASSERT(((uint32_t)reboot_seed) == 0x10007c00);
|
||||
ASSERT(((uint32_t)hdr_copy) == RAM_HEADER_BASE);
|
||||
ASSERT(((uint32_t)reboot_seed) == 0x20007c00);
|
||||
ASSERT(((uint32_t)hdr_copy) == RAM_HEADER_BASE_MK4);
|
||||
|
||||
// populate seed w/ noise
|
||||
memset(reboot_seed, 0x55, 1024);
|
||||
@ -149,12 +149,24 @@ system_startup(void)
|
||||
// wipe all of SRAM (except our own memory, which was already wiped)
|
||||
wipe_all_sram();
|
||||
|
||||
puts("AE setup start");
|
||||
puts2("AE setup: ");
|
||||
// secure element setup
|
||||
ae_setup();
|
||||
ae_set_gpio(0); // not checking return on purpose
|
||||
|
||||
puts("AE setup done");
|
||||
puts("done");
|
||||
|
||||
#if 0
|
||||
{ uint8_t config[128] = {0};
|
||||
int x = ae_config_read(config);
|
||||
if(x == 0) {
|
||||
puts("config[128]:");
|
||||
hex_dump(config, 128);
|
||||
} else {
|
||||
puts("config read fail");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// protect our flash, and/or check it's protected
|
||||
// - and pick pairing secret if we don't already have one
|
||||
|
||||
1
stm32/mk4-bootloader/mk-sigheader.py
Symbolic link
1
stm32/mk4-bootloader/mk-sigheader.py
Symbolic link
@ -0,0 +1 @@
|
||||
../bootloader/mk-sigheader.py
|
||||
@ -3,12 +3,13 @@
|
||||
*/
|
||||
#include "oled.h"
|
||||
#include "delay.h"
|
||||
#include "stm32l4xx_hal_gpio.h"
|
||||
#include "stm32l4xx_hal_rcc.h"
|
||||
#include "stm32l4xx_hal_dma.h"
|
||||
#include "stm32l4xx_hal_spi.h"
|
||||
#include "console.h"
|
||||
#include "stm32l4xx_hal.h"
|
||||
#include <string.h>
|
||||
|
||||
// OLED pins block use of MCO for testing
|
||||
#undef DISABLE_OLED
|
||||
|
||||
// Reset and config sequence.
|
||||
//
|
||||
// As measured! No attempt to understand them here.
|
||||
@ -48,17 +49,20 @@ static const uint8_t before_show[] = {
|
||||
#define SPI_SCK GPIO_PIN_5
|
||||
#define SPI_MOSI GPIO_PIN_7
|
||||
|
||||
HAL_StatusTypeDef HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);
|
||||
|
||||
#ifndef DISABLE_OLED
|
||||
static SPI_HandleTypeDef spi_port;
|
||||
#endif
|
||||
|
||||
// write_bytes()
|
||||
//
|
||||
static inline void
|
||||
write_bytes(int len, const uint8_t *buf)
|
||||
{
|
||||
#ifndef DISABLE_OLED
|
||||
// send via SPI(1)
|
||||
HAL_SPI_Transmit(&spi_port, (uint8_t *)buf, len, HAL_MAX_DELAY);
|
||||
#endif
|
||||
}
|
||||
|
||||
// oled_write_cmd()
|
||||
@ -106,6 +110,7 @@ oled_write_data(int len, const uint8_t *pixels)
|
||||
void
|
||||
oled_spi_setup(void)
|
||||
{
|
||||
#ifndef DISABLE_OLED
|
||||
// might already be setup
|
||||
if(spi_port.Instance == SPI1) return;
|
||||
|
||||
@ -126,6 +131,7 @@ oled_spi_setup(void)
|
||||
spi_port.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLED;
|
||||
|
||||
HAL_SPI_Init(&spi_port);
|
||||
#endif
|
||||
}
|
||||
|
||||
// oled_setup()
|
||||
@ -135,6 +141,10 @@ oled_spi_setup(void)
|
||||
void
|
||||
oled_setup(void)
|
||||
{
|
||||
#ifdef DISABLE_OLED
|
||||
puts("oled disabled");return; // disable so I can use MCO
|
||||
#endif
|
||||
|
||||
static uint32_t inited;
|
||||
|
||||
if(inited == 0x238a572F) {
|
||||
|
||||
@ -291,7 +291,6 @@ pin_prefix_words(const char *pin_prefix, int prefix_len, uint32_t *result)
|
||||
static void
|
||||
_hmac_attempt(const pinAttempt_t *args, uint8_t result[32])
|
||||
{
|
||||
|
||||
SHA256_CTX ctx;
|
||||
|
||||
sha256_init(&ctx);
|
||||
@ -307,9 +306,7 @@ _hmac_attempt(const pinAttempt_t *args, uint8_t result[32])
|
||||
sha256_final(&ctx, result);
|
||||
|
||||
// and a second-sha256 on that, just in case.
|
||||
sha256_init(&ctx);
|
||||
sha256_update(&ctx, result, 32);
|
||||
sha256_final(&ctx, result);
|
||||
sha256_single(result, 32, result);
|
||||
}
|
||||
|
||||
// _validate_attempt()
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
*/
|
||||
#include "psram.h"
|
||||
#include "oled.h"
|
||||
#include "clocks.h"
|
||||
#include "assets/screens.h"
|
||||
#include <string.h>
|
||||
#include "delay.h"
|
||||
@ -19,9 +20,13 @@
|
||||
#include "faster_sha256.h"
|
||||
#include "misc.h"
|
||||
|
||||
#undef INCL_SELFTEST
|
||||
|
||||
uint8_t psram_chip_eid[8];
|
||||
|
||||
//static void psram_memtest(bool simple);
|
||||
#ifdef INCL_SELFTEST
|
||||
static void psram_memtest(bool simple);
|
||||
#endif
|
||||
|
||||
// psram_send_byte()
|
||||
//
|
||||
@ -82,7 +87,13 @@ psram_setup(void)
|
||||
qh.Init.DelayHoldQuarterCycle = HAL_OSPI_DHQC_ENABLE; // maybe?
|
||||
qh.Init.FreeRunningClock = HAL_OSPI_FREERUNCLK_DISABLE; // required!
|
||||
qh.Init.ClockMode = HAL_OSPI_CLOCK_MODE_0; // low clock between ops (required, see errata)
|
||||
#if HCLK_FREQUENCY == 80000000
|
||||
qh.Init.ClockPrescaler = 1; // prescaler (1=>80Mhz, 2=>40Mhz, etc)
|
||||
#elif HCLK_FREQUENCY == 120000000
|
||||
qh.Init.ClockPrescaler = 2; // prescaler (1=>120Mhz, 2=>60Mhz, etc)
|
||||
#else
|
||||
# error "testing needed"
|
||||
#endif
|
||||
qh.Init.DelayBlockBypass = HAL_OSPI_DELAY_BLOCK_BYPASSED; // dont need it?
|
||||
|
||||
// ESP-PSRAM64H calls for max of 8us w/ CS low. Needs it for refresh time.
|
||||
@ -185,13 +196,10 @@ psram_setup(void)
|
||||
if(rv != HAL_OK) goto fail;
|
||||
}
|
||||
|
||||
#if 0
|
||||
while(1) {
|
||||
psram_memtest(1);
|
||||
psram_memtest(0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef INCL_SELFTEST
|
||||
psram_memtest(1);
|
||||
psram_memtest(0);
|
||||
#else
|
||||
// Only a quick operational check only here. Non-destructive.
|
||||
{ __IO uint32_t *ptr = (uint32_t *)(PSRAM_BASE+PSRAM_SIZE-4);
|
||||
uint32_t tmp;
|
||||
@ -201,6 +209,7 @@ psram_setup(void)
|
||||
if(*ptr != 0x55aa1234) goto fail;
|
||||
*ptr = tmp;
|
||||
}
|
||||
#endif
|
||||
|
||||
return;
|
||||
|
||||
@ -218,12 +227,14 @@ fail:
|
||||
void
|
||||
psram_wipe(void)
|
||||
{
|
||||
if(OCTOSPI1->CR == 0) return; // PSRAM not enabled (yet?)
|
||||
|
||||
puts2("PSRAM Wipe: ");
|
||||
memset4((uint32_t *)PSRAM_BASE, rng_sample(), PSRAM_SIZE);
|
||||
puts("done");
|
||||
}
|
||||
|
||||
#if 0
|
||||
#ifdef INCL_SELFTEST
|
||||
// psram_memtest()
|
||||
//
|
||||
static void
|
||||
|
||||
1
stm32/mk4-bootloader/sigheader.h
Symbolic link
1
stm32/mk4-bootloader/sigheader.h
Symbolic link
@ -0,0 +1 @@
|
||||
../bootloader/sigheader.h
|
||||
1
stm32/mk4-bootloader/sigheader.py
Symbolic link
1
stm32/mk4-bootloader/sigheader.py
Symbolic link
@ -0,0 +1 @@
|
||||
../bootloader/sigheader.py
|
||||
@ -89,8 +89,8 @@ reset_entry:
|
||||
bl callgate_entry0
|
||||
|
||||
// get a ptr to real code
|
||||
// load R1 with 0x08008000 value: start of firmware's area
|
||||
movw r1, (0x08008000 >> 12)
|
||||
// load R1 with first byte of firmware's area
|
||||
movw r1, (MPY_FLASH_BASE >> 12)
|
||||
lsl r1, 12
|
||||
|
||||
// set stack pointer to their preference
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
******************************************************************************
|
||||
* @file stm32l4xx_hal_firewall.c
|
||||
* @author MCD Application Team
|
||||
* @version V1.7.2
|
||||
* @date 16-June-2017
|
||||
* @brief FIREWALL HAL module driver.
|
||||
* This file provides firmware functions to manage the Firewall
|
||||
* Peripheral initialization and enabling.
|
||||
@ -34,29 +32,13 @@
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
|
||||
* <h2><center>© Copyright (c) 2017 STMicroelectronics.
|
||||
* All rights reserved.</center></h2>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* This software component is licensed by ST under BSD 3-Clause license,
|
||||
* the "License"; You may not use this file except in compliance with the
|
||||
* License. You may obtain a copy of the License at:
|
||||
* opensource.org/licenses/BSD-3-Clause
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
@ -137,19 +119,24 @@ HAL_StatusTypeDef HAL_FIREWALL_Config(FIREWALL_InitTypeDef * fw_init)
|
||||
|
||||
/* Check Firewall configuration addresses and lengths when segment is protected */
|
||||
/* Code segment */
|
||||
if (fw_init->CodeSegmentLength != 0)
|
||||
if (fw_init->CodeSegmentLength != 0U)
|
||||
{
|
||||
assert_param(IS_FIREWALL_CODE_SEGMENT_ADDRESS(fw_init->CodeSegmentStartAddress));
|
||||
assert_param(IS_FIREWALL_CODE_SEGMENT_LENGTH(fw_init->CodeSegmentStartAddress, fw_init->CodeSegmentLength));
|
||||
/* Make sure that NonVDataSegmentLength is properly set to prevent code segment access */
|
||||
if (fw_init->NonVDataSegmentLength < 0x100U)
|
||||
{
|
||||
return HAL_ERROR;
|
||||
}
|
||||
}
|
||||
/* Non volatile data segment */
|
||||
if (fw_init->NonVDataSegmentLength != 0)
|
||||
if (fw_init->NonVDataSegmentLength != 0U)
|
||||
{
|
||||
assert_param(IS_FIREWALL_NONVOLATILEDATA_SEGMENT_ADDRESS(fw_init->NonVDataSegmentStartAddress));
|
||||
assert_param(IS_FIREWALL_NONVOLATILEDATA_SEGMENT_LENGTH(fw_init->NonVDataSegmentStartAddress, fw_init->NonVDataSegmentLength));
|
||||
}
|
||||
/* Volatile data segment */
|
||||
if (fw_init->VDataSegmentLength != 0)
|
||||
if (fw_init->VDataSegmentLength != 0U)
|
||||
{
|
||||
assert_param(IS_FIREWALL_VOLATILEDATA_SEGMENT_ADDRESS(fw_init->VDataSegmentStartAddress));
|
||||
assert_param(IS_FIREWALL_VOLATILEDATA_SEGMENT_LENGTH(fw_init->VDataSegmentStartAddress, fw_init->VDataSegmentLength));
|
||||
@ -159,21 +146,22 @@ HAL_StatusTypeDef HAL_FIREWALL_Config(FIREWALL_InitTypeDef * fw_init)
|
||||
assert_param(IS_FIREWALL_VOLATILEDATA_EXECUTE(fw_init->VolatileDataExecution));
|
||||
assert_param(IS_FIREWALL_VOLATILEDATA_SHARE(fw_init->VolatileDataShared));
|
||||
|
||||
|
||||
/* Configuration */
|
||||
|
||||
/* Protected code segment start address configuration */
|
||||
WRITE_REG(FIREWALL->CSSA, (FW_CSSA_ADD & fw_init->CodeSegmentStartAddress));
|
||||
/* Protected code segment length configuration */
|
||||
/* Protected code segment length configuration */
|
||||
WRITE_REG(FIREWALL->CSL, (FW_CSL_LENG & fw_init->CodeSegmentLength));
|
||||
|
||||
/* Protected non volatile data segment start address configuration */
|
||||
WRITE_REG(FIREWALL->NVDSSA, (FW_NVDSSA_ADD & fw_init->NonVDataSegmentStartAddress));
|
||||
/* Protected non volatile data segment length configuration */
|
||||
/* Protected non volatile data segment length configuration */
|
||||
WRITE_REG(FIREWALL->NVDSL, (FW_NVDSL_LENG & fw_init->NonVDataSegmentLength));
|
||||
|
||||
/* Protected volatile data segment start address configuration */
|
||||
WRITE_REG(FIREWALL->VDSSA, (FW_VDSSA_ADD & fw_init->VDataSegmentStartAddress));
|
||||
/* Protected volatile data segment length configuration */
|
||||
/* Protected volatile data segment length configuration */
|
||||
WRITE_REG(FIREWALL->VDSL, (FW_VDSL_LENG & fw_init->VDataSegmentLength));
|
||||
|
||||
/* Set Firewall Configuration Register VDE and VDS bits
|
||||
|
||||
@ -237,11 +237,13 @@ verify_firmware(void)
|
||||
// but only if we arrived at same hash before. It decides.
|
||||
int not_green = ae_set_gpio_secure(world_check);
|
||||
|
||||
#if 0
|
||||
// XXX change this, no more dev key
|
||||
// maybe show big warning if not an "approved" key
|
||||
if(not_green) {
|
||||
check_factory_key(FW_HDR->pubkey_num);
|
||||
}
|
||||
#endif
|
||||
|
||||
puts("good firmware");
|
||||
oled_show_progress(screen_verify, 100);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user