mirror of https://github.com/wolfSSL/wolfBoot.git
[SAMA5D3] Added test-app, moved to SP_ASM
parent
888d538760
commit
76920599b3
14
arch.mk
14
arch.mk
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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, "ient, &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, "ient, &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];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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*)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
Loading…
Reference in New Issue