Merge pull request #4 from tomoveu/add-stm32f4-example
Add new STM32F4 and measured boot examplepull/6/head
commit
b09c5e1291
|
@ -0,0 +1,4 @@
|
|||
tar rem:3333
|
||||
file wolfboot.elf
|
||||
foc c
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
# Inherit our settings for wolfBoot, TARGET, ARCH, etc.
|
||||
-include measured.wolfboot.config
|
||||
|
||||
# Make sure environment variables do not corrupt the binary output for MacOS users
|
||||
LANG=
|
||||
LC_COLLATE="C"
|
||||
LC_CTYPE="C"
|
||||
LC_MESSAGES="C"
|
||||
LC_MONETARY="C"
|
||||
LC_NUMERIC="C"
|
||||
LC_TIME="C"
|
||||
LC_ALL=
|
||||
|
||||
APPSRC:=./src
|
||||
WOLFBOOT_ROOT:=../wolfBoot
|
||||
WOLFSSL_ROOT:=../wolfBoot/lib/wolfssl
|
||||
WOLFTPM_ROOT:=../wolfBoot/lib/wolfTPM
|
||||
ECCKEY:=$(WOLFBOOT_ROOT)/ecc256.der
|
||||
DEBUG?=1
|
||||
|
||||
include $(WOLFBOOT_ROOT)/tools/config.mk
|
||||
export WOLFBOOT_ROOT
|
||||
|
||||
|
||||
ifneq ("$(wildcard $(WOLFBOOT_ROOT)/tools/keytools/keygen)","")
|
||||
KEYGEN_TOOL:=$(WOLFBOOT_ROOT)/tools/keytools/keygen
|
||||
else
|
||||
ifneq ("$(wildcard $(WOLFBOOT_ROOT)/tools/keytools/keygen.exe)","")
|
||||
KEYGEN_TOOL:=$(WOLFBOOT_ROOT)/tools/keytools/keygen.exe
|
||||
else
|
||||
KEYGEN_TOOL:=python3 $(WOLFBOOT_ROOT)/tools/keytools/keygen.py
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ("$(wildcard $(WOLFBOOT_ROOT)/tools/keytools/sign)","")
|
||||
SIGN_TOOL:=$(WOLFBOOT_ROOT)/tools/keytools/sign
|
||||
else
|
||||
ifneq ("$(wildcard $(WOLFBOOT_ROOT)/tools/keytools/sign.exe)","")
|
||||
SIGN_TOOL:=$(WOLFBOOT_ROOT)/tools/keytools/sign.exe
|
||||
else
|
||||
SIGN_TOOL:=python3 $(WOLFBOOT_ROOT)/tools/keytools/sign.py
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
CFLAGS:=-g -ggdb -Wall -Wstack-usage=1024 -ffreestanding -Wno-unused -DPLATFORM_$(TARGET) \
|
||||
-I$(WOLFBOOT_ROOT)/include -I$(WOLFBOOT_ROOT) -I$(WOLFSSL_ROOT) -I$(WOLFTPM_ROOT) \
|
||||
-DWOLFBOOT_MEASURED_PCR_A -nostartfiles
|
||||
CFLAGS+=-DWOLFBOOT_HASH_SHA256
|
||||
CFLAGS+=-DWOLFSSL_USER_SETTINGS
|
||||
CFLAGS+=-DWOLFTPM_USER_SETTINGS
|
||||
|
||||
APP_OBJS:= \
|
||||
$(APPSRC)/app_$(TARGET).o \
|
||||
$(APPSRC)/led.o \
|
||||
$(APPSRC)/system.o \
|
||||
$(APPSRC)/timer.o \
|
||||
$(WOLFBOOT_ROOT)/hal/$(TARGET).o \
|
||||
$(WOLFBOOT_ROOT)/src/libwolfboot.o \
|
||||
$(WOLFBOOT_ROOT)/hal/spi/spi_drv_stm32.o \
|
||||
$(APPSRC)/startup_arm.o
|
||||
|
||||
# Add objects for wolfCrypt support required by wolfTPM
|
||||
APP_OBJS+= \
|
||||
$(WOLFSSL_ROOT)/wolfcrypt/src/hmac.o \
|
||||
$(WOLFSSL_ROOT)/wolfcrypt/src/aes.o \
|
||||
$(WOLFSSL_ROOT)/wolfcrypt/src/wc_port.o
|
||||
|
||||
# Add objects for wolfTPM support
|
||||
APP_OBJS+= \
|
||||
$(WOLFTPM_ROOT)/src/tpm2.o \
|
||||
$(WOLFTPM_ROOT)/src/tpm2_packet.o \
|
||||
$(WOLFTPM_ROOT)/src/tpm2_tis.o \
|
||||
$(WOLFTPM_ROOT)/src/tpm2_wrap.o \
|
||||
$(WOLFTPM_ROOT)/src/tpm2_param_enc.o
|
||||
|
||||
# Inherit cross-compiler and similar settings from wolfBoot
|
||||
include ../wolfBoot/arch.mk
|
||||
|
||||
ifneq ($(DEBUG),0)
|
||||
CFLAGS+=-O0 -ggdb3
|
||||
else
|
||||
CFLAGS+=-Os
|
||||
endif
|
||||
|
||||
vpath %.c $(dir $(WOLFSSL_ROOT)/src)
|
||||
vpath %.c $(dir $(WOLFSSL_ROOT)/wolfcrypt/src)
|
||||
vpath %.c $(dir $(WOLFBOOT_ROOT))/lib/wolfTPM/wolftpm)
|
||||
|
||||
ENTRY_POINT=`cat .entry-point-address`
|
||||
LSCRIPT:=$(APPSRC)/target-app.ld
|
||||
LSCRIPT_TEMPLATE:=$(APPSRC)/$(ARCH).ld
|
||||
LDFLAGS:=$(CFLAGS) -T $(LSCRIPT) -Wl,-gc-sections -Wl,-Map=image.map
|
||||
|
||||
|
||||
wolfboot-example: wolfboot_align.bin image.bin
|
||||
$(SIGN_TOOL) --ecc256 image.bin $(ECCKEY) 1
|
||||
cat wolfboot-align.bin image_v1_signed.bin >factory.bin
|
||||
|
||||
wolfboot-align.bin:LSCRIPT:=$(WOLFBOOT_ROOT)/target.ld
|
||||
wolfboot_align.bin:CFLAGS+=-DWOLFBOOT_HASH_SHA256
|
||||
wolfboot_align.bin: wolfboot_target
|
||||
make -C $(WOLFBOOT_ROOT) align
|
||||
cp $(WOLFBOOT_ROOT)/wolfboot-align.bin .
|
||||
cp $(WOLFBOOT_ROOT)/wolfboot.elf .
|
||||
|
||||
image.bin: wolfboot_target image.elf
|
||||
$(OBJCOPY) -O binary image.elf $@
|
||||
$(SIZE) image.elf
|
||||
|
||||
image.elf: wolfboot_target $(APP_OBJS) $(LSCRIPT)
|
||||
@echo "\t[LD] $@"
|
||||
$(Q)$(LD) $(LDFLAGS) $(APP_OBJS) -o $@
|
||||
|
||||
wolfboot_target: FORCE
|
||||
cp -f measured.wolfboot.config $(WOLFBOOT_ROOT)/.config
|
||||
make -C $(WOLFBOOT_ROOT) include/target.h
|
||||
|
||||
%.o:%.c
|
||||
@echo "\t[CC-$(ARCH)] $@"
|
||||
$(Q)$(CC) $(CFLAGS) -c -o $@ $^
|
||||
|
||||
%.o:%.S
|
||||
@echo "\t[AS-$(ARCH)] $@"
|
||||
$(Q)$(CC) $(CFLAGS) -c -o $@ $^
|
||||
|
||||
clean:
|
||||
make -C $(WOLFBOOT_ROOT) clean
|
||||
@rm -f *.bin *.elf $(OBJS) wolfboot.map *.bin *.hex src/*.o tags *.map
|
||||
|
||||
$(LSCRIPT): $(LSCRIPT_TEMPLATE) FORCE
|
||||
@printf "%d" $(WOLFBOOT_PARTITION_BOOT_ADDRESS) > .wolfboot-offset
|
||||
@printf "%d" $(WOLFBOOT_PARTITION_SIZE) > .partition-size
|
||||
@printf "%d" $(IMAGE_HEADER_SIZE) > .header-size
|
||||
@expr `cat .wolfboot-offset` + `cat .header-size` > .entry-point
|
||||
@printf "0x%X" `cat .entry-point` > .entry-point
|
||||
@expr `cat .partition-size` - `cat .header-size` > .app-size
|
||||
@printf "0x%X" `cat .app-size` > .app-size
|
||||
@ cat $(LSCRIPT_TEMPLATE) | \
|
||||
sed -e "s/##WOLFBOOT_TEST_APP_SIZE##/`cat .app-size`/g" | \
|
||||
sed -e "s/##WOLFBOOT_TEST_APP_ADDRESS##/`cat .entry-point`/g" \
|
||||
> $(@)
|
||||
@rm -f .app-size .entry-point .wolfboot-offset .partition-size .header-size
|
||||
|
||||
flash: FORCE
|
||||
st-flash write factory.bin 0x08000000
|
||||
|
||||
erase: FORCE
|
||||
st-flash erase
|
||||
|
||||
FORCE:
|
||||
|
||||
.PHONY: FORCE clean
|
|
@ -0,0 +1,196 @@
|
|||
# STM32F407-Discovery-Measured-Boot
|
||||
|
||||
Measured Boot example running on STM32F407-Discovery board.
|
||||
|
||||
This project is meant to demonstrate Measured Boot using the [wolfBoot secure bootloader](https://github.com/wolfssl/wolfBoot), powered by wolfSSL.
|
||||
|
||||
The bootloader expects a Trusted Platform Module(TPM) to be available in hardware.
|
||||
|
||||
## Components
|
||||
- Bootloader: [wolfBoot](https://github.com/wolfssl/wolfBoot) by wolfSSL
|
||||
- Application: Test app printing the extended PCR value that wolfBoot created
|
||||
- TPM2.0 stack: [wolfTPM](https://github.com/wolfssl/wolfTPM) by wolfSSL
|
||||
|
||||
## Motivation
|
||||
|
||||
Measured Boot provides the application with a trace of the boot process. This trace(log) is resistant to spoofing and tampering.
|
||||
|
||||
This is achieved by using a TPM which has unique Platform Configuration Registers(PCR) to store hash measurements.
|
||||
|
||||
The application(runtime) then can use this tamper-proof log to determine whether the system is in a good known state (trustworthy) or if the system is infected with malware.
|
||||
|
||||
After a measurement is stored into one of the TPM's PCRs, the user could perform local attestation using a TPM2.0 Quote and report the log to a remote sever for evaluation:
|
||||
- The remote server can compare the log to golden value(s) and alert system owners in case of mismatch.
|
||||
- The remote server can directly take action with the device.
|
||||
|
||||
The following diagram is a big picture overview of the different guarantee Secure and Measured Boot provide:
|
||||
|
||||

|
||||
|
||||
## Details
|
||||
|
||||
Secure Boot is a way for the system owner to guarantee that the device started with a geniune software. However, this information is not available to the system later on. Therefore, the application runtime must assume any and all software that was run before it is geniune. Measured Boot eliminates the guessing element and provides a way for the application to know the state of the system before it took control.
|
||||
|
||||
Measured Boot could evaluate a single component like firmware or application image, or can evaluate multiple components like system settings and user configuration. Additionally, the golden value could be stored within the system for the application to self-evaluate its state without the need of a remote server.
|
||||
|
||||
This example performs measured boot, stores the measurement of the firmware image into PCR16 and then boots into a test application. The test application prints the result of the measured boot(the value of the PCR).
|
||||
|
||||
This example could be extended to support multiple measurements.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- `STM32F4-Discovery` board (STM32F407)
|
||||
with
|
||||
- `LetsTrust TPM2.0` module or `Infineon SLB9670` module
|
||||
|
||||
Hardware connections must be made between the TPM2.0 module and the STM32F4 board. Here is a wiring table for the Infineon module:
|
||||
|
||||
| STM32F4 | Pin function | TPM2.0 module |
|
||||
|----------|:-------------:|--------------:|
|
||||
| PE0 | SPI CS | Pin 26 |
|
||||
| PB3 | SPI CLK | Pin 23 |
|
||||
| PB4 | SPI MISO | Pin 21 |
|
||||
| PB5 | SPI MOSI | Pin 19 |
|
||||
| 3V | +3V | Pin 1 |
|
||||
| GND | Ground | Pin 6 |
|
||||
|
||||
|
||||
UART1 on the STM32F4 is used by default. The default baud rate is 115200.
|
||||
|
||||
The UART Pinout can be found below:
|
||||
|
||||
| STM32F4 | Pin function |
|
||||
|----------|:------------:|
|
||||
| PB6 | UART TX |
|
||||
| PB7 | UART RX |
|
||||
| GND | Ground |
|
||||
|
||||
Note: The ST-Link USB UDC is UART 2 on PA3 (TX) / PA2 (RX). This can be changed in app_stm32f4.c using APP_UART.
|
||||
|
||||
Note: Make sure the Ground connection between your USB-UART converter is connected to the STM32F4 board, otherwise UART levels will float and communication will be corrupted.
|
||||
|
||||
|
||||
## Compiling
|
||||
|
||||
Before compiling make sure the git submodules are initialized and updated correctly. Use the following commands to make sure:
|
||||
|
||||
`wolfboot-examples/$ git submodule --init --update`
|
||||
|
||||
`wolfboot-examples/$ cd wolfBoot`
|
||||
|
||||
`wolfboot-examples/wolfBoot$ git submodule --init --update`
|
||||
|
||||
Enter the project folder for this example:
|
||||
|
||||
`wolfboot-examples/wolfBoot$ cd ../test-app-STM32F4-measured-boot`
|
||||
|
||||
Makefile in the project folder takes care of compiling wolfTPM, wolfBoot, compiling the test application and signing the firmware:
|
||||
|
||||
`wolfboot-examples/wolfBoot$ make`
|
||||
|
||||
The following files will be available in the project folder after successful build:
|
||||
|
||||
- factory.bin - Test-app and wolfboot combined, ready for flashing
|
||||
- wolfboot.elf - WolfBoot with Debug information, useful for gdb
|
||||
- image.bin - Test-app without signature
|
||||
- image.elf - Test-app with Debug information, useful for gdb
|
||||
- image_v1_signed.bin - Test-app with signature
|
||||
- image.map - Listing of the Test-app
|
||||
|
||||
## Usage
|
||||
|
||||
After successful compilation, the `flash` target can be used to flash the `factory.bin` image to the STM32F4-Discovery board using ST-Link2
|
||||
|
||||
`make flash`
|
||||
|
||||
Typical output:
|
||||
|
||||
```
|
||||
test-app-STM32F4-measured-boot % make flash
|
||||
st-flash write factory.bin 0x08000000
|
||||
st-flash 1.6.1
|
||||
2021-01-27T19:24:01 INFO common.c: F4xx: 192 KiB SRAM, 1024 KiB flash in at least 16 KiB pages.
|
||||
file factory.bin md5 checksum: 7cc2a98a3e5366ecc54bbb79a646286, stlink checksum: 0x01c745fb
|
||||
2021-01-27T19:24:01 INFO common.c: Attempting to write 143576 (0x230d8) bytes to stm32 address: 134217728 (0x8000000)
|
||||
EraseFlash - Sector:0x0 Size:0x4000 2021-01-27T19:24:01 INFO common.c: Flash page at addr: 0x08000000 erased
|
||||
EraseFlash - Sector:0x1 Size:0x4000 2021-01-27T19:24:02 INFO common.c: Flash page at addr: 0x08004000 erased
|
||||
EraseFlash - Sector:0x2 Size:0x4000 2021-01-27T19:24:02 INFO common.c: Flash page at addr: 0x08008000 erased
|
||||
EraseFlash - Sector:0x3 Size:0x4000 2021-01-27T19:24:02 INFO common.c: Flash page at addr: 0x0800c000 erased
|
||||
EraseFlash - Sector:0x4 Size:0x10000 2021-01-27T19:24:03 INFO common.c: Flash page at addr: 0x08010000 erased
|
||||
EraseFlash - Sector:0x5 Size:0x20000 2021-01-27T19:24:05 INFO common.c: Flash page at addr: 0x08020000 erased
|
||||
2021-01-27T19:24:05 INFO common.c: Finished erasing 6 pages of 131072 (0x20000) bytes
|
||||
2021-01-27T19:24:05 INFO common.c: Starting Flash write for F2/F4/L4
|
||||
2021-01-27T19:24:05 INFO flash_loader.c: Successfully loaded flash loader in sram
|
||||
enabling 32-bit flash writes
|
||||
size: 32768
|
||||
size: 32768
|
||||
size: 32768
|
||||
size: 32768
|
||||
size: 12504
|
||||
2021-01-27T19:24:07 INFO common.c: Starting verification of write complete
|
||||
2021-01-27T19:24:08 INFO common.c: Flash written and verified! jolly good!
|
||||
```
|
||||
|
||||
To debug start first start GDB server (see GDB Server section below).
|
||||
|
||||
1. Launch arm-none-eabi-gdb and perform the following steps for debugging
|
||||
|
||||
2. Load symbol file for test application. Wolfboot.elf is already loaded thanks to .gdbinit supplied with the project.
|
||||
|
||||
`add-symbol-file image.elf`
|
||||
|
||||
3. Set breakpoints at "main", two breakpoints should be created, one for main() in wolfBoot and one for main() in the test app.
|
||||
|
||||
`b main`
|
||||
|
||||
4. Set breakpoints at "measure_boot", "read_measured_boot"
|
||||
|
||||
`b measure_boot`
|
||||
`b read_measured_boot`
|
||||
|
||||
5. Start execution by invoking "continue" to gdb
|
||||
|
||||
`c`
|
||||
|
||||
6. Expected output on the connected UART terminal (see UART pinout in `Prerequisites`)
|
||||
|
||||
```
|
||||
App started
|
||||
Measured Boot PCR is = 0x01020304050607080910
|
||||
```
|
||||
|
||||
This value is the one created by wolfBoot during start of the device. This value is the result of PCR Extend operation and depends on the firmware image loaded. Using the same firmware image should produce the same PCR measurement. By using different firmware images a change in the PCR value can be obsereved, simulating tampering.
|
||||
|
||||
For more information about measured boot contact us at facts@wolfssl.com
|
||||
|
||||
## GDB Server
|
||||
|
||||
The supplied openocd.config is prepared for STM32F407-Discovery revision D that uses newer ST-LINK2 variant.
|
||||
|
||||
If you are using STM32F407-Discovery revision B, then modify the very first line in the config file:
|
||||
|
||||
`source [find interface/stlink-v2-1.cfg]`
|
||||
|
||||
with
|
||||
|
||||
`source [find interface/stlink-v2.cfg]`
|
||||
|
||||
Start new openocd session using
|
||||
|
||||
`openocd -f openocd.config`
|
||||
|
||||
Start new gdb session as described in `Usage`.
|
||||
|
||||
Note: You can also use the ST-Util for GDB server using: `st-util -p 3333`.
|
||||
|
||||
Please contact us at support@wolfssl.com for any questions about using this example.
|
||||
|
||||
## Copyright notice
|
||||
|
||||
This example is Copyright (c) 2020 wolfSSL Inc., and distributed under the term of GNU GPL2.
|
||||
|
||||
wolfBoot, wolfSSL (formerly known as CyaSSL) and wolfCrypt are Copyright (c) 2006-2018 wolfSSL Inc., and licensed for use under GPLv2.
|
||||
|
||||
wolfTPM is Copyright (c) 2018-2020 wolfSSL Inc., and licensed for use under GPLv2.
|
||||
|
||||
See the documentation within each component subdirectory for more information about using and distributing this software.
|
|
@ -0,0 +1,26 @@
|
|||
ARCH?=ARM
|
||||
TARGET?=stm32f4
|
||||
SIGN?=ECC256
|
||||
HASH?=SHA256
|
||||
DEBUG?=1
|
||||
VTOR?=1
|
||||
CORTEX_M0?=0
|
||||
NO_ASM?=0
|
||||
EXT_FLASH?=0
|
||||
SPI_FLASH?=0
|
||||
ALLOW_DOWNGRADE?=0
|
||||
NVM_FLASH_WRITEONCE?=0
|
||||
WOLFBOOT_VERSION?=0
|
||||
V?=0
|
||||
SPMATH?=1
|
||||
RAM_CODE?=0
|
||||
DUALBANK_SWAP?=0
|
||||
IMAGE_HEADER_SIZE?=256
|
||||
WOLFBOOT_PARTITION_SIZE?=0x20000
|
||||
WOLFBOOT_SECTOR_SIZE?=0x20000
|
||||
WOLFBOOT_PARTITION_BOOT_ADDRESS?=0x20000
|
||||
WOLFBOOT_PARTITION_UPDATE_ADDRESS?=0x40000
|
||||
WOLFBOOT_PARTITION_SWAP_ADDRESS?=0x60000
|
||||
WOLFTPM?=1
|
||||
MEASURED_BOOT?=1
|
||||
MEASURED_PCR_A?=16
|
Binary file not shown.
After Width: | Height: | Size: 88 KiB |
|
@ -0,0 +1,8 @@
|
|||
source [find interface/stlink-v2-1.cfg]
|
||||
source [find target/stm32f4x.cfg]
|
||||
$_TARGETNAME configure -event reset-init {
|
||||
mmw 0xe0042004 0x7 0x0
|
||||
}
|
||||
init
|
||||
reset
|
||||
halt
|
|
@ -0,0 +1,45 @@
|
|||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = ##WOLFBOOT_TEST_APP_ADDRESS##, LENGTH = ##WOLFBOOT_TEST_APP_SIZE##
|
||||
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 16K /* Run in lowmem */
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
_start_text = .;
|
||||
KEEP(*(.isr_vector))
|
||||
*(.init)
|
||||
*(.fini)
|
||||
*(.text*)
|
||||
*(.rodata*)
|
||||
. = ALIGN(4);
|
||||
_end_text = .;
|
||||
} > FLASH
|
||||
|
||||
_stored_data = .;
|
||||
|
||||
.data : AT (_stored_data)
|
||||
{
|
||||
_start_data = .;
|
||||
KEEP(*(.data*))
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.ramcode))
|
||||
. = ALIGN(4);
|
||||
_end_data = .;
|
||||
} > RAM
|
||||
|
||||
.bss :
|
||||
{
|
||||
_start_bss = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
_end_bss = .;
|
||||
_end = .;
|
||||
} > RAM
|
||||
}
|
||||
|
||||
PROVIDE(_start_heap = _end);
|
||||
PROVIDE(_end_stack = ORIGIN(RAM) + LENGTH(RAM));
|
|
@ -0,0 +1,444 @@
|
|||
/* app_stm32f4.c
|
||||
*
|
||||
* Test bare-metal application for reporting measured boot value over UART
|
||||
*
|
||||
* Copyright (C) 2021 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfBoot.
|
||||
*
|
||||
* wolfBoot is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfBoot 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "system.h"
|
||||
#include "timer.h"
|
||||
#include "led.h"
|
||||
#include "hal.h"
|
||||
#include "wolfboot/wolfboot.h"
|
||||
#include "spi_flash.h"
|
||||
#include "spi_drv.h"
|
||||
#include "spi_tpm.h"
|
||||
|
||||
#include "wolftpm/tpm2.h"
|
||||
#include "wolftpm/tpm2_wrap.h"
|
||||
static WOLFTPM2_DEV wolftpm_dev;
|
||||
|
||||
#define UART1 (0x40011000)
|
||||
#define UART2 (0x40014400)
|
||||
|
||||
#ifndef APP_UART
|
||||
#define APP_UART UART1
|
||||
#endif
|
||||
#define UART_SR (*(volatile uint32_t *)(APP_UART))
|
||||
#define UART_DR (*(volatile uint32_t *)(APP_UART + 0x04))
|
||||
#define UART_BRR (*(volatile uint32_t *)(APP_UART + 0x08))
|
||||
#define UART_CR1 (*(volatile uint32_t *)(APP_UART + 0x0c))
|
||||
#define UART_CR2 (*(volatile uint32_t *)(APP_UART + 0x10))
|
||||
|
||||
#define UART_CR1_UART_ENABLE (1 << 13)
|
||||
#define UART_CR1_SYMBOL_LEN (1 << 12)
|
||||
#define UART_CR1_PARITY_ENABLED (1 << 10)
|
||||
#define UART_CR1_PARITY_ODD (1 << 9)
|
||||
#define UART_CR1_TX_ENABLE (1 << 3)
|
||||
#define UART_CR1_RX_ENABLE (1 << 2)
|
||||
#define UART_CR2_STOPBITS (3 << 12)
|
||||
#define UART_SR_TX_EMPTY (1 << 7)
|
||||
#define UART_SR_RX_NOTEMPTY (1 << 5)
|
||||
|
||||
|
||||
#define CLOCK_SPEED (168000000)
|
||||
|
||||
#define APB2_CLOCK_ER (*(volatile uint32_t *)(0x40023844))
|
||||
#define UART1_APB2_CLOCK_ER (1 << 4)
|
||||
#define UART2_APB2_CLOCK_ER (1 << 17)
|
||||
|
||||
#define AHB1_CLOCK_ER (*(volatile uint32_t *)(0x40023830))
|
||||
#define GPIOA_AHB1_CLOCK_ER (1 << 0)
|
||||
#define GPIOB_AHB1_CLOCK_ER (1 << 1)
|
||||
|
||||
#ifndef GPIOA_BASE
|
||||
#define GPIOA_BASE 0x48000000
|
||||
#endif
|
||||
#define GPIOA_MODE (*(volatile uint32_t *)(GPIOA_BASE + 0x00))
|
||||
#define GPIOA_AFL (*(volatile uint32_t *)(GPIOA_BASE + 0x20))
|
||||
#define GPIOA_AFH (*(volatile uint32_t *)(GPIOA_BASE + 0x24))
|
||||
#ifndef GPIOB_BASE
|
||||
#define GPIOB_BASE 0x48000400
|
||||
#endif
|
||||
#define GPIOB_MODE (*(volatile uint32_t *)(GPIOB_BASE + 0x00))
|
||||
#define GPIOB_AFL (*(volatile uint32_t *)(GPIOB_BASE + 0x20))
|
||||
#define GPIOB_AFH (*(volatile uint32_t *)(GPIOB_BASE + 0x24))
|
||||
|
||||
#define UART_PIN_AF 7
|
||||
#define UART1_RX_PIN 7 /* PB7 */
|
||||
#define UART1_TX_PIN 6 /* PB6 */
|
||||
#define UART2_RX_PIN 3 /* PA3 */
|
||||
#define UART2_TX_PIN 2 /* PA2 */
|
||||
|
||||
#define MSGSIZE 16
|
||||
#define PAGESIZE (256)
|
||||
static uint8_t page[PAGESIZE];
|
||||
static const char ERR='!';
|
||||
static const char START='*';
|
||||
static const char UPDATE='U';
|
||||
static const char ACK='#';
|
||||
static uint8_t msg[MSGSIZE];
|
||||
static const char startString[]="App started";
|
||||
static const char TPMfailString[]="tpm_init failed";
|
||||
static const char TPMpcrString[]="Measured Boot PCR is = ";
|
||||
static const char HEX [16] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
|
||||
|
||||
volatile uint32_t time_elapsed = 0; /* Used for PWM on LED */
|
||||
|
||||
void uart_write(const char c)
|
||||
{
|
||||
uint32_t reg;
|
||||
do {
|
||||
reg = UART_SR;
|
||||
} while ((reg & UART_SR_TX_EMPTY) == 0);
|
||||
UART_DR = c;
|
||||
}
|
||||
|
||||
void uart_write_hex(const char c)
|
||||
{
|
||||
uart_write(HEX[(c >> 4) & 0x0F]);
|
||||
uart_write(HEX[c & 0x0F]);
|
||||
}
|
||||
|
||||
static void uart_pins_setup(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
#if APP_UART == UART1
|
||||
AHB1_CLOCK_ER |= GPIOB_AHB1_CLOCK_ER;
|
||||
/* Set mode = AF */
|
||||
reg = GPIOB_MODE & ~ (0x03 << (UART1_RX_PIN * 2));
|
||||
GPIOB_MODE = reg | (2 << (UART1_RX_PIN * 2));
|
||||
reg = GPIOB_MODE & ~ (0x03 << (UART1_TX_PIN * 2));
|
||||
GPIOB_MODE = reg | (2 << (UART1_TX_PIN * 2));
|
||||
|
||||
/* Alternate function: use low pins (6 and 7) */
|
||||
reg = GPIOB_AFL & ~(0xf << ((UART1_TX_PIN) * 4));
|
||||
GPIOB_AFL = reg | (UART_PIN_AF << ((UART1_TX_PIN) * 4));
|
||||
reg = GPIOB_AFL & ~(0xf << ((UART1_RX_PIN) * 4));
|
||||
GPIOB_AFL = reg | (UART_PIN_AF << ((UART1_RX_PIN) * 4));
|
||||
#elif APP_UART == UART2
|
||||
AHB1_CLOCK_ER |= GPIOA_AHB1_CLOCK_ER;
|
||||
/* Set mode = AF */
|
||||
reg = GPIOA_MODE & ~ (0x03 << (UART2_RX_PIN * 2));
|
||||
GPIOA_MODE = reg | (2 << (UART2_RX_PIN * 2));
|
||||
reg = GPIOA_MODE & ~ (0x03 << (UART2_TX_PIN * 2));
|
||||
GPIOA_MODE = reg | (2 << (UART2_TX_PIN * 2));
|
||||
|
||||
/* Alternate function: use low pins (6 and 7) */
|
||||
reg = GPIOA_AFL & ~(0xf << ((UART2_TX_PIN) * 4));
|
||||
GPIOA_AFL = reg | (UART_PIN_AF << ((UART2_TX_PIN) * 4));
|
||||
reg = GPIOA_AFL & ~(0xf << ((UART2_RX_PIN) * 4));
|
||||
GPIOA_AFL = reg | (UART_PIN_AF << ((UART2_RX_PIN) * 4));
|
||||
#else
|
||||
#error Please configure the UART pins
|
||||
#endif
|
||||
}
|
||||
|
||||
int uart_setup(uint32_t bitrate, uint8_t data, char parity, uint8_t stop)
|
||||
{
|
||||
uint32_t reg;
|
||||
/* Enable pins and configure for AF7 */
|
||||
uart_pins_setup();
|
||||
/* Turn on the device */
|
||||
#if APP_UART == UART1
|
||||
APB2_CLOCK_ER |= UART1_APB2_CLOCK_ER;
|
||||
#elif APP_UART == UART2
|
||||
APB2_CLOCK_ER |= UART2_APB2_CLOCK_ER;
|
||||
#endif
|
||||
|
||||
/* Configure for TX + RX */
|
||||
UART_CR1 |= (UART_CR1_TX_ENABLE | UART_CR1_RX_ENABLE);
|
||||
|
||||
/* Configure clock */
|
||||
UART_BRR = CLOCK_SPEED / bitrate;
|
||||
|
||||
/* Configure data bits */
|
||||
if (data == 8)
|
||||
UART_CR1 &= ~UART_CR1_SYMBOL_LEN;
|
||||
else
|
||||
UART_CR1 |= UART_CR1_SYMBOL_LEN;
|
||||
|
||||
/* Configure parity */
|
||||
switch (parity) {
|
||||
case 'O':
|
||||
UART_CR1 |= UART_CR1_PARITY_ODD;
|
||||
/* fall through to enable parity */
|
||||
case 'E':
|
||||
UART_CR1 |= UART_CR1_PARITY_ENABLED;
|
||||
break;
|
||||
default:
|
||||
UART_CR1 &= ~(UART_CR1_PARITY_ENABLED | UART_CR1_PARITY_ODD);
|
||||
}
|
||||
/* Set stop bits */
|
||||
reg = UART_CR2 & ~UART_CR2_STOPBITS;
|
||||
if (stop > 1)
|
||||
UART_CR2 = reg & (2 << 12);
|
||||
else
|
||||
UART_CR2 = reg;
|
||||
|
||||
/* Turn on uart */
|
||||
UART_CR1 |= UART_CR1_UART_ENABLE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char uart_read(void)
|
||||
{
|
||||
char c;
|
||||
volatile uint32_t reg;
|
||||
do {
|
||||
reg = UART_SR;
|
||||
} while ((reg & UART_SR_RX_NOTEMPTY) == 0);
|
||||
c = (char)(UART_DR & 0xff);
|
||||
return c;
|
||||
}
|
||||
|
||||
static void ack(uint32_t _off)
|
||||
{
|
||||
uint8_t *off = (uint8_t *)(&_off);
|
||||
int i;
|
||||
uart_write(ACK);
|
||||
for (i = 0; i < 4; i++) {
|
||||
uart_write(off[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static int check(uint8_t *pkt, int size)
|
||||
{
|
||||
int i;
|
||||
uint16_t c = 0;
|
||||
uint16_t c_rx = *((uint16_t *)(pkt + 2));
|
||||
uint16_t *p = (uint16_t *)(pkt + 4);
|
||||
for (i = 0; i < ((size - 4) >> 1); i++)
|
||||
c += p[i];
|
||||
if (c == c_rx)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int app_tpm2_IoCb(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
|
||||
word16 xferSz, void* userCtx)
|
||||
{
|
||||
(void)userCtx;
|
||||
(void)ctx;
|
||||
word16 i;
|
||||
|
||||
spi_cs_on(SPI_CS_TPM);
|
||||
|
||||
XMEMSET(rxBuf, 0, xferSz);
|
||||
for (i = 0; i < xferSz; i++)
|
||||
{
|
||||
spi_write(txBuf[i]);
|
||||
rxBuf[i] = spi_read();
|
||||
}
|
||||
spi_cs_off(SPI_CS_TPM);
|
||||
|
||||
/*
|
||||
printf("\r\nSPI TX: ");
|
||||
printbin(txBuf, xferSz);
|
||||
printf("SPI RX: ");
|
||||
printbin(rxBuf, xferSz);
|
||||
printf("\r\n");
|
||||
*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int app_tpm2_init(void)
|
||||
{
|
||||
int rc;
|
||||
WOLFTPM2_CAPS caps;
|
||||
|
||||
spi_init(0,0);
|
||||
|
||||
/* Init the TPM2 device */
|
||||
rc = wolfTPM2_Init(&wolftpm_dev, app_tpm2_IoCb, NULL);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Get device capabilities + options */
|
||||
rc = wolfTPM2_GetCapabilities(&wolftpm_dev, &caps);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Reads out the TPM measurement created by wolfBoot */
|
||||
static int read_measured_boot(uint8_t* digest)
|
||||
{
|
||||
int rc;
|
||||
PCR_Read_In pcrReadCmd;
|
||||
PCR_Read_Out pcrReadResp;
|
||||
|
||||
XMEMSET(&pcrReadCmd, 0, sizeof(pcrReadCmd));
|
||||
TPM2_SetupPCRSel(&pcrReadCmd.pcrSelectionIn, TPM_ALG_SHA256, WOLFBOOT_MEASURED_PCR_A);
|
||||
rc = TPM2_PCR_Read(&pcrReadCmd, &pcrReadResp);
|
||||
if (rc == TPM_RC_SUCCESS) {
|
||||
XMEMCPY(digest, pcrReadResp.pcrValues.digests[0].buffer,
|
||||
pcrReadResp.pcrValues.digests[0].size);
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
uint32_t tlen = 0;
|
||||
volatile uint32_t recv_seq;
|
||||
uint32_t r_total = 0;
|
||||
uint32_t tot_len = 0;
|
||||
uint32_t next_seq = 0;
|
||||
uint32_t version = 0;
|
||||
uint8_t *v_array = (uint8_t *)&version;
|
||||
uint8_t boot_measurement[WOLFBOOT_SHA_DIGEST_SIZE];
|
||||
int i;
|
||||
memset(page, 0xFF, PAGESIZE);
|
||||
boot_led_on();
|
||||
flash_set_waitstates();
|
||||
clock_config();
|
||||
led_pwm_setup();
|
||||
pwm_init(CPU_FREQ, 0);
|
||||
|
||||
/* Dim the led by altering the PWM duty-cicle
|
||||
* in isr_tim2 (timer.c)
|
||||
*
|
||||
* Every 50ms, the duty cycle of the PWM connected
|
||||
* to the blue led increases/decreases making a pulse
|
||||
* effect.
|
||||
*/
|
||||
timer_init(CPU_FREQ, 1, 50);
|
||||
uart_setup(115200, 8, 'N', 1);
|
||||
memset(page, 0xFF, PAGESIZE);
|
||||
asm volatile ("cpsie i");
|
||||
|
||||
while(time_elapsed == 0)
|
||||
WFI();
|
||||
|
||||
|
||||
hal_flash_unlock();
|
||||
version = wolfBoot_current_firmware_version();
|
||||
if ((version & 0x01) == 0)
|
||||
wolfBoot_success();
|
||||
#ifdef EXT_ENCRYPTED
|
||||
wolfBoot_set_encrypt_key("0123456789abcdef0123456789abcdef", 32);
|
||||
#endif
|
||||
|
||||
for(i=0; i < sizeof(startString); i++) {
|
||||
uart_write(startString[i++]);
|
||||
}
|
||||
|
||||
uart_write(START);
|
||||
for (i = 3; i >= 0; i--) {
|
||||
uart_write(v_array[i]);
|
||||
}
|
||||
|
||||
if(app_tpm2_init() != 0) {
|
||||
for(i=0; i < sizeof(TPMfailString); i++) {
|
||||
uart_write(TPMfailString[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if(read_measured_boot(boot_measurement) == 0) {
|
||||
for(i = 0; i < sizeof(TPMpcrString); i++) {
|
||||
uart_write(TPMpcrString[i]);
|
||||
}
|
||||
/* Print the digest of the measurement */
|
||||
for(i=0; i < sizeof(boot_measurement); i++) {
|
||||
uart_write_hex(boot_measurement[i]);
|
||||
}
|
||||
/* For better view on the UART terminal */
|
||||
uart_write('\n');
|
||||
uart_write('\r');
|
||||
}
|
||||
|
||||
while (1) {
|
||||
r_total = 0;
|
||||
do {
|
||||
while(r_total < 2) {
|
||||
msg[r_total++] = uart_read();
|
||||
if ((r_total == 2) && ((msg[0] != 0xA5) || msg[1] != 0x5A)) {
|
||||
r_total = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
msg[r_total++] = uart_read();
|
||||
if ((tot_len == 0) && r_total == 2 + sizeof(uint32_t))
|
||||
break;
|
||||
if ((r_total > 8) && (tot_len <= ((r_total - 8) + next_seq)))
|
||||
break;
|
||||
} while (r_total < MSGSIZE);
|
||||
if (tot_len == 0) {
|
||||
tlen = msg[2] + (msg[3] << 8) + (msg[4] << 16) + (msg[5] << 24);
|
||||
if (tlen > WOLFBOOT_PARTITION_SIZE - 8) {
|
||||
uart_write(ERR);
|
||||
uart_write(ERR);
|
||||
uart_write(ERR);
|
||||
uart_write(ERR);
|
||||
uart_write(START);
|
||||
recv_seq = 0;
|
||||
tot_len = 0;
|
||||
continue;
|
||||
}
|
||||
tot_len = tlen;
|
||||
ack(0);
|
||||
continue;
|
||||
}
|
||||
if (check(msg, r_total) < 0) {
|
||||
ack(next_seq);
|
||||
continue;
|
||||
}
|
||||
recv_seq = msg[4] + (msg[5] << 8) + (msg[6] << 16) + (msg[7] << 24);
|
||||
if (recv_seq == next_seq)
|
||||
{
|
||||
int psize = r_total - 8;
|
||||
int page_idx = recv_seq % PAGESIZE;
|
||||
memcpy(&page[recv_seq % PAGESIZE], msg + 8, psize);
|
||||
page_idx += psize;
|
||||
if ((page_idx == PAGESIZE) || (next_seq + psize >= tot_len)) {
|
||||
uint32_t dst = (WOLFBOOT_PARTITION_UPDATE_ADDRESS + recv_seq + psize) - page_idx;
|
||||
if ((dst % WOLFBOOT_SECTOR_SIZE) == 0) {
|
||||
hal_flash_erase(dst, WOLFBOOT_SECTOR_SIZE);
|
||||
}
|
||||
hal_flash_write(dst, page, PAGESIZE);
|
||||
memset(page, 0xFF, PAGESIZE);
|
||||
}
|
||||
next_seq += psize;
|
||||
}
|
||||
ack(next_seq);
|
||||
if (next_seq >= tot_len) {
|
||||
/* Update complete */
|
||||
spi_flash_probe();
|
||||
wolfBoot_update_trigger();
|
||||
spi_release();
|
||||
hal_flash_lock();
|
||||
break;
|
||||
}
|
||||
}
|
||||
/* Wait for reboot */
|
||||
while(1)
|
||||
;
|
||||
}
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
/* led.c
|
||||
*
|
||||
* Test bare-metal blinking led application
|
||||
*
|
||||
* Copyright (C) 2020 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfBoot.
|
||||
*
|
||||
* wolfBoot is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfBoot 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
#include <stdint.h>
|
||||
#include "wolfboot/wolfboot.h"
|
||||
|
||||
#ifdef PLATFORM_stm32f4
|
||||
|
||||
#define AHB1_CLOCK_ER (*(volatile uint32_t *)(0x40023830))
|
||||
#define GPIOD_AHB1_CLOCK_ER (1 << 3)
|
||||
|
||||
#define GPIOD_BASE 0x40020c00
|
||||
#define GPIOD_MODE (*(volatile uint32_t *)(GPIOD_BASE + 0x00))
|
||||
#define GPIOD_OTYPE (*(volatile uint32_t *)(GPIOD_BASE + 0x04))
|
||||
#define GPIOD_OSPD (*(volatile uint32_t *)(GPIOD_BASE + 0x08))
|
||||
#define GPIOD_PUPD (*(volatile uint32_t *)(GPIOD_BASE + 0x0c))
|
||||
#define GPIOD_ODR (*(volatile uint32_t *)(GPIOD_BASE + 0x14))
|
||||
#define GPIOD_BSRR (*(volatile uint32_t *)(GPIOD_BASE + 0x18))
|
||||
#define GPIOD_AFL (*(volatile uint32_t *)(GPIOD_BASE + 0x20))
|
||||
#define GPIOD_AFH (*(volatile uint32_t *)(GPIOD_BASE + 0x24))
|
||||
#define LED_PIN (15)
|
||||
#define LED_BOOT_PIN (14)
|
||||
#define GPIO_OSPEED_100MHZ (0x03)
|
||||
void led_pwm_setup(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
AHB1_CLOCK_ER |= GPIOD_AHB1_CLOCK_ER;
|
||||
reg = GPIOD_MODE & ~ (0x03 << (LED_PIN * 2));
|
||||
GPIOD_MODE = reg | (2 << (LED_PIN * 2));
|
||||
|
||||
reg = GPIOD_OSPD & ~(0x03 << (LED_PIN * 2));
|
||||
GPIOD_OSPD = reg | (0x03 << (LED_PIN * 2));
|
||||
|
||||
reg = GPIOD_PUPD & ~(0x03 << (LED_PIN * 2));
|
||||
GPIOD_PUPD = reg | (0x02 << (LED_PIN * 2));
|
||||
|
||||
/* Alternate function: use high pin */
|
||||
reg = GPIOD_AFH & ~(0xf << ((LED_PIN - 8) * 4));
|
||||
GPIOD_AFH = reg | (0x2 << ((LED_PIN - 8) * 4));
|
||||
}
|
||||
|
||||
void boot_led_on(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
uint32_t pin = LED_BOOT_PIN;// - 2 * (wolfBoot_current_firmware_version() & 0x01);
|
||||
AHB1_CLOCK_ER |= GPIOD_AHB1_CLOCK_ER;
|
||||
reg = GPIOD_MODE & ~(0x03 << (pin * 2));
|
||||
GPIOD_MODE = reg | (1 << (pin * 2));
|
||||
reg = GPIOD_PUPD & ~(0x03 << (pin * 2));
|
||||
GPIOD_PUPD = reg | (1 << (pin * 2));
|
||||
GPIOD_BSRR |= (1 << pin);
|
||||
}
|
||||
|
||||
#endif /* PLATFORM_stm32f4 */
|
||||
|
||||
#ifdef PLATFORM_stm32l0
|
||||
#define LED_BOOT_PIN (5)
|
||||
|
||||
#define RCC_IOPENR (*(volatile uint32_t *)(0x4002102C))
|
||||
#define IOPAEN (1 << 0)
|
||||
|
||||
|
||||
#define GPIOA_BASE 0x50000000
|
||||
#define GPIOA_MODE (*(volatile uint32_t *)(GPIOA_BASE + 0x00))
|
||||
#define GPIOA_OTYPE (*(volatile uint32_t *)(GPIOA_BASE + 0x04))
|
||||
#define GPIOA_OSPD (*(volatile uint32_t *)(GPIOA_BASE + 0x08))
|
||||
#define GPIOA_PUPD (*(volatile uint32_t *)(GPIOA_BASE + 0x0c))
|
||||
#define GPIOA_ODR (*(volatile uint32_t *)(GPIOA_BASE + 0x14))
|
||||
#define GPIOA_BSRR (*(volatile uint32_t *)(GPIOA_BASE + 0x18))
|
||||
#define GPIOA_AFL (*(volatile uint32_t *)(GPIOA_BASE + 0x20))
|
||||
#define GPIOA_AFH (*(volatile uint32_t *)(GPIOA_BASE + 0x24))
|
||||
|
||||
|
||||
void boot_led_on(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
uint32_t pin = LED_BOOT_PIN;
|
||||
RCC_IOPENR |= IOPAEN;
|
||||
reg = GPIOA_MODE & ~(0x03 << (pin * 2));
|
||||
GPIOA_MODE = reg | (1 << (pin * 2));
|
||||
reg = GPIOA_PUPD & ~(0x03 << (pin * 2));
|
||||
GPIOA_PUPD = reg | (1 << (pin * 2));
|
||||
GPIOA_BSRR |= (1 << pin);
|
||||
}
|
||||
|
||||
|
||||
#endif /* PLATFORM_stm32l0 */
|
||||
|
||||
#ifdef PLATFORM_stm32g0
|
||||
#include <stdint.h>
|
||||
#include "wolfboot/wolfboot.h"
|
||||
|
||||
|
||||
/*GPIOA5*/
|
||||
#define RCC_IOPENR (*(volatile uint32_t *)(0x40021034)) // 40021034
|
||||
#define RCC_IOPENR_GPIOAEN (1 << 0)
|
||||
|
||||
#define GPIOA_BASE 0x50000000
|
||||
#define GPIOA_MODE (*(volatile uint32_t *)(GPIOA_BASE + 0x00))
|
||||
#define GPIOA_OTYPE (*(volatile uint32_t *)(GPIOA_BASE + 0x04))
|
||||
#define GPIOA_OSPD (*(volatile uint32_t *)(GPIOA_BASE + 0x08))
|
||||
#define GPIOA_PUPD (*(volatile uint32_t *)(GPIOA_BASE + 0x0c))
|
||||
#define GPIOA_ODR (*(volatile uint32_t *)(GPIOA_BASE + 0x14))
|
||||
#define GPIOA_BSRR (*(volatile uint32_t *)(GPIOA_BASE + 0x18))
|
||||
#define GPIOA_AFL (*(volatile uint32_t *)(GPIOA_BASE + 0x20))
|
||||
#define GPIOA_AFH (*(volatile uint32_t *)(GPIOA_BASE + 0x24))
|
||||
#define LED_PIN (5)
|
||||
#define LED_BOOT_PIN (5)
|
||||
#define GPIO_OSPEED_100MHZ (0x03)
|
||||
|
||||
void boot_led_on(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
uint32_t pin = LED_BOOT_PIN;
|
||||
RCC_IOPENR |= RCC_IOPENR_GPIOAEN;
|
||||
reg = GPIOA_MODE & ~(0x03 << (pin * 2));
|
||||
GPIOA_MODE = reg | (1 << (pin * 2)); // general purpose output mode
|
||||
reg = GPIOA_PUPD & ~(0x03 << (pin * 2));
|
||||
GPIOA_PUPD = reg | (1 << (pin * 2)); // pull-up
|
||||
GPIOA_BSRR |= (1 << pin); // set pin
|
||||
}
|
||||
|
||||
#endif /** PLATFORM_stm32g0 **/
|
||||
|
||||
#ifdef PLATFORM_stm32wb
|
||||
#define LED_BOOT_PIN (0)
|
||||
#define RCC_AHB2_CLOCK_ER (*(volatile uint32_t *)(0x5800004C))
|
||||
#define GPIOB_AHB2_CLOCK_ER (1 << 1)
|
||||
|
||||
#define GPIOB_BASE 0x48000400
|
||||
#define GPIOB_MODE (*(volatile uint32_t *)(GPIOB_BASE + 0x00))
|
||||
#define GPIOB_OTYPE (*(volatile uint32_t *)(GPIOB_BASE + 0x04))
|
||||
#define GPIOB_OSPD (*(volatile uint32_t *)(GPIOB_BASE + 0x08))
|
||||
#define GPIOB_PUPD (*(volatile uint32_t *)(GPIOB_BASE + 0x0c))
|
||||
#define GPIOB_ODR (*(volatile uint32_t *)(GPIOB_BASE + 0x14))
|
||||
#define GPIOB_BSRR (*(volatile uint32_t *)(GPIOB_BASE + 0x18))
|
||||
#define GPIOB_AFL (*(volatile uint32_t *)(GPIOB_BASE + 0x20))
|
||||
#define GPIOB_AFH (*(volatile uint32_t *)(GPIOB_BASE + 0x24))
|
||||
|
||||
|
||||
void boot_led_on(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
uint32_t pin = LED_BOOT_PIN;
|
||||
RCC_AHB2_CLOCK_ER |= GPIOB_AHB2_CLOCK_ER;
|
||||
reg = GPIOB_MODE & ~(0x03 << (pin * 2));
|
||||
GPIOB_MODE = reg | (1 << (pin * 2));
|
||||
reg = GPIOB_PUPD & ~(0x03 << (pin * 2));
|
||||
GPIOB_PUPD = reg | (1 << (pin * 2));
|
||||
GPIOB_BSRR |= (1 << pin);
|
||||
}
|
||||
|
||||
void boot_led_off(void)
|
||||
{
|
||||
uint32_t reg;
|
||||
uint32_t pin = LED_BOOT_PIN;
|
||||
GPIOB_BSRR |= (1 << (pin + 16));
|
||||
}
|
||||
|
||||
|
||||
#endif /* PLATFORM_stm32wb */
|
|
@ -0,0 +1,35 @@
|
|||
/* led.h
|
||||
*
|
||||
* Test bare-metal blinking led application
|
||||
*
|
||||
* Copyright (C) 2020 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfBoot.
|
||||
*
|
||||
* wolfBoot is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfBoot 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
#ifndef GPIO_H_INCLUDED
|
||||
#define GPIO_H_INCLUDED
|
||||
|
||||
int led_setup(void);
|
||||
void led_on(void);
|
||||
void led_off(void);
|
||||
void led_toggle(void);
|
||||
void led_pwm_setup(void);
|
||||
void boot_led_on(void);
|
||||
void boot_led_off(void);
|
||||
|
||||
#endif /* !GPIO_H_INCLUDED */
|
|
@ -0,0 +1,36 @@
|
|||
/* tpm_spi.h
|
||||
*
|
||||
* wolfBoot is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfBoot 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
/** SPI settings for TPM2.0 module **/
|
||||
|
||||
#undef SPI_GPIO
|
||||
#define SPI_GPIO GPIOB_BASE
|
||||
|
||||
#undef SPI_CS_GPIO
|
||||
#define SPI_CS_GPIO GPIOE_BASE
|
||||
|
||||
#undef SPI_CS_TPM
|
||||
#define SPI_CS_TPM 0 /* TPM CS connected to GPIOE0 */
|
||||
|
||||
#undef SPI1_CLOCK_PIN
|
||||
#define SPI1_CLOCK_PIN 3 /* SPI_SCK: PB3 */
|
||||
|
||||
#undef SPI1_MISO_PIN
|
||||
#define SPI1_MISO_PIN 4 /* SPI_MISO PB4 */
|
||||
|
||||
#undef SPI1_MOSI_PIN
|
||||
#define SPI1_MOSI_PIN 5 /* SPI_MOSI PB5 */
|
|
@ -0,0 +1,337 @@
|
|||
/* startup_arm.c
|
||||
*
|
||||
* Test bare-metal blinking led application
|
||||
*
|
||||
* Copyright (C) 2020 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfBoot.
|
||||
*
|
||||
* wolfBoot is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfBoot 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
extern unsigned int _stored_data;
|
||||
extern unsigned int _start_data;
|
||||
extern unsigned int _end_data;
|
||||
extern unsigned int _start_bss;
|
||||
extern unsigned int _end_bss;
|
||||
extern unsigned int _end_stack;
|
||||
extern unsigned int _start_heap;
|
||||
|
||||
static int zeroed_variable_in_bss;
|
||||
static int initialized_variable_in_data = 42;
|
||||
|
||||
extern void isr_tim2(void);
|
||||
|
||||
#define STACK_PAINTING
|
||||
|
||||
static volatile unsigned int avail_mem = 0;
|
||||
static unsigned int sp;
|
||||
|
||||
extern void main(void);
|
||||
|
||||
void isr_reset(void) {
|
||||
register unsigned int *src, *dst;
|
||||
src = (unsigned int *) &_stored_data;
|
||||
dst = (unsigned int *) &_start_data;
|
||||
while (dst < (unsigned int *)&_end_data) {
|
||||
*dst = *src;
|
||||
dst++;
|
||||
src++;
|
||||
}
|
||||
|
||||
dst = &_start_bss;
|
||||
while (dst < (unsigned int *)&_end_bss) {
|
||||
*dst = 0U;
|
||||
dst++;
|
||||
}
|
||||
|
||||
avail_mem = &_end_stack - &_start_heap;
|
||||
#ifdef STACK_PAINTING
|
||||
{
|
||||
asm volatile("mrs %0, msp" : "=r"(sp));
|
||||
dst = ((unsigned int *)(&_end_stack)) - (8192 / sizeof(unsigned int)); ;
|
||||
while ((unsigned int)dst < sp) {
|
||||
*dst = 0xDEADC0DE;
|
||||
dst++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
main();
|
||||
}
|
||||
|
||||
void isr_fault(void)
|
||||
{
|
||||
/* Panic. */
|
||||
while(1) ;;
|
||||
|
||||
}
|
||||
|
||||
void isr_memfault(void)
|
||||
{
|
||||
/* Panic. */
|
||||
while(1) ;;
|
||||
}
|
||||
|
||||
void isr_busfault(void)
|
||||
{
|
||||
/* Panic. */
|
||||
while(1) ;;
|
||||
}
|
||||
|
||||
void isr_usagefault(void)
|
||||
{
|
||||
/* Panic. */
|
||||
while(1) ;;
|
||||
}
|
||||
|
||||
|
||||
void isr_empty(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
__attribute__ ((section(".isr_vector")))
|
||||
void (* const IV[])(void) =
|
||||
{
|
||||
(void (*)(void))(&_end_stack),
|
||||
isr_reset, // Reset
|
||||
isr_fault, // NMI
|
||||
isr_fault, // HardFault
|
||||
isr_memfault, // MemFault
|
||||
isr_busfault, // BusFault
|
||||
isr_usagefault, // UsageFault
|
||||
0, // SecureFault
|
||||
0, // reserved
|
||||
0, // reserved
|
||||
0, // reserved
|
||||
isr_empty, // SVC
|
||||
isr_empty, // DebugMonitor
|
||||
0, // reserved
|
||||
isr_empty, // PendSV
|
||||
isr_empty, // SysTick
|
||||
|
||||
/* Device specific IRQs for LM3S */
|
||||
|
||||
#ifdef LM3S
|
||||
isr_empty, // GPIO Port A
|
||||
isr_empty, // GPIO Port B
|
||||
isr_empty, // GPIO Port C
|
||||
isr_empty, // GPIO Port D
|
||||
isr_empty, // GPIO Port E
|
||||
isr_empty, // UART0 Rx and Tx
|
||||
isr_empty, // UART1 Rx and Tx
|
||||
isr_empty, // SSI0 Rx and Tx
|
||||
isr_empty, // I2C0 Master and Slave
|
||||
isr_empty, // PWM Fault
|
||||
isr_empty, // PWM Generator 0
|
||||
isr_empty, // PWM Generator 1
|
||||
isr_empty, // PWM Generator 2
|
||||
isr_empty, // Quadrature Encoder 0
|
||||
isr_empty, // ADC Sequence 0
|
||||
isr_empty, // ADC Sequence 1
|
||||
isr_empty, // ADC Sequence 2
|
||||
isr_empty, // ADC Sequence 3
|
||||
isr_empty, // Watchdog timer
|
||||
isr_empty, // Timer 0 subtimer A
|
||||
isr_empty, // Timer 0 subtimer B
|
||||
isr_empty, // Timer 1 subtimer A
|
||||
isr_empty, // Timer 1 subtimer B
|
||||
isr_empty, // Timer 2 subtimer A
|
||||
isr_empty, // Timer 3 subtimer B
|
||||
isr_empty, // Analog Comparator 0
|
||||
isr_empty, // Analog Comparator 1
|
||||
isr_empty, // Analog Comparator 2
|
||||
isr_empty, // System Control (PLL, OSC, BO)
|
||||
isr_empty, // FLASH Control
|
||||
isr_empty, // GPIO Port F
|
||||
isr_empty, // GPIO Port G
|
||||
isr_empty, // GPIO Port H
|
||||
isr_empty, // UART2 Rx and Tx
|
||||
isr_empty, // SSI1 Rx and Tx
|
||||
isr_empty, // Timer 3 subtimer A
|
||||
isr_empty, // Timer 3 subtimer B
|
||||
isr_empty, // I2C1 Master and Slave
|
||||
isr_empty, // Quadrature Encoder 1
|
||||
isr_empty, // CAN0
|
||||
isr_empty, // CAN1
|
||||
isr_empty, // CAN2
|
||||
isr_empty, // Ethernet
|
||||
isr_empty, // Hibernate
|
||||
#elif PLATFORM_stm32l5
|
||||
isr_empty, // WWDG_IRQHandler
|
||||
isr_empty, // PVD_PVM_IRQHandler
|
||||
isr_empty, // RTC_IRQHandler
|
||||
isr_empty, // RTC_S_IRQHandler
|
||||
isr_empty, // TAMP_IRQHandler
|
||||
isr_empty, // TAMP_S_IRQHandler
|
||||
isr_empty, // FLASH_IRQHandler
|
||||
isr_empty, // FLASH_S_IRQHandler
|
||||
isr_empty, // GTZC_IRQHandler
|
||||
isr_empty, // RCC_IRQHandler
|
||||
isr_empty, // RCC_S_IRQHandler
|
||||
isr_empty, // EXTI0_IRQHandler
|
||||
isr_empty, // EXTI1_IRQHandler
|
||||
isr_empty, // EXTI2_IRQHandler
|
||||
isr_empty, // EXTI3_IRQHandler
|
||||
isr_empty, // EXTI4_IRQHandler
|
||||
isr_empty, // EXTI5_IRQHandler
|
||||
isr_empty, // EXTI6_IRQHandler
|
||||
isr_empty, // EXTI7_IRQHandler
|
||||
isr_empty, // EXTI8_IRQHandler
|
||||
isr_empty, // EXTI9_IRQHandler
|
||||
isr_empty, // EXTI10_IRQHandler
|
||||
isr_empty, // EXTI11_IRQHandler
|
||||
isr_empty, // EXTI12_IRQHandler
|
||||
isr_empty, // EXTI13_IRQHandler
|
||||
isr_empty, // EXTI14_IRQHandler
|
||||
isr_empty, // EXTI15_IRQHandler
|
||||
isr_empty, // DMAMUX1_IRQHandler
|
||||
isr_empty, // DMAMUX1_S_IRQHandler
|
||||
isr_empty, // DMA1_Channel1_IRQHandler
|
||||
isr_empty, // DMA1_Channel2_IRQHandler
|
||||
isr_empty, // DMA1_Channel3_IRQHandler
|
||||
isr_empty, // DMA1_Channel4_IRQHandler
|
||||
isr_empty, // DMA1_Channel5_IRQHandler
|
||||
isr_empty, // DMA1_Channel6_IRQHandler
|
||||
isr_empty, // DMA1_Channel7_IRQHandler
|
||||
isr_empty, // DMA1_Channel8_IRQHandler
|
||||
isr_empty, // ADC1_2_IRQHandler
|
||||
isr_empty, // DAC_IRQHandler
|
||||
isr_empty, // FDCAN1_IT0_IRQHandler
|
||||
isr_empty, // FDCAN1_IT1_IRQHandler
|
||||
isr_empty, // TIM1_BRK_IRQHandler
|
||||
isr_empty, // TIM1_UP_IRQHandler
|
||||
isr_empty, // TIM1_TRG_COM_IRQHandler
|
||||
isr_empty, // TIM1_CC_IRQHandler
|
||||
isr_empty, // TIM2_IRQHandler
|
||||
isr_empty, // TIM3_IRQHandler
|
||||
isr_empty, // TIM4_IRQHandler
|
||||
isr_empty, // TIM5_IRQHandler
|
||||
isr_empty, // TIM6_IRQHandler
|
||||
isr_empty, // TIM7_IRQHandler
|
||||
isr_empty, // TIM8_BRK_IRQHandler
|
||||
isr_empty, // TIM8_UP_IRQHandler
|
||||
isr_empty, // TIM8_TRG_COM_IRQHandler
|
||||
isr_empty, // TIM8_CC_IRQHandler
|
||||
isr_empty, // I2C1_EV_IRQHandler
|
||||
isr_empty, // I2C1_ER_IRQHandler
|
||||
isr_empty, // I2C2_EV_IRQHandler
|
||||
isr_empty, // I2C2_ER_IRQHandler
|
||||
isr_empty, // SPI1_IRQHandler
|
||||
isr_empty, // SPI2_IRQHandler
|
||||
isr_empty, // USART1_IRQHandler
|
||||
isr_empty, // USART2_IRQHandler
|
||||
isr_empty, // USART3_IRQHandler
|
||||
isr_empty, // UART4_IRQHandler
|
||||
isr_empty, // UART5_IRQHandler
|
||||
isr_empty, // LPUART1_IRQHandler
|
||||
isr_empty, // LPTIM1_IRQHandler
|
||||
isr_empty, // LPTIM2_IRQHandler
|
||||
isr_empty, // TIM15_IRQHandler
|
||||
isr_empty, // TIM16_IRQHandler
|
||||
isr_empty, // TIM17_IRQHandler
|
||||
isr_empty, // COMP_IRQHandler
|
||||
isr_empty, // USB_FS_IRQHandler
|
||||
isr_empty, // CRS_IRQHandler
|
||||
isr_empty, // FMC_IRQHandler
|
||||
isr_empty, // OCTOSPI1_IRQHandler
|
||||
isr_empty, // 0
|
||||
isr_empty, // SDMMC1_IRQHandler
|
||||
isr_empty, // 0
|
||||
isr_empty, // DMA2_Channel1_IRQHandler
|
||||
isr_empty, // DMA2_Channel2_IRQHandler
|
||||
isr_empty, // DMA2_Channel3_IRQHandler
|
||||
isr_empty, // DMA2_Channel4_IRQHandler
|
||||
isr_empty, // DMA2_Channel5_IRQHandler
|
||||
isr_empty, // DMA2_Channel6_IRQHandler
|
||||
isr_empty, // DMA2_Channel7_IRQHandler
|
||||
isr_empty, // DMA2_Channel8_IRQHandler
|
||||
isr_empty, // I2C3_EV_IRQHandler
|
||||
isr_empty, // I2C3_ER_IRQHandler
|
||||
isr_empty, // SAI1_IRQHandler
|
||||
isr_empty, // SAI2_IRQHandler
|
||||
isr_empty, // TSC_IRQHandler
|
||||
isr_empty, // AES_IRQHandler
|
||||
isr_empty, // RNG_IRQHandler
|
||||
isr_empty, // FPU_IRQHandler
|
||||
isr_empty, // HASH_IRQHandler
|
||||
isr_empty, // PKA_IRQHandler
|
||||
isr_empty, // LPTIM3_IRQHandler
|
||||
isr_empty, // SPI3_IRQHandler
|
||||
isr_empty, // I2C4_ER_IRQHandler
|
||||
isr_empty, // I2C4_EV_IRQHandler
|
||||
isr_empty, // DFSDM1_FLT0_IRQHandler
|
||||
isr_empty, // DFSDM1_FLT1_IRQHandler
|
||||
isr_empty, // DFSDM1_FLT2_IRQHandler
|
||||
isr_empty, // DFSDM1_FLT3_IRQHandler
|
||||
isr_empty, // UCPD1_IRQHandler
|
||||
isr_empty, // ICACHE_IRQHandler
|
||||
isr_empty, // OTFDEC1_IRQHandler
|
||||
#else /* For STM32F4 */
|
||||
isr_empty, // NVIC_WWDG_IRQ 0
|
||||
isr_empty, // PVD_IRQ 1
|
||||
isr_empty, // TAMP_STAMP_IRQ 2
|
||||
isr_empty, // RTC_WKUP_IRQ 3
|
||||
isr_empty, // FLASH_IRQ 4
|
||||
isr_empty, // RCC_IRQ 5
|
||||
isr_empty, // EXTI0_IRQ 6
|
||||
isr_empty, // EXTI1_IRQ 7
|
||||
isr_empty, // EXTI2_IRQ 8
|
||||
isr_empty, // EXTI3_IRQ 9
|
||||
isr_empty, // EXTI4_IRQ 10
|
||||
isr_empty, // DMA1_STREAM0_IRQ 11
|
||||
isr_empty, // DMA1_STREAM1_IRQ 12
|
||||
isr_empty, // DMA1_STREAM2_IRQ 13
|
||||
isr_empty, // DMA1_STREAM3_IRQ 14
|
||||
isr_empty, // DMA1_STREAM4_IRQ 15
|
||||
isr_empty, // DMA1_STREAM5_IRQ 16
|
||||
isr_empty, // DMA1_STREAM6_IRQ 17
|
||||
isr_empty, // ADC_IRQ 18
|
||||
isr_empty, // CAN1_TX_IRQ 19
|
||||
isr_empty, // CAN1_RX0_IRQ 20
|
||||
isr_empty, // CAN1_RX1_IRQ 21
|
||||
isr_empty, // CAN1_SCE_IRQ 22
|
||||
isr_empty, // EXTI9_5_IRQ 23
|
||||
isr_empty, // TIM1_BRK_TIM9_IRQ 24
|
||||
isr_empty, // TIM1_UP_TIM10_IRQ 25
|
||||
isr_empty, // TIM1_TRG_COM_TIM11_IRQ 26
|
||||
isr_empty, // TIM1_CC_IRQ 27
|
||||
isr_tim2, // TIM2_IRQ 28
|
||||
isr_empty, // TIM3_IRQ 29
|
||||
isr_empty, // TIM4_IRQ 30
|
||||
isr_empty, // I2C1_EV_IRQ 31
|
||||
isr_empty, // I2C1_ER_IRQ 32
|
||||
isr_empty, // I2C2_EV_IRQ 33
|
||||
isr_empty, // I2C2_ER_IRQ 34
|
||||
isr_empty, // SPI1_IRQ 35
|
||||
isr_empty, // SPI2_IRQ 36
|
||||
isr_empty, // USART1_IRQ 37
|
||||
isr_empty, // USART2_IRQ 38
|
||||
isr_empty, // USART3_IRQ 39
|
||||
isr_empty, // EXTI15_10_IRQ 40
|
||||
isr_empty, // RTC_ALARM_IRQ 41
|
||||
isr_empty, // USB_FS_WKUP_IRQ 42
|
||||
isr_empty, // TIM8_BRK_TIM12_IRQ 43
|
||||
isr_empty, // TIM8_UP_TIM13_IRQ 44
|
||||
isr_empty, // TIM8_TRG_COM_TIM14_IRQ 45
|
||||
isr_empty, // TIM8_CC_IRQ 46
|
||||
isr_empty, // DMA1_STREAM7_IRQ 47
|
||||
|
||||
#endif
|
||||
};
|
|
@ -0,0 +1,147 @@
|
|||
/* system.c
|
||||
*
|
||||
* Test bare-metal blinking led application
|
||||
*
|
||||
* Copyright (C) 2020 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfBoot.
|
||||
*
|
||||
* wolfBoot is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfBoot 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
#if defined(PLATFORM_stm32f4) || defined(PLATFORM_stm32f7)
|
||||
#include <stdint.h>
|
||||
#include "system.h"
|
||||
|
||||
/*** FLASH ***/
|
||||
#define FLASH_BASE (0x40023C00)
|
||||
#define FLASH_ACR (*(volatile uint32_t *)(FLASH_BASE + 0x00))
|
||||
#define FLASH_ACR_ENABLE_DATA_CACHE (1 << 10)
|
||||
#define FLASH_ACR_ENABLE_INST_CACHE (1 << 9)
|
||||
|
||||
/*** RCC ***/
|
||||
|
||||
#define RCC_BASE (0x40023800)
|
||||
#define RCC_CR (*(volatile uint32_t *)(RCC_BASE + 0x00))
|
||||
#define RCC_PLLCFGR (*(volatile uint32_t *)(RCC_BASE + 0x04))
|
||||
#define RCC_CFGR (*(volatile uint32_t *)(RCC_BASE + 0x08))
|
||||
#define RCC_CR (*(volatile uint32_t *)(RCC_BASE + 0x00))
|
||||
|
||||
#define RCC_CR_PLLRDY (1 << 25)
|
||||
#define RCC_CR_PLLON (1 << 24)
|
||||
#define RCC_CR_HSERDY (1 << 17)
|
||||
#define RCC_CR_HSEON (1 << 16)
|
||||
#define RCC_CR_HSIRDY (1 << 1)
|
||||
#define RCC_CR_HSION (1 << 0)
|
||||
|
||||
#define RCC_CFGR_SW_HSI 0x0
|
||||
#define RCC_CFGR_SW_HSE 0x1
|
||||
#define RCC_CFGR_SW_PLL 0x2
|
||||
|
||||
|
||||
#define RCC_PLLCFGR_PLLSRC (1 << 22)
|
||||
|
||||
#define RCC_PRESCALER_DIV_NONE 0
|
||||
#define RCC_PRESCALER_DIV_2 8
|
||||
#define RCC_PRESCALER_DIV_4 9
|
||||
|
||||
|
||||
/* STM32F4-Discovery, 168 MHz */
|
||||
#ifdef PLATFORM_stm32f4
|
||||
# define PLLM 8
|
||||
# define PLLN 336
|
||||
# define PLLP 2
|
||||
# define PLLQ 7
|
||||
# define PLLR 0
|
||||
# define TARGET_FLASH_WAITSTATES 5
|
||||
#endif
|
||||
|
||||
/* STM32F7-Discovery, 216 MHz */
|
||||
#ifdef PLATFORM_stm32f7
|
||||
# define PLLM 25
|
||||
# define PLLN 432
|
||||
# define PLLP 2
|
||||
# define PLLQ 9
|
||||
# define PLLR 0
|
||||
# define TARGET_FLASH_WAITSTATES 7
|
||||
#endif
|
||||
|
||||
void flash_set_waitstates(void)
|
||||
{
|
||||
FLASH_ACR |= TARGET_FLASH_WAITSTATES | FLASH_ACR_ENABLE_DATA_CACHE | FLASH_ACR_ENABLE_INST_CACHE;
|
||||
}
|
||||
|
||||
|
||||
void clock_config(void)
|
||||
{
|
||||
uint32_t reg32;
|
||||
/* Enable internal high-speed oscillator. */
|
||||
RCC_CR |= RCC_CR_HSION;
|
||||
DMB();
|
||||
while ((RCC_CR & RCC_CR_HSIRDY) == 0) {};
|
||||
|
||||
/* Select HSI as SYSCLK source. */
|
||||
|
||||
reg32 = RCC_CFGR;
|
||||
reg32 &= ~((1 << 1) | (1 << 0));
|
||||
RCC_CFGR = (reg32 | RCC_CFGR_SW_HSI);
|
||||
DMB();
|
||||
|
||||
/* Enable external high-speed oscillator 8MHz. */
|
||||
RCC_CR |= RCC_CR_HSEON;
|
||||
DMB();
|
||||
while ((RCC_CR & RCC_CR_HSERDY) == 0) {};
|
||||
|
||||
/*
|
||||
* Set prescalers for AHB, ADC, ABP1, ABP2.
|
||||
*/
|
||||
reg32 = RCC_CFGR;
|
||||
reg32 &= ~(0xF0);
|
||||
RCC_CFGR = (reg32 | (RCC_PRESCALER_DIV_NONE << 4));
|
||||
DMB();
|
||||
reg32 = RCC_CFGR;
|
||||
reg32 &= ~(0x1C00);
|
||||
RCC_CFGR = (reg32 | (RCC_PRESCALER_DIV_2 << 10));
|
||||
DMB();
|
||||
reg32 = RCC_CFGR;
|
||||
reg32 &= ~(0x07 << 13);
|
||||
RCC_CFGR = (reg32 | (RCC_PRESCALER_DIV_4 << 13));
|
||||
DMB();
|
||||
|
||||
/* Set PLL config */
|
||||
reg32 = RCC_PLLCFGR;
|
||||
reg32 &= ~(PLL_FULL_MASK);
|
||||
RCC_PLLCFGR = reg32 | RCC_PLLCFGR_PLLSRC | PLLM |
|
||||
(PLLN << 6) | (((PLLP >> 1) - 1) << 16) |
|
||||
(PLLQ << 24);
|
||||
DMB();
|
||||
/* Enable PLL oscillator and wait for it to stabilize. */
|
||||
RCC_CR |= RCC_CR_PLLON;
|
||||
DMB();
|
||||
while ((RCC_CR & RCC_CR_PLLRDY) == 0) {};
|
||||
|
||||
/* Select PLL as SYSCLK source. */
|
||||
reg32 = RCC_CFGR;
|
||||
reg32 &= ~((1 << 1) | (1 << 0));
|
||||
RCC_CFGR = (reg32 | RCC_CFGR_SW_PLL);
|
||||
DMB();
|
||||
|
||||
/* Wait for PLL clock to be selected. */
|
||||
while ((RCC_CFGR & ((1 << 1) | (1 << 0))) != RCC_CFGR_SW_PLL) {};
|
||||
|
||||
/* Disable internal high-speed oscillator. */
|
||||
RCC_CR &= ~RCC_CR_HSION;
|
||||
}
|
||||
|
||||
#endif /* PLATFORM_stm32f4 */
|
|
@ -0,0 +1,67 @@
|
|||
/* system.h
|
||||
*
|
||||
*
|
||||
* Copyright (C) 2020 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfBoot.
|
||||
*
|
||||
* wolfBoot is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfBoot 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
#ifndef SYSTEM_H_INCLUDED
|
||||
#define SYSTEM_H_INCLUDED
|
||||
|
||||
/* System specific: PLL with 8 MHz external oscillator, CPU at 168MHz */
|
||||
#define CPU_FREQ (168000000)
|
||||
#define PLL_FULL_MASK (0x7F037FFF)
|
||||
|
||||
/* Assembly helpers */
|
||||
#define DMB() asm volatile ("dmb");
|
||||
#define WFI() asm volatile ("wfi");
|
||||
|
||||
/* Master clock setting */
|
||||
void clock_config(void);
|
||||
void flash_set_waitstates(void);
|
||||
|
||||
|
||||
/* NVIC */
|
||||
/* NVIC ISER Base register (Cortex-M) */
|
||||
|
||||
#define NVIC_TIM2_IRQN (28)
|
||||
#define NVIC_ISER_BASE (0xE000E100)
|
||||
#define NVIC_ICER_BASE (0xE000E180)
|
||||
#define NVIC_IPRI_BASE (0xE000E400)
|
||||
|
||||
static inline void nvic_irq_enable(uint8_t n)
|
||||
{
|
||||
int i = n / 32;
|
||||
volatile uint32_t *nvic_iser = ((volatile uint32_t *)(NVIC_ISER_BASE + 4 * i));
|
||||
*nvic_iser |= (1 << (n % 32));
|
||||
}
|
||||
|
||||
static inline void nvic_irq_disable(uint8_t n)
|
||||
{
|
||||
int i = n / 32;
|
||||
volatile uint32_t *nvic_icer = ((volatile uint32_t *)(NVIC_ICER_BASE + 4 * i));
|
||||
*nvic_icer |= (1 << (n % 32));
|
||||
}
|
||||
|
||||
static inline void nvic_irq_setprio(uint8_t n, uint8_t prio)
|
||||
{
|
||||
volatile uint8_t *nvic_ipri = ((volatile uint8_t *)(NVIC_IPRI_BASE + n));
|
||||
*nvic_ipri = prio;
|
||||
}
|
||||
|
||||
#endif /* !SYSTEM_H_INCLUDED */
|
|
@ -0,0 +1,45 @@
|
|||
MEMORY
|
||||
{
|
||||
FLASH (rx) : ORIGIN = 0x20100, LENGTH = 0x1FF00
|
||||
RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 16K /* Run in lowmem */
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
_start_text = .;
|
||||
KEEP(*(.isr_vector))
|
||||
*(.init)
|
||||
*(.fini)
|
||||
*(.text*)
|
||||
*(.rodata*)
|
||||
. = ALIGN(4);
|
||||
_end_text = .;
|
||||
} > FLASH
|
||||
|
||||
_stored_data = .;
|
||||
|
||||
.data : AT (_stored_data)
|
||||
{
|
||||
_start_data = .;
|
||||
KEEP(*(.data*))
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.ramcode))
|
||||
. = ALIGN(4);
|
||||
_end_data = .;
|
||||
} > RAM
|
||||
|
||||
.bss :
|
||||
{
|
||||
_start_bss = .;
|
||||
*(.bss*)
|
||||
*(COMMON)
|
||||
. = ALIGN(4);
|
||||
_end_bss = .;
|
||||
_end = .;
|
||||
} > RAM
|
||||
}
|
||||
|
||||
PROVIDE(_start_heap = _end);
|
||||
PROVIDE(_end_stack = ORIGIN(RAM) + LENGTH(RAM));
|
|
@ -0,0 +1,171 @@
|
|||
/* timer.c
|
||||
*
|
||||
* Test bare-metal blinking led application
|
||||
*
|
||||
* Copyright (C) 2020 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfBoot.
|
||||
*
|
||||
* wolfBoot is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfBoot 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
#ifdef PLATFORM_stm32f4
|
||||
#include <stdint.h>
|
||||
|
||||
#include "system.h"
|
||||
#include "led.h"
|
||||
|
||||
|
||||
/* STM32 specific defines */
|
||||
#define APB1_CLOCK_ER (*(volatile uint32_t *)(0x40023840))
|
||||
#define APB1_CLOCK_RST (*(volatile uint32_t *)(0x40023820))
|
||||
#define TIM4_APB1_CLOCK_ER_VAL (1 << 2)
|
||||
#define TIM2_APB1_CLOCK_ER_VAL (1 << 0)
|
||||
|
||||
#define TIM2_BASE (0x40000000)
|
||||
#define TIM2_CR1 (*(volatile uint32_t *)(TIM2_BASE + 0x00))
|
||||
#define TIM2_DIER (*(volatile uint32_t *)(TIM2_BASE + 0x0c))
|
||||
#define TIM2_SR (*(volatile uint32_t *)(TIM2_BASE + 0x10))
|
||||
#define TIM2_PSC (*(volatile uint32_t *)(TIM2_BASE + 0x28))
|
||||
#define TIM2_ARR (*(volatile uint32_t *)(TIM2_BASE + 0x2c))
|
||||
|
||||
#define TIM4_BASE (0x40000800)
|
||||
#define TIM4_CR1 (*(volatile uint32_t *)(TIM4_BASE + 0x00))
|
||||
#define TIM4_DIER (*(volatile uint32_t *)(TIM4_BASE + 0x0c))
|
||||
#define TIM4_SR (*(volatile uint32_t *)(TIM4_BASE + 0x10))
|
||||
#define TIM4_CCMR1 (*(volatile uint32_t *)(TIM4_BASE + 0x18))
|
||||
#define TIM4_CCMR2 (*(volatile uint32_t *)(TIM4_BASE + 0x1c))
|
||||
#define TIM4_CCER (*(volatile uint32_t *)(TIM4_BASE + 0x20))
|
||||
#define TIM4_PSC (*(volatile uint32_t *)(TIM4_BASE + 0x28))
|
||||
#define TIM4_ARR (*(volatile uint32_t *)(TIM4_BASE + 0x2c))
|
||||
#define TIM4_CCR4 (*(volatile uint32_t *)(TIM4_BASE + 0x40))
|
||||
|
||||
#define TIM_DIER_UIE (1 << 0)
|
||||
#define TIM_SR_UIF (1 << 0)
|
||||
#define TIM_CR1_CLOCK_ENABLE (1 << 0)
|
||||
#define TIM_CR1_UPD_RS (1 << 2)
|
||||
#define TIM_CR1_ARPE (1 << 7)
|
||||
|
||||
#define TIM_CCER_CC4_ENABLE (1 << 12)
|
||||
#define TIM_CCMR1_OC1M_PWM1 (0x06 << 4)
|
||||
#define TIM_CCMR2_OC4M_PWM1 (0x06 << 12)
|
||||
|
||||
#define AHB1_CLOCK_ER (*(volatile uint32_t *)(0x40023830))
|
||||
#define GPIOD_AHB1_CLOCK_ER (1 << 3)
|
||||
|
||||
#define GPIOD_BASE 0x40020c00
|
||||
#define GPIOD_MODE (*(volatile uint32_t *)(GPIOD_BASE + 0x00))
|
||||
#define GPIOD_OTYPE (*(volatile uint32_t *)(GPIOD_BASE + 0x04))
|
||||
#define GPIOD_PUPD (*(volatile uint32_t *)(GPIOD_BASE + 0x0c))
|
||||
#define GPIOD_ODR (*(volatile uint32_t *)(GPIOD_BASE + 0x14))
|
||||
|
||||
static uint32_t master_clock = 0;
|
||||
|
||||
/** Use TIM4_CH4, which is linked to PD15 AF1 **/
|
||||
int pwm_init(uint32_t clock, uint32_t threshold)
|
||||
{
|
||||
uint32_t val = (clock / 100000); /* Frequency is 100 KHz */
|
||||
uint32_t lvl;
|
||||
master_clock = clock;
|
||||
|
||||
if (threshold > 100)
|
||||
return -1;
|
||||
|
||||
lvl = (val * threshold) / 100;
|
||||
if (lvl != 0)
|
||||
lvl--;
|
||||
|
||||
APB1_CLOCK_RST |= TIM4_APB1_CLOCK_ER_VAL;
|
||||
asm volatile ("dmb");
|
||||
APB1_CLOCK_RST &= ~TIM4_APB1_CLOCK_ER_VAL;
|
||||
APB1_CLOCK_ER |= TIM4_APB1_CLOCK_ER_VAL;
|
||||
|
||||
/* disable CC */
|
||||
TIM4_CCER &= ~TIM_CCER_CC4_ENABLE;
|
||||
TIM4_CR1 = 0;
|
||||
TIM4_PSC = 0;
|
||||
TIM4_ARR = val - 1;
|
||||
TIM4_CCR4 = lvl;
|
||||
TIM4_CCMR1 &= ~(0x03 << 0);
|
||||
TIM4_CCMR1 &= ~(0x07 << 4);
|
||||
TIM4_CCMR1 |= TIM_CCMR1_OC1M_PWM1;
|
||||
TIM4_CCMR2 &= ~(0x03 << 8);
|
||||
TIM4_CCMR2 &= ~(0x07 << 12);
|
||||
TIM4_CCMR2 |= TIM_CCMR2_OC4M_PWM1;
|
||||
TIM4_CCER |= TIM_CCER_CC4_ENABLE;
|
||||
TIM4_CR1 |= TIM_CR1_CLOCK_ENABLE | TIM_CR1_ARPE;
|
||||
asm volatile ("dmb");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int timer_init(uint32_t clock, uint32_t prescaler, uint32_t interval_ms)
|
||||
{
|
||||
uint32_t val = 0;
|
||||
uint32_t psc = 1;
|
||||
uint32_t err = 0;
|
||||
clock = ((clock * prescaler) / 1000) * interval_ms;
|
||||
|
||||
while (psc < 65535) {
|
||||
val = clock / psc;
|
||||
err = clock % psc;
|
||||
if ((val < 65535) && (err == 0)) {
|
||||
val--;
|
||||
break;
|
||||
}
|
||||
val = 0;
|
||||
psc++;
|
||||
}
|
||||
if (val == 0)
|
||||
return -1;
|
||||
|
||||
nvic_irq_enable(NVIC_TIM2_IRQN);
|
||||
nvic_irq_setprio(NVIC_TIM2_IRQN, 0);
|
||||
APB1_CLOCK_RST |= TIM2_APB1_CLOCK_ER_VAL;
|
||||
asm volatile ("dmb");
|
||||
APB1_CLOCK_RST &= ~TIM2_APB1_CLOCK_ER_VAL;
|
||||
APB1_CLOCK_ER |= TIM2_APB1_CLOCK_ER_VAL;
|
||||
|
||||
TIM2_CR1 = 0;
|
||||
asm volatile ("dmb");
|
||||
TIM2_PSC = psc;
|
||||
TIM2_ARR = val;
|
||||
TIM2_CR1 |= TIM_CR1_CLOCK_ENABLE;
|
||||
TIM2_DIER |= TIM_DIER_UIE;
|
||||
asm volatile ("dmb");
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern volatile uint32_t time_elapsed;
|
||||
void isr_tim2(void)
|
||||
{
|
||||
static volatile uint32_t tim2_ticks = 0;
|
||||
TIM2_SR &= ~TIM_SR_UIF;
|
||||
|
||||
/* Dim the led by altering the PWM duty-cicle */
|
||||
if (++tim2_ticks > 15)
|
||||
tim2_ticks = 0;
|
||||
if (tim2_ticks > 8)
|
||||
pwm_init(master_clock, 10 * (16 - tim2_ticks));
|
||||
else
|
||||
pwm_init(master_clock, 10 * tim2_ticks);
|
||||
|
||||
time_elapsed++;
|
||||
}
|
||||
#else
|
||||
void isr_tim2(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* PLATFORM_stm32f4 */
|
|
@ -0,0 +1,30 @@
|
|||
/* timer.h
|
||||
*
|
||||
* Test bare-metal blinking led application
|
||||
*
|
||||
* Copyright (C) 2020 wolfSSL Inc.
|
||||
*
|
||||
* This file is part of wolfBoot.
|
||||
*
|
||||
* wolfBoot is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* wolfBoot 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 General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
||||
*/
|
||||
|
||||
#ifndef TIMER_H_INCLUDED
|
||||
#define TIMER_H_INCLUDED
|
||||
|
||||
int pwm_init(uint32_t clock, uint32_t threshold);
|
||||
int timer_init(uint32_t clock, uint32_t scaler, uint32_t interval);
|
||||
|
||||
#endif /* !TIMER_H_INCLUDED */
|
2
wolfBoot
2
wolfBoot
|
@ -1 +1 @@
|
|||
Subproject commit 19f328cffdd1fe65b9ed764d4812adada3c819cf
|
||||
Subproject commit 3516620f1a4df029e18734ef5cd9ee22813174e7
|
Loading…
Reference in New Issue