[SAMA5D3] Added test-app, moved to SP_ASM

pull/494/head
Daniele Lacamera 2024-09-16 20:10:46 +02:00 committed by Daniele Lacamera
parent 888d538760
commit 76920599b3
8 changed files with 249 additions and 26 deletions

14
arch.mk
View File

@ -178,18 +178,24 @@ ifeq ($(ARCH),ARM)
ifeq ($(TARGET),sama5d3)
CORTEX_A5=1
UPDATE_OBJS:=src/update_ram.o
CFLAGS+=-DWOLFBOOT_DUALBOOT -DEXT_FLASH -DNAND_FLASH
CFLAGS+=-DWOLFBOOT_DUALBOOT -DEXT_FLASH -DNAND_FLASH -fno-builtin -ffreestanding
#CFLAGS+=-DWOLFBOOT_USE_STDLIBC
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
FPU=-mfpu=vfp4-d16
CFLAGS+=-mcpu=cortex-a5 -mtune=cortex-a5 -static -z noexecstack
LDLAGS+=-mcpu=cortex-a5 -mtune=cortex-a5 -mtune=cortex-a5 -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
ifeq ($(NO_ASM),1)
MATH_OBJS+=./lib/wolfssl/wolfcrypt/src/sp_c32.o
else
MATH_OBJS+=./lib/wolfssl/wolfcrypt/src/sp_arm32.o
CFLAGS+=-DWOLFSSL_SP_ARM32_ASM
endif
else
# All others use boot_arm.o
OBJS+=src/boot_arm.o

View File

@ -14,10 +14,10 @@ SPMATH?=1
WOLFBOOT_PARTITION_SIZE?=0x1000000
WOLFBOOT_NO_PARTITIONS=0
WOLFBOOT_SECTOR_SIZE?=0x1000
WOLFBOOT_LOAD_ADDRESS=0x380000
WOLFBOOT_LOAD_DTS_ADDRESS=0x3C0000
WOLFBOOT_PARTITION_BOOT_ADDRESS=0x40000
WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x80000
WOLFBOOT_LOAD_ADDRESS=0x201000
WOLFBOOT_LOAD_DTS_ADDRESS=0x281000
WOLFBOOT_PARTITION_BOOT_ADDRESS=0x400000
WOLFBOOT_PARTITION_UPDATE_ADDRESS=0x800000
WOLFBOOT_PARTITION_SWAP_ADDRESS=0x0
NO_XIP=1
IMAGE_HEADER_SIZE=2048

View File

@ -48,10 +48,9 @@ extern void *kernel_addr, *update_addr, *dts_addr;
#define NAND_MASK_ALE (1 << 21)
#define NAND_MASK_CLE (1 << 22)
#define NAND_CMD (*((volatile uint8_t *)(NAND_BASE | NAND_MASK_CLE)))
#define NAND_CMD (*((volatile uint8_t *)(NAND_BASE | NAND_MASK_CLE)))
#define NAND_ADDR (*((volatile uint8_t *)(NAND_BASE | NAND_MASK_ALE)))
#define NAND_DATA (*((volatile uint8_t *)(NAND_BASE)))
#define NAND_DATAW (*((volatile uint32_t *)(NAND_BASE)))
/* Command set */
#define NAND_CMD_STATUS 0x70
@ -141,6 +140,80 @@ extern void *kernel_addr, *update_addr, *dts_addr;
#define MAX_ECC_BYTES 8
/* Manual division operation */
int division(uint32_t dividend,
uint32_t divisor,
uint32_t *quotient,
uint32_t *remainder)
{
uint32_t shift;
uint32_t divisor_shift;
uint32_t factor = 0;
unsigned char end_flag = 0;
if (!divisor)
return 0xffffffff;
if (dividend < divisor) {
*quotient = 0;
*remainder = dividend;
return 0;
}
while (dividend >= divisor) {
for (shift = 0, divisor_shift = divisor;
dividend >= divisor_shift;
divisor_shift <<= 1, shift++) {
if (dividend - divisor_shift < divisor_shift) {
factor += 1 << shift;
dividend -= divisor_shift;
end_flag = 1;
break;
}
}
if (end_flag)
continue;
factor += 1 << (shift - 1);
dividend -= divisor_shift >> 1;
}
if (quotient)
*quotient = factor;
if (remainder)
*remainder = dividend;
return 0;
}
uint32_t div(uint32_t dividend, uint32_t divisor)
{
uint32_t quotient = 0;
uint32_t remainder = 0;
int ret;
ret = division(dividend, divisor, &quotient, &remainder);
if (ret)
return 0xffffffff;
return quotient;
}
uint32_t mod(uint32_t dividend, uint32_t divisor)
{
uint32_t quotient = 0;
uint32_t remainder = 0;
int ret;
ret = division(dividend, divisor, &quotient, &remainder);
if (ret)
return 0xffffffff;
return remainder;
}
/* Static variables to hold nand info */
static uint8_t nand_manif_id;
static uint8_t nand_dev_id;
@ -245,7 +318,7 @@ static void nand_read_info(void)
nand_flash.bad_block_pos = (*(uint16_t *)(onfi_data + PARAMS_POS_FEATURES)) & 1;
nand_flash.ext_page_len = *(uint16_t *)(onfi_data + PARAMS_POS_EXT_PARAM_PAGE_LEN);
nand_flash.parameter_page = *(uint16_t *)(onfi_data + PARAMS_POS_PARAMETER_PAGE);
nand_flash.pages_per_block = nand_flash.block_size / nand_flash.page_size;
nand_flash.pages_per_block = div(nand_flash.block_size, nand_flash.page_size);
nand_flash.pages_per_device = nand_flash.pages_per_block * nand_flash.block_count;
nand_flash.oob_size = *(uint16_t *)(onfi_data + PARAMS_POS_OOBSIZE);
nand_flash.revision = *(uint16_t *)(onfi_data + PARAMS_POS_REVISION);
@ -342,14 +415,14 @@ static int nand_check_bad_block(uint32_t block)
}
static uint8_t buffer_page[NAND_FLASH_PAGE_SIZE];
int ext_flash_read(uintptr_t address, uint8_t *data, int len)
{
uint32_t block = address / nand_flash.block_size; /* The block where the address falls in */
uint32_t page = address / nand_flash.page_size; /* The page where the address falls in */
uint32_t start_page_in_block = page % nand_flash.pages_per_block; /* The start page within this block */
uint32_t in_block_offset = address % nand_flash.block_size; /* The offset of the address within the block */
uint8_t buffer_page[NAND_FLASH_PAGE_SIZE];
uint32_t block = div(address, nand_flash.block_size); /* The block where the address falls in */
uint32_t page = div(address, nand_flash.page_size); /* The page where the address falls in */
uint32_t start_page_in_block = mod(page, nand_flash.pages_per_block); /* The start page within this block */
uint32_t in_block_offset = mod(address, nand_flash.block_size); /* The offset of the address within the block */
uint32_t remaining = nand_flash.block_size - in_block_offset; /* How many bytes remaining to read in the first block */
uint32_t len_to_read = len;
uint8_t *buffer = data;
@ -378,7 +451,7 @@ int ext_flash_read(uintptr_t address, uint8_t *data, int len)
} while (ret < 0);
/* Amount of pages to be read from this block */
pages_to_read = (sz + nand_flash.page_size - 1) / nand_flash.page_size;
pages_to_read = div((sz + nand_flash.page_size - 1), nand_flash.page_size);
if (pages_to_read * nand_flash.page_size > remaining)
pages_to_read--;
@ -397,7 +470,8 @@ int ext_flash_read(uintptr_t address, uint8_t *data, int len)
if (copy) {
uint32_t *dst = (uint32_t *)data;
uint32_t *src = (uint32_t *)buffer_page;
for (i = 0; i < (len / sizeof(uint32_t)); i++) {
uint32_t tot_len = (uint32_t)len;
for (i = 0; i < (tot_len >> 2); i++) {
dst[i] = src[i];
}
}

View File

@ -3,7 +3,7 @@ OUTPUT_ARCH(arm)
MEMORY
{
DDR_MEM(rwx): ORIGIN = 0x00300000, LENGTH = 0x0007F000
DDR_MEM(rwx): ORIGIN = 0x00000000, LENGTH = 0x0000F000
}
ENTRY(reset_vector_entry)
@ -12,9 +12,9 @@ SECTIONS
.text : {
_start_text = .;
*(.text)
*(.rodata)
*(.rodata*)
. = ALIGN(4);
*(.rodata)
*(.rodata*)
. = ALIGN(4);
*(.glue_7)
. = ALIGN(4);
*(.eh_frame)
@ -46,8 +46,8 @@ SECTIONS
}
}
kernel_addr = 0x040000;
update_addr = 0x080000;
kernel_addr = 0x0400000;
update_addr = 0x0800000;
_romsize = _end_data - _start_text;
_sramsize = _end_bss - _start_text;

View File

@ -3,7 +3,7 @@ OUTPUT_ARCH(arm)
MEMORY
{
DDR_MEM(rwx): ORIGIN = 0x00340000, LENGTH = 0x000100000
DDR_MEM(rwx): ORIGIN = 0x00311000, LENGTH = 0x000080000
}
ENTRY(reset_vector_entry)
@ -11,6 +11,7 @@ SECTIONS
{
.text : {
_start_text = .;
*(.iv)
*(.text)
*(.rodata)
*(.rodata*)

View File

@ -146,7 +146,7 @@ ifeq ($(TARGET),stm32c0)
endif
ifeq ($(TARGET),sama5d3)
APP_OBJS+=../src/boot_arm32_start.o
APP_OBJS+=./boot_arm32_start.o
LSCRIPT_TEMPLATE:=$(ARCH)-$(TARGET).ld
endif

View File

@ -28,11 +28,54 @@
#include "wolfboot/wolfboot.h"
#ifdef TARGET_sama5d3
/* Blue LED is PE23, Red LED is PE24 */
#define GPIOE_BASE 0xFFFFFA00
#define GPIOE_PER *(volatile uint32_t *)(GPIOE_BASE + 0x00)
#define GPIOE_PDR *(volatile uint32_t *)(GPIOE_BASE + 0x04)
#define GPIOE_PSR *(volatile uint32_t *)(GPIOE_BASE + 0x08)
#define GPIOE_OER *(volatile uint32_t *)(GPIOE_BASE + 0x10)
#define GPIOE_ODR *(volatile uint32_t *)(GPIOE_BASE + 0x14)
#define GPIOE_OSR *(volatile uint32_t *)(GPIOE_BASE + 0x18)
#define GPIOE_SODR *(volatile uint32_t *)(GPIOE_BASE + 0x30)
#define GPIOE_CODR *(volatile uint32_t *)(GPIOE_BASE + 0x34)
#define GPIOE_IER *(volatile uint32_t *)(GPIOE_BASE + 0x40)
#define GPIOE_IDR *(volatile uint32_t *)(GPIOE_BASE + 0x44)
#define GPIOE_MDER *(volatile uint32_t *)(GPIOE_BASE + 0x50)
#define GPIOE_MDDR *(volatile uint32_t *)(GPIOE_BASE + 0x54)
#define GPIOE_PPUDR *(volatile uint32_t *)(GPIOE_BASE + 0x60)
#define GPIOE_PPUER *(volatile uint32_t *)(GPIOE_BASE + 0x64)
#define BLUE_LED_PIN 23
#define RED_LED_PIN 24
void led_init(uint32_t pin)
{
uint32_t mask = 1U << pin;
GPIOE_MDDR |= mask;
GPIOE_PER |= mask;
GPIOE_IDR |= mask;
GPIOE_PPUDR |= mask;
GPIOE_CODR |= mask;
}
void led_put(uint32_t pin, int val)
{
uint32_t mask = 1U << pin;
if (val)
GPIOE_SODR |= mask;
else
GPIOE_CODR |= mask;
}
volatile uint32_t time_elapsed = 0;
void main(void) {
/* Wait for reboot */
led_init(RED_LED_PIN);
led_put(RED_LED_PIN, 1);
while(1)
;
}

View File

@ -0,0 +1,99 @@
/**
* 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
.section .iv
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