[SAMA5D3] Port for 32bit Cortex-A

pull/494/head
Daniele Lacamera 2024-08-23 07:05:03 +02:00
parent 03675979a4
commit 4cbfdf8cf1
7 changed files with 472 additions and 64 deletions

View File

@ -130,6 +130,10 @@ ifeq ($(TARGET),nxp_t1024)
MAIN_TARGET:=factory_wstage1.bin
endif
ifeq ($(TARGET),sama5d3)
MAIN_TARGET:=wolfboot.bin
endif
ifeq ($(FLASH_OTP_KEYSTORE),1)
MAIN_TARGET+=tools/keytools/otp/otp-keystore-primer.bin
endif

141
arch.mk
View File

@ -70,7 +70,6 @@ ifeq ($(ARCH),ARM)
CROSS_COMPILE?=arm-none-eabi-
CFLAGS+=-mthumb -mlittle-endian -mthumb-interwork -DARCH_ARM
LDFLAGS+=-mthumb -mlittle-endian -mthumb-interwork
OBJS+=src/boot_arm.o
## Target specific configuration
ifeq ($(TARGET),samr21)
@ -176,88 +175,102 @@ ifeq ($(ARCH),ARM)
SPI_TARGET=stm32
endif
## Cortex-M CPU
ifeq ($(CORTEX_M33),1)
CFLAGS+=-mcpu=cortex-m33 -DCORTEX_M33
LDFLAGS+=-mcpu=cortex-m33
ifeq ($(TZEN),1)
OBJS+=hal/stm32_tz.o
CFLAGS+=-mcmse
ifeq ($(WOLFCRYPT_TZ),1)
SECURE_OBJS+=./src/wc_callable.o
SECURE_OBJS+=./lib/wolfssl/wolfcrypt/src/random.o
CFLAGS+=-DWOLFCRYPT_SECURE_MODE
SECURE_LDFLAGS+=-Wl,--cmse-implib -Wl,--out-implib=./src/wc_secure_calls.o
endif
endif # TZEN=1
ifeq ($(NO_ASM),1)
ifeq ($(SPMATH),1)
ifeq ($(NO_ASM),1)
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_c32.o
else
CFLAGS+=-DWOLFSSL_SP_ASM -DWOLFSSL_SP_ARM_CORTEX_M_ASM
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_cortexm.o
endif
endif
else
ifeq ($(SPMATH),1)
CFLAGS+=-DWOLFSSL_SP_ASM -DWOLFSSL_SP_ARM_CORTEX_M_ASM
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_cortexm.o
endif
ifeq ($(TARGET),sama5d3)
CORTEX_A5=1
endif
## Cortex CPU
ifeq ($(CORTEX_A5),1)
CFLAGS+=-mcpu=cortex-a5 -mtune=cortex-a5 -mfpu=vfpv4-d16 -static -z noexecstack
LDLAGS+=-mcpu=cortex-a5 -mtune=cortex-a5 -mtune=cortex-a5 -mfpu=vfpv4-d16 -static -z noexecstack -Ttext 0x300000
# Cortex-A uses boot_arm32.o
OBJS+=src/boot_arm32.o src/boot_arm32_start.o
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_c32.o
else
ifeq ($(CORTEX_M7),1)
CFLAGS+=-mcpu=cortex-m7
LDFLAGS+=-mcpu=cortex-m7
ifeq ($(SPMATH),1)
ifeq ($(NO_ASM),1)
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_c32.o
else
CFLAGS+=-DWOLFSSL_SP_ASM -DWOLFSSL_SP_ARM_CORTEX_M_ASM
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_cortexm.o
# All others use boot_arm.o
OBJS+=src/boot_arm.o
ifeq ($(CORTEX_M33),1)
CFLAGS+=-mcpu=cortex-m33 -DCORTEX_M33
LDFLAGS+=-mcpu=cortex-m33
ifeq ($(TZEN),1)
OBJS+=hal/stm32_tz.o
CFLAGS+=-mcmse
ifeq ($(WOLFCRYPT_TZ),1)
SECURE_OBJS+=./src/wc_callable.o
SECURE_OBJS+=./lib/wolfssl/wolfcrypt/src/random.o
CFLAGS+=-DWOLFCRYPT_SECURE_MODE
SECURE_LDFLAGS+=-Wl,--cmse-implib -Wl,--out-implib=./src/wc_secure_calls.o
endif
endif
else
ifeq ($(CORTEX_M0),1)
CFLAGS+=-mcpu=cortex-m0
LDFLAGS+=-mcpu=cortex-m0
endif # TZEN=1
ifeq ($(NO_ASM),1)
ifeq ($(SPMATH),1)
ifeq ($(NO_ASM),1)
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_c32.o
else
CFLAGS+=-DWOLFSSL_SP_ASM -DWOLFSSL_SP_ARM_THUMB_ASM
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_armthumb.o
CFLAGS+=-DWOLFSSL_SP_ASM -DWOLFSSL_SP_ARM_CORTEX_M_ASM
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_cortexm.o
endif
endif
else
ifeq ($(CORTEX_M3),1)
CFLAGS+=-mcpu=cortex-m3
LDFLAGS+=-mcpu=cortex-m3
ifeq ($(SPMATH),1)
CFLAGS+=-DWOLFSSL_SP_ASM -DWOLFSSL_SP_ARM_CORTEX_M_ASM
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_cortexm.o
endif
endif
else
ifeq ($(CORTEX_M7),1)
CFLAGS+=-mcpu=cortex-m7
LDFLAGS+=-mcpu=cortex-m7
ifeq ($(SPMATH),1)
ifeq ($(NO_ASM),1)
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_c32.o
else
CFLAGS+=-DWOLFSSL_SP_ASM -DWOLFSSL_SP_ARM_CORTEX_M_ASM
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_cortexm.o
endif
endif
else
ifeq ($(CORTEX_M0),1)
CFLAGS+=-mcpu=cortex-m0
LDFLAGS+=-mcpu=cortex-m0
ifeq ($(SPMATH),1)
ifeq ($(NO_ASM),1)
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_c32.o
else
CFLAGS+=-DWOLFSSL_SP_ASM -DWOLFSSL_SP_ARM_THUMB_ASM
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_armthumb.o
endif
endif
else
ifeq ($(CORTEX_M3),1)
CFLAGS+=-mcpu=cortex-m3
LDFLAGS+=-mcpu=cortex-m3
ifeq ($(NO_ASM),1)
ifeq ($(SPMATH),1)
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_c32.o
endif
else
ifeq ($(SPMATH),1)
CFLAGS+=-DWOLFSSL_SP_ASM -DWOLFSSL_SP_ARM_CORTEX_M_ASM -DWOLFSSL_SP_NO_UMAAL
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_cortexm.o
endif
endif
else
# default Cortex M4
CFLAGS+=-mcpu=cortex-m4
LDFLAGS+=-mcpu=cortex-m4
ifeq ($(NO_ASM),1)
ifeq ($(SPMATH),1)
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_c32.o
endif
else
CFLAGS+=-fomit-frame-pointer # required with debug builds only
ifeq ($(SPMATH),1)
CFLAGS+=-DWOLFSSL_SP_ASM -DWOLFSSL_SP_ARM_CORTEX_M_ASM -DWOLFSSL_SP_NO_UMAAL
CFLAGS+=-DWOLFSSL_SP_ASM -DWOLFSSL_SP_ARM_CORTEX_M_ASM
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_cortexm.o
endif
endif
else
# default Cortex M4
CFLAGS+=-mcpu=cortex-m4
LDFLAGS+=-mcpu=cortex-m4
ifeq ($(NO_ASM),1)
ifeq ($(SPMATH),1)
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_c32.o
endif
else
CFLAGS+=-fomit-frame-pointer # required with debug builds only
ifeq ($(SPMATH),1)
CFLAGS+=-DWOLFSSL_SP_ASM -DWOLFSSL_SP_ARM_CORTEX_M_ASM
MATH_OBJS += ./lib/wolfssl/wolfcrypt/src/sp_cortexm.o
endif
endif
endif
endif

View File

@ -8,6 +8,7 @@ This README describes configuration of supported targets.
* [Cypress PSoC-6](#cypress-psoc-6)
* [Infineon AURIX TC3xx](#infineon-aurix-tc3xx)
* [Intel x86-64 Intel FSP](#intel-x86_64-with-intel-fsp-support)
* [Microchip SAMA5D3](#microchip-sama5d3)
* [Microchip SAME51](#microchip-same51)
* [NXP Kinetis](#nxp-kinetis)
* [NXP LPC54xxx](#nxp-lpc54xxx)
@ -1405,6 +1406,51 @@ the monitor command sequence below:
(gdb) mon psoc6 reset_halt
```
## Microchip SAMA5D3
SAMA5D3 is a Cortex-A5 Microprocessor. The ATSAMA5D3-XPLAINED is the evaluation
board used for wolfBoot port, which also equips a 2MB NAND flash. WolfBoot
replaces the default first stage bootloader (at91bootstrap).
### Building wolfBoot
An example configuration file is provided.
`cp config/examples/sama5d3.config .config`
Run make to build wolfBoot.bin and the test application
`make`
### Programming wolfboot.bin into NAND flash
To flash any firmware image into the device NVMs, you need the tool `sam-ba`,
distributed by Microchip.
This procedure has been tested using sam-ba v.3.8 using ATSAMA5D3-XPLAINED board,
with JP6 (aka the `SPI_CS` jumper) removed, so the system boots from NAND by
default.
Step 1: install the tool, connect a J-Link device to the J24 JTAG connector then run the
following command to activate "lowlevel" mode:
`sam-ba -p j-link -b sama5d3-xplained -t 5 -a lowlevel`
Step 2: erase the entire NAND flash:
`sam-ba -p j-link -b sama5d3-xplained -t 5 -a nandflash -c erase`
Step 3: program `wolfboot.bin` to the beginning of the flash:
`sam-ba -p j-link -b sama5d3-xplained -t 5 -a nandflash -c writeboot:wolfboot.bin`
### Programming the test application into NAND flash
(TODO)
## Microchip SAME51
SAME51 is a Cortex-M4 microcontroller with a dual-bank, 1MB flash memory divided

94
hal/sama5d3.c 100644
View File

@ -0,0 +1,94 @@
/* atsama5d3.c
*
* Copyright (C) 2024 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 3 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 <string.h>
#include <target.h>
#include "image.h"
#ifndef ARCH_ARM
# error "wolfBoot atsama5d3 HAL: wrong architecture selected. Please compile with ARCH=ARM."
#endif
#define TEST_ENCRYPT
/* Fixed addresses */
extern void *kernel_addr, *update_addr, *dts_addr;
void* hal_get_primary_address(void)
{
return (void*)&kernel_addr;
}
void* hal_get_update_address(void)
{
return (void*)&update_addr;
}
void* hal_get_dts_address(void)
{
return (void*)&dts_addr;
}
void* hal_get_dts_update_address(void)
{
return NULL; /* Not yet supported */
}
/* QSPI functions */
void qspi_init(uint32_t cpu_clock, uint32_t flash_freq)
{
}
void zynq_init(uint32_t cpu_clock)
{
}
/* public HAL functions */
void hal_init(void)
{
}
void hal_prepare_boot(void)
{
}
int RAMFUNCTION hal_flash_write(uintptr_t address, const uint8_t *data, int len)
{
return 0;
}
void RAMFUNCTION hal_flash_unlock(void)
{
}
void RAMFUNCTION hal_flash_lock(void)
{
}
int RAMFUNCTION hal_flash_erase(uintptr_t address, int len)
{
return 0;
}

53
hal/sama5d3.ld 100644
View File

@ -0,0 +1,53 @@
OUTPUT_FORMAT("elf32-littlearm")
OUTPUT_ARCH(arm)
MEMORY
{
DDR_MEM(rwx): ORIGIN = 0x00300000, LENGTH = 0x000100000
}
ENTRY(reset_vector_entry)
SECTIONS
{
.text : {
_start_text = .;
*(.text)
*(.rodata)
*(.rodata*)
. = ALIGN(4);
*(.glue_7)
. = ALIGN(4);
*(.eh_frame)
. = ALIGN(4);
_end_text = . ;
}
/* collect all initialized .data sections */
/* .data : AT ( ADDR (.text) + SIZEOF (.text) SIZEOF (.ARM.*) { */
. = ALIGN(4);
.dummy : {
_edummy = .;
}
.data : AT (LOADADDR(.dummy)) {
_start_data = .;
*(.vectors)
*(.data)
_end_data = .;
}
/* collect all uninitialized .bss sections */
.bss (NOLOAD) : {
. = ALIGN(4);
_start_bss = .;
*(.bss)
_end_bss = .;
}
}
_romsize = _end_data - _start_text;
_sramsize = _end_bss - _start_text;
END_STACK = _start_text;
_stack_top = ORIGIN(DDR_MEM) + LENGTH(DDR_MEM);
end = .; /* define a global symbol marking the end of application */

100
src/boot_arm32.c 100644
View File

@ -0,0 +1,100 @@
/* boot_arm32.c
*
* Bring up, vectors and do_boot for 32bit Cortex-A microprocessors.
*
* Copyright (C) 2024 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 3 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 "image.h"
#include "loader.h"
#include "wolfboot/wolfboot.h"
extern unsigned int __bss_start__;
extern unsigned int __bss_end__;
static volatile unsigned int cpu_id;
extern unsigned int *END_STACK;
extern void main(void);
void boot_entry_C(void)
{
register unsigned int *dst;
/* Initialize the BSS section to 0 */
dst = &__bss_start__;
while (dst < (unsigned int *)&__bss_end__) {
*dst = 0U;
dst++;
}
/* Run wolfboot! */
main();
}
/* This is the main loop for the bootloader.
*
* It performs the following actions:
* - Call the application entry point
*
*/
#ifdef MMU
void RAMFUNCTION do_boot(const uint32_t *app_offset, const uint32_t* dts_offset)
#else
void RAMFUNCTION do_boot(const uint32_t *app_offset)
#endif
{
/* Set application address via r4 */
asm volatile("mov r4, %0" : : "r"(app_offset));
#ifdef MMU
/* Move the dts pointer to r5 (as first argument) */
asm volatile("mov r5, %0" : : "r"(dts_offset));
#else
asm volatile("mov r5, 0");
#endif
/* Zero registers r1, r2, r3 */
asm volatile("mov r3, 0");
asm volatile("mov r2, 0");
asm volatile("mov r1, 0");
/* Move the dts pointer to r0 (as first argument) */
asm volatile("mov r0, r5");
/* Unconditionally jump to app_entry at r4 */
asm volatile("bx r4");
}
#ifdef RAM_CODE
#define AIRCR *(volatile uint32_t *)(0xE000ED0C)
#define AIRCR_VKEY (0r05FA << 16)
#define AIRCR_SYSRESETREQ (1 << 2)
void RAMFUNCTION arch_reboot(void)
{
AIRCR = AIRCR_SYSRESETREQ | AIRCR_VKEY;
while(1)
;
wolfBoot_panic();
}
#endif

View File

@ -0,0 +1,98 @@
/**
* Arm32 (32bit Cortex-A) boot up
* Copyright (C) 2024 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 3 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
*/
.section start
.text
/* startup entry point */
.globl reset_vector_entry
.align 4
reset_vector_entry:
/* Exception vectors (should be a branch to be detected as a valid code by the rom */
_exception_vectors:
b isr_reset /* reset */
b isr_empty /* Undefined Instruction */
b isr_swi /* Software Interrupt */
b isr_pabt /* Prefetch Abort */
b dabt_vector /* Data Abort */
.word _romsize /* Size of the binary for ROMCode loading */
b isr_irq /* IRQ : read the AIC */
b isr_fiq /* FIQ */
isr_empty:
b isr_empty
isr_swi:
b isr_swi
isr_pabt:
b isr_pabt
dabt_vector:
subs pc, r14, #4 /* return */
nop
isr_rsvd:
b isr_rsvd
isr_irq:
b isr_irq
isr_fiq:
b isr_fiq
/* Reset handler procedure. Prepare the memory and call main() */
isr_reset:
/* Initialize the stack pointer */
ldr sp,=_stack_top
/* Save BootROM supplied boot source information to stack */
push {r4}
/* Copy the data section */
ldr r2, =_lp_data
ldmia r2, {r1, r3, r4}
1:
cmp r3, r4
ldrcc r2, [r1], #4
strcc r2, [r3], #4
bcc 1b
/* Zero bss area */
adr r2, _lp_bss
ldmia r2, {r3, r4}
mov r2, #0
1:
cmp r3, r4
strcc r2, [r3], #4
bcc 1b
/* Jump to main() */
ldr r4, = main
mov lr, pc
bx r4
/* main() should never return */
_panic:
b _panic
.align
_lp_data:
.word _start_data
.word _end_data
_lp_bss:
.word _start_bss
.word _end_bss