sw_apps:zynqmp_fsbl: Publishing zynqmp FSBL to HEAD of embeddedsw

Initial publishing of zynqmp_fsbl in the embeddedsw repo.

Signed-off-by: Sarat Chand Savitala <saratcha@xilinx.com>
This commit is contained in:
Sarat Chand Savitala 2015-01-07 17:53:46 +05:30 committed by Suneel Garapati
parent d95f16e2d1
commit e5bc1ff112
32 changed files with 10011 additions and 0 deletions

View file

@ -0,0 +1,44 @@
#/******************************************************************************
#*
#* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
#*
#* Permission is hereby granted, free of charge, to any person obtaining a copy
#* of this software and associated documentation files (the "Software"), to deal
#* in the Software without restriction, including without limitation the rights
#* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
#* copies of the Software, and to permit persons to whom the Software is
#* furnished to do so, subject to the following conditions:
#*
#* The above copyright notice and this permission notice shall be included in
#* all copies or substantial portions of the Software.
#*
#* Use of the Software is limited solely to applications:
#* (a) running on a Xilinx device, or
#* (b) that interact with a Xilinx device through a bus or interconnect.
#*
#* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
#* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
#* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
#* SOFTWARE.
#*
#* Except as contained in this notice, the name of the Xilinx shall not be used
#* in advertising or otherwise to promote the sale, use or other dealings in
#* this Software without prior written authorization from Xilinx.
#*
#******************************************************************************/
PARAMETER VERSION = 2.2.0
BEGIN OS
PARAMETER OS_NAME = standalone
PARAMETER STDIN = *
PARAMETER STDOUT = *
END
BEGIN LIBRARY
PARAMETER LIBRARY_NAME = xilffs
END

View file

@ -0,0 +1,126 @@
#/******************************************************************************
#*
#* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
#*
#* Permission is hereby granted, free of charge, to any person obtaining a copy
#* of this software and associated documentation files (the "Software"), to deal
#* in the Software without restriction, including without limitation the rights
#* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
#* copies of the Software, and to permit persons to whom the Software is
#* furnished to do so, subject to the following conditions:
#*
#* The above copyright notice and this permission notice shall be included in
#* all copies or substantial portions of the Software.
#*
#* Use of the Software is limited solely to applications:
#* (a) running on a Xilinx device, or
#* (b) that interact with a Xilinx device through a bus or interconnect.
#*
#* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
#* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
#* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
#* SOFTWARE.
#*
#* Except as contained in this notice, the name of the Xilinx shall not be used
#* in advertising or otherwise to promote the sale, use or other dealings in
#* this Software without prior written authorization from Xilinx.
#*
#******************************************************************************/
proc swapp_get_name {} {
return "Zynq MP FSBL";
}
proc swapp_get_description {} {
return "First Stage Bootloader (FSBL) for Zynq MP. The FSBL configures the FPGA with HW bit stream (if it exists) \
and loads the Operating System (OS) Image or Standalone (SA) Image or 2nd Stage Boot Loader image from the \
non-volatile memory (NAND/SD/QSPI) to RAM (DDR) and takes A5x/R5 out of reset. It supports multiple partitions, \
and each partition can be a code image or a bit stream.";
}
proc check_standalone_os {} {
set oslist [get_os];
if { [llength $oslist] != 1 } {
return 0;
}
set os [lindex $oslist 0];
if { $os != "standalone" } {
error "This application is supported only on the Standalone Board Support Package.";
}
}
proc swapp_is_supported_sw {} {
# make sure we are using standalone OS
#check_standalone_os;
# make sure xilffs is available
set librarylist [get_libs -filter "NAME==xilffs"];
if { [llength $librarylist] == 0 } {
error "This application requires xilffs library in the Board Support Package.";
} elseif { [llength $librarylist] > 1} {
error "Multiple xilffs libraries present in the Board Support Package."
}
}
proc swapp_is_supported_hw {} {
# check processor type
set proc_instance [get_sw_processor];
set hw_processor [get_property HW_INSTANCE $proc_instance]
set proc_type [get_property IP_NAME [get_cells $hw_processor]];
if { $proc_type != "pss_cortexr5" && $proc_type != "pss_cortexa53" } {
error "This application is supported only for CortexA53/CortexR5 processors.";
}
return 1;
}
proc get_stdout {} {
set os [get_os];
set stdout [get_property CONFIG.STDOUT $os];
return $stdout;
}
proc check_stdout_hw {} {
set ps_uarts [get_cells -filter "IP_NAME=pss_uart"];
}
proc swapp_generate {} {
#delete unnecessary files (only pss_init.c & pss_init.h are needed for FSBL)
set file "pss_init.html"
if { [file exists $file] } {
file delete -force $file
}
set file "pss_init.tcl"
if { [file exists $file] } {
file delete -force $file
}
set file "pss_init_gpl.c"
if { [file exists $file] } {
file delete -force $file
}
set file "pss_init_gpl.h"
if { [file exists $file] } {
file delete -force $file
}
}
proc swapp_get_linker_constraints {} {
# don't generate a linker script. fsbl has its own linker script
return "lscript no";
}

View file

@ -0,0 +1,107 @@
#/******************************************************************************
#*
#* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
#*
#* Permission is hereby granted, free of charge, to any person obtaining a copy
#* of this software and associated documentation files (the "Software"), to deal
#* in the Software without restriction, including without limitation the rights
#* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
#* copies of the Software, and to permit persons to whom the Software is
#* furnished to do so, subject to the following conditions:
#*
#* The above copyright notice and this permission notice shall be included in
#* all copies or substantial portions of the Software.
#*
#* Use of the Software is limited solely to applications:
#* (a) running on a Xilinx device, or
#* (b) that interact with a Xilinx device through a bus or interconnect.
#*
#* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
#* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
#* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
#* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
#* SOFTWARE.
#*
#* Except as contained in this notice, the name of the Xilinx shall not be used
#* in advertising or otherwise to promote the sale, use or other dealings in
#* this Software without prior written authorization from Xilinx.
#*
#******************************************************************************/
PROC ?= a53
CROSS ?=
BSP_DIR := .
ECFLAGS :=
LSCRIPT := -Tlscript_a53.ld
BOARD :=
EXEC := ron_a53_fsbl.elf
c_SOURCES := $(wildcard *.c)
S_SOURCES := $(wildcard *.S)
s_SOURCES := $(wildcard *.s)
INCLUDES := $(wildcard *.h)
OBJS := $(patsubst %.c, %.o, $(c_SOURCES))
OBJS += $(patsubst %.S, %.o, $(S_SOURCES))
OBJS += $(patsubst %.s, %.o, $(s_SOURCES))
ifeq '$(PROC)' 'r5'
CROSS :=
CC := $(CROSS)arm-none-eabi-gcc
AS := $(CROSS)arm-none-eabi-gcc
LINKER := $(CROSS)arm-none-eabi-gcc
DUMP := $(CROSS)arm-none-eabi-objdump -xSD
CFLAGS = -Wall -O0 -g3 -fmessage-length=0 \
-mcpu=cortex-r5 -mfloat-abi=softfp
LSCRIPT := -Tlscript.ld
EXEC := ron_r5_fsbl.elf
INCLUDEPATH := -I$(BSP_DIR)/ps8_cortexr5_0/include -I.
LIBPATH := $(BSP_DIR)/ps8_cortexr5_0/lib
LDFLAGS := -Wl,--start-group,-lxil,-lxilffs,-lgcc,-lc,--end-group -L$(LIBPATH) -L./ -Wl,--build-id=none
endif
ifeq '$(PROC)' 'a53'
CROSS :=
CC := $(CROSS)aarch64-none-elf-gcc
AS := $(CROSS)aarch64-none-elf-gcc
LINKER := $(CROSS)aarch64-none-elf-gcc
DUMP := $(CROSS)aarch64-none-elf-objdump -xSD
CFLAGS = -Wall -O0 -g3 -fmessage-length=0 \
-march=armv8-a -DXFSBL_A53
LSCRIPT := -Tlscript_a53.ld
EXEC := ron_a53_fsbl.elf
INCLUDEPATH := -I$(BSP_DIR)/ps8_cortexa53_0/include -I.
LIBPATH := $(BSP_DIR)/ps8_cortexa53_0/lib
LDFLAGS := -Wl,--start-group,-lxil,-lxilffs,-lgcc,-lc,--end-group -L$(LIBPATH) -L./ -Wl,--build-id=none
endif
ifeq "$(CC)" "armcc"
AS=armasm
LINKER=armlink
CFLAGS += -c --c99 --wchar32
CC_FLAGS += --cpu=Cortex-A9 --fpu=VFPv3_FP16
LDFLAGS = --entry=_vector_table "$(LIBPATH)/libxil.a(*.o)" --no_search_dynamic_libraries --userlibpath=$(LIBPATH),. --library=xil
LSCRIPT = --scatter="scatter.scat"
endif
all: $(EXEC)
$(EXEC): $(OBJS) $(INCLUDES)
$(LINKER) -o $@ $(OBJS) $(CC_FLAGS) $(LDFLAGS) $(LSCRIPT)
$(DUMP) $(EXEC) > dump
cp $(EXEC) fsbl.elf
rm -rf $(OBJS)
%.o:%.c
$(CC) $(CC_FLAGS) $(CFLAGS) $(ECFLAGS) -c $< -o $@ $(INCLUDEPATH)
%.o:%.S
$(AS) $(CC_FLAGS) $(CFLAGS) $(ECFLAGS) -c $< -o $@ $(INCLUDEPATH)
%.o:%.s
$(AS) $(CC_FLAGS) $(CFLAGS) $(ECFLAGS) -c $< -o $@ $(INCLUDEPATH)
clean:
rm -rf $(OBJS) *.elf dump

View file

@ -0,0 +1,311 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*******************************************************************/
/* */
/* Description : FSBL R5 Linker Script */
/* */
/*******************************************************************/
_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x4000;
_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 1024;
_ABORT_STACK_SIZE = DEFINED(_ABORT_STACK_SIZE) ? _ABORT_STACK_SIZE : 1024;
_SUPERVISOR_STACK_SIZE = DEFINED(_SUPERVISOR_STACK_SIZE) ? _SUPERVISOR_STACK_SIZE : 2048;
_IRQ_STACK_SIZE = DEFINED(_IRQ_STACK_SIZE) ? _IRQ_STACK_SIZE : 1024;
_FIQ_STACK_SIZE = DEFINED(_FIQ_STACK_SIZE) ? _FIQ_STACK_SIZE : 1024;
_UNDEF_STACK_SIZE = DEFINED(_UNDEF_STACK_SIZE) ? _UNDEF_STACK_SIZE : 1024;
/* Define Memories in the system */
MEMORY
{
ps7_ram_0_S_AXI_BASEADDR : ORIGIN = 0xfffc0000, LENGTH = 0x0002FF00
ps7_ram_1_S_AXI_BASEADDR : ORIGIN = 0xffff0040, LENGTH = 0x0000FE00
}
/* Specify the default entry point to the program */
ENTRY(_vector_table)
/* Define the sections, and where they are mapped in memory */
SECTIONS
{
.text : {
*(.vectors)
*(.boot)
*(.text)
*(.text.*)
*(.gnu.linkonce.t.*)
*(.plt)
*(.gnu_warning)
*(.gcc_execpt_table)
*(.glue_7)
*(.glue_7t)
*(.vfp11_veneer)
*(.ARM.extab)
*(.gnu.linkonce.armextab.*)
} > ps7_ram_0_S_AXI_BASEADDR
.init : {
KEEP (*(.init))
} > ps7_ram_0_S_AXI_BASEADDR
.fini : {
KEEP (*(.fini))
} > ps7_ram_0_S_AXI_BASEADDR
.rodata : {
__rodata_start = .;
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
__rodata_end = .;
} > ps7_ram_0_S_AXI_BASEADDR
.rodata1 : {
__rodata1_start = .;
*(.rodata1)
*(.rodata1.*)
__rodata1_end = .;
} > ps7_ram_0_S_AXI_BASEADDR
.sdata2 : {
__sdata2_start = .;
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
__sdata2_end = .;
} > ps7_ram_0_S_AXI_BASEADDR
.sbss2 : {
__sbss2_start = .;
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
__sbss2_end = .;
} > ps7_ram_0_S_AXI_BASEADDR
.data : {
__data_start = .;
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
*(.jcr)
*(.got)
*(.got.plt)
__data_end = .;
} > ps7_ram_0_S_AXI_BASEADDR
.data1 : {
__data1_start = .;
*(.data1)
*(.data1.*)
__data1_end = .;
} > ps7_ram_0_S_AXI_BASEADDR
.got : {
*(.got)
} > ps7_ram_0_S_AXI_BASEADDR
.ctors : {
__CTOR_LIST__ = .;
___CTORS_LIST___ = .;
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__CTOR_END__ = .;
___CTORS_END___ = .;
} > ps7_ram_0_S_AXI_BASEADDR
.dtors : {
__DTOR_LIST__ = .;
___DTORS_LIST___ = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
__DTOR_END__ = .;
___DTORS_END___ = .;
} > ps7_ram_0_S_AXI_BASEADDR
.fixup : {
__fixup_start = .;
*(.fixup)
__fixup_end = .;
} > ps7_ram_0_S_AXI_BASEADDR
.eh_frame : {
*(.eh_frame)
} > ps7_ram_0_S_AXI_BASEADDR
.eh_framehdr : {
__eh_framehdr_start = .;
*(.eh_framehdr)
__eh_framehdr_end = .;
} > ps7_ram_0_S_AXI_BASEADDR
.gcc_except_table : {
*(.gcc_except_table)
} > ps7_ram_0_S_AXI_BASEADDR
.mmu_tbl (ALIGN(16384)) : {
__mmu_tbl_start = .;
*(.mmu_tbl)
__mmu_tbl_end = .;
} > ps7_ram_0_S_AXI_BASEADDR
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx*)
*(.gnu.linkonce.armexidix.*.*)
__exidx_end = .;
} > ps7_ram_0_S_AXI_BASEADDR
.preinit_array : {
__preinit_array_start = .;
KEEP (*(SORT(.preinit_array.*)))
KEEP (*(.preinit_array))
__preinit_array_end = .;
} > ps7_ram_0_S_AXI_BASEADDR
.init_array : {
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
} > ps7_ram_0_S_AXI_BASEADDR
.fini_array : {
__fini_array_start = .;
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array))
__fini_array_end = .;
} > ps7_ram_0_S_AXI_BASEADDR
.ARM.attributes : {
__ARM.attributes_start = .;
*(.ARM.attributes)
__ARM.attributes_end = .;
} > ps7_ram_0_S_AXI_BASEADDR
.sdata : {
__sdata_start = .;
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
__sdata_end = .;
} > ps7_ram_0_S_AXI_BASEADDR
.sbss (NOLOAD) : {
__sbss_start = .;
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
__sbss_end = .;
} > ps7_ram_0_S_AXI_BASEADDR
.tdata : {
__tdata_start = .;
*(.tdata)
*(.tdata.*)
*(.gnu.linkonce.td.*)
__tdata_end = .;
} > ps7_ram_0_S_AXI_BASEADDR
.tbss : {
__tbss_start = .;
*(.tbss)
*(.tbss.*)
*(.gnu.linkonce.tb.*)
__tbss_end = .;
} > ps7_ram_1_S_AXI_BASEADDR
.bss (NOLOAD) : {
__bss_start = .;
__bss_start__ = .;
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
__bss_end = .;
__bss_end__ = .;
} > ps7_ram_1_S_AXI_BASEADDR
_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 );
_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 );
/* Generate Stack and Heap definitions */
.heap (NOLOAD) : {
. = ALIGN(16);
_heap = .;
HeapBase = .;
_heap_start = .;
. += _HEAP_SIZE;
_heap_end = .;
HeapLimit = .;
} > ps7_ram_1_S_AXI_BASEADDR
.stack (NOLOAD) : {
. = ALIGN(16);
_stack_end = .;
. += _STACK_SIZE;
_stack = .;
__stack = _stack;
. = ALIGN(16);
_irq_stack_end = .;
. += _IRQ_STACK_SIZE;
__irq_stack = .;
_supervisor_stack_end = .;
. += _SUPERVISOR_STACK_SIZE;
. = ALIGN(16);
__supervisor_stack = .;
_abort_stack_end = .;
. += _ABORT_STACK_SIZE;
. = ALIGN(16);
__abort_stack = .;
_fiq_stack_end = .;
. += _FIQ_STACK_SIZE;
. = ALIGN(16);
__fiq_stack = .;
_undef_stack_end = .;
. += _UNDEF_STACK_SIZE;
. = ALIGN(16);
__undef_stack = .;
} > ps7_ram_1_S_AXI_BASEADDR
_end = .;
}

View file

@ -0,0 +1,333 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*******************************************************************/
/* */
/* Description : FSBL A53 Linker Script */
/* */
/*******************************************************************/
_STACK_SIZE = DEFINED(_STACK_SIZE) ? _STACK_SIZE : 0x4000;
_HEAP_SIZE = DEFINED(_HEAP_SIZE) ? _HEAP_SIZE : 1024;
_EL0_STACK_SIZE = DEFINED(_ABORT_STACK_SIZE) ? _ABORT_STACK_SIZE : 1024;
_EL1_STACK_SIZE = DEFINED(_SUPERVISOR_STACK_SIZE) ? _SUPERVISOR_STACK_SIZE : 2048;
_EL2_STACK_SIZE = DEFINED(_IRQ_STACK_SIZE) ? _IRQ_STACK_SIZE : 1024;
_EL3_STACK_SIZE = DEFINED(_FIQ_STACK_SIZE) ? _FIQ_STACK_SIZE : 1024;
/* Define Memories in the system */
MEMORY
{
ps8_ocm_ram_0_S_AXI_BASEADDR : ORIGIN = 0xFFFC0000, LENGTH = 0x0002FF00
ps8_ocm_ram_1_S_AXI_BASEADDR : ORIGIN = 0xFFFF0040, LENGTH = 0x0000FE00
}
/* Specify the default entry point to the program */
ENTRY(_vector_table)
/* Define the sections, and where they are mapped in memory */
SECTIONS
{
.text : {
*(.vectors)
*(.boot)
*(.text)
*(.text.*)
*(.gnu.linkonce.t.*)
*(.plt)
*(.gnu_warning)
*(.gcc_execpt_table)
*(.glue_7)
*(.glue_7t)
*(.ARM.extab)
*(.gnu.linkonce.armextab.*)
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.init (ALIGN(64)): {
KEEP (*(.init))
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.fini (ALIGN(64)): {
KEEP (*(.fini))
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.interp : {
__interp_start = .;
KEEP (*(.interp))
__interp_end = .;
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.note-ABI-tag : {
__note-ABI-tag_start = .;
KEEP (*(.note-ABI-tag))
__note-ABI-tag_end = .;
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.rodata (ALIGN(64)): {
__rodata_start = .;
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
__rodata_end = .;
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.rodata1 (ALIGN(64)): {
__rodata1_start = .;
*(.rodata1)
*(.rodata1.*)
__rodata1_end = .;
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.sdata2 (ALIGN(64)): {
__sdata2_start = .;
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
__sdata2_end = .;
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.sbss2 (ALIGN(64)): {
__sbss2_start = .;
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
__sbss2_end = .;
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.data (ALIGN(64)): {
__data_start = .;
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
*(.jcr)
*(.got)
*(.got.plt)
__data_end = .;
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.data1 (ALIGN(64)): {
__data1_start = .;
*(.data1)
*(.data1.*)
__data1_end = .;
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.got : {
*(.got)
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.got1 : {
*(.got1)
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.got2 : {
*(.got2)
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.ctors (ALIGN(64)): {
__CTOR_LIST__ = .;
___CTORS_LIST___ = .;
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE(*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
__CTOR_END__ = .;
___CTORS_END___ = .;
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.dtors (ALIGN(64)): {
__DTOR_LIST__ = .;
___DTORS_LIST___ = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE(*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
__DTOR_END__ = .;
___DTORS_END___ = .;
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.fixup : {
__fixup_start = .;
*(.fixup)
__fixup_end = .;
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.eh_frame : {
*(.eh_frame)
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.eh_framehdr : {
__eh_framehdr_start = .;
*(.eh_framehdr)
__eh_framehdr_end = .;
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.gcc_except_table : {
*(.gcc_except_table)
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.mmu_tbl0 (ALIGN(4096)) : {
__mmu_tbl0_start = .;
*(.mmu_tbl0)
__mmu_tbl0_end = .;
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.mmu_tbl1 (ALIGN(4096)) : {
__mmu_tbl1_start = .;
*(.mmu_tbl1)
__mmu_tbl1_end = .;
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.mmu_tbl2 (ALIGN(4096)) : {
__mmu_tbl2_start = .;
*(.mmu_tbl2)
__mmu_tbl2_end = .;
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.ARM.exidx : {
__exidx_start = .;
*(.ARM.exidx*)
*(.gnu.linkonce.armexidix.*.*)
__exidx_end = .;
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.preinit_array (ALIGN(64)): {
__preinit_array_start = .;
KEEP (*(SORT(.preinit_array.*)))
KEEP (*(.preinit_array))
__preinit_array_end = .;
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.init_array (ALIGN(64)): {
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.fini_array (ALIGN(64)): {
__fini_array_start = .;
KEEP (*(SORT(.fini_array.*)))
KEEP (*(.fini_array))
__fini_array_end = .;
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.ARM.attributes : {
__ARM.attributes_start = .;
*(.ARM.attributes)
__ARM.attributes_end = .;
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.sdata (ALIGN(64)): {
__sdata_start = .;
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
__sdata_end = .;
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.sbss (NOLOAD) : {
. = ALIGN(64);
__sbss_start = .;
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
. = ALIGN(64);
__sbss_end = .;
} > ps8_ocm_ram_1_S_AXI_BASEADDR
.tdata (ALIGN(64)): {
__tdata_start = .;
*(.tdata)
*(.tdata.*)
*(.gnu.linkonce.td.*)
__tdata_end = .;
} > ps8_ocm_ram_0_S_AXI_BASEADDR
.tbss (ALIGN(64)): {
__tbss_start = .;
*(.tbss)
*(.tbss.*)
*(.gnu.linkonce.tb.*)
__tbss_end = .;
} > ps8_ocm_ram_1_S_AXI_BASEADDR
.bss (NOLOAD) : {
. = ALIGN(64);
__bss_start__ = .;
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(64);
__bss_end__ = .;
} > ps8_ocm_ram_1_S_AXI_BASEADDR
_SDA_BASE_ = __sdata_start + ((__sbss_end - __sdata_start) / 2 );
_SDA2_BASE_ = __sdata2_start + ((__sbss2_end - __sdata2_start) / 2 );
/* Generate Stack and Heap definitions */
.heap (NOLOAD) : {
. = ALIGN(64);
_heap = .;
HeapBase = .;
_heap_start = .;
. += _HEAP_SIZE;
_heap_end = .;
HeapLimit = .;
} > ps8_ocm_ram_1_S_AXI_BASEADDR
.stack (NOLOAD) : {
. = ALIGN(64);
_el3_stack_end = .;
. += _STACK_SIZE;
__el3_stack = .;
_el2_stack_end = .;
. += _EL2_STACK_SIZE;
. = ALIGN(64);
__el2_stack = .;
_el1_stack_end = .;
. += _EL1_STACK_SIZE;
. = ALIGN(64);
__el1_stack = .;
_el0_stack_end = .;
. += _EL0_STACK_SIZE;
. = ALIGN(64);
__el0_stack = .;
} > ps8_ocm_ram_1_S_AXI_BASEADDR
_end = .;
}

View file

@ -0,0 +1,425 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
*******************************************************************************/
/*****************************************************************************/
/**
*
* @file xfsbl_authentication.c
*
* Contains the function definitions for RSA Signature verification.
*
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xfsbl_hw.h"
#ifdef XFSBL_RSA
#include "xfsbl_authentication.h"
/*****************************************************************************/
const u8 XFsbl_TPadSha3[] = {0x30, 0x41, 0x30, 0x0D, 0x06, 0x09, 0x60,
0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
0x02, 0x05, 0x00, 0x04, 0x30 };
const u8 XFsbl_TPadSha2[] = {0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60,
0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02,
0x01, 0x05, 0x00, 0x04, 0x20 };
/*****************************************************************************/
/**
* Configure the RSA and SHA for the SPK
* Signature verification.
* If SPK Signature verification fails
* then return unique error code saying
* XFSBL_STAGE3_SPK_SIGN_VERIF_ERROR.
*
* @param
*
* @return
*
******************************************************************************/
u32 XFsbl_SpkVer(u64 AcOffset, u32 HashLen)
{
u8 SpkHash[XFSBL_HASH_TYPE_SHA3] __attribute__ ((aligned (4)));
u8 * PpkModular = (u8 *)NULL;
u8 * PpkModularEx = (u8 *)NULL;
u32 PpkExp = 0;
u8 * AcPtr = (u8*) (PTRSIZE) AcOffset;
u32 Status = XFSBL_SUCCESS;
void * ShaCtx = (void * )NULL;
(void)XFsbl_ShaStart( ShaCtx, HashLen);
/**
* Hash the PPK + SPK choice
*/
XFsbl_ShaUpdate( ShaCtx, AcPtr, 8, HashLen);
/**
* Set PPK pointer
*/
AcPtr += XFSBL_RSA_AC_ALIGN;
PpkModular = (u8 *)AcPtr;
AcPtr += XFSBL_SPK_SIG_SIZE;
PpkModularEx = (u8 *)AcPtr;
AcPtr += XFSBL_SPK_SIG_SIZE;
PpkExp = *((u32 *)AcPtr);
AcPtr += XFSBL_RSA_AC_ALIGN;
XFsbl_Printf(DEBUG_DETAILED,
"XFsbl_SpkVer: Ppk Mod %0x, Ppk Mod Ex %0x, Ppk Exp %0x\r\n",
PpkModular, PpkModularEx, PpkExp);
/**
* Calculate SPK + Auth header(PPK and SPK Selectoin both) Hash
*/
XFsbl_ShaUpdate( ShaCtx, (u8 *)AcPtr, XFSBL_PPK_SIZE, HashLen);
XFsbl_ShaFinish( ShaCtx, (u8 *)SpkHash, HashLen);
/**
* Set SPK Signature pointer
*/
AcPtr += XFSBL_SPK_SIZE;
/**
* Decrypt SPK Signature.
*/
if(XFSBL_SUCCESS !=
XFsbl_RsaDecrypt(AcPtr, PpkModular,
PpkModularEx, (u8 *)&PpkExp, XFsbl_RsaSha3Array, 0) )
{
XFsbl_Printf(DEBUG_GENERAL,
"XFsbl_SpkVer: XFSBL_ERROR_SPK_RSA_DECRYPT\r\n");
Status = XFSBL_ERROR_SPK_RSA_DECRYPT;
goto END;
}
/**
* Authenticate SPK Signature.
*/
if(XFSBL_SUCCESS != XFsbl_CheckPadding(XFsbl_RsaSha3Array,
SpkHash, HashLen))
{
XFsbl_PrintArray(DEBUG_INFO, SpkHash,
HashLen, "Calculated Partition Hash");
XFsbl_PrintArray(DEBUG_INFO, XFsbl_RsaSha3Array,
512, "RSA decrypted Hash");
XFsbl_Printf(DEBUG_GENERAL,
"XFsbl_SpkVer: XFSBL_ERROR_SPK_SIGNATURE\r\n");
Status = XFSBL_ERROR_SPK_SIGNATURE;
}
END:
return Status;
}
/*****************************************************************************/
/**
* Configure the RSA and SHA for the
* Boot Header Signature verification.
* If Boot Header Signature verification
* fails then return unique error code saying
* XFSBL_STAGE3_BOOT_HDR_SIGN_VERIF_ERROR.
*
* @param
*
* @return
*
******************************************************************************/
u32 XFsbl_PartitionSignVer(u64 PartitionOffset, u32 PartitionLen,
u64 AcOffset, u32 HashLen)
{
u8 PartitionHash[XFSBL_HASH_TYPE_SHA3] __attribute__ ((aligned (4)));
u8 * SpkModular = (u8 *)NULL;
u8 * SpkModularEx = (u8 *)NULL;
u32 SpkExp = 0;
u8 * AcPtr = (u8*)(PTRSIZE) AcOffset;
u32 Status = XFSBL_SUCCESS;
u32 HashDataLen=0U;
XFsbl_Printf(DEBUG_INFO,"Doing Partition Sign verification\r\n");
/**
* hash to be calculated will be total length with AC minus
* signature size
*/
HashDataLen = PartitionLen - XFSBL_FSBL_SIG_SIZE;
/**
* Set SPK pointer
*/
AcPtr += (XFSBL_RSA_AC_ALIGN + XFSBL_PPK_SIZE);
SpkModular = (u8 *)AcPtr;
AcPtr += XFSBL_BHDR_SIG_SIZE;
SpkModularEx = (u8 *)AcPtr;
AcPtr += XFSBL_BHDR_SIG_SIZE;
SpkExp = *((u32 *)AcPtr);
AcPtr += XFSBL_RSA_AC_ALIGN;
/**
* Calculate Partition Hash
*/
XFsbl_ShaDigest((const u8 *)(PTRSIZE)PartitionOffset, HashDataLen,
PartitionHash, HashLen);
/**
* Increment by SPK Signature pointer
*/
AcPtr += XFSBL_SPK_SIG_SIZE;
/**
* Increment by BHDR Signature pointer
*/
AcPtr += XFSBL_BHDR_SIG_SIZE;
XFsbl_Printf(DEBUG_DETAILED,
"XFsbl_PartVer: Spk Mod %0x, Spk Mod Ex %0x, Spk Exp %0x\r\n",
SpkModular, SpkModularEx, SpkExp);
/**
* Decrypt Partition Signature.
*/
if(XFSBL_SUCCESS !=
XFsbl_RsaDecrypt(AcPtr, SpkModular,
SpkModularEx, (u8 *)&SpkExp, XFsbl_RsaSha3Array, 0) )
{
XFsbl_Printf(DEBUG_GENERAL,
"XFsbl_SpkVer: XFSBL_ERROR_PART_RSA_DECRYPT\r\n");
Status = XFSBL_ERROR_PART_RSA_DECRYPT;
goto END;
}
/**
* Authenticate Partition Signature.
*/
if(XFSBL_SUCCESS != XFsbl_CheckPadding(XFsbl_RsaSha3Array,
PartitionHash, HashLen))
{
XFsbl_PrintArray(DEBUG_INFO, PartitionHash,
HashLen, "Calculated Partition Hash");
XFsbl_PrintArray(DEBUG_INFO, XFsbl_RsaSha3Array,
512, "RSA decrypted Hash");
XFsbl_Printf(DEBUG_GENERAL,
"XFsbl_SpkVer: XFSBL_ERROR_PART_SIGNATURE\r\n");
Status = XFSBL_ERROR_PART_SIGNATURE;
goto END;
}
END:
return Status;
}
/*****************************************************************************/
/**
* DT 764500(Add feature for basic integrity check of
the FSBL Image by FSBL.)
*
* @param
*
* @return
*
******************************************************************************/
u32 XFsbl_IntegrityCheck(u64 PartitionOffset, u32 PartitionLen,
u64 CheckSumOffset, u32 HashLen)
{
u32 Status = XFSBL_SUCCESS;
u8 PartitionHash[XFSBL_HASH_TYPE_SHA3] __attribute__ ((aligned (4)));
u32 ii=0;
u8 *HashPtr = (u8 *)NULL;
void * ShaCtx = (void * )NULL;
XFsbl_Printf(DEBUG_INFO,"XFsbl_IntegrityCheck: Doing Partition"
" Integrity Check HashLen=%d\r\n",HashLen);
HashPtr = (u8 *)(PTRSIZE)CheckSumOffset;
(void)XFsbl_ShaStart(ShaCtx, HashLen);
/**
* Calculate FSBL Hash
*/
XFsbl_ShaUpdate( ShaCtx, (u8 *)(PTRSIZE)PartitionOffset,
PartitionLen, HashLen);
XFsbl_ShaFinish( ShaCtx, (u8 *)PartitionHash, HashLen);
/**
* Compare the calculated and builtin hash
*/
for (ii = 0; ii < HashLen; ii++)
{
if (HashPtr[ii] != PartitionHash[ii])
{
Status = XFSBL_FAILURE;
XFsbl_Printf(DEBUG_INFO,"Check Failed!!!!!\r\n");
goto END;
}
}
XFsbl_Printf(DEBUG_INFO,"Check Passed!!!!!\r\n");
END:
return Status;
}
/*****************************************************************************/
/**
*
* @param
*
* @return
*
******************************************************************************/
u32 XFsbl_CheckPadding(u8 *Signature, u8 *Hash, u32 HashLen)
{
u8 * Tpadding = (u8 *)NULL;
u32 Pad = XFSBL_FSBL_SIG_SIZE - 3 - 19 - HashLen;
u8 * PadPtr = Signature;
u32 ii;
u32 Status = 0;
if(XFSBL_HASH_TYPE_SHA3 == HashLen)
{
Tpadding = (u8 *)XFsbl_TPadSha3;
}
else
{
Tpadding = (u8 *)XFsbl_TPadSha2;
}
/**
* Re-Create PKCS#1v1.5 Padding
* MSB ----------------------------------------------------------------LSB
* 0x0 || 0x1 || 0xFF(for 202 bytes) || 0x0 || T_padding || SHA256/384 Hash
*/
if (0x00 != *PadPtr)
{
Status = 1;
goto END;
}
PadPtr++;
if (0x01 != *PadPtr)
{
Status = 2;
goto END;
}
PadPtr++;
for (ii = 0; ii < Pad; ii++)
{
if (0xFF != *PadPtr)
{
Status = 3;
goto END;
}
PadPtr++;
}
if (0x00 != *PadPtr)
{
Status = 4;
goto END;
}
PadPtr++;
for (ii = 0; ii < 19; ii++)
{
if (*PadPtr != Tpadding[ii])
{
Status = 5;
goto END;
}
PadPtr++;
}
for (ii = 0; ii < HashLen; ii++)
{
if (*PadPtr != Hash[ii])
{
Status = 6;
goto END;
}
PadPtr++;
}
END:
XFsbl_Printf(DEBUG_INFO,"XFsbl_CheckPadding: Error:0x%x\r\n",Status);
return Status;
}
/*****************************************************************************/
/**
*
* @param None
*
* @return None
*
******************************************************************************/
u32 XFsbl_Authentication(u64 PartitionOffset, u32 PartitionLen,
u64 AcOffset, u32 HashLen)
{
u32 Status = XFSBL_SUCCESS;
XFsbl_Printf(DEBUG_INFO,
"Auth: Partition Offset %0x, PartitionLen %0x,"
" AcOffset %0x, HashLen %0x\r\n",
(PTRSIZE )PartitionOffset, PartitionLen,
(PTRSIZE )AcOffset, HashLen);
/**
* Do SPK Signature verification using PPK
*/
Status = XFsbl_SpkVer(AcOffset, HashLen);
if(XFSBL_SUCCESS != Status)
{
goto END;
}
/**
* Do Partition Signature verification using SPK
*/
Status = XFsbl_PartitionSignVer(PartitionOffset, PartitionLen,
AcOffset, HashLen);
if(XFSBL_SUCCESS != Status)
{
goto END;
}
END:
return Status;
}
#endif /* end of XFSBL_RSA */

View file

@ -0,0 +1,131 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
*
*******************************************************************************/
/*****************************************************************************/
/**
*
* @file xcbr_authentication.h
*
* Contains the function prototypes, defines and macros for
* the RSA DSA functionality.
*
*
******************************************************************************/
#ifndef XFSBL_AUTHENTICATION_H
#define XFSBL_AUTHENTICATION_H
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xfsbl_hw.h"
/***************************** Type defines *********************************/
#define XFSBL_HASH_TYPE_SHA3 (48U)
#define XFSBL_HASH_TYPE_SHA2 (32U)
#define XFSBL_PPK_SIZE (512U+512U+64U)
#define XFSBL_SPK_SIZE XFSBL_PPK_SIZE
#define XFSBL_SPK_SIG_SIZE (512U)
#define XFSBL_BHDR_SIG_SIZE (512U)
#define XFSBL_FSBL_SIG_SIZE (512U)
#define XFSBL_RSA_KEY_LEN (4096U)
#define XFSBL_RSA_BIG_ENDIAN (0x1U)
#define XFSBL_RSA_AC_ALIGN (64U)
#define XFSBL_AUTH_HEADER_SIZE (8U)
#define XFSBL_AUTH_CERT_USER_DATA (64U - XFSBL_AUTH_HEADER_SIZE)
#define XFSBL_AUTH_CERT_MIN_SIZE (XFSBL_AUTH_HEADER_SIZE \
+ XFSBL_AUTH_CERT_USER_DATA \
+ XFSBL_PPK_SIZE \
+ XFSBL_PPK_SIZE \
+ XFSBL_SPK_SIG_SIZE \
+ XFSBL_BHDR_SIG_SIZE \
+ XFSBL_FSBL_SIG_SIZE)
#define XFSBL_AUTH_CERT_MAX_SIZE (XFSBL_AUTH_CERT_MIN_SIZE + 60)
#define XFSBL_PARTIAL_AC_SIZE (XFSBL_AUTH_CERT_MIN_SIZE - XFSBL_FSBL_SIG_SIZE)
/**
* CSU RSA Register Map
*/
#define XFSBL_CSU_RSA_CONTROL_2048 (0xA0U)
#define XFSBL_CSU_RSA_CONTROL_4096 (0xC0U)
#define XFSBL_CSU_RSA_CONTROL_DCA (0x08U)
#define XFSBL_CSU_RSA_CONTROL_NOP (0x00U)
#define XFSBL_CSU_RSA_CONTROL_EXP (0x01U)
#define XFSBL_CSU_RSA_CONTROL_EXP_PRE (0x05U)
#define XFSBL_CSU_RSA_CONTROL_MASK (XFSBL_CSU_RSA_CONTROL_4096 + XFSBL_CSU_RSA_CONTROL_EXP_PRE)
#define XFSBL_CSU_RSA_RAM_EXPO (0)
#define XFSBL_CSU_RSA_RAM_MOD (1)
#define XFSBL_CSU_RSA_RAM_DIGEST (2)
#define XFSBL_CSU_RSA_RAM_SPAD (3)
#define XFSBL_CSU_RSA_RAM_RES_Y (4)
#define XFSBL_CSU_RSA_RAM_RES_Q (5)
#define XFSBL_CSU_RSA_RAM_WORDS (6)
/**
* CSU SHA3 Memory Map
*/
#define XFSBL_SHA3_BLOCK_LEN (104)
#define XFSBL_SHA3_LAST_PACKET (0x1)
u32 XFsbl_Authentication(u64 PartitionOffset, u32 PartitionLen,
u64 AcOffset, u32 HashLen);
u32 XFsbl_PartitionSignVer(u64 PartitionOffset, u32 PartitionLen,
u64 AcOffset, u32 HashLen);
u32 XFsbl_SpkVer(u64 AcOffset, u32 HashLen);
//u32 XFsbl_IntegrityCheck(XCbrBootRom *InstancePtr);
u32 XFsbl_CheckPadding(u8 *Signature, u8 *Hash, u32 HashLen);
u32 XFsbl_RsaDecrypt(u8* EncText, u8* Mod, u8* ModExt, u8* ModExpo, u8* Result, u8 Reuse);
void XFsbl_ShaDigest(const u8 *In, const u32 Size, u8 *Out, u32 HashLen);
void XFsbl_ShaStart( void * Ctx, u32 HashLen);
void XFsbl_ShaUpdate(void * Ctx, u8 * Data, u32 Size, u32 HashLen);
void XFsbl_ShaFinish(void * Ctx, u8 * Hash, u32 HashLen);
extern u8 XFsbl_RsaSha3Array[512];
#ifdef __cplusplus
extern "C" }
#endif
#endif /** XFSBL_AUTHENTICATION_H */

View file

@ -0,0 +1,147 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xfsbl_config.h
*
* This is the header file which contains FSBL configuration
* for users.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 kc 10/21/13 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
#ifndef XFSBL_CONFIG_H
#define XFSBL_CONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/**
* @name FSBL Debug options
*
* FSBL by default doesn't have any prints enabled. If user
* want to enable the prints, they can define the following
* options to have FSBL prints
* FSBL supports three types of debug levels.
* - FSBL_DEBUG Defining this will print the FSBL header and
* same basic information and error prints if any
* - FSBL_DEBUG_INFO Defining this will have prints enabled with
* in addition to the basic information
* - FSBL_DEBUG_DETAILED Defining this will print information with
* all data exchanged.
*/
#define FSBL_DEBUG_VAL (0U)
#define FSBL_DEBUG_INFO_VAL (1U)
#define FSBL_DEBUG_DETAILED_VAL (0U)
/**
* FSBL Debug options
*/
#if FSBL_DEBUG_VAL
#define FSBL_DEBUG
#endif
#if FSBL_DEBUG_INFO_VAL
#define FSBL_DEBUG_INFO
#endif
#if FSBL_DEBUG_DETAILED_VAL
#define FSBL_DEBUG_DETAILED
#endif
/**
* @name FSBL code include options
*
* FSBL by default all the code is included.
* Unwanted code can be excluded from the elf by defining here
* Below blocks can be excluded from the code.
* - FSBL_NAND_EXCLUDE NAND code will be excluded
* - FSBL_QSPI_EXCLUDE QSPI code will be excluded
* - FSBL_SD_EXCLUDE SD code will be excluded
* - FSBL_RSA_EXCLUDE RSA code will be excluded
*/
#define FSBL_NAND_EXCLUDE_VAL (0U)
#define FSBL_QSPI_EXCLUDE_VAL (0U)
#define FSBL_SD_EXCLUDE_VAL (0U)
#define FSBL_RSA_EXCLUDE_VAL (0U)
#define FSBL_SHA2_EXCLUDE_VAL (1U)
#if FSBL_NAND_EXCLUDE_VAL
#define FSBL_NAND_EXCLUDE
#endif
#if FSBL_QSPI_EXCLUDE_VAL
#define FSBL_QSPI_EXCLUDE
#endif
#if FSBL_SD_EXCLUDE_VAL
#define FSBL_SD_EXCLUDE
#endif
#if FSBL_RSA_EXCLUDE_VAL
#define FSBL_RSA_EXCLUDE
#endif
#if FSBL_SHA2_EXCLUDE_VAL
#define FSBL_SHA2_EXCLUDE
#endif
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
#ifdef __cplusplus
}
#endif
#endif /* XFSBL_CONFIG_H */

View file

@ -0,0 +1,182 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
*******************************************************************************/
/*****************************************************************************/
/**
*
* @file xfsbl_csu_dma.c
*
* This contains code for the CSU DMA driver.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 kc 07/22/14 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xfsbl_csu_dma.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
/*****************************************************************************/
/**
*
* This function will configure dst/src DMA address
* and size and also start the CSU DMA.
*
* @param None
*
* @return None
*
******************************************************************************/
void XFsbl_CsuDmaStart(XFSBL_CSU_DMA_CHANNEL Channel, u32 Addr, u32 Size)
{
XASSERT_VOID((Addr & 3) == 0);
if(XFSBL_CSU_DMA_SRC == Channel)
{
XASSERT_VOID((Size & 2) == 0);
}
else
{
XASSERT_VOID((Size & 3) == 0);
}
XFsbl_Out32(CSUDMA_BASEADDR + Channel + XFSBL_CSU_DMA_ADDR_REG, Addr);
/**
* Writes to SIZE to start the channel, this starts
* the DMA.
*/
/** ASM Code */
mb();
XFsbl_Out32(CSUDMA_BASEADDR + Channel + XFSBL_CSU_DMA_SIZE_REG, Size);
}
/*****************************************************************************/
/**
*
* This function will stop/pause the CSU DMA.
*
* @param None
*
* @return None
*
******************************************************************************/
void XFsbl_CsuDmaStop(u32 Flags)
{
/**
* This function is TBD.
*/
}
/*****************************************************************************/
/**
*
* This function will wait for CSU DMA done.
*
* @param None
*
* @return None
*
******************************************************************************/
void XFsbl_CsuDmaWaitForDone(XFSBL_CSU_DMA_CHANNEL Channel)
{
volatile u32 Status = 0;
/** ASM Code */
mb();
/* Busy wait for the DMA. */
/**
* TBD: May need to have some timeout for this loop.
*/
do
{
Status = XFsbl_In32(CSUDMA_BASEADDR + Channel +
XFSBL_CSU_DMA_STATUS_REG);
} while (Status & XFSBL_CSU_DMA_STATUS_BUSY);
}
/*****************************************************************************/
/**
*
* This function will start the dma transfer
* and wait for DST DMA done.
*
* @param None
*
* @return None
*
******************************************************************************/
void XFsbl_CsuDmaXfer(u32 SrcAddr, u32 DestAddr, u32 ImgLen)
{
XFsbl_Printf(DEBUG_INFO,"In XCbr_CsuDmaXfer: SrcAddr:0x%x "
"DestAddr:0x%x ImgLen:0x%x\r\n",SrcAddr,DestAddr,ImgLen);
XFsbl_CsuDmaStart(XFSBL_CSU_DMA_DST, DestAddr, ((ImgLen/4) << 2) );
/**
* In case of PSTP, the Src DMA channel is not used.
* For this function SrcAddr == 0 means we are calling
* this function for PS_TEST boot mode
*/
if(0 != SrcAddr)
{
XFsbl_CsuDmaStart(XFSBL_CSU_DMA_SRC, SrcAddr, (ImgLen/4) << 2);
XFsbl_CsuDmaWaitForDone(XFSBL_CSU_DMA_SRC);
}
/**
* TBD: Need to enhance this to return
* timeout error
*/
XFsbl_CsuDmaWaitForDone(XFSBL_CSU_DMA_DST);
}

View file

@ -0,0 +1,275 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
*******************************************************************************/
/*****************************************************************************/
/**
*
* @file xcbr_csu_dma.h
*
* Contains enums/typedefs and macros for CSU DMA driver.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 kc 07/22/14 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
#ifndef XFSBL_CSU_DMA_H
#define XFSBL_CSU_DMA_H
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xfsbl_hw.h"
/**************************** Macros Definitions *****************************/
#define XASSERT_VOID(expression)
#define mb() asm("dsb sy")
u8 XFsbl_RsaSha3Array[512];
/**************************** Type Definitions *******************************/
/**
* Definition for DMA channels.
*/
typedef enum
{
XFSBL_CSU_DMA_SRC = 0x000U,
XFSBL_CSU_DMA_DST = 0x800U
}XFSBL_CSU_DMA_CHANNEL;
/**
* Definition for DMA registers.
*/
typedef enum
{
XFSBL_CSU_DMA_ADDR_REG = 0x00U,
XFSBL_CSU_DMA_SIZE_REG = 0x04U,
XFSBL_CSU_DMA_STATUS_REG = 0x08U,
XFSBL_CSU_DMA_CTRL_REG = 0x0CU,
XFSBL_CSU_DMA_CRC_REG = 0x10U,
XFSBL_CSU_DMA_INT_STATUS_REG = 0x14U,
XFSBL_CSU_DMA_INT_ENABLE_REG = 0x18U,
XFSBL_CSU_DMA_INT_DISABLE_REG = 0x1CU,
XFSBL_CSU_DMA_INT_MASK_REG = 0x20U,
}XFSBL_CSU_DMA_REG_OFFSET;
/**
* Definition for DMA EOP.
*/
enum
{
XFSBL_CSU_DMA_SIZE_EOP = 0x1U
};
/**
* Definition for DMA Status reg bits.
*/
typedef enum
{
XFSBL_CSU_DMA_STATUS_BUSY = (0x1U << 0x0U),
XFSBL_CSU_DMA_STATUS_DONE_CNT_SHIFT = (13U),
XFSBL_CSU_DMA_STATUS_DONE_CNT_MASK = (0x7U << XFSBL_CSU_DMA_STATUS_DONE_CNT_SHIFT)
}XFSBL_CSU_DMA_STATUS;
/**
* Definition for DMA Control reg bits.
*/
typedef enum
{
XFSBL_CSU_DMA_CTRL_PAUSE_MEM = (0x1U << 0x0U),
XFSBL_CSU_DMA_CTRL_PAUSE_STREAM = (0x1U << 0x1U),
XFSBL_CSU_DMA_CTRL_FIFO_THRESH_SHIFT = 0x2U,
XFSBL_CSU_DMA_CTRL_TIMEOUT_SHIFT = 10U,
XFSBL_CSU_DMA_CTRL_AXI_BURST_INCR = (0x0U << 22U),
XFSBL_CSU_DMA_CTRL_AXI_BURST_FIXED = (0x1U << 22U),
XFSBL_CSU_DMA_CTRL_ENDIANNESS = (0x1U << 23U),
XFSBL_CSU_DMA_CTRL_ERR_RESPONSE = (0x1U << 24U),
XFSBL_CSU_DMA_CTRL_IF_FIFO_THRESH_SHIFT = 25U
}XFSBL_CSU_DMA_CTRL;
/**
* Definition for DMA Interrupt reg bits.
*/
typedef enum
{
XFSBL_CSU_DMA_INT_INVALID_APB_ACCESS = (0x1U << 0x5U),
XFSBL_CSU_DMA_INT_FIFO_THRESH_HIT = (0x1U << 0x4U),
XFSBL_CSU_DMA_INT_DMA_TIMEOUT = (0x1U << 0x3U),
XFSBL_CSU_DMA_INT_AXI_RD__ERR = (0x1U << 0x2U),
XFSBL_CSU_DMA_INT_DMA_DONE = (0x1U << 0x1U),
XFSBL_CSU_DMA_INT_DMA_MEM_DONE = (0x1U << 0x0U)
}XFSBL_CSU_DMA_INT;
/*
* Definition for SSS reg Source bits.
*/
typedef enum
{
XFSBL_CSU_SSS_SRC_PCAP = 0x3U,
XFSBL_CSU_SSS_SRC_SRC_DMA = 0x5U,
XFSBL_CSU_SSS_SRC_AES = 0xAU,
XFSBL_CSU_SSS_SRC_PSTP = 0xCU,
XFSBL_CSU_SSS_SRC_NONE = 0x0U,
XFSBL_CSU_SSS_SRC_MASK = 0xFU
}XFSBL_CSU_SSS_SRC;
/**
* Definition for SSS reg Destination bits.
*/
typedef enum
{
XFSBL_CSU_SSS_PCAP_SHIFT = 0U,
XFSBL_CSU_SSS_DMA_SHIFT = 4U,
XFSBL_CSU_SSS_AES_SHIFT = 8U,
XFSBL_CSU_SSS_SHA_SHIFT = 12U,
XFSBL_CSU_SSS_PSTP_SHIFT = 16U
}XFSBL_CSU_SSS_DEST_SHIFT;
/**************************** Macros Definitions *****************************/
/**
* Definition for DMA inline functions
*/
static inline void XFsbl_DmaControl(XFSBL_CSU_DMA_CHANNEL Channel, u32 Val)
{
XFsbl_Out32((CSUDMA_BASEADDR + Channel + XFSBL_CSU_DMA_CTRL_REG), Val);
}
static inline void XFsbl_DmaEndian(XFSBL_CSU_DMA_CHANNEL Channel, u32 Enable)
{
u32 Value = XFsbl_In32(CSUDMA_BASEADDR + Channel + XFSBL_CSU_DMA_CTRL_REG);
if(Enable)
{
Value |= XFSBL_CSU_DMA_CTRL_ENDIANNESS;
}
else
{
Value &= ~XFSBL_CSU_DMA_CTRL_ENDIANNESS;
}
XFsbl_Out32((CSUDMA_BASEADDR + Channel + XFSBL_CSU_DMA_CTRL_REG), Value);
}
static inline int XFsbl_DmaIsBusy(XFSBL_CSU_DMA_CHANNEL Channel)
{
return (XFsbl_In32(CSUDMA_BASEADDR + Channel + XFSBL_CSU_DMA_STATUS_REG) &
XFSBL_CSU_DMA_STATUS_BUSY);
}
static inline unsigned int XFsbl_DmaDoneCount(XFSBL_CSU_DMA_CHANNEL Channel)
{
u32 Count;
Count = XFsbl_In32(CSUDMA_BASEADDR + Channel + XFSBL_CSU_DMA_STATUS_REG);
Count &= XFSBL_CSU_DMA_STATUS_DONE_CNT_MASK;
Count >>= XFSBL_CSU_DMA_STATUS_DONE_CNT_SHIFT;
return Count;
}
static inline void XFsbl_DmaZeroDoneCount(XFSBL_CSU_DMA_CHANNEL Channel)
{
XFsbl_Out32(CSUDMA_BASEADDR + Channel + XFSBL_CSU_DMA_STATUS_REG,
XFSBL_CSU_DMA_STATUS_DONE_CNT_MASK);
/** ASM Code */
mb();
}
/* The CRC function is only available on SRC channels. */
static inline u32 XFsbl_DmaSrcGetCrc(void)
{
return (XFsbl_In32(CSUDMA_BASEADDR + XFSBL_CSU_DMA_SRC +
XFSBL_CSU_DMA_CRC_REG));
}
static inline void XFsbl_DmaSrcSetCrc(u32 Crc)
{
XFsbl_Out32(CSUDMA_BASEADDR + XFSBL_CSU_DMA_SRC +
XFSBL_CSU_DMA_CRC_REG, Crc);
/** ASM Code */
mb();
}
void XFsbl_CsuDmaWaitForDone(XFSBL_CSU_DMA_CHANNEL Channel);
void XFsbl_CsuDmaStart(XFSBL_CSU_DMA_CHANNEL Channel, u32 Addr, u32 Size);
void XFsbl_CsuDmaXfer(u32 SrcAddr, u32 DestAddr, u32 ImgLen);
/**
* Definition for SSS inline functions
*/
static inline u32 XFsbl_SssInputPcap(XFSBL_CSU_SSS_SRC Src)
{
Src &= XFSBL_CSU_SSS_SRC_MASK;
return (Src << XFSBL_CSU_SSS_PCAP_SHIFT);
}
static inline u32 XFsbl_SssInputDstDma(XFSBL_CSU_SSS_SRC Src)
{
Src &= XFSBL_CSU_SSS_SRC_MASK;
return (Src << XFSBL_CSU_SSS_DMA_SHIFT);
}
static inline u32 XFsbl_SssInputAes(XFSBL_CSU_SSS_SRC Src)
{
Src &= XFSBL_CSU_SSS_SRC_MASK;
return (Src << XFSBL_CSU_SSS_AES_SHIFT);
}
static inline u32 XFsbl_SssInputSha3(XFSBL_CSU_SSS_SRC Src)
{
Src &= XFSBL_CSU_SSS_SRC_MASK;
return (Src << XFSBL_CSU_SSS_SHA_SHIFT);
}
static inline u32 XFsbl_SssInputPstp(XFSBL_CSU_SSS_SRC Src)
{
Src &= XFSBL_CSU_SSS_SRC_MASK;
return (Src << XFSBL_CSU_SSS_PSTP_SHIFT);
}
static inline void XFsbl_SssSetup(u32 Cfg)
{
XFsbl_Out32(CSU_CSU_SSS_CFG, Cfg);
}
#endif /* XFSBL_CSU_DMA_H*/

View file

@ -0,0 +1,102 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
*****************************************************************************/
/*****************************************************************************/
/**
*
* @file xfsbl_debug.h
*
* This file contains the debug verbose information for FSBL print functionality
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00a kc 11/05/13 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
#ifndef XFSBL_DEBUG_H
#define XFSBL_DEBUG_H
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_printf.h"
#include "xfsbl_config.h"
#include "xil_types.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
/**
* Debug levels for FSBL
*/
#define DEBUG_GENERAL (0x00000001U) /* general debug messages */
#define DEBUG_INFO (0x00000002U) /* More debug information */
#define DEBUG_DETAILED (0x00000004U) /* More debug information */
#if defined (FSBL_DEBUG_DETAILED)
#define XFsblDbgCurrentTypes ((DEBUG_DETAILED) | (DEBUG_INFO) | (DEBUG_GENERAL))
#elif defined (FSBL_DEBUG_INFO)
#define XFsblDbgCurrentTypes ((DEBUG_INFO) | (DEBUG_GENERAL))
#elif defined (FSBL_DEBUG)
#define XFsblDbgCurrentTypes (DEBUG_GENERAL)
#else
#define XFsblDbgCurrentTypes (0U)
#endif
#if 0
__inline void XFsbl_Printf(u32 DebugType,char *Format, ...);
#else
#define XFsbl_Printf(DebugType,...) \
if (((DebugType) & XFsblDbgCurrentTypes) != 0U) {xil_printf (__VA_ARGS__); }
#endif
#ifdef __cplusplus
}
#endif
#endif /* XFSBL_DEBUG_H */

View file

@ -0,0 +1,164 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xfsbl_error.h
*
* This is the header file which contains error codes for the FSBL.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 kc 10/21/13 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
#ifndef XFSBL_ERROR_H
#define XFSBL_ERROR_H
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
/************************** Constant Definitions *****************************/
/**
* @name FSBL error codes description
*
* XXYY - Error code format
*
* YY - error code irrespective of stage
*
* XX -> x1 x2 x3 x4 x5 x6 x7 x8
*
* x1 -> FSBL / CSUROM error
* x2x3 -> Stage at which error happened
* 00 -> Error at stage 1
* 01 -> Error at stage 2
* 10 -> Error at stage 3
* 11 -> Error at stage 4
* x4x5x6 -> Error source for next 10 bits
* 000 -> FSBL error code
* 001 -> ps8 init failure
* 010 -> ps8 postconfig failure
* 011 -> Driver error code
* x7x8 ->
*/
#define XFSBL_ERROR_STAGE_1 (0x0000U)
#define XFSBL_ERROR_STAGE_2 (0x2000U)
#define XFSBL_ERROR_STAGE_3 (0x4000U)
#define XFSBL_ERROR_STAGE_4 (0x6000U)
#define XFSBL_PS8_INIT_FAILED (0x0800U)
#define XFSBL_PS8_POSTCONFIG_FAILED (0x1000U)
#define XFSBL_SUCCESS (0x0U)
#define XFSBL_STATUS_JTAG (0x1U)
#define XFSBL_SUCCESS_NOT_PARTITION_OWNER (0x2U)
#define XFSBL_ERROR_UNSUPPORTED_BOOT_MODE (0x6U)
#define XFSBL_WDT_INIT_FAILED (0x7U)
#define XFSBL_INVALID_DEST_CPU (0x8U)
#define XFSBL_ERROR_SYSTEM_WDT_RESET (0x9U)
#define XFSBL_ERROR_QSPI_READ_ID (0xAU)
#define XFSBL_ERROR_UNSUPPORTED_QSPI (0xBU)
#define XFSBL_ERROR_QSPI_INIT (0xCU)
#define XFSBL_ERROR_NO_OF_PARTITIONS (0xDU)
#define XFSBL_ERROR_PPD (0xEU)
#define XFSBL_ERROR_XIP_AUTH_ENC_PRESENT (0xFU)
#define XFSBL_ERROR_XIP_EXEC_ADDRESS (0x10U)
#define XFSBL_ERROR_PARTITION_LENGTH (0x11U)
#define XFSBL_ERROR_INVALID_CHECKSUM_TYPE (0x12U)
#define XFSBL_ERROR_INVALID_CPU_TYPE (0x13U)
#define XFSBL_ERROR_LS_CPU_TYPE (0x14U)
#define XFSBL_ERROR_INVALID_DEST_DEVICE (0x15U)
#define XFSBL_ERROR_INVALID_LOAD_ADDRESS (0x16U)
#define XFSBL_ERROR_PH_CHECKSUM_FAILED (0x17U)
#define XFSBL_ERROR_PWR_UP_CPU (0x18U)
#define XFSBL_ERROR_QSPI_LENGTH (0x19U)
#define XFSBL_ERROR_INVALID_QSPI_CONNECTION (0x1AU)
#define XFSBL_ERROR_UNDEFINED_EXCEPTION (0x1BU)
#define XFSBL_ERROR_SVC_EXCEPTION (0x1CU)
#define XFSBL_ERROR_PREFETCH_ABORT_EXCEPTION (0x1DU)
#define XFSBL_ERROR_DATA_ABORT_EXCEPTION (0x1EU)
#define XFSBL_ERROR_IRQ_EXCEPTION (0x1FU)
#define XFSBL_ERROR_FIQ_EXCEPTION (0x20U)
#define XFSBL_ERROR_IHT_CHECKSUM (0x21U)
#define XFSBL_ERROR_QSPI_READ (0x22U)
#define XFSBL_ERROR_HANDOFF_CPUID (0x23U)
#define XFSBL_ERROR_LOAD_ADDRESS (0x24U)
#define XFSBL_ERROR_HOOK_BEFORE_BITSTREAM_DOWNLOAD (0x25U)
#define XFSBL_ERROR_HOOK_AFTER_BITSTREAM_DOWNLOAD (0x26U)
#define XFSBL_ERROR_HOOK_BEFORE_HANDOFF (0x27U)
#define XFSBL_ERROR_SD_INIT (0x28U)
#define XFSBL_ERROR_SD_F_OPEN (0x29U)
#define XFSBL_ERROR_SD_F_LSEEK (0x2AU)
#define XFSBL_ERROR_SD_F_READ (0x2BU)
#define XFSBL_ERROR_NAND_INIT (0x2CU)
#define XFSBL_ERROR_NAND_READ (0x2DU)
#define XFSBL_ERROR_ADDRESS (0x2EU)
#define XFSBL_ERROR_RSA_NOT_ENABLED (0x2DU)
#define XFSBL_ERROR_SPK_RSA_DECRYPT (0x2FU)
#define XFSBL_ERROR_SPK_SIGNATURE (0x30U)
#define XFSBL_ERROR_PART_RSA_DECRYPT (0x31U)
#define XFSBL_ERROR_PART_SIGNATURE (0x32U)
#define XFSBL_ERROR_DDR_INIT_FAIL (0x33U)
#define XFSBL_FAILURE (0x3FFU)
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
#ifdef __cplusplus
}
#endif
#endif /* XFSBL_ERROR_H */

View file

@ -0,0 +1,141 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
*******************************************************************************/
/*****************************************************************************/
/**
*
* @file xfsbl_exit.s
*
* This is the main file which contains exit code for the FSBL.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 kc 11/13/13 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
/***************************** Include Files *********************************/
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
.globl XFsbl_Exit
/************************** Variable Definitions *****************************/
XFsbl_Exit:
#ifndef XFSBL_A53
mov lr, r0 /* move the destination address into link register */
mcr 15,0,r0,cr7,cr5,0 /* Invalidate Instruction cache */
mcr 15,0,r0,cr7,cr5,6 /* Invalidate branch predictor array */
dsb
isb /* make sure it completes */
mrc p15,0,r4,c1,c0,0 /* Read SCTLR */
bic r4, r4, #0x04 /* disable L1 I Cache */
bic r4, r4, #0x1000 /* Disable L1 D Cache */
mcr 15,0,r4,cr1,cr0,0 /* disable the DCache, ICache */
isb /* make sure it completes */
/* set exception vector to HIVEC */
/* this is done because, in LOVEC we can not disable the MPU as */
/* OCM region is not present in default MPU regions when in LOVEC*/
mrc p15, 0, r0, c1, c0, 0 /* Read SCTLR */
orr r0, r0, #0x2000
mcr 15, 0, r0, cr1, cr0, 0
isb
/* disable the MPU */
mrc p15,0,r4,c1,c0,0 /* Read SCTLR */
bic r4, r4, #0x01
mcr 15,0,r4,cr1,cr0,0
isb
cmp r1,#0
bne XFsbl_StartApp
#else
mov x30, x0 /* move the destination address into x30 register */
tlbi ALLE3 /* invalidate All E3 translation tables */
ic IALLU /* invalidate I Cache All to PoU, Inner Shareable */
dsb sy
isb /* make sure it completes */
mrs x5, SCTLR_EL3 /* Read control register */
mov x6, #0x1005 /* D, I , M bits disable */
bic x5, x5, x6 /* Disable MMU, L1 and L2 I/D cache */
msr SCTLR_EL3, x5 /* */
isb
cmp x1, #0 /* exit to wfe */
beq XFsbl_Loop
cmp x1, #1 /* x1 is 1 - exit in aarch64 */
beq XFsbl_StartApp
/* x1 is 2 - exit in aarch32 */
mov x2, #3 /* request for warm reset and aarch32 */
msr RMR_EL3,x2 /* write to reset management register */
isb
#endif
XFsbl_Loop:
wfe /* wait for event */
b XFsbl_Loop
.Ldone:
b .Ldone /* Paranoia: we should never get here */
XFsbl_StartApp:
#ifdef XFSBL_A53
br x30 /* branch to */
#else
bx lr;
#endif
.end

View file

@ -0,0 +1,867 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xfsbl_handoff.c
*
* This is the main file which contains handoff code for the FSBL.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 kc 10/21/13 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xfsbl_hw.h"
#include "xil_cache.h"
#include "pss_init.h"
#include "xfsbl_main.h"
#include "xfsbl_image_header.h"
/************************** Constant Definitions *****************************/
#define XFSBL_CPU_POWER_UP (0x1U)
#define XFSBL_CPU_SWRST (0x2U)
/**
* Aarch32 or Aarch64 CPU definitions
*/
#define APU_CONFIG_0_AA64N32_MASK_CPU0 (0x1U)
#define APU_CONFIG_0_AA64N32_MASK_CPU1 (0x2U)
#define APU_CONFIG_0_AA64N32_MASK_CPU2 (0x4U)
#define APU_CONFIG_0_AA64N32_MASK_CPU3 (0x8U)
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
#define XFSBL_IVT_ADDRESS (0xFFFF0000U)
#define XFSBL_HANDOFF_ADDR_PTR (0xFFFFFF00U)
#define XFSBL_HANDOFF_FLAG_ADDR (0xFFFFFF80U)
/************************** Function Prototypes ******************************/
static u32 XFsbl_SetCpuPwrSettings (u32 CpuSettings, u32 Flags);
static void XFsbl_UpdateResetVector (u64 HandOffAddress, u32 CpuSettings);
static void XFsbl_CopyIVT(u32 CpuSettings);
static int XFsbl_Is32BitCpu(u32 CpuSettings);
/**
* Functions defined in xfsbl_handoff.S
*/
extern void XFsbl_Exit(PTRSIZE HandoffAddress, u32 Flags);
/************************** Variable Definitions *****************************/
/**
* Variabled defined in xfsbl_partition_load.c
*/
extern u8 TcmVectorArray[32];
extern u32 TcmSkipLength;
extern PTRSIZE TcmSkipAddress;
int XFsbl_Is32BitCpu(u32 CpuSettings)
{
int Status;
u32 CpuId=0U;
u32 ExecState=0U;
CpuId = CpuSettings & XIH_PH_ATTRB_DEST_CPU_MASK;
ExecState = CpuSettings & XIH_PH_ATTRB_A53_EXEC_ST_MASK;
if ((CpuId == XIH_PH_ATTRB_DEST_CPU_R5_0) ||
(CpuId == XIH_PH_ATTRB_DEST_CPU_R5_1) ||
(CpuId == XIH_PH_ATTRB_DEST_CPU_R5_L) ||
(ExecState == XIH_PH_ATTRB_A53_EXEC_ST_AA32))
{
Status = TRUE;
} else {
Status = FALSE;
}
return Status;
}
/****************************************************************************/
/**
* This function will set up the settings for the CPU's
* This can power up the CPU or do a soft reset to the CPU's
*
* @param CpuId specifies for which CPU settings should be done
*
* @param Flags is used to specify the settings for the CPU
* XFSBL_CPU_POWER_UP - This is used to power up the CPU
* XFSBL_CPU_SWRST - This is used to trigger the reset to CPU
*
* @return
* - XFSBL_SUCCESS on successful settings
* - XFSBL_FAILURE
*
* @note
*
*****************************************************************************/
static u32 XFsbl_SetCpuPwrSettings (u32 CpuSettings, u32 Flags)
{
u32 RegValue=0U;
u32 Status=XFSBL_SUCCESS;
u32 CpuId=0U;
u32 ExecState=0U;
CpuId = CpuSettings & XIH_PH_ATTRB_DEST_CPU_MASK;
ExecState = CpuSettings & XIH_PH_ATTRB_A53_EXEC_ST_MASK;
/**
* Reset the CPU
*/
if ((Flags & XFSBL_CPU_SWRST) != 0U)
{
switch(CpuId)
{
case XIH_PH_ATTRB_DEST_CPU_A53_0:
/**
* Set to Aarch32 if enabled
*/
if (ExecState == XIH_PH_ATTRB_A53_EXEC_ST_AA32)
{
RegValue = XFsbl_In32(APU_CONFIG_0);
RegValue &= ~(APU_CONFIG_0_AA64N32_MASK_CPU0);
XFsbl_Out32(APU_CONFIG_0, RegValue);
}
/**
* Release reset
*/
RegValue = XFsbl_In32(CRF_APB_RST_FPD_APU);
RegValue &= ~(CRF_APB_RST_FPD_APU_ACPU0_RESET_MASK);
RegValue &= ~(CRF_APB_RST_FPD_APU_APU_L2_RESET_MASK);
XFsbl_Out32(CRF_APB_RST_FPD_APU, RegValue);
/**
* Enable the clock
*/
RegValue = XFsbl_In32(CRF_APB_ACPU_CTRL);
RegValue |= (CRF_APB_ACPU_CTRL_CLKACT_FULL_MASK |
CRF_APB_ACPU_CTRL_CLKACT_HALF_MASK);
XFsbl_Out32(CRF_APB_ACPU_CTRL, RegValue);
break;
case XIH_PH_ATTRB_DEST_CPU_A53_1:
/**
* Set to Aarch32 if enabled
*/
if (ExecState == XIH_PH_ATTRB_A53_EXEC_ST_AA32)
{
RegValue = XFsbl_In32(APU_CONFIG_0);
RegValue &= ~(APU_CONFIG_0_AA64N32_MASK_CPU1);
XFsbl_Out32(APU_CONFIG_0, RegValue);
}
/**
* Release reset
*/
RegValue = XFsbl_In32(CRF_APB_RST_FPD_APU);
RegValue &= ~(CRF_APB_RST_FPD_APU_ACPU1_RESET_MASK);
RegValue &= ~(CRF_APB_RST_FPD_APU_APU_L2_RESET_MASK);
XFsbl_Out32(CRF_APB_RST_FPD_APU, RegValue);
/**
* Enable the clock
*/
RegValue = XFsbl_In32(CRF_APB_ACPU_CTRL);
RegValue |= (CRF_APB_ACPU_CTRL_CLKACT_FULL_MASK |
CRF_APB_ACPU_CTRL_CLKACT_HALF_MASK);
XFsbl_Out32(CRF_APB_ACPU_CTRL, RegValue);
break;
case XIH_PH_ATTRB_DEST_CPU_A53_2:
/**
* Set to Aarch32 if enabled
*/
if (ExecState == XIH_PH_ATTRB_A53_EXEC_ST_AA32)
{
RegValue = XFsbl_In32(APU_CONFIG_0);
RegValue &= ~(APU_CONFIG_0_AA64N32_MASK_CPU2);
XFsbl_Out32(APU_CONFIG_0, RegValue);
}
/**
* Release reset
*/
RegValue = XFsbl_In32(CRF_APB_RST_FPD_APU);
RegValue &= ~(CRF_APB_RST_FPD_APU_ACPU2_RESET_MASK);
RegValue &= ~(CRF_APB_RST_FPD_APU_APU_L2_RESET_MASK);
XFsbl_Out32(CRF_APB_RST_FPD_APU, RegValue);
/**
* Enable the clock
*/
RegValue = XFsbl_In32(CRF_APB_ACPU_CTRL);
RegValue |= (CRF_APB_ACPU_CTRL_CLKACT_FULL_MASK |
CRF_APB_ACPU_CTRL_CLKACT_HALF_MASK);
XFsbl_Out32(CRF_APB_ACPU_CTRL, RegValue);
break;
case XIH_PH_ATTRB_DEST_CPU_A53_3:
/**
* Set to Aarch32 if enabled
*/
if (ExecState == XIH_PH_ATTRB_A53_EXEC_ST_AA32)
{
RegValue = XFsbl_In32(APU_CONFIG_0);
RegValue &= ~(APU_CONFIG_0_AA64N32_MASK_CPU3);
XFsbl_Out32(APU_CONFIG_0, RegValue);
}
/**
* Release reset
*/
RegValue = XFsbl_In32(CRF_APB_RST_FPD_APU);
RegValue &= ~(CRF_APB_RST_FPD_APU_ACPU3_RESET_MASK);
RegValue &= ~(CRF_APB_RST_FPD_APU_APU_L2_RESET_MASK);
XFsbl_Out32(CRF_APB_RST_FPD_APU, RegValue);
/**
* Enable the clock
*/
RegValue = XFsbl_In32(CRF_APB_ACPU_CTRL);
RegValue |= (CRF_APB_ACPU_CTRL_CLKACT_FULL_MASK |
CRF_APB_ACPU_CTRL_CLKACT_HALF_MASK);
XFsbl_Out32(CRF_APB_ACPU_CTRL, RegValue);
break;
case XIH_PH_ATTRB_DEST_CPU_R5_0:
/**
* Place R5, TCM's in split mode
*/
RegValue = XFsbl_In32(RPU_RPU_GLBL_CNTL);
RegValue |= (RPU_RPU_GLBL_CNTL_SLSPLIT_MASK);
RegValue &= ~(RPU_RPU_GLBL_CNTL_TCM_COMB_MASK);
RegValue &= ~(RPU_RPU_GLBL_CNTL_SLCLAMP_MASK);
XFsbl_Out32(RPU_RPU_GLBL_CNTL, RegValue);
/**
* Place R5-0 in HALT state
*/
RegValue = XFsbl_In32(RPU_RPU_0_CFG);
RegValue &= ~(RPU_RPU_0_CFG_NCPUHALT_MASK);
XFsbl_Out32(RPU_RPU_0_CFG, RegValue);
/**
* Enable the clock
*/
RegValue = XFsbl_In32(CRL_APB_CPU_R5_CTRL);
RegValue |= (CRL_APB_CPU_R5_CTRL_CLKACT_MASK);
XFsbl_Out32(CRL_APB_CPU_R5_CTRL, RegValue);
/**
* Provide some delay,
* so that clock propogates properly.
*/
//Status = usleep(0x50U);
(void)usleep(0x50U);
/**
* Release reset to R5-0
*/
RegValue = XFsbl_In32(CRL_APB_RST_LPD_TOP);
RegValue &= ~(CRL_APB_RST_LPD_TOP_RPU_R50_RESET_MASK);
RegValue &= ~(CRL_APB_RST_LPD_TOP_RPU_AMBA_RESET_MASK);
XFsbl_Out32(CRL_APB_RST_LPD_TOP, RegValue);
/**
* Take R5-0 out of HALT state
*/
RegValue = XFsbl_In32(RPU_RPU_0_CFG);
RegValue |= RPU_RPU_0_CFG_NCPUHALT_MASK;
XFsbl_Out32(RPU_RPU_0_CFG, RegValue);
break;
case XIH_PH_ATTRB_DEST_CPU_R5_1:
/**
* Place R5, TCM's in split mode
*/
RegValue = XFsbl_In32(RPU_RPU_GLBL_CNTL);
RegValue |= RPU_RPU_GLBL_CNTL_SLSPLIT_MASK;
RegValue &= ~(RPU_RPU_GLBL_CNTL_TCM_COMB_MASK);
RegValue &= ~(RPU_RPU_GLBL_CNTL_SLCLAMP_MASK);
XFsbl_Out32(RPU_RPU_GLBL_CNTL, RegValue);
/**
* Place R5-1 in HALT state
*/
RegValue = XFsbl_In32(RPU_RPU_1_CFG);
RegValue &= ~(RPU_RPU_1_CFG_NCPUHALT_MASK);
XFsbl_Out32(RPU_RPU_1_CFG, RegValue);
/**
* Enable the clock
*/
RegValue = XFsbl_In32(CRL_APB_CPU_R5_CTRL);
RegValue |= CRL_APB_CPU_R5_CTRL_CLKACT_MASK;
XFsbl_Out32(CRL_APB_CPU_R5_CTRL, RegValue);
/**
* Provide some delay,
* so that clock propogates properly.
*/
//Status = usleep(0x50U);
(void)usleep(0x50U);
/**
* Release reset to R5-1
*/
RegValue = XFsbl_In32(CRL_APB_RST_LPD_TOP);
RegValue &= ~(CRL_APB_RST_LPD_TOP_RPU_R51_RESET_MASK);
RegValue &= ~(CRL_APB_RST_LPD_TOP_RPU_AMBA_RESET_MASK);
XFsbl_Out32(CRL_APB_RST_LPD_TOP, RegValue);
/**
* Take R5-1 out of HALT state
*/
RegValue = XFsbl_In32(RPU_RPU_1_CFG);
RegValue |= RPU_RPU_1_CFG_NCPUHALT_MASK;
XFsbl_Out32(RPU_RPU_1_CFG, RegValue);
break;
case XIH_PH_ATTRB_DEST_CPU_R5_L:
/**
* Place R5, TCM's in safe mode
*/
RegValue = XFsbl_In32(RPU_RPU_GLBL_CNTL);
RegValue &= ~(RPU_RPU_GLBL_CNTL_SLSPLIT_MASK);
RegValue |= RPU_RPU_GLBL_CNTL_TCM_COMB_MASK;
RegValue |= RPU_RPU_GLBL_CNTL_SLCLAMP_MASK;
XFsbl_Out32(RPU_RPU_GLBL_CNTL, RegValue);
/**
* Place R5-0 in HALT state
*/
RegValue = XFsbl_In32(RPU_RPU_0_CFG);
RegValue &= ~(RPU_RPU_0_CFG_NCPUHALT_MASK);
XFsbl_Out32(RPU_RPU_0_CFG, RegValue);
/**
* Place R5-1 in HALT state
*/
RegValue = XFsbl_In32(RPU_RPU_1_CFG);
RegValue &= ~(RPU_RPU_1_CFG_NCPUHALT_MASK);
XFsbl_Out32(RPU_RPU_1_CFG, RegValue);
/**
* Enable the clock
*/
RegValue = XFsbl_In32(CRL_APB_CPU_R5_CTRL);
RegValue |= CRL_APB_CPU_R5_CTRL_CLKACT_MASK;
XFsbl_Out32(CRL_APB_CPU_R5_CTRL, RegValue);
/**
* Provide some delay,
* so that clock propogates properly.
*/
//Status = usleep(0x50U);
(void )usleep(0x50U);
/**
* Release reset to R5-0, R5-1
*/
RegValue = XFsbl_In32(CRL_APB_RST_LPD_TOP);
RegValue &= ~(CRL_APB_RST_LPD_TOP_RPU_R50_RESET_MASK);
RegValue &= ~(CRL_APB_RST_LPD_TOP_RPU_R51_RESET_MASK);
RegValue &= ~(CRL_APB_RST_LPD_TOP_RPU_AMBA_RESET_MASK);
XFsbl_Out32(CRL_APB_RST_LPD_TOP, RegValue);
/**
* Take R5-0 out of HALT state
*/
RegValue = XFsbl_In32(RPU_RPU_0_CFG);
RegValue |= RPU_RPU_0_CFG_NCPUHALT_MASK;
XFsbl_Out32(RPU_RPU_0_CFG, RegValue);
/**
* Take R5-1 out of HALT state
*/
RegValue = XFsbl_In32(RPU_RPU_1_CFG);
RegValue |= RPU_RPU_1_CFG_NCPUHALT_MASK;
XFsbl_Out32(RPU_RPU_1_CFG, RegValue);
break;
default:
XFsbl_Printf(DEBUG_GENERAL,
"XFSBL_ERROR_HANDOFF_CPUID\n\r");
Status = XFSBL_ERROR_HANDOFF_CPUID;
break;
}
}
return Status;
}
/****************************************************************************/
/**
* FSBL exit function before the assembly code
*
* @param HandoffAddress is handoff address for the FSBL running cpu
*
* @param Flags is to determine whether to handoff to applicatio or
* to be in wfe state
*
* @return None
*
*
*****************************************************************************/
void XFsbl_HandoffExit(u64 HandoffAddress, u32 Flags)
{
/**
* Flush the L1 data cache and L2 cache
*/
Xil_DCacheFlush();
/**
* Disable Data Cache
*/
Xil_DCacheDisable();
XFsbl_Printf(DEBUG_GENERAL,"Exit from FSBL \n\r");
/**
* Exit to handoff address
* PTRSIZE is used since handoff is in same running cpu
* and address is of PTRSIZE
*/
XFsbl_Exit((PTRSIZE) HandoffAddress, Flags);
/**
* should not reach here
*/
return ;
}
/****************************************************************************/
/**
*
* @param
*
* @return
*
* @note
*
*
*****************************************************************************/
static void XFsbl_UpdateResetVector (u64 HandOffAddress, u32 CpuSettings)
{
u32 HandOffAddressLow=0U;
u32 HandOffAddressHigh=0U;
u32 LowAddressReg=0U;
u32 HighAddressReg=0U;
u32 CpuId;
CpuId = CpuSettings & XIH_PH_ATTRB_DEST_CPU_MASK;
/**
* copy the IVT to 0xffff0000
*/
XFsbl_CopyIVT(CpuSettings);
/**
* Writing u64/u32 will be decided on the handoff Cpu
*/
if (XFsbl_Is32BitCpu(CpuSettings) == TRUE)
{
/**
* for R5 cpu, write 32bit handoff address
*/
XFsbl_Out32(XFSBL_HANDOFF_ADDR_PTR,
(u32 )HandOffAddress);
} else {
/**
* for A53 cpu, write 64bit handoff address
* to the RVBARADDR in APU
*/
HandOffAddressLow = (u32 )(HandOffAddress & 0xFFFFFFFFU);
HandOffAddressHigh = (u32 )((HandOffAddress>>32)
& 0xFFFFFFFFU);
switch (CpuId)
{
case XIH_PH_ATTRB_DEST_CPU_A53_0:
LowAddressReg = APU_RVBARADDR0L;
HighAddressReg = APU_RVBARADDR0H;
break;
case XIH_PH_ATTRB_DEST_CPU_A53_1:
LowAddressReg = APU_RVBARADDR1L;
HighAddressReg = APU_RVBARADDR1H;
break;
case XIH_PH_ATTRB_DEST_CPU_A53_2:
LowAddressReg = APU_RVBARADDR2L;
HighAddressReg = APU_RVBARADDR2H;
break;
case XIH_PH_ATTRB_DEST_CPU_A53_3:
LowAddressReg = APU_RVBARADDR3L;
HighAddressReg = APU_RVBARADDR3H;
break;
default:
/**
* error can be triggered here
*/
break;
}
XFsbl_Out32(LowAddressReg, HandOffAddressLow);
XFsbl_Out32(HighAddressReg, HandOffAddressHigh);
}
return;
}
/****************************************************************************/
/**
* This function will copy the Arm predefined code to the Reset IVT address
*
* @param CpuId is used to determine which arm predefined code to be loaded
Supports R5, A53/A53 processors
*
* @return
*
* @note
*
*****************************************************************************/
static void XFsbl_CopyIVT(u32 CpuSettings)
{
u32 Index=0U;
const u32 XFsbl_ArmR5PredefinedCode[] =
{
/**
* 1. Move 0xffffff00 to r0
* 2. load value stored in r0 to lr
* 3. dsb
* 4. isb
* 5. Move 0xAA to r1
* 6. Move 0xffffff80 to r0
* 7. str r1 to [r0]
* 8. dsb
* 9. isb
* 10. branch to lr
*/
/* mvn r0, #255 */
0xE3E000FFU,
/* ldr lr, [r0] */
0xE590E000U,
/* dsb */
0xF57FF04FU,
/* isb */
0xF57FF06FU,
/* mov r1, #170 */
0xE3A010AAU,
/* mvn r0, #127 */
0xE3E0007FU,
/* str r1, [r0] */
0xE5801000U,
/* dsb */
0xF57FF04FU,
/* isb */
0xF57FF06FU,
/* bx lr */
0xE12FFF1EU
};
/**
* Load the predefined ARM code to the reset vector address
* For R5 load the R5 code otherwise A53 code
*/
if (XFsbl_Is32BitCpu(CpuSettings) == TRUE)
{
/**
* Load R5 code
*/
for (Index=0U;Index<10U;Index++)
{
XFsbl_Out32(XFSBL_IVT_ADDRESS + (Index*4U),
XFsbl_ArmR5PredefinedCode[Index]);
}
}
return;
}
/*****************************************************************************/
/**
* This function handoff the images to the respective cpu's
*
* @param FsblInstancePtr is pointer to the XFsbl Instance
*
* @return returns the error codes described in xfsbl_error.h on any error
*
* @note This function should not return incase of success
*
*****************************************************************************/
u32 XFsbl_Handoff (XFsblPs * FsblInstancePtr)
{
u32 Status=XFSBL_SUCCESS;
u32 CpuIndex=0U;
u32 CpuId=0U;
u32 ExecState=0U;
u32 CpuSettings=0U;
u64 HandoffAddress=0U;
u64 RunningCpuHandoffAddress=0U;
u32 RunningCpuExecState=0U;
s32 RunningCpuHandoffAddressPresent=FALSE;
/**
* post config from ps8_init.c
*/
/**
* if JTAG bootmode, be in while loop as of now
* Check if Process can be parked in HALT state
*/
if (FsblInstancePtr->PrimaryBootDevice ==
XFSBL_JTAG_BOOT_MODE)
{
/**
* Mark Error status with Fsbl completed
*/
XFsbl_Out32(XFSBL_ERROR_STATUS_REGISTER_OFFSET,
XFSBL_COMPLETED);
if (XFSBL_PLATFORM == XFSBL_PLATFORM_VELOCE)
{
/**
* Flush the L1 data cache and L2 cache
*/
Xil_DCacheFlush();
/**
* Disable Data Cache
*/
Xil_DCacheDisable();
XFsbl_Printf(DEBUG_GENERAL,"VeloceExit from FSBL \n\r");
#ifdef XFSBL_A53
XFsbl_Out32(0xFFFC0000U, 0x14000000U);
#else
XFsbl_Out32(0xFFFC0000U, 0xEAFFFFFEU);
#endif
XFsbl_Exit(0xFFFC0000U, XFSBL_HANDOFFEXIT);
} else {
/**
* Exit from FSBL
*/
XFsbl_HandoffExit(0U, XFSBL_NO_HANDOFFEXIT);
}
}
/**
* if XIP image present
* Put QSPI in linear mode
*/
/**
* FSBL hook before Handoff
*/
Status = XFsbl_HookBeforeHandoff();
if (Status != XFSBL_SUCCESS)
{
Status = XFSBL_ERROR_HOOK_BEFORE_HANDOFF;
XFsbl_Printf(DEBUG_GENERAL,
"XFSBL_ERROR_HOOK_BEFORE_HANDOFF\r\n");
goto END;
}
/**
* Flush the L1 data cache and L2 cache
*/
Xil_DCacheFlush();
/**
* Disable Data Cache to have smooth data
* transfer between the processors.
* Data transfer is required to update flag for CPU out of reset
*/
Xil_DCacheDisable();
/**
* get cpu out of reset
*
*/
CpuIndex=0U;
while (CpuIndex < FsblInstancePtr->HandoffCpuNo)
{
CpuSettings =
FsblInstancePtr->HandoffValues[CpuIndex].CpuSettings;
CpuId = CpuSettings & XIH_PH_ATTRB_DEST_CPU_MASK;
ExecState = CpuSettings & XIH_PH_ATTRB_A53_EXEC_ST_MASK;
/**
* Check if handoff address is present
*/
if (CpuId != FsblInstancePtr->ProcessorID)
{
/**
* Check for power status of the cpu
* Update the IVT
* Take cpu out of reset
*/
Status = XFsbl_SetCpuPwrSettings(
CpuSettings, XFSBL_CPU_POWER_UP);
if (XFSBL_SUCCESS != Status)
{
XFsbl_Printf(DEBUG_GENERAL,"Power Up "
"Cpu 0x%0lx failed \n\r", CpuId);
XFsbl_Printf(DEBUG_GENERAL,
"XFSBL_ERROR_PWR_UP_CPU\n\r");
Status = XFSBL_ERROR_PWR_UP_CPU;
goto END;
}
/**
* Read the handoff address from structure
*/
HandoffAddress = (u64 )
FsblInstancePtr->HandoffValues[CpuIndex].HandoffAddress;
/**
* Update the handoff address at reset vector address
*/
XFsbl_UpdateResetVector(HandoffAddress, CpuSettings);
XFsbl_Printf(DEBUG_INFO,"CPU 0x%0lx reset release, "
"Exec State 0x%0lx, HandoffAddress: %0lx\n\r",
CpuId, ExecState, (PTRSIZE )HandoffAddress);
/**
* Reset the flag at 0xffffff80
* Write Zero at 0xffffff80
*/
XFsbl_Out32(XFSBL_HANDOFF_FLAG_ADDR, 0U);
/**
* Take CPU out of reset
*/
Status = XFsbl_SetCpuPwrSettings(
CpuSettings, XFSBL_CPU_SWRST);
if (XFSBL_SUCCESS != Status)
{
goto END;
}
/**
* Wait till the CPU executed the
* predefined code for R5
*/
if ((CpuId == XIH_PH_ATTRB_DEST_CPU_R5_0) ||
(CpuId == XIH_PH_ATTRB_DEST_CPU_R5_1) ||
(CpuId == XIH_PH_ATTRB_DEST_CPU_R5_L) )
{
while (XFsbl_In32(XFSBL_HANDOFF_FLAG_ADDR)
!= 0xAAU)
{
/**
* wait for flag
* block for MISRA C compliance
*/
};
}
} else {
/**
* Update the running cpu handoff address
*/
RunningCpuHandoffAddressPresent = TRUE;
RunningCpuHandoffAddress = (u64 )
FsblInstancePtr->HandoffValues[CpuIndex].HandoffAddress;
RunningCpuExecState = ExecState;
}
/**
* Go to the next cpu
*/
CpuIndex++;
}
/**
* Remove the R5 vectors from TCM and load APP data
* if present
*/
if (TcmSkipLength != 0U)
{
XFsbl_MemCpy((u8 *)TcmSkipAddress, TcmVectorArray,
TcmSkipLength);
}
/**
* Mark Error status with Fsbl completed
*/
XFsbl_Out32(XFSBL_ERROR_STATUS_REGISTER_OFFSET, XFSBL_COMPLETED);
/**
* call to the handoff routine
* which will never return
*/
if (RunningCpuHandoffAddressPresent == TRUE)
{
XFsbl_Printf(DEBUG_INFO,
"Running Cpu Handoff address: 0x%0lx, Exec State: %0lx\n\r",
(PTRSIZE )RunningCpuHandoffAddress, RunningCpuExecState);
if (RunningCpuExecState == XIH_PH_ATTRB_A53_EXEC_ST_AA32)
{
XFsbl_HandoffExit(RunningCpuHandoffAddress,
XFSBL_HANDOFFEXIT_32);
} else {
XFsbl_HandoffExit(RunningCpuHandoffAddress,
XFSBL_HANDOFFEXIT);
}
} else {
XFsbl_HandoffExit(0U, XFSBL_NO_HANDOFFEXIT);
}
END:
return Status;
}

View file

@ -0,0 +1,99 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xfsbl_hooks.c
*
* This is the file which contains FSBL hook functions.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 kc 04/21/14 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xfsbl_hw.h"
#include "xfsbl_hooks.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
u32 XFsbl_HookBeforeBSDownload(void )
{
u32 Status = XFSBL_SUCCESS;
/**
* Add the code here
*/
return Status;
}
u32 XFsbl_HookAfterBSDownload(void )
{
u32 Status = XFSBL_SUCCESS;
/**
* Add the code here
*/
return Status;
}
u32 XFsbl_HookBeforeHandoff(void )
{
u32 Status = XFSBL_SUCCESS;
/**
* Add the code here
*/
return Status;
}

View file

@ -0,0 +1,84 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xfsbl_hooks.h
*
* This is the header file which contains definitions for the FSBL hooks
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 kc 10/21/13 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
#ifndef XFSBL_HOOKS_H
#define XFSBL_HOOKS_H
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xfsbl_hw.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
u32 XFsbl_HookBeforeBSDownload(void );
u32 XFsbl_HookAfterBSDownload(void );
u32 XFsbl_HookBeforeHandoff(void );
#ifdef __cplusplus
}
#endif
#endif /* XFSBL_HOOKS_H */

View file

@ -0,0 +1,540 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xfsbl_hw.h
*
* This is the header file which contains definitions for the hardware
* registers.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 kc 10/21/13 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
#ifndef XFSBL_HW_H
#define XFSBL_HW_H
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_io.h"
#include "xparameters.h"
#include "xil_types.h"
#include "sleep.h"
#include "xfsbl_config.h"
#include "xfsbl_debug.h"
#include "xfsbl_error.h"
#include "xfsbl_hooks.h"
#include "xfsbl_misc.h"
/************************** Constant Definitions *****************************/
/* csu */
/**
* CSU Base Address
*/
#define CSU_BASEADDR 0XFFCA0000U
/**
* Register: CSU_CSU_SSS_CFG
*/
#define CSU_CSU_SSS_CFG ( ( CSU_BASEADDR ) + 0X00000008U )
#define CSU_CSU_SSS_CFG_PCAP_SSS_MASK 0X0000000FU
/**
* Register: CSU_PCAP_STATUS
*/
#define CSU_PCAP_STATUS ( ( CSU_BASEADDR ) + 0X00003010U )
/**
* Register: CSU_PCAP_RDWR
*/
#define CSU_PCAP_RDWR ( ( CSU_BASEADDR ) + 0X00003004U )
/**
* Register: CSU_VERSION
*/
#define CSU_VERSION ( ( CSU_BASEADDR ) + 0X00000044U )
#define CSU_VERSION_RTL_VERSION_MASK 0X00000FF0U
#define CSU_VERSION_PLATFORM_MASK 0X0000F000U
/**
* Register: CSU_CSU_MULTI_BOOT
*/
#define CSU_CSU_MULTI_BOOT ( ( CSU_BASEADDR ) + 0X00000010U )
/**
* Register: CSU_SHA_RESET
*/
#define CSU_SHA_RESET ( ( CSU_BASEADDR ) + 0X00002004U )
#define CSU_SHA_RESET_RESET_MASK 0X00000001U
/**
* Register: CSU_SHA_START
*/
#define CSU_SHA_START ( ( CSU_BASEADDR ) + 0X00002000U )
#define CSU_SHA_START_START_MSG_MASK 0X00000001U
/**
* Register: CSU_SHA_DONE
*/
#define CSU_SHA_DONE ( ( CSU_BASEADDR ) + 0X00002008U )
#define CSU_SHA_DONE_SHA_DONE_MASK 0X00000001U
/**
* Register: CSU_SHA_DIGEST_0
*/
#define CSU_SHA_DIGEST_0 ( ( CSU_BASEADDR ) + 0X00002010U )
/* efuse */
/**
* EFUSE Base Address
*/
#define EFUSE_BASEADDR 0XFFCC0000U
/**
* Register: EFUSE_SEC_CTRL
*/
#define EFUSE_SEC_CTRL ( ( EFUSE_BASEADDR ) + 0X00001000U )
/**
* Register: EFUSE_RSA_CTRL
*/
#define EFUSE_RSA_CTRL ( ( EFUSE_BASEADDR ) + 0X00001060U )
#define EFUSE_RSA_CTRL_RSA_EN_MASK 0X00000001U
/* csudma */
/**
* CSUDMA Base Address
*/
#define CSUDMA_BASEADDR 0XFFC80000U
/* crf_apb */
/**
* CRF_APB Base Address
*/
#define CRF_APB_BASEADDR 0XFD1A0000U
/**
* Register: CRF_APB_RST_FPD_APU
*/
#define CRF_APB_RST_FPD_APU ( ( CRF_APB_BASEADDR ) + 0X00000104U )
#define CRF_APB_RST_FPD_APU_ACPU0_RESET_MASK 0X00000001U
#define CRF_APB_RST_FPD_APU_APU_L2_RESET_MASK 0X00000100U
/**
* Register: CRF_APB_ACPU_CTRL
*/
#define CRF_APB_ACPU_CTRL ( ( CRF_APB_BASEADDR ) + 0X00000060U )
#define CRF_APB_ACPU_CTRL_CLKACT_FULL_MASK 0X01000000U
#define CRF_APB_ACPU_CTRL_CLKACT_HALF_MASK 0X02000000U
#define CRF_APB_RST_FPD_APU_ACPU1_RESET_MASK 0X00000002U
#define CRF_APB_RST_FPD_APU_ACPU2_RESET_MASK 0X00000004U
#define CRF_APB_RST_FPD_APU_ACPU3_RESET_MASK 0X00000008U
/* crl_apb */
/**
* CRL_APB Base Address
*/
#define CRL_APB_BASEADDR 0XFF5E0000U
/**
* Register: CRL_APB_CPU_R5_CTRL
*/
#define CRL_APB_CPU_R5_CTRL ( ( CRL_APB_BASEADDR ) + 0X00000090U )
#define CRL_APB_CPU_R5_CTRL_CLKACT_MASK 0X01000000U
/**
* Register: CRL_APB_RST_LPD_TOP
*/
#define CRL_APB_RST_LPD_TOP ( ( CRL_APB_BASEADDR ) + 0X0000023CU )
#define CRL_APB_RST_LPD_TOP_RPU_R50_RESET_MASK 0X00000001U
#define CRL_APB_RST_LPD_TOP_RPU_AMBA_RESET_MASK 0X00000004U
#define CRL_APB_RST_LPD_TOP_RPU_R51_RESET_MASK 0X00000002U
/**
* Register: CRL_APB_BOOT_MODE_USER
*/
#define CRL_APB_BOOT_MODE_USER ( ( CRL_APB_BASEADDR ) + 0X00000200U )
#define CRL_APB_BOOT_MODE_USER_BOOT_MODE_MASK 0X0000000FU
/* apu */
/**
* APU Base Address
*/
#define APU_BASEADDR 0XFD5C0000U
/**
* Register: APU_CONFIG_0
*/
#define APU_CONFIG_0 ( ( APU_BASEADDR ) + 0X00000020U )
/**
* Register: APU_RVBARADDR0L
*/
#define APU_RVBARADDR0L ( ( APU_BASEADDR ) + 0X00000040U )
/**
* Register: APU_RVBARADDR0H
*/
#define APU_RVBARADDR0H ( ( APU_BASEADDR ) + 0X00000044U )
/**
* Register: APU_RVBARADDR1L
*/
#define APU_RVBARADDR1L ( ( APU_BASEADDR ) + 0X00000048U )
/**
* Register: APU_RVBARADDR1H
*/
#define APU_RVBARADDR1H ( ( APU_BASEADDR ) + 0X0000004CU )
/**
* Register: APU_RVBARADDR2L
*/
#define APU_RVBARADDR2L ( ( APU_BASEADDR ) + 0X00000050U )
/**
* Register: APU_RVBARADDR2H
*/
#define APU_RVBARADDR2H ( ( APU_BASEADDR ) + 0X00000054U )
/**
* Register: APU_RVBARADDR3L
*/
#define APU_RVBARADDR3L ( ( APU_BASEADDR ) + 0X00000058U )
/**
* Register: APU_RVBARADDR3H
*/
#define APU_RVBARADDR3H ( ( APU_BASEADDR ) + 0X0000005CU )
/* pmu_global */
/**
* Register: PMU_GLOBAL_PERS_GLOB_GEN_STORAGE1
*/
#define PMU_GLOBAL_PERS_GLOB_GEN_STORAGE1 ( ( PMU_GLOBAL_BASEADDR ) + 0X00000054U )
/**
* PMU_GLOBAL Base Address
*/
#define PMU_GLOBAL_BASEADDR 0XFFD80000U
/* rpu */
/**
* RPU Base Address
*/
#define RPU_BASEADDR 0XFF9A0000U
/**
* Register: RPU_RPU_GLBL_CNTL
*/
#define RPU_RPU_GLBL_CNTL ( ( RPU_BASEADDR ) + 0X00000000U )
#define RPU_RPU_GLBL_CNTL_SLSPLIT_MASK 0X00000008U
#define RPU_RPU_GLBL_CNTL_TCM_COMB_MASK 0X00000040U
#define RPU_RPU_GLBL_CNTL_SLCLAMP_MASK 0X00000010U
/**
* Register: RPU_RPU_0_CFG
*/
#define RPU_RPU_0_CFG ( ( RPU_BASEADDR ) + 0X00000100U )
#define RPU_RPU_0_CFG_NCPUHALT_MASK 0X00000001U
/**
* Register: RPU_RPU_1_CFG
*/
#define RPU_RPU_1_CFG ( ( RPU_BASEADDR ) + 0X00000200U )
#define RPU_RPU_1_CFG_NCPUHALT_MASK 0X00000001U
/* rsa */
/**
* RSA Base Address
*/
#define RSA_BASEADDR 0XFFCE002CU
/**
* Register: RSA_WR_DATA_0
*/
#define RSA_WR_DATA_0 ( ( RSA_BASEADDR ) + 0X00000000U )
/**
* Register: RSA_WR_ADDR
*/
#define RSA_WR_ADDR ( ( RSA_BASEADDR ) + 0X00000018U )
/**
* Register: RSA_RD_ADDR
*/
#define RSA_RD_ADDR ( ( RSA_BASEADDR ) + 0X00000034U )
/**
* Register: RSA_RD_DATA_0
*/
#define RSA_RD_DATA_0 ( ( RSA_BASEADDR ) + 0X0000001CU )
/* rsa_core */
/**
* RSA_CORE Base Address
*/
#define RSA_CORE_BASEADDR 0XFFCE0000U
/**
* Register: RSA_CORE_MINV0
*/
#define RSA_CORE_MINV0 ( ( RSA_CORE_BASEADDR ) + 0X00000018U )
/**
* Register: RSA_CORE_MINV1
*/
#define RSA_CORE_MINV1 ( ( RSA_CORE_BASEADDR ) + 0X0000001CU )
/**
* Register: RSA_CORE_MINV2
*/
#define RSA_CORE_MINV2 ( ( RSA_CORE_BASEADDR ) + 0X00000020U )
/**
* Register: RSA_CORE_MINV3
*/
#define RSA_CORE_MINV3 ( ( RSA_CORE_BASEADDR ) + 0X00000024U )
/**
* Register: RSA_CORE_STATUS
*/
#define RSA_CORE_STATUS ( ( RSA_CORE_BASEADDR ) + 0X00000014U )
#define RSA_CORE_STATUS_ERROR_MASK 0X00000004U
#define RSA_CORE_STATUS_DONE_MASK 0X00000001U
/**
* Register: RSA_CORE_CTRL
*/
#define RSA_CORE_CTRL ( ( RSA_CORE_BASEADDR ) + 0X00000010U )
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/**
* For error reporting PMU_GLOBAL_PERS_GLOB_GEN_STORAGE1 is used
*/
#define XFSBL_ERROR_STATUS_REGISTER_OFFSET (PMU_GLOBAL_PERS_GLOB_GEN_STORAGE1)
#define XFSBL_PMU_RAM_ADDRESS (0xFFDC0000U)
/**
* ARM Processor defines
*/
#define XFSBL_CLUSTER_ID_MASK (0x00000F00U)
#define XFSBL_A53_PROCESSOR (0x00000000U)
#define XFSBL_R5_PROCESSOR (0x00000100U)
/**
* Other FSBL defines
* this can defined in xfsbl_main.h
*/
#define XFSBL_DDR_TEMP_ADDRESS (0x100000U)
#define XFSBL_R5_0 (0x1U)
#define XFSBL_R5_L (0x2U)
/**
* TCM address for R5
*/
#define XFSBL_R5_TCM_START_ADDRESS (0x0U)
#define XFSBL_R5_TCM_END_ADDRESS (0x20000U)
#define XFSBL_R5L_TCM_END_ADDRESS (0x40000U)
#define XFSBL_R50_HIGH_TCM_START_ADDRESS (0xFFE00000U)
#define XFSBL_R51_HIGH_TCM_START_ADDRESS (0xFFE90000U)
#define XFSBL_R5_TCM_LENGTH (0x10000U)
/**
* defines for the FSBL peripherals present
*/
/**
* Definition for WDT to be included
*/
#ifdef XPAR_XWDTPS_0_DEVICE_ID
/*#define XFSBL_WDT_PRESENT*/
#endif
/**
* Definition for SD to be included
*/
#if !defined(FSBL_SD_EXCLUDE) & defined( XPAR_XSDPS_0_DEVICE_ID)
#define XFSBL_SD
#endif
/**
* Definition for QSPI to be included
*/
#if !defined(FSBL_QSPI_EXCLUDE) & defined(XPAR_XQSPIPS_0_DEVICE_ID)
#define XFSBL_QSPI
#define XFSBL_QSPI_BASEADDRESS XPAR_XQSPIPS_0_BASEADDR
#endif
/**
* Definition for NAND to be included
*/
#if !defined(FSBL_NAND_EXCLUDE) & defined(XPAR_XNANDPS8_0_DEVICE_ID)
#define XFSBL_NAND
#endif
/**
* Definition for RSA to be included
*/
#if !defined(FSBL_RSA_EXCLUDE)
#define XFSBL_RSA
#endif
#define XFSBL_QSPI_LINEAR_BASE_ADDRESS_START (0xC0000000U)
#define XFSBL_QSPI_LINEAR_BASE_ADDRESS_END (0xDFFFFFFFU)
#define XFSBL_PS_DDR
#define XFSBL_PS_DDR_START_ADDRESS (0x0U)
#define XFSBL_PS_DDR_END_ADDRESS (0x80000000U) //2GB of DDR
#define XFSBL_OCM
#define XFSBL_OCM_START_ADDRESS (0xFFFE2000U)
#define XFSBL_OCM_END_ADDRESS (0xFFFF0000U)
#ifdef XFSBL_A53
#define PTRSIZE u64
#else
#define PTRSIZE u32
#endif
/****************************************************************************/
/**
*
* Read the given register.
*
* @param BaseAddr is the base address of the device
* @param RegOffset is the register offset to be read
*
* @return The 32-bit value of the register
*
* @note C-style signature:
* u32 XFsbl_ReadReg(u32 BaseAddr, u32 RegOffset)
*
*****************************************************************************/
#define XFsbl_ReadReg(BaseAddr, RegOffset) \
Xil_In32((BaseAddr) + (RegOffset))
#define XFsbl_In32(Addr) Xil_In32(Addr)
#define XFsbl_In64(Addr) Xil_In64(Addr)
/****************************************************************************/
/**
*
* Write to the given register.
*
* @param BaseAddr is the base address of the device
* @param RegOffset is the register offset to be written
* @param Data is the 32-bit value to write to the register
*
* @return None.
*
* @note C-style signature:
* void XFsbl_WriteReg(u32 BaseAddr, u32 RegOffset, u32 Data)
*
*****************************************************************************/
#define XFsbl_WriteReg(BaseAddr, RegOffset, Data) \
Xil_Out32((BaseAddr) + (RegOffset), (Data))
#define XFsbl_Out32(Addr, Data) Xil_Out32(Addr, Data)
#define XFsbl_Out64(Addr, Data) Xil_Out64(Addr, Data)
/**
* Platform
*/
#if 1
#define XFSBL_PLATFORM \
(Xil_In32(CSU_VERSION) & CSU_VERSION_PLATFORM_MASK )
#else
#define XFSBL_PLATFORM XFSBL_PLATFORM_VELOCE
#endif
#define XFSBL_RTL_VERSION \
(Xil_In32(CSU_VERSION) & CSU_VERSION_RTL_VERSION_MASK )
#define XFSBL_PLATFORM_SILICON (0X00000000U)
#define XFSBL_PLATFORM_REMUS (0X00001000U)
#define XFSBL_PLATFORM_VELOCE (0X00002000U)
#define XFSBL_PLATFORM_QEMU (0X00003000U)
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
#ifdef __cplusplus
}
#endif
#endif /* XFSBL_HW_H */

View file

@ -0,0 +1,733 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xfsbl_image_header.c
*
* This is the image header C file which does validation for the image header.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 kc 10/21/13 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xfsbl_hw.h"
#include "xfsbl_image_header.h"
#include "xfsbl_misc_drivers.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
__inline u32 XFsbl_GetPartitionOwner(
XFsblPs_PartitionHeader * PartitionHeader)
{
return PartitionHeader->PartitionAttributes &
XIH_PH_ATTRB_PART_OWNER_MASK;
}
__inline u32 XFsbl_IsRsaSignaturePresent(
XFsblPs_PartitionHeader * PartitionHeader)
{
return PartitionHeader->PartitionAttributes &
XIH_PH_ATTRB_RSA_SIGNATURE_MASK;
}
__inline u32 XFsbl_GetChecksumType(
XFsblPs_PartitionHeader * PartitionHeader)
{
return PartitionHeader->PartitionAttributes &
XIH_PH_ATTRB_CHECKSUM_MASK;
}
__inline u32 XFsbl_GetDestinationCpu(
XFsblPs_PartitionHeader * PartitionHeader)
{
return PartitionHeader->PartitionAttributes &
XIH_PH_ATTRB_DEST_CPU_MASK;
}
__inline u32 XFsbl_IsEncrypted(
XFsblPs_PartitionHeader * PartitionHeader)
{
return PartitionHeader->PartitionAttributes &
XIH_PH_ATTRB_ENCRYPTION_MASK;
}
__inline u32 XFsbl_GetDestinationDevice(
XFsblPs_PartitionHeader * PartitionHeader)
{
return PartitionHeader->PartitionAttributes &
XIH_PH_ATTRB_DEST_DEVICE_MASK;
}
__inline u32 XFsbl_GetA53ExecState(
XFsblPs_PartitionHeader * PartitionHeader)
{
return PartitionHeader->PartitionAttributes &
XIH_PH_ATTRB_A53_EXEC_ST_MASK;
}
/************************** Function Prototypes ******************************/
static u32 XFsbl_ValidateImageHeaderTable(
XFsblPs_ImageHeaderTable * ImageHeaderTable);
static u32 XFsbl_CheckValidMemoryAddress(u64 Address, u32 CpuId);
/************************** Variable Definitions *****************************/
/****************************************************************************/
/**
* This function is used to validate the word checksum for the image header
* table and partition headers.
* Checksum is based on the below formulae
* Checksum = ~(X1 + X2 + X3 + .... + Xn)
*
* @param Buffer pointer for the data words.
*
* @param Length of the buffer for which checksum should be calculated.
* last word is taken as checksum for the data to be compared against
*
* @return
* - XFSBL_SUCCESS for successful checksum validation
* - XFSBL_FAILURE if checksum validation fails
*
* @note
*
*****************************************************************************/
u32 XFsbl_ValidateChecksum(u32 Buffer[], u32 Length)
{
u32 Status=XFSBL_SUCCESS;
u32 Checksum=0U;
u32 Count=0U;
/**
* Length has to be atleast equal to 2,
*/
if (Length < 2U)
{
Status = XFSBL_FAILURE;
goto END;
}
/**
* Checksum = ~(X1 + X2 + X3 + .... + Xn)
* Calculate the checksum
*/
for (Count = 0U; Count < (Length-1U); Count++) {
/**
* Read the word from the header
*/
Checksum += Buffer[Count];
}
/**
* Invert checksum
*/
Checksum ^= 0xFFFFFFFFU;
/**
* Validate the checksum
*/
if (Buffer[Length-1U] != Checksum) {
XFsbl_Printf(DEBUG_GENERAL,
"Error: Checksum 0x%0lx != %0lx\r\n",
Checksum, Buffer[Length-1U]);
Status = XFSBL_FAILURE;
}
END:
return Status;
}
/****************************************************************************/
/**
* This function checks the fields of the image header table and validates
* them. Image header table contains the fields that common across the
* partitions and for image
*
* @param ImageHeaderTable pointer to the image header table.
*
* @return
* - XFSBL_SUCCESS on successful image header table validation
* - errors as mentioned in xfsbl_error.h
*
* @note
*
*****************************************************************************/
static u32 XFsbl_ValidateImageHeaderTable(
XFsblPs_ImageHeaderTable * ImageHeaderTable)
{
u32 Status = XFSBL_SUCCESS;
u32 PartitionPresentDevice=0U;
/**
* Check the check sum of the image header table
*/
Status = XFsbl_ValidateChecksum((u32 *)ImageHeaderTable,
XIH_IHT_LEN/XIH_PARTITION_WORD_LENGTH);
if (XFSBL_SUCCESS != Status)
{
Status = XFSBL_ERROR_IHT_CHECKSUM;
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_IHT_CHECKSUM\n\r");
goto END;
}
/**
* check for no of partitions
*/
if ((ImageHeaderTable->NoOfPartitions <= XIH_MIN_PARTITIONS ) ||
(ImageHeaderTable->NoOfPartitions > XIH_MAX_PARTITIONS) )
{
Status = XFSBL_ERROR_NO_OF_PARTITIONS;
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_NO_OF_PARTITIONS\n\r");
goto END;
}
/**
* check for the partition present device
*/
PartitionPresentDevice = ImageHeaderTable->PartitionPresentDevice;
if ((PartitionPresentDevice != XIH_IHT_PPD_SAME) &&
(PartitionPresentDevice != XIH_IHT_PPD_PCIE) &&
(PartitionPresentDevice != XIH_IHT_PPD_ETHERNET) &&
(PartitionPresentDevice != XIH_IHT_PPD_SATA) )
{
Status = XFSBL_ERROR_PPD;
XFsbl_Printf(DEBUG_GENERAL,
"XFSBL_ERROR_PPD\n\r");
goto END;
}
/**
* Print the Image header table details
* Print the Bootgen version
*/
XFsbl_Printf(DEBUG_INFO,"*****Image Header Table Details******** \n\r");
XFsbl_Printf(DEBUG_INFO,"Boot Gen Ver: 0x%0lx \n\r",
ImageHeaderTable->Version);
XFsbl_Printf(DEBUG_INFO,"No of Partitions: 0x%0lx \n\r",
ImageHeaderTable->NoOfPartitions);
XFsbl_Printf(DEBUG_INFO,"Partition Header Address: 0x%0lx \n\r",
ImageHeaderTable->PartitionHeaderAddress);
XFsbl_Printf(DEBUG_INFO,"Partition Present Device: 0x%0lx \n\r",
ImageHeaderTable->PartitionPresentDevice);
END:
return Status;
}
/****************************************************************************/
/**
* This function reads the image header from flash device. Image header
* reads the image header table and partition headers
*
* @param ImageHeader pointer to the image header at which image header to
* be stored
*
* @param DeviceOps pointer deviceops structure which contains the
* function pointer to flash read function
*
* @param FlashImageOffsetAddress base offset to the image in the flash
*
* @return
* - XFSBL_SUCCESS on successful reading image header
* - errors as mentioned in xfsbl_error.h
*
* @note
*****************************************************************************/
u32 XFsbl_ReadImageHeader(XFsblPs_ImageHeader * ImageHeader,
XFsblPs_DeviceOps * DeviceOps,
u32 FlashImageOffsetAddress)
{
u32 Status = XFSBL_SUCCESS;
u32 ImageHeaderTableAddressOffset=0U;
u32 PartitionHeaderAddress=0U;
u32 PartitionIndex=0U;
/**
* Read the Image Header Table offset from
* Boot Header
*/
Status = DeviceOps->DeviceCopy(FlashImageOffsetAddress
+ XIH_BH_IH_TABLE_OFFSET,
(PTRSIZE ) &ImageHeaderTableAddressOffset, XIH_FIELD_LEN);
if (XFSBL_SUCCESS != Status)
{
XFsbl_Printf(DEBUG_GENERAL,"Device Copy Failed \n\r");
goto END;
}
XFsbl_Printf(DEBUG_INFO,"Image Header Table Offset 0x%0lx \n\r",
ImageHeaderTableAddressOffset);
/**
* Read the Image header table of 64 bytes
* and update the image header table structure
*/
Status = DeviceOps->DeviceCopy(FlashImageOffsetAddress +
ImageHeaderTableAddressOffset,
(PTRSIZE ) &(ImageHeader->ImageHeaderTable),
XIH_IHT_LEN);
if (XFSBL_SUCCESS != Status)
{
XFsbl_Printf(DEBUG_GENERAL,"Device Copy Failed \n\r");
goto END;
}
/**
* Check the validity of Image Header Table
*/
Status = XFsbl_ValidateImageHeaderTable(
&(ImageHeader->ImageHeaderTable));
if (XFSBL_SUCCESS != Status)
{
XFsbl_Printf(DEBUG_GENERAL,"Image Header Table "
"Validation failed \n\r");
goto END;
}
/**
* Update the first partition address
*/
PartitionHeaderAddress =
(ImageHeader->ImageHeaderTable.PartitionHeaderAddress)
* XIH_PARTITION_WORD_LENGTH;
/**
* Read the partitions based on the partition offset
* and update the partition header structure
*/
for (PartitionIndex=0U;
PartitionIndex<ImageHeader->ImageHeaderTable.NoOfPartitions;
PartitionIndex++)
{
/**
* Read the Image header table of 64 bytes
* and update the image header table structure
*/
Status = DeviceOps->DeviceCopy(
FlashImageOffsetAddress + PartitionHeaderAddress,
(PTRSIZE ) &(ImageHeader->PartitionHeader[PartitionIndex]),
XIH_PH_LEN);
if (XFSBL_SUCCESS != Status)
{
XFsbl_Printf(DEBUG_GENERAL,"Device Copy Failed \n\r");
goto END;
}
#if 0
/**
* Check the validity of Image Header Table
*/
Status = XFsbl_ValidatePartitionHeader(
&ImageHeader->PartitionHeader[PartitionIndex]);
if (XFSBL_SUCCESS != Status)
{
XFsbl_Printf(DEBUG_GENERAL,"Partition %x Header "
"Validation failed \n\r", PartitionIndex);
goto END;
}
#endif
/**
* Update the next partition present address
*/
PartitionHeaderAddress =
(ImageHeader->PartitionHeader[PartitionIndex].NextPartitionOffset)
* XIH_PARTITION_WORD_LENGTH;
}
END:
return Status;
}
static u32 XFsbl_CheckValidMemoryAddress(u64 Address, u32 CpuId)
{
u32 Status = XFSBL_SUCCESS;
/**
* Check if Address is in the range of TCM for R5
*/
if ((CpuId == XIH_PH_ATTRB_DEST_CPU_R5_0) ||
(CpuId == XIH_PH_ATTRB_DEST_CPU_R5_1) ||
(CpuId == XIH_PH_ATTRB_DEST_CPU_R5_L) )
{
if ((Address >= XFSBL_R5_TCM_START_ADDRESS) &&
(Address < XFSBL_R5_TCM_END_ADDRESS) )
{
goto END;
}
}
#ifdef XFSBL_PS_DDR
/**
* Check if Address is in the range of PS DDR
*/
if ((Address >= XFSBL_PS_DDR_START_ADDRESS) &&
(Address < XFSBL_PS_DDR_END_ADDRESS) )
{
goto END;
}
#endif
#ifdef XFSBL_PL_DDR
/**
* Check if Address is in the range of PS DDR
*/
if ((Address >= XFSBL_PL_DDR_START_ADDRESS) &&
(Address < XFSBL_PL_DDR_END_ADDRESS) )
{
goto END;
}
#endif
#ifdef XFSBL_OCM
/**
* Check if Address is in the range of last bank of OCM
*/
if ((Address >= XFSBL_OCM_START_ADDRESS) &&
(Address < XFSBL_OCM_END_ADDRESS) )
{
goto END;
}
#endif
/**
* Not a valid address
*/
Status = XFSBL_ERROR_ADDRESS;
XFsbl_Printf(DEBUG_GENERAL,
"XFSBL_ERROR_ADDRESS\n\r");
END:
return Status;
}
/****************************************************************************/
/**
* This function validates the partition header.
*
* @param PartitionHeader is pointer to the XFsblPs_PartitionHeader structure
*
* @return
* - XFSBL_SUCCESS on successful partition header validation
* - errors as mentioned in xfsbl_error.h
*
* @note
*
*****************************************************************************/
u32 XFsbl_ValidatePartitionHeader(
XFsblPs_PartitionHeader * PartitionHeader, u32 RunningCpu)
{
u32 Status = XFSBL_SUCCESS;
u32 DestinationCpu=0U;
/* u32 RpuGlobalCntl=0; */
s32 IsEncrypted=FALSE, IsAuthenticated=FALSE;
/**
* Update the variables
*/
if (XFsbl_IsEncrypted(PartitionHeader) ==
XIH_PH_ATTRB_ENCRYPTION )
{
IsEncrypted = TRUE;
}
if (XFsbl_IsRsaSignaturePresent(PartitionHeader) ==
XIH_PH_ATTRB_RSA_SIGNATURE )
{
IsAuthenticated = TRUE;
}
DestinationCpu = XFsbl_GetDestinationCpu(PartitionHeader);
/**
* Partition fields Validation
*/
/**
* check for XIP image - partition lengths should be zero
* execution address should be in QSPI
*/
if (PartitionHeader->UnEncryptedDataWordLength == 0U)
{
if ((IsAuthenticated == TRUE ) ||
(IsEncrypted == TRUE ))
{
Status = XFSBL_ERROR_XIP_AUTH_ENC_PRESENT;
XFsbl_Printf(DEBUG_GENERAL,
"XFSBL_ERROR_XIP_AUTH_ENC_PRESENT\n\r");
goto END;
}
if ((PartitionHeader->DestinationExecutionAddress
< XFSBL_QSPI_LINEAR_BASE_ADDRESS_START) ||
(PartitionHeader->DestinationExecutionAddress
> XFSBL_QSPI_LINEAR_BASE_ADDRESS_END))
{
Status = XFSBL_ERROR_XIP_EXEC_ADDRESS;
XFsbl_Printf(DEBUG_GENERAL,
"XFSBL_ERROR_XIP_EXEC_ADDRESS\n\r");
goto END;
}
}
/**
* check for authentication and encryption length
*/
if ((IsAuthenticated == FALSE ) &&
(IsEncrypted == FALSE ))
{
/**
* all lengths should be equal
*/
if ((PartitionHeader->UnEncryptedDataWordLength !=
PartitionHeader->EncryptedDataWordLength) ||
(PartitionHeader->EncryptedDataWordLength !=
PartitionHeader->TotalDataWordLength))
{
Status = XFSBL_ERROR_PARTITION_LENGTH;
XFsbl_Printf(DEBUG_GENERAL,
"XFSBL_ERROR_PARTITION_LENGTH\n\r");
goto END;
}
} else if ((IsAuthenticated == TRUE ) &&
(IsEncrypted == FALSE ))
{
/**
* TotalDataWordLength should be more
*/
if ((PartitionHeader->UnEncryptedDataWordLength !=
PartitionHeader->EncryptedDataWordLength) ||
(PartitionHeader->EncryptedDataWordLength >=
PartitionHeader->TotalDataWordLength))
{
Status = XFSBL_ERROR_PARTITION_LENGTH;
XFsbl_Printf(DEBUG_GENERAL,
"XFSBL_ERROR_PARTITION_LENGTH\n\r");
goto END;
}
} else if ((IsAuthenticated == FALSE ) &&
(IsEncrypted == TRUE ))
{
/**
* EncryptedDataWordLength should be more
*/
if ((PartitionHeader->UnEncryptedDataWordLength >=
PartitionHeader->EncryptedDataWordLength) ||
(PartitionHeader->EncryptedDataWordLength !=
PartitionHeader->TotalDataWordLength))
{
Status = XFSBL_ERROR_PARTITION_LENGTH;
XFsbl_Printf(DEBUG_GENERAL,
"XFSBL_ERROR_PARTITION_LENGTH\n\r");
goto END;
}
} else /* Authenticated and Encrypted */
{
/**
* TotalDataWordLength should be more
*/
if ((PartitionHeader->UnEncryptedDataWordLength >=
PartitionHeader->EncryptedDataWordLength) ||
(PartitionHeader->EncryptedDataWordLength >=
PartitionHeader->TotalDataWordLength))
{
Status = XFSBL_ERROR_PARTITION_LENGTH;
XFsbl_Printf(DEBUG_GENERAL,
"XFSBL_ERROR_PARTITION_LENGTH\n\r");
goto END;
}
}
/**
* handled on partition copy block
* Check for Destination Load Address,
* executable address
* Address not in TCM, OCM, DDR, PL
* No DDR and address in DDR
*/
Status = XFsbl_CheckValidMemoryAddress(
PartitionHeader->DestinationLoadAddress,
DestinationCpu);
if (Status != XFSBL_SUCCESS)
{
goto END;
}
/**
* R5 can't access the DDR 0 address as TCM is present there
*/
if ( ((RunningCpu == XIH_PH_ATTRB_DEST_CPU_R5_0) ||
(RunningCpu == XIH_PH_ATTRB_DEST_CPU_R5_L))
&&
((DestinationCpu == XIH_PH_ATTRB_DEST_CPU_A53_0) ||
(DestinationCpu == XIH_PH_ATTRB_DEST_CPU_A53_1) ||
(DestinationCpu == XIH_PH_ATTRB_DEST_CPU_A53_2) ||
(DestinationCpu == XIH_PH_ATTRB_DEST_CPU_A53_3) ))
{
/**
* DDR address for A53-x should be greater than TCM
*/
if (PartitionHeader->DestinationLoadAddress < 0x80000U)
{
Status = XFSBL_ERROR_ADDRESS;
XFsbl_Printf(DEBUG_GENERAL,
"XFSBL_ERROR_ADDRESS\n\r");
goto END;
}
}
/**
* Checks for invalid checksum type
*/
if ((XFsbl_GetChecksumType(PartitionHeader) !=
XIH_PH_ATTRB_NOCHECKSUM)
&& (XFsbl_GetChecksumType(PartitionHeader) !=
XIH_PH_ATTRB_CHECKSUM_MD5))
{
Status = XFSBL_ERROR_INVALID_CHECKSUM_TYPE;
XFsbl_Printf(DEBUG_GENERAL,
"XFSBL_ERROR_INVALID_CHECKSUM_TYPE\n\r");
goto END;
}
/**
* check for invalid cpu
*/
if (DestinationCpu > XIH_PH_ATTRB_DEST_CPU_R5_L)
{
Status = XFSBL_ERROR_INVALID_CPU_TYPE;
XFsbl_Printf(DEBUG_GENERAL,
"XFSBL_ERROR_INVALID_CPU_TYPE\n\r");
goto END;
}
/**
* check if
* 1. if FSBL on R5-0 and Destination CPU is R5-L
* 2. if FSBL on R5-L and Destination CPU is R5-0/R5-1
*/
if (
(((DestinationCpu == XIH_PH_ATTRB_DEST_CPU_R5_0) ||
(DestinationCpu == XIH_PH_ATTRB_DEST_CPU_R5_1)) &&
(RunningCpu == XIH_PH_ATTRB_DEST_CPU_R5_L) ) ||
((DestinationCpu == XIH_PH_ATTRB_DEST_CPU_R5_L) &&
(RunningCpu == XIH_PH_ATTRB_DEST_CPU_R5_0))
)
{
Status = XFSBL_ERROR_LS_CPU_TYPE;
XFsbl_Printf(DEBUG_GENERAL,
"XFSBL_ERROR_LS_CPU_TYPE\n\r");
goto END;
}
/**
* check for invalid destination device
*/
if (XFsbl_GetDestinationDevice(PartitionHeader) >
XIH_PH_ATTRB_DEST_DEVICE_PMU)
{
Status = XFSBL_ERROR_INVALID_DEST_DEVICE;
XFsbl_Printf(DEBUG_GENERAL,
"XFSBL_ERROR_INVALID_DEST_DEVICE\n\r");
goto END;
}
/**
* Check for PMU address not in PMU RAM
*/
if (XFsbl_GetDestinationDevice(PartitionHeader) ==
XIH_PH_ATTRB_DEST_DEVICE_PMU)
{
if (PartitionHeader->DestinationLoadAddress !=
XFSBL_PMU_RAM_ADDRESS)
{
Status = XFSBL_ERROR_INVALID_LOAD_ADDRESS;
XFsbl_Printf(DEBUG_GENERAL,
"XFSBL_ERROR_INVALID_LOAD_ADDRESS\n\r");
goto END;
}
}
/**
* Print Partition Header Details
*/
XFsbl_Printf(DEBUG_INFO,"UnEncrypted data Length: 0x%0lx \n\r",
PartitionHeader->UnEncryptedDataWordLength);
XFsbl_Printf(DEBUG_INFO,"Data word offset: 0x%0lx \n\r",
PartitionHeader->EncryptedDataWordLength);
XFsbl_Printf(DEBUG_INFO,"Total Data word length: 0x%0lx \n\r",
PartitionHeader->TotalDataWordLength);
XFsbl_Printf(DEBUG_INFO,"Destination Load Address: 0x%0lx \n\r",
(PTRSIZE)PartitionHeader->DestinationLoadAddress);
XFsbl_Printf(DEBUG_INFO,"Execution Address: 0x%0lx \n\r",
(PTRSIZE)PartitionHeader->DestinationExecutionAddress);
XFsbl_Printf(DEBUG_INFO,"Data word offset: 0x%0lx \n\r",
PartitionHeader->DataWordOffset);
XFsbl_Printf(DEBUG_INFO,"Partition Attributes: 0x%0lx \n\r",
PartitionHeader->PartitionAttributes);
END:
return Status;
}

View file

@ -0,0 +1,249 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xfsbl_image_header.h
*
* This is the image header file which contains definitions for the image header.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 kc 10/21/13 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
#ifndef XFSBL_IH_H
#define XFSBL_IH_H
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xfsbl_misc_drivers.h"
/************************** Constant Definitions *****************************/
#define XIH_MIN_PARTITIONS (1U)
#define XIH_MAX_PARTITIONS (32U)
#define XIH_RESERVED_OLD_IH (0x380U)
#define XIH_PARTITION_WORD_LENGTH (0x4U)
/**
* Boot header field offset
*/
#define XIH_BH_IH_OFFSET (0x3CU)
#define XIH_BH_IMAGE_ATTRB_OFFSET (0x44U)
#define XIH_BH_IH_TABLE_OFFSET (0x98U)
#define XIH_BH_PH_TABLE_OFFSET (0x9CU)
#define XIH_BH_IMAGE_ATTRB_RSA_MASK (0xC000U)
#define XIH_BH_IMAGE_ATTRB_SHA2_MASK (0x3000U)
/**
* Defines for length of the headers
*/
#define XIH_FIELD_LEN (4U)
#define XIH_IHT_LEN (64U)
#define XIH_PH_LEN (64U)
/**
* Image header table field offsets
*/
#define XIH_IHT_VERSION_OFFSET (0x0U)
#define XIH_IHT_NO_OF_PARTITONS_OFFSET (0x4U)
#define XIH_IHT_PH_ADDR_OFFSET (0x8U)
#define XIH_IHT_PPD_OFFSET (0x14U)
#define XIH_IHT_CHECKSUM_OFFSET (0x3CU)
/**
* Partition Header Fields
*/
#define XIH_PH_ENC_DATAWORD_LENGTH (0x0U)
#define XIH_PH_UNENC_DATAWORD_LENGTH (0x4U)
#define XIH_PH_TOTAL_DATAWORD_LENGTH (0x8U)
#define XIH_PH_NEXT_PARTITION_OFFSET (0xCU)
#define XIH_PH_DEST_EXECUTION_ADDRESS (0x10U)
#define XIH_PH_DEST_LOAD_ADDRESS (0x18U)
#define XIH_PH_DATA_WORD_OFFSET (0x20U)
#define XIH_PH_ATTRB_OFFSET (0x24U)
#define XIH_PH_SECTION_COUNT (0x28U)
#define XIH_PH_CHECKSUM_WORD_OFFSET (0x2CU)
#define XIH_PH_IMAGEHEADER_OFFSET (0x30U)
#define XIH_PH_AUTHCERTIFICATE_OFFSET (0x34U)
#define XIH_PH_CHECKSUM (0x3CU)
/**
* Partition Present Devices(PPD) in IHT
*/
#define XIH_IHT_PPD_SAME (0x0U)
#define XIH_IHT_PPD_QSPI (0x1U)
#define XIH_IHT_PPD_NAND (0x2U)
#define XIH_IHT_PPD_SD (0x3U)
#define XIH_IHT_PPD_MMC (0x4U)
#define XIH_IHT_PPD_USB (0x5U)
#define XIH_IHT_PPD_ETHERNET (0x6U)
#define XIH_IHT_PPD_PCIE (0x7U)
#define XIH_IHT_PPD_SATA (0x8U)
/**
* Partition Attribute fields
*/
#define XIH_PH_ATTRB_PART_OWNER_MASK (0x30000U)
#define XIH_PH_ATTRB_RSA_SIGNATURE_MASK (0x8000U)
#define XIH_PH_ATTRB_CHECKSUM_MASK (0x7000U)
#define XIH_PH_ATTRB_DEST_CPU_MASK (0x0F00U)
#define XIH_PH_ATTRB_ENCRYPTION_MASK (0x0080U)
#define XIH_PH_ATTRB_DEST_DEVICE_MASK (0x0070U)
#define XIH_PH_ATTRB_A53_EXEC_ST_MASK (0x0008U)
/**
* Partition Attribute Values
*/
#define XIH_PH_ATTRB_PART_OWNER_FSBL (0x00000U)
#define XIH_PH_ATTRB_RSA_SIGNATURE (0x8000U)
#define XIH_PH_ATTRB_NOCHECKSUM (0x0000U)
#define XIH_PH_ATTRB_CHECKSUM_MD5 (0x1000U)
#define XIH_PH_ATTRB_DEST_CPU_NONE (0x0000U)
#define XIH_PH_ATTRB_DEST_CPU_A53_0 (0x0100U)
#define XIH_PH_ATTRB_DEST_CPU_A53_1 (0x0200U)
#define XIH_PH_ATTRB_DEST_CPU_A53_2 (0x0300U)
#define XIH_PH_ATTRB_DEST_CPU_A53_3 (0x0400U)
#define XIH_PH_ATTRB_DEST_CPU_R5_0 (0x0500U)
#define XIH_PH_ATTRB_DEST_CPU_R5_1 (0x0600U)
#define XIH_PH_ATTRB_DEST_CPU_R5_L (0x0700U)
#define XIH_PH_ATTRB_ENCRYPTION (0x0080U)
#define XIH_PH_ATTRB_DEST_DEVICE_NONE (0x0000U)
#define XIH_PH_ATTRB_DEST_DEVICE_PS (0x0010U)
#define XIH_PH_ATTRB_DEST_DEVICE_PL (0x0020U)
#define XIH_PH_ATTRB_DEST_DEVICE_PMU (0x0030U)
#define XIH_PH_ATTRB_A53_EXEC_ST_AA32 (0x0008U)
#define XIH_PH_ATTRB_A53_EXEC_ST_AA64 (0x0000U)
/**************************** Type Definitions *******************************/
/**
* Structure to store the image header table details.
* It contains all the information of image header table in order.
*/
typedef struct {
u32 Version; /**< bootgen version used */
u32 NoOfPartitions; /**< No of partition present */
u32 PartitionHeaderAddress; /**< Address to start of partition header*/
u32 Reserved_0xC; /**< Reserved */
u32 Reserved_0x10; /**< Reserved */
u32 PartitionPresentDevice;
/**< Partition present device for secondary boot modes*/
u32 Reserved[9]; /**< Reserved */
u32 Checksum; /**< Checksum of the image header table */
} XFsblPs_ImageHeaderTable;
/**
* Structure to store the partition header details.
* It contains all the information of partition header in order.
*/
typedef struct {
u32 EncryptedDataWordLength; /**< Encrypted word length of partition*/
u32 UnEncryptedDataWordLength; /**< unencrypted word length */
u32 TotalDataWordLength;
/**< Total word length including the authentication
certificate if any*/
u32 NextPartitionOffset; /**< Address of the next partition header*/
u64 DestinationExecutionAddress; /**< Execution address */
u64 DestinationLoadAddress; /**< Load address in DDR/TCM */
u32 DataWordOffset; /**< */
u32 PartitionAttributes; /**< partition attributes */
u32 SectionCount; /**< section count */
u32 ChecksumWordOffset; /**< address to checksum when enabled */
u32 ImageHeaderOffset; /**< address to image header */
u32 AuthCertificateOffset;
/**< address to the authentication certificate when enabled */
u32 Reserved[1]; /**< Reserved */
u32 Checksum; /**< checksum of the partition header */
} XFsblPs_PartitionHeader;
/**
* Structure of the image header which contains
* information of image header table and
* partition headers.
*/
typedef struct {
XFsblPs_ImageHeaderTable ImageHeaderTable;
/**< Image header table structure */
XFsblPs_PartitionHeader PartitionHeader[XIH_MAX_PARTITIONS];
/**< Partition header */
} XFsblPs_ImageHeader;
/***************** Macros (Inline Functions) Definitions *********************/
__inline u32 XFsbl_GetPartitionOwner(
XFsblPs_PartitionHeader * PartitionHeader);
__inline u32 XFsbl_IsRsaSignaturePresent(
XFsblPs_PartitionHeader * PartitionHeader);
__inline u32 XFsbl_GetChecksumType(
XFsblPs_PartitionHeader * PartitionHeader);
__inline u32 XFsbl_GetDestinationCpu(
XFsblPs_PartitionHeader * PartitionHeader);
__inline u32 XFsbl_IsEncrypted(
XFsblPs_PartitionHeader * PartitionHeader);
__inline u32 XFsbl_GetDestinationDevice(
XFsblPs_PartitionHeader * PartitionHeader);
__inline u32 XFsbl_GetA53ExecState(
XFsblPs_PartitionHeader * PartitionHeader);
/************************** Function Prototypes ******************************/
u32 XFsbl_ValidateChecksum(u32 Buffer[], u32 Length);
u32 XFsbl_ReadImageHeader(XFsblPs_ImageHeader * ImageHeader,
XFsblPs_DeviceOps * DeviceOps, u32 FlashImageOffsetAddress);
u32 XFsbl_ValidateImageHeader(XFsblPs_ImageHeaderTable * ImageHeaderTable);
u32 XFsbl_ValidatePartitionHeader(XFsblPs_PartitionHeader * PartitionHeader,
u32 RunningCpu);
#ifdef __cplusplus
}
#endif
#endif /* XFSBL_IH_H */

View file

@ -0,0 +1,721 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xfsbl_initilization.c
*
* This is the file which contains initialization code for the FSBL.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 kc 10/21/13 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xfsbl_hw.h"
#include "xfsbl_main.h"
#include "xfsbl_misc_drivers.h"
#include "pss_init.h"
#include "xfsbl_qspi.h"
/************************** Constant Definitions *****************************/
#define XFSBL_R5_VECTOR_VALUE 0xEAFEFFFEU
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
static u32 XFsbl_ProcessorInit(XFsblPs * FsblInstancePtr);
static u32 XFsbl_ResetValidation(XFsblPs * FsblInstancePtr);
static u32 XFsbl_SystemInit(XFsblPs * FsblInstancePtr);
static u32 XFsbl_PrimaryBootDeviceInit(XFsblPs * FsblInstancePtr);
static u32 XFsbl_ValidateHeader(XFsblPs * FsblInstancePtr);
static u32 XFsbl_SecondaryBootDeviceInit(XFsblPs * FsblInstancePtr);
/**
* Functions from xfsbl_misc.c
*/
void XFsbl_RegisterHandlers(void);
/**
*Functions from xfsbl_qspi.c
*/
/************************** Variable Definitions *****************************/
/****************************************************************************/
/**
* This function is used to initialize the FsblInstance with the
* default values
*
* @param FsblInstancePtr is pointer to the XFsbl Instance
*
* @return None
*
* @note
*
*****************************************************************************/
void XFsbl_CfgInitialize (XFsblPs * FsblInstancePtr)
{
FsblInstancePtr->Version = 0x3U;
FsblInstancePtr->ErrorCode = XFSBL_SUCCESS;
FsblInstancePtr->HandoffCpuNo = 0U;
}
/*****************************************************************************/
/**
* This function is initializes the processor and system.
*
* @param FsblInstancePtr is pointer to the XFsbl Instance
*
* @return
* - returns the error codes described in xfsbl_error.h on any error
* - returns XFSBL_SUCCESS on success
*
*****************************************************************************/
u32 XFsbl_Initialize(XFsblPs * FsblInstancePtr)
{
u32 Status = XFSBL_SUCCESS;
/**
* Configure the system as in PS8
*/
Status = XFsbl_SystemInit(FsblInstancePtr);
if (XFSBL_SUCCESS != Status)
{
goto END;
}
#ifdef STDOUT_BASEADDRESS
Init_Uart();
#endif
/**
* Print the FSBL banner
*/
XFsbl_PrintFsblBanner();
/**
* Initialize the processor
*/
Status = XFsbl_ProcessorInit(FsblInstancePtr);
if (XFSBL_SUCCESS != Status)
{
goto END;
}
/**
* Validate the reset reason
*/
Status = XFsbl_ResetValidation(FsblInstancePtr);
if (XFSBL_SUCCESS != Status)
{
goto END;
}
XFsbl_Printf(DEBUG_INFO,"Processor Initialization Done \n\r");
END:
return Status;
}
/*****************************************************************************/
/**
* This function initializes the primary and secondary boot devices
* and validates the image header
*
* @param FsblInstancePtr is pointer to the XFsbl Instance
*
* @return returns the error codes described in xfsbl_error.h on any error
* returns XFSBL_SUCCESS on success
******************************************************************************/
u32 XFsbl_BootDeviceInitAndValidate(XFsblPs * FsblInstancePtr)
{
u32 Status = XFSBL_SUCCESS;
/**
* Configure the primary boot device
*/
Status = XFsbl_PrimaryBootDeviceInit(FsblInstancePtr);
if (XFSBL_SUCCESS != Status)
{
goto END;
}
/**
* Read and Validate the header
*/
Status = XFsbl_ValidateHeader(FsblInstancePtr);
if (XFSBL_SUCCESS != Status)
{
goto END;
}
/**
* Update the secondary boot device
*/
FsblInstancePtr->SecondaryBootDevice =
FsblInstancePtr->ImageHeader.ImageHeaderTable.PartitionPresentDevice;
/**
* Configure the secondary boot device if required
*/
if (FsblInstancePtr->SecondaryBootDevice !=
FsblInstancePtr->PrimaryBootDevice)
{
Status = XFsbl_SecondaryBootDeviceInit(FsblInstancePtr);
if (XFSBL_SUCCESS != Status)
{
goto END;
}
}
END:
return Status;
}
/*****************************************************************************/
/**
* This function initializes the processor and updates the cluster id
* which indicates CPU on which fsbl is running
*
* @param FsblInstancePtr is pointer to the XFsbl Instance
*
* @return returns the error codes described in xfsbl_error.h on any error
* returns XFSBL_SUCCESS on success
*
******************************************************************************/
static u32 XFsbl_ProcessorInit(XFsblPs * FsblInstancePtr)
{
u32 Status = XFSBL_SUCCESS;
//u64 ClusterId=0U;
PTRSIZE ClusterId=0U;
u32 RegValue;
u32 Index=0U;
/**
* Read the cluster ID and Update the Processor ID
* Initialize the processor settings that are not done in
* BSP startup code
*/
#ifdef XFSBL_A53
ClusterId = mfcp(MPIDR_EL1);
#else
ClusterId = mfcp(XREG_CP15_MULTI_PROC_AFFINITY);
#endif
XFsbl_Printf(DEBUG_INFO,"Cluster ID 0x%0lx\n\r", ClusterId);
if (XFSBL_PLATFORM == XFSBL_PLATFORM_QEMU)
{
/**
* Remmaping for R5 in QEMU
*/
if (ClusterId == 0x80000004U)
{
ClusterId = 0xC0000100U;
}
}
/**
* store the processor ID based on the cluster ID
* Need a check for unsupported Cluster ID
*/
if ((ClusterId & XFSBL_CLUSTER_ID_MASK) == XFSBL_A53_PROCESSOR)
{
XFsbl_Printf(DEBUG_GENERAL,"Running on A53-0 Processor \n\r");
FsblInstancePtr->ProcessorID =
XIH_PH_ATTRB_DEST_CPU_A53_0;
} else {
RegValue = XFsbl_In32(RPU_RPU_GLBL_CNTL);
if ((RegValue & RPU_RPU_GLBL_CNTL_SLSPLIT_MASK) == 0U)
{
XFsbl_Printf(DEBUG_GENERAL,
"Running on R5 Processor in Lockstep \n\r");
FsblInstancePtr->ProcessorID =
XIH_PH_ATTRB_DEST_CPU_R5_L;
} else {
XFsbl_Printf(DEBUG_GENERAL,
"Running on R5-0 Processor \n\r");
FsblInstancePtr->ProcessorID =
XIH_PH_ATTRB_DEST_CPU_R5_0;
}
/**
* Update the Vector locations in R5 TCM
*/
while (Index<32U)
{
XFsbl_Out32(Index, 0U);
XFsbl_Out32(Index, XFSBL_R5_VECTOR_VALUE);
Index += 4;
}
}
/**
* Enable the exceptions
* Register the exception handlers
*/
#ifndef XFSBL_A53
XFsbl_RegisterHandlers();
#endif
return Status;
}
/*****************************************************************************/
/**
* This function validates the reset reason
*
* @param FsblInstancePtr is pointer to the XFsbl Instance
*
* @return returns the error codes described in xfsbl_error.h on any error
* returns XFSBL_SUCCESS on success
*
******************************************************************************/
static u32 XFsbl_ResetValidation(XFsblPs * FsblInstancePtr)
{
u32 Status = XFSBL_SUCCESS;
#if 0
u32 FsblErrorStatus=0U;
u32 ResetReasonValue=0U;
/**
* Read the Error Status register
* If WDT reset, do fallback
*/
FsblErrorStatus = XFsbl_In32(XFSBL_ERROR_STATUS_REGISTER_OFFSET);
ResetReasonValue = XFsbl_In32(CRL_APB_RESET_REASON);
/**
* Add LPD_SWDT for r5
* check if the reset is due to system WDT during
* previous FSBL execution
*/
/* WDT reset is missing in reset reason */
if (((ResetReasonValue & CRL_APB_RESET_REASON_FPD_SWDT_MASK)
== CRL_APB_RESET_REASON_FPD_SWDT_MASK) &&
(FsblErrorStatus == XFSBL_RUNNING))
{
/**
* reset is due to System WDT.
* Do a fallback
*/
Status = XFSBL_ERROR_SYSTEM_WDT_RESET;
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_SYSTEM_WDT_RESET\n\r");
goto END;
}
/**
* Mark FSBL running in error status register to
* detect the WDT reset while FSBL execution
*/
if (FsblErrorStatus != XFSBL_RUNNING)
{
XFsbl_Out32(XFSBL_ERROR_STATUS_REGISTER_OFFSET,
XFSBL_RUNNING);
}
/**
* Read system error status register
* provide FsblHook function for any action
*/
END:
#endif
return Status;
}
/*****************************************************************************/
/**
* This function initializes the system using the ps8_init()
*
* @param FsblInstancePtr is pointer to the XFsbl Instance
*
* @return returns the error codes described in xfsbl_error.h on any error
* returns XFSBL_SUCCESS on success
*
******************************************************************************/
static u32 XFsbl_SystemInit(XFsblPs * FsblInstancePtr)
{
u32 Status = XFSBL_SUCCESS;
/**
* ps8 initialization
*/
Status = (u32 )pss_init();
if (XFSBL_SUCCESS != Status)
{
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_PS8_INIT_FAILED\n\r");
/**
* Need to check a way to communicate both FSBL code
* and PS8 init error code
*/
Status = XFSBL_PS8_INIT_FAILED + Status;
goto END;
}
/**
* DDR Check if present
*/
/**
* Poweroff the unused blocks as per PS8
*/
END:
return Status;
}
/*****************************************************************************/
/**
* This function initializes the primary boot device
*
* @param FsblInstancePtr is pointer to the XFsbl Instance
*
* @return returns the error codes described in xfsbl_error.h on any error
* returns XFSBL_SUCCESS on success
*
******************************************************************************/
static u32 XFsbl_PrimaryBootDeviceInit(XFsblPs * FsblInstancePtr)
{
u32 Status = XFSBL_SUCCESS;
u32 BootMode=0U;
/**
* Read Boot Mode register and update the value
*/
BootMode = XFsbl_In32(CRL_APB_BOOT_MODE_USER) &
CRL_APB_BOOT_MODE_USER_BOOT_MODE_MASK;
FsblInstancePtr->PrimaryBootDevice = BootMode;
/**
* Enable drivers only if they are device boot modes
* Not required for JTAG modes
*/
if ( (BootMode == XFSBL_QSPI24_BOOT_MODE) ||
(BootMode == XFSBL_QSPI32_BOOT_MODE) ||
(BootMode == XFSBL_NAND_BOOT_MODE) ||
(BootMode == XFSBL_SD_BOOT_MODE) ||
(BootMode == XFSBL_EMMC_BOOT_MODE) )
{
/**
* Initialize the WDT and CSU drivers
*/
#ifdef XFSBL_WDT_PRESENT
Status = XFsbl_InitWdt();
if (XFSBL_SUCCESS != Status)
{
XFsbl_Printf(DEBUG_GENERAL,"WDT initialization failed \n\r");
goto END;
}
#endif
}
switch(BootMode)
{
/**
* For JTAG boot mode, it will be in while loop
*/
case XFSBL_JTAG_BOOT_MODE:
{
XFsbl_Printf(DEBUG_GENERAL,"In JTAG Boot Mode \n\r");
Status = XFSBL_STATUS_JTAG;
}
break;
case XFSBL_QSPI24_BOOT_MODE:
{
#ifdef XFSBL_QSPI
XFsbl_Printf(DEBUG_GENERAL,"QSPI 24bit Boot Mode \n\r");
/**
* Update the deviceops structure with necessary values
*/
FsblInstancePtr->DeviceOps.DeviceInit = XFsbl_Qspi24Init;
FsblInstancePtr->DeviceOps.DeviceCopy = XFsbl_Qspi24Copy;
FsblInstancePtr->DeviceOps.DeviceRelease = XFsbl_Qspi24Release;
#else
/**
* This bootmode is not supported in this release
*/
XFsbl_Printf(DEBUG_GENERAL,
"XFSBL_ERROR_UNSUPPORTED_BOOT_MODE\n\r");
Status = XFSBL_ERROR_UNSUPPORTED_BOOT_MODE;
#endif
}
break;
case XFSBL_QSPI32_BOOT_MODE:
{
XFsbl_Printf(DEBUG_GENERAL,"QSPI 32 bit Boot Mode \n\r");
/**
* Update the deviceops structure with necessary values
*
*/
/**
* This bootmode is not supported in this release
*/
XFsbl_Printf(DEBUG_GENERAL,
"XFSBL_ERROR_UNSUPPORTED_BOOT_MODE\n\r");
Status = XFSBL_ERROR_UNSUPPORTED_BOOT_MODE;
}break;
case XFSBL_NAND_BOOT_MODE:
{
XFsbl_Printf(DEBUG_GENERAL,"NAND Boot Mode \n\r");
#ifdef XFSBL_NAND
/**
* Update the deviceops structure with necessary values
*
*/
FsblInstancePtr->DeviceOps.DeviceInit = XFsbl_NandInit;
FsblInstancePtr->DeviceOps.DeviceCopy = XFsbl_NandCopy;
FsblInstancePtr->DeviceOps.DeviceRelease =
XFsbl_NandRelease;
#else
/**
* This bootmode is not supported in this release
*/
XFsbl_Printf(DEBUG_GENERAL,
"XFSBL_ERROR_UNSUPPORTED_BOOT_MODE\n\r");
Status = XFSBL_ERROR_UNSUPPORTED_BOOT_MODE;
#endif
} break;
case XFSBL_SD_BOOT_MODE:
{
XFsbl_Printf(DEBUG_GENERAL,"SD Boot Mode \n\r");
#ifdef XFSBL_SD
/**
* Update the deviceops structure with necessary values
*/
FsblInstancePtr->DeviceOps.DeviceInit = XFsbl_SdInit;
FsblInstancePtr->DeviceOps.DeviceCopy = XFsbl_SdCopy;
FsblInstancePtr->DeviceOps.DeviceRelease = XFsbl_SdRelease;
#else
/**
* This bootmode is not supported in this release
*/
XFsbl_Printf(DEBUG_GENERAL,
"XFSBL_ERROR_UNSUPPORTED_BOOT_MODE\n\r");
Status = XFSBL_ERROR_UNSUPPORTED_BOOT_MODE;
#endif
} break;
case XFSBL_EMMC_BOOT_MODE:
{
XFsbl_Printf(DEBUG_GENERAL,"eMMC Boot Mode \n\r");
/**
* Update the deviceops structure with necessary values
*
*/
/**
* This bootmode is not supported in this release
*/
XFsbl_Printf(DEBUG_GENERAL,
"XFSBL_ERROR_UNSUPPORTED_BOOT_MODE\n\r");
Status = XFSBL_ERROR_UNSUPPORTED_BOOT_MODE;
} break;
case XFSBL_USB_BOOT_MODE:
{
XFsbl_Printf(DEBUG_GENERAL,"USB Boot Mode \n\r");
/**
* Update the deviceops structure with necessary values
*
*/
/**
* This bootmode is not supported in this release
*/
XFsbl_Printf(DEBUG_GENERAL,
"XFSBL_ERROR_UNSUPPORTED_BOOT_MODE\n\r");
Status = XFSBL_ERROR_UNSUPPORTED_BOOT_MODE;
} break;
default:
{
XFsbl_Printf(DEBUG_GENERAL,
"XFSBL_ERROR_UNSUPPORTED_BOOT_MODE\n\r");
Status = XFSBL_ERROR_UNSUPPORTED_BOOT_MODE;
} break;
}
/**
* In case of error or Jtag boot, goto end
*/
if (XFSBL_SUCCESS != Status)
{
goto END;
}
/**
* Initialize the Device Driver
*/
Status = FsblInstancePtr->DeviceOps.DeviceInit();
if (XFSBL_SUCCESS != Status)
{
goto END;
}
END:
return Status;
}
/*****************************************************************************/
/**
* This function validates the image header
*
* @param FsblInstancePtr is pointer to the XFsbl Instance
*
* @return returns the error codes described in xfsbl_error.h on any error
* returns XFSBL_SUCCESS on success
*
******************************************************************************/
static u32 XFsbl_ValidateHeader(XFsblPs * FsblInstancePtr)
{
u32 Status = XFSBL_SUCCESS;
u32 MultiBootOffset=0U;
u32 BootHdrAttrb=0U;
u32 FlashImageOffsetAddress=0U;
u32 EfuseCtrl=0U;
/**
* Read the Multiboot Register
*/
MultiBootOffset = XFsbl_In32(CSU_CSU_MULTI_BOOT);
XFsbl_Printf(DEBUG_INFO,"Multiboot Reg : 0x%0lx \n\r", MultiBootOffset);
/**
* Calculate the Flash Offset Address
*/
FsblInstancePtr->ImageOffsetAddress =
MultiBootOffset * XFSBL_IMAGE_SEARCH_OFFSET;
FlashImageOffsetAddress = FsblInstancePtr->ImageOffsetAddress;
/**
* Read Boot Image attributes
*/
Status = FsblInstancePtr->DeviceOps.DeviceCopy(FlashImageOffsetAddress
+ XIH_BH_IMAGE_ATTRB_OFFSET,
(PTRSIZE ) &BootHdrAttrb, XIH_FIELD_LEN);
if (XFSBL_SUCCESS != Status)
{
XFsbl_Printf(DEBUG_GENERAL,"Device Copy Failed \n\r");
goto END;
}
FsblInstancePtr->BootHdrAttributes = BootHdrAttrb;
/**
* Read Image Header and validate Image Header Table
*/
Status = XFsbl_ReadImageHeader(&FsblInstancePtr->ImageHeader,
&FsblInstancePtr->DeviceOps,
FlashImageOffsetAddress);
if (XFSBL_SUCCESS != Status)
{
goto END;
}
/**
* Read Efuse bit and check Boot Header for Authentication
*/
EfuseCtrl = XFsbl_In32(EFUSE_RSA_CTRL);
if (((EfuseCtrl & EFUSE_RSA_CTRL_RSA_EN_MASK) != 0) ||
((BootHdrAttrb & XIH_BH_IMAGE_ATTRB_RSA_MASK)
== XIH_BH_IMAGE_ATTRB_RSA_MASK))
{
XFsbl_Printf(DEBUG_INFO,"Authentication Enabled\r\n");
#ifdef XFSBL_RSA
/**
* Authenticate the image header
*/
#else
XFsbl_Printf(DEBUG_GENERAL,"Rsa code not Enabled\r\n");
Status = XFSBL_ERROR_RSA_NOT_ENABLED;
goto END;
#endif
}
END:
return Status;
}
/*****************************************************************************/
/**
* This function initializes secondary boot device
*
* @param FsblInstancePtr is pointer to the XFsbl Instance
*
* @return returns the error codes described in xfsbl_error.h on any error
* returns XFSBL_SUCCESS on success
*
******************************************************************************/
static u32 XFsbl_SecondaryBootDeviceInit(XFsblPs * FsblInstancePtr)
{
u32 Status = XFSBL_SUCCESS;
/**
* Update the deviceops structure
*/
/**
* Initialize the Secondary Boot Device Driver
*/
return Status;
}

View file

@ -0,0 +1,416 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xfsbl_main.c
*
* This is the main file which contains code for the FSBL.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 kc 10/21/13 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xfsbl_hw.h"
#include "xfsbl_main.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
XFsblPs FsblInstancePtr;
/*****************************************************************************/
/** This is the FSBL main function and is implemented stage wise.
*
* @param None
*
* @return None
*
*****************************************************************************/
int main(void )
{
/**
* Local variables
*/
u32 FsblStatus = XFSBL_SUCCESS;
u32 FsblStage = XFSBL_STAGE1;
u32 PartitionNum=0U;
/**
* Initialize globals.
*/
FsblInstancePtr.ErrorCode = FsblStatus;
while (1) {
switch (FsblStage)
{
case XFSBL_STAGE1:
{
/**
* Initialize the system
*/
XFsbl_CfgInitialize(&FsblInstancePtr);
FsblStatus = XFsbl_Initialize(&FsblInstancePtr);
if (XFSBL_SUCCESS != FsblStatus)
{
FsblStatus += XFSBL_ERROR_STAGE_1;
FsblStage = XFSBL_STAGE_ERR;
} else {
/**
*
* Include the code for FSBL time measurements
* Initialize the global timer and get the value
*/
FsblStage = XFSBL_STAGE2;
}
}break;
case XFSBL_STAGE2:
{
XFsbl_Printf(DEBUG_INFO,
"================= In Stage 2 ============ \n\r");
/**
* Primary Device
* Secondary boot device
* DeviceOps
* image header
* partition header
*/
FsblStatus = XFsbl_BootDeviceInitAndValidate(&FsblInstancePtr);
if ( (XFSBL_SUCCESS != FsblStatus) &&
(XFSBL_STATUS_JTAG != FsblStatus) )
{
XFsbl_Printf(DEBUG_GENERAL,"Boot Device "
"Initialization failed 0x%0lx\n\r", FsblStatus);
FsblStatus += XFSBL_ERROR_STAGE_2;
FsblStage = XFSBL_STAGE_ERR;
} else if (XFSBL_STATUS_JTAG == FsblStatus) {
/**
* This is JTAG boot mode, go to the handoff stage
*/
FsblStage = XFSBL_STAGE4;
} else {
XFsbl_Printf(DEBUG_INFO,"Initialization Success \n\r");
/**
* Start the partition loading from 1
* 0th partition will be FSBL
*/
PartitionNum = 0x1U;
FsblStage = XFSBL_STAGE3;
}
} break;
case XFSBL_STAGE3:
{
XFsbl_Printf(DEBUG_INFO,
"======= In Stage 3, Partition No:%d ======= \n\r",
PartitionNum);
/**
* Load the partitions
* image header
* partition header
* partition parameters
*/
FsblStatus = XFsbl_PartitionLoad(&FsblInstancePtr,
PartitionNum);
if (XFSBL_SUCCESS != FsblStatus)
{
/**
* Error
*/
XFsbl_Printf(DEBUG_GENERAL,"Partition %d Load Failed, 0x%0lx\n\r",
PartitionNum, FsblStatus);
FsblStatus += XFSBL_ERROR_STAGE_3;
FsblStage = XFSBL_STAGE_ERR;
} else {
XFsbl_Printf(DEBUG_INFO,"Partition %d Load Success \n\r",
PartitionNum);
/**
* Check loading all partitions is completed
*/
if (PartitionNum <
(FsblInstancePtr.ImageHeader.ImageHeaderTable.NoOfPartitions-1U))
{
/**
* No need to change the Fsbl Stage
* Load the next partition
*/
PartitionNum++;
} else {
/**
* No more partitions present, go to handoff stage
*/
XFsbl_Printf(DEBUG_INFO,"All Partitions Loaded \n\r");
FsblStage = XFSBL_STAGE4;
}
} /* End of else loop for Load Success */
} break;
case XFSBL_STAGE4:
{
XFsbl_Printf(DEBUG_INFO,
"================= In Stage 4 ============ \n\r");
/**
* Handoff to the applications
* Handoff address
* xip
* ps7 post config
*/
FsblStatus = XFsbl_Handoff(&FsblInstancePtr);
if (XFSBL_SUCCESS != FsblStatus)
{
/**
* Error
*/
XFsbl_Printf(DEBUG_GENERAL,"Handoff Failed 0x%0lx\n\r", FsblStatus);
FsblStatus += XFSBL_ERROR_STAGE_4;
FsblStage = XFSBL_STAGE_ERR;
} else {
/**
* we should never be here
*/
FsblStage = XFSBL_STAGE_DEFAULT;
}
} break;
case XFSBL_STAGE_ERR:
{
XFsbl_Printf(DEBUG_INFO,
"================= In Stage Err ============ \n\r");
XFsbl_ErrorLockDown(FsblStatus);
/**
* we should never be here
*/
FsblStage = XFSBL_STAGE_DEFAULT;
}break;
case XFSBL_STAGE_DEFAULT:
default:
{
/**
* we should never be here
*/
XFsbl_Printf(DEBUG_GENERAL,"In default stage: "
"We should never be here \n\r");
/**
* Exit FSBL
*/
XFsbl_HandoffExit(0U, XFSBL_NO_HANDOFFEXIT);
}break;
} /* End of switch(FsblStage) */
} /* End of while(1) */
/**
* We should never be here
*/
XFsbl_Printf(DEBUG_GENERAL,"In default stage: "
"We should never be here \n\r");
/**
* Exit FSBL
*/
XFsbl_HandoffExit(0U, XFSBL_NO_HANDOFFEXIT);
return 0;
}
void XFsbl_PrintFsblBanner(void )
{
/**
* Print the FSBL Banner
*/
XFsbl_Printf(DEBUG_GENERAL,"Xilinx First Stage Boot Loader \n\r");
XFsbl_Printf(DEBUG_GENERAL,"Release SW Beta1 %s-%s\r\n",
__DATE__,__TIME__);
/**
* Print the platform
*/
if (XFSBL_PLATFORM == XFSBL_PLATFORM_QEMU)
{
XFsbl_Printf(DEBUG_GENERAL, "Platform: QEMU, ");
} else if (XFSBL_PLATFORM == XFSBL_PLATFORM_REMUS)
{
XFsbl_Printf(DEBUG_GENERAL, "Platform: REMUS, ");
} else if (XFSBL_PLATFORM == XFSBL_PLATFORM_VELOCE)
{
XFsbl_Printf(DEBUG_GENERAL, "Platform: VELOCE, ");
} else {
XFsbl_Printf(DEBUG_GENERAL, "Platform Not identified \r\n");
}
/**
* Print the RTL Version
*/
XFsbl_Printf(DEBUG_GENERAL, "RTL Version: %0lx\r\n", XFSBL_RTL_VERSION);
return ;
}
/*****************************************************************************/
/**
* This function is called in FSBL error cases. Error status
* register is updated and fallback is applied
*
* @param ErrorStatus is the error code which is written to the
* error status register
*
* @return none
*
* @note Fallback is applied only for fallback supported bootmodes
*****************************************************************************/
void XFsbl_ErrorLockDown(u32 ErrorStatus)
{
u32 BootMode=0U;
/**
* Print the FSBL error
*/
XFsbl_Printf(DEBUG_GENERAL,"Fsbl Error Status: 0x%08lx\r\n",
ErrorStatus);
/**
* Update the error status register
* and Fsbl instance structure
*/
XFsbl_Out32(XFSBL_ERROR_STATUS_REGISTER_OFFSET, ErrorStatus);
FsblInstancePtr.ErrorCode = ErrorStatus;
/**
* Read Boot Mode register
*/
BootMode = XFsbl_In32(CRL_APB_BOOT_MODE_USER) &
CRL_APB_BOOT_MODE_USER_BOOT_MODE_MASK;
/**
* Fallback if bootmode supports
*/
if ( (BootMode == XFSBL_QSPI24_BOOT_MODE) ||
(BootMode == XFSBL_QSPI32_BOOT_MODE) ||
(BootMode == XFSBL_NAND_BOOT_MODE) ||
(BootMode == XFSBL_SD_BOOT_MODE) ||
(BootMode == XFSBL_EMMC_BOOT_MODE) )
{
XFsbl_FallBack();
} else {
/**
* Be in while loop if fallback is not supported
*/
XFsbl_Printf(DEBUG_GENERAL,"Fallback not supported \n\r");
/**
* Exit FSBL
*/
XFsbl_HandoffExit(0U, XFSBL_NO_HANDOFFEXIT);
}
/**
* Should never be here
*/
return ;
}
/*****************************************************************************/
/**
* In Fallback, soft reset is applied to the system after incrementing
* the multiboot register. A hook is provided to before the fallback so
* that users can write their own code before soft reset
*
* @param none
*
* @return none
*
* @note We will not return from this function as it does soft reset
*****************************************************************************/
void XFsbl_FallBack(void )
{
/**
* Increment the Multiboot register
*/
/**
* Hook before FSBL Fallback
*/
/**
* dsb and isb to make sure every thing completes
*/
/**
* Soft reset the system
*/
/**
* Fall back is not supported now, placing CPU in wfe state
* Exit FSBL
*/
XFsbl_HandoffExit(0U, XFSBL_NO_HANDOFFEXIT);
return ;
}

View file

@ -0,0 +1,165 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xfsbl_main.h
*
* This is the main header file which contains definitions for the FSBL.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 kc 10/21/13 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
#ifndef XFSBL_MAIN_H
#define XFSBL_MAIN_H
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xfsbl_image_header.h"
#include "xfsbl_misc_drivers.h"
#include "xfsbl_hw.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/**
* This stores the handoff Address of the different cpu's
*/
typedef struct {
u32 CpuSettings;
u64 HandoffAddress;
} XFsblPs_HandoffValues;
/**
* This is FSBL instance pointer. This stores all the information
* required for FSBL
*/
typedef struct {
u32 Version; /**< FSBL Version */
u32 PresentStage; /**< Stage */
u32 ProcessorID; /**< One of R5-0, R5-LS, A53-0 */
u32 BootHdrAttributes; /**< Boot Header attributes */
u32 ImageOffsetAddress; /**< Flash offset address */
XFsblPs_ImageHeader ImageHeader; /** Image header */
u32 ErrorCode; /**< Error code during FSBL failure */
u32 PrimaryBootDevice; /**< Primary boot device used for booting */
u32 SecondaryBootDevice; /**< Secondary boot device in image header*/
XFsblPs_DeviceOps DeviceOps; /**< Device operations for bootmodes */
u32 HandoffCpuNo; /**< Number of CPU's FSBL will handoff to */
XFsblPs_HandoffValues HandoffValues[10];
/**< Handoff address for different CPU's */
} XFsblPs;
/***************** Macros (Inline Functions) Definitions *********************/
#define XFSBL_RELEASE_YEAR 2014
#define XFSBL_RELEASE_VERSION 3
#define XFSBL_RUNNING (0xFFFFU)
#define XFSBL_COMPLETED (0x0U)
#define XFSBL_IMAGE_SEARCH_OFFSET (0x8000U) /**< 32KB offset */
/**
* Fsbl exit definitions
*/
#define XFSBL_NO_HANDOFFEXIT (0x0U)
#define XFSBL_HANDOFFEXIT (0x1U)
#define XFSBL_HANDOFFEXIT_32 (0x2U)
/**
* Boot Modes definition
*/
#define XFSBL_JTAG_BOOT_MODE (0x0U)
#define XFSBL_QSPI24_BOOT_MODE (0x1U)
#define XFSBL_QSPI32_BOOT_MODE (0x2U)
#define XFSBL_NAND_BOOT_MODE (0x4U)
#define XFSBL_SD_BOOT_MODE (0x5U)
#define XFSBL_EMMC_BOOT_MODE (0x6U)
#define XFSBL_USB_BOOT_MODE (0x7U)
/**
* FSBL stages definition
*/
#define XFSBL_STAGE1 (0x1U)
#define XFSBL_STAGE2 (0x2U)
#define XFSBL_STAGE3 (0x3U)
#define XFSBL_STAGE4 (0x4U)
#define XFSBL_STAGE_ERR (0x5U)
#define XFSBL_STAGE_DEFAULT (0x6U)
/************************** Function Prototypes ******************************/
/**
* Functions defined in xfsbl_main.c
*/
void XFsbl_PrintFsblBanner(void );
void XFsbl_ErrorLockDown(u32 ErrorStatus);
void XFsbl_FallBack(void );
/**
* Functions defined in xfsbl_initialization.c
*/
void XFsbl_CfgInitialize (XFsblPs * FsblInstancePtr);
u32 XFsbl_Initialize(XFsblPs * FsblInstancePtr);
u32 XFsbl_BootDeviceInitAndValidate(XFsblPs * FsblInstancePtr);
/**
* Functions defined in xfsbl_partition_load.c
*/
u32 XFsbl_PartitionLoad(XFsblPs * FsblInstancePtr, u32 PartitionNum);
/**
* Functions defined in xfsbl_handoff.c
*/
u32 XFsbl_Handoff (XFsblPs * FsblInstancePtr);
void XFsbl_HandoffExit(u64 HandoffAddress, u32 Flags);
/************************** Variable Definitions *****************************/
#ifdef __cplusplus
}
#endif
#endif /* XFSBL_MAIN_H */

View file

@ -0,0 +1,489 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xfsbl_common.c
*
* This is the file which contains common code for the FSBL.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 kc 10/21/13 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xfsbl_hw.h"
#include "xil_exception.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
#if 0
__inline void XFsbl_Printf(u32 DebugType,char *Format, ...)
{
#ifdef STDOUT_BASEADDRESS
va_list Args;
if (((DebugType) & XFsblDbgCurrentTypes) != 0)
{
va_start(Args, Format);
xil_printf(Format, Args);
va_end(Args);
}
#endif
}
#endif
/************************** Function Prototypes ******************************/
static char * XFsbl_Itoa(u32 Val, u32 Base);
static void XFsbl_UndefHandler (void);
#ifndef XFSBL_A53
static void XFsbl_SvcHandler (void);
static void XFsbl_PreFetchAbortHandler (void);
#endif
static void XFsbl_DataAbortHandler (void);
static void XFsbl_IrqHandler (void);
static void XFsbl_FiqHandler (void);
/**
* functions from xfsbl_main.c
*/
extern void XFsbl_ErrorLockDown(u32 ErrorStatus);
/************************** Variable Definitions *****************************/
static char ItoaBuf[20];
static const char *ItoaStringPtr = "0123456789abcdef";
/****************************************************************************/
/**
* This function is used to print the entire array in bytes as specified by the
* debug type
*
* @param DebugType printing of the array will happen as defined by the
* debug type
*
* @param Buf pointer to the buffer to be printed
*
* @param Len length of the bytes to be printed
*
* @param Str pointer to the data that is printed along the
* data
*
* @return None
*
* @note
*
*****************************************************************************/
void XFsbl_PrintArray (u32 DebugType, const u8 Buf[], u32 Len, const char *Str)
{
u32 Index=0U;
if ((DebugType & XFsblDbgCurrentTypes) != 0U)
{
XFsbl_Printf(DebugType, "%s START\r\n", Str);
for (Index=0U;Index<Len;Index++)
{
XFsbl_Printf(DEBUG_INFO, "%02lx ",Buf[Index]);
if (((Index+1U)%16U) == 0U){
XFsbl_Printf(DEBUG_INFO, "\r\n");
}
}
XFsbl_Printf(DebugType,"\r\n%s END\r\n",Str);
}
return;
}
/*****************************************************************************/
/**
*
*
*
* @param None
*
* @return None
*
******************************************************************************/
static char * XFsbl_Itoa(u32 Val, u32 Base)
{
u32 Count = 0;
ItoaBuf[17] = '\0';
ItoaBuf[18] = '\0';
for(Count=16U; ((0U < Val) && (0U < Count)) ; Count--)
{
ItoaBuf[Count] = ItoaStringPtr[Val % Base];
Val /= Base;
}
return (char *)(&ItoaBuf[Count+1]);
}
/*****************************************************************************/
/**
*
*
*
* @param None
*
* @return None
*
******************************************************************************/
char *XFsbl_Strcpy(char *DestPtr, const char *SrcPtr)
{
u32 Count;
for (Count=0U; SrcPtr[Count] != '\0'; ++Count)
{
DestPtr[Count] = SrcPtr[Count];
}
DestPtr[Count] = '\0';
return DestPtr;
}
/*****************************************************************************/
/**
*
*
*
* @param None
*
* @return None
*
******************************************************************************/
char * XFsbl_Strcat(char* Str1Ptr, const char* Str2Ptr)
{
while( *Str1Ptr )
{
Str1Ptr++;
}
while( *Str2Ptr )
{
*Str1Ptr = *Str2Ptr;
Str1Ptr++; Str2Ptr++;
}
*Str1Ptr = '\0';
return --Str1Ptr;
}
/*****************************************************************************/
/**
*
*
*
* @param None
*
* @return None
*
******************************************************************************/
void XFsbl_MemSet(void *SrcPtr, u8 Char, u32 Len)
{
u8 *UsPtr = SrcPtr;
while (Len != 0)
{
*UsPtr = Char;
UsPtr++;
Len--;
}
}
/*****************************************************************************/
/**
*
*
*
* @param None
*
* @return None
*
******************************************************************************/
void *XFsbl_MemCpy(void * DestPtr, const void * SrcPtr, u32 Len)
{
u8 *Dst = DestPtr;
const u8 *Src = SrcPtr;
/* Loop and copy. */
while (Len != 0)
{
*Dst = *Src;
Dst++;
Src++;
Len--;
}
return DestPtr;
}
/*****************************************************************************/
/**
*
*
*
* @param None
*
* @return None
*
******************************************************************************/
int XFsbl_MemCmp(const void *Str1Ptr, const void *Str2Ptr, u32 Count)
{
const u8 *S1Ptr = (const u8 *)Str1Ptr;
const u8 *S2Ptr = (const u8 *)Str2Ptr;
int Status = 0;
while (Count--)
{
if (*S1Ptr != *S2Ptr)
{
Status = ((*S1Ptr < *S2Ptr) ? -1 : 1);
break;
}
S1Ptr++;
S2Ptr++;
}
return Status;
}
/*****************************************************************************/
/**
*
*
*
* @param None
*
* @return None
*
******************************************************************************/
u32 XFsbl_Htonl(u32 Value1)
{
u32 Value2 = 0;
Value2 |= (Value1 & 0xFF000000) >> 24;
Value2 |= (Value1 & 0x00FF0000) >> 8;
Value2 |= (Value1 & 0x0000FF00) << 8;
Value2 |= (Value1 & 0x000000FF) << 24;
return Value2;
}
/*****************************************************************************/
/**
*
*
*
* @param None
*
* @return None
*
******************************************************************************/
void XFsbl_MakeSdFileName(char *XFsbl_SdEmmcFileName, u32 MultibootReg)
{
XFsbl_MemSet((void *)XFsbl_SdEmmcFileName, '\0', 32);
(void)XFsbl_Strcpy((char *)XFsbl_SdEmmcFileName, "BOOT");
(void)XFsbl_Strcat((char *)XFsbl_SdEmmcFileName,
(char*)XFsbl_Itoa(MultibootReg, 10));
(void)XFsbl_Strcat((char *)XFsbl_SdEmmcFileName, ".BIN");
XFsbl_Printf(DEBUG_INFO,
"File name is %s\r\n",XFsbl_SdEmmcFileName);
}
/****************************************************************************/
/**
*
* @param
*
* @return
*
* @note
*
*
*****************************************************************************/
static void XFsbl_UndefHandler (void)
{
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_UNDEFINED_EXCEPTION\n\r");
XFsbl_ErrorLockDown(XFSBL_ERROR_UNDEFINED_EXCEPTION);
}
#ifndef XFSBL_A53
/****************************************************************************/
/**
*
* @param
*
* @return
*
* @note
*
*
*****************************************************************************/
static void XFsbl_SvcHandler (void)
{
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_SVC_EXCEPTION\n\r");
XFsbl_ErrorLockDown(XFSBL_ERROR_SVC_EXCEPTION);
}
/****************************************************************************/
/**
*
* @param
*
* @return
*
* @note
*
*****************************************************************************/
static void XFsbl_PreFetchAbortHandler (void)
{
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_PREFETCH_ABORT_EXCEPTION\n\r");
XFsbl_ErrorLockDown(XFSBL_ERROR_PREFETCH_ABORT_EXCEPTION);
}
#endif
/****************************************************************************/
/**
*
* @param
*
* @return
*
* @note
*
*
*****************************************************************************/
static void XFsbl_DataAbortHandler (void)
{
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_DATA_ABORT_EXCEPTION\n\r");
XFsbl_ErrorLockDown(XFSBL_ERROR_DATA_ABORT_EXCEPTION);
}
/****************************************************************************/
/**
*
* @param
*
* @return
*
* @note
*
*
*****************************************************************************/
static void XFsbl_IrqHandler (void)
{
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_IRQ_EXCEPTION\n\r");
XFsbl_ErrorLockDown(XFSBL_ERROR_IRQ_EXCEPTION);
}
/****************************************************************************/
/**
*
* @param
*
* @return
*
* @note
*
*
*****************************************************************************/
static void XFsbl_FiqHandler (void)
{
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_FIQ_EXCEPTION\n\r");
XFsbl_ErrorLockDown(XFSBL_ERROR_FIQ_EXCEPTION);
}
/*****************************************************************************/
/**
*
* This function Registers the Exception Handlers
*
* @param None.
*
* @return None.
*
* @note None.
*
****************************************************************************/
void XFsbl_RegisterHandlers(void)
{
Xil_ExceptionInit();
/*
* Initialize the vector table. Register the stub Handler for each
* exception.
*/
#ifdef XFSBL_A53
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_SYNC_INT,
(Xil_ExceptionHandler)XFsbl_UndefHandler,(void *) 0);
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
(Xil_ExceptionHandler)XFsbl_IrqHandler,(void *) 0);
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_FIQ_INT,
(Xil_ExceptionHandler)XFsbl_FiqHandler,(void *) 0);
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_SERROR_ABORT_INT,
(Xil_ExceptionHandler)XFsbl_DataAbortHandler,(void *) 0);
#else
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_UNDEFINED_INT,
(Xil_ExceptionHandler)XFsbl_UndefHandler,(void *) 0);
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_SWI_INT,
(Xil_ExceptionHandler)XFsbl_SvcHandler,(void *) 0);
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_PREFETCH_ABORT_INT,
(Xil_ExceptionHandler)XFsbl_PreFetchAbortHandler,(void *) 0);
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_DATA_ABORT_INT,
(Xil_ExceptionHandler)XFsbl_DataAbortHandler,(void *) 0);
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_IRQ_INT,
(Xil_ExceptionHandler)XFsbl_IrqHandler,(void *) 0);
Xil_ExceptionRegisterHandler(XIL_EXCEPTION_ID_FIQ_INT,
(Xil_ExceptionHandler)XFsbl_FiqHandler,(void *) 0);
#endif
Xil_ExceptionEnable();
}

View file

@ -0,0 +1,87 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xfsbl_common.c
*
* This is the file which contains common code for the FSBL.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 kc 10/21/13 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
#ifndef XFSBL_MISC_H
#define XFSBL_MISC_H
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xfsbl_hw.h"
#include "xil_exception.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
void XFsbl_PrintArray (u32 DebugType, const u8 Buf[], u32 Len, const char *Str);
void XFsbl_MemSet(void *SrcPtr, u8 Char, u32 Len);
void *XFsbl_MemCpy(void * DestPtr, const void * SrcPtr, u32 Len);
int XFsbl_MemCmp(const void *Str1Ptr, const void *Str2Ptr, u32 Count);
char *XFsbl_Strcpy(char *DestPtr, const char *SrcPtr);
char * XFsbl_Strcat(char* Str1Ptr, const char* Str2Ptr);
void XFsbl_MakeSdFileName(char *XFsbl_SdEmmcFileName, u32 MultibootReg);
u32 XFsbl_Htonl(u32 Value1);
#ifndef XFSBL_A53
void XFsbl_RegisterHandlers(void);
#endif
#ifdef __cplusplus
}
#endif
#endif /* XFSBL_MISC_H */

View file

@ -0,0 +1,222 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xfsbl_misc_drivers.c
*
* This is the header file which contains definitions for wrapper functions for
* WDT, CSUDMA drivers
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 kc 10/21/13 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xfsbl_hw.h"
#include "xfsbl_misc_drivers.h"
/**
* Include WDT only if WDT is present
*/
#ifdef XFSBL_WDT_PRESENT
#include "xwdtps.h"
#endif
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
#ifdef XFSBL_WDT_PRESENT
static XWdtPs Watchdog; /* Instance of WatchDog Timer */
#endif
/*****************************************************************************/
/**
* Include WDT code only if WDT is present
*/
#ifdef XFSBL_WDT_PRESENT
/**
* WDT driver wrapper functions
*/
/*****************************************************************************/
/**
* This function is used to initialize the system
*
* @param None
*
* @return None
*
*****************************************************************************/
u32 XFsbl_InitWdt()
{
u32 Status = XFSBL_SUCCESS;
XWdtPs_Config *ConfigPtr; /* Config structure of the WatchDog Timer */
u32 CounterValue = 1;
/**
* Initialize the WDT timer
*/
ConfigPtr = XWdtPs_LookupConfig(XFSBL_WDT_DEVICE_ID);
Status = XWdtPs_CfgInitialize(&Watchdog,
ConfigPtr,
ConfigPtr->BaseAddress);
if (Status != XST_SUCCESS) {
XFsbl_Printf(DEBUG_INFO, "XFSBL_WDT_INIT_FAILED\n\r");
Status = XFSBL_WDT_INIT_FAILED;
goto END;
}
/**
* Setting the divider value
*/
XWdtPs_SetControlValue(&Watchdog,
XWDTPS_CLK_PRESCALE,
XWDTPS_CCR_PSCALE_4096);
/**
* Convert time to Watchdog counter reset value
*/
CounterValue = XFsbl_ConvertTime_WdtCounter(XFSBL_WDT_EXPIRE_TIME);
/**
* Set the Watchdog counter reset value
*/
XWdtPs_SetControlValue(&Watchdog,
XWDTPS_COUNTER_RESET,
CounterValue);
/**
* enable reset output, as we are only using this as a basic counter
*/
XWdtPs_EnableOutput(&Watchdog, XWDTPS_RESET_SIGNAL);
/**
* Start the Watchdog timer
*/
XWdtPs_Start(&Watchdog);
XWdtPs_RestartWdt(&Watchdog);
END:
return Status;
}
/******************************************************************************
*
* This function converts time into Watchdog counter value
*
* @param watchdog expire time in seconds
*
* @return
* Counter value for Watchdog
*
* @note None
*
*******************************************************************************/
u32 XFsbl_ConvertTime_WdtCounter(u32 seconds)
{
double time = 0.0;
double CounterValue;
u32 Crv = 0;
u32 Prescaler=0;
u32 PrescalerValue=0;
Prescaler = XWdtPs_GetControlValue(&Watchdog, XWDTPS_CLK_PRESCALE);
if (Prescaler == XWDTPS_CCR_PSCALE_0008) {
PrescalerValue = 8;
} if (Prescaler == XWDTPS_CCR_PSCALE_0064) {
PrescalerValue = 64;
} if (Prescaler == XWDTPS_CCR_PSCALE_4096) {
PrescalerValue = 4096;
}
time = (double)(PrescalerValue) / (double)XPAR_PS8_WDT_0_WDT_CLK_FREQ_HZ;
CounterValue = seconds / time;
Crv = (u32)CounterValue;
Crv >>= XFSBL_WDT_CRV_SHIFT;
return Crv;
}
/******************************************************************************
*
* This function is used to restart Watchdog
*
* @param None
*
* @return None
*
* @note None
*
*******************************************************************************/
void XFsbl_RestartWdt()
{
XWdtPs_RestartWdt(&Watchdog);
}
/******************************************************************************
*
* This function is used to stop Watchdog
*
* @param None
*
* @return None
*
* @note None
*
*******************************************************************************/
void XFsbl_StopWdt()
{
XWdtPs_Stop(&Watchdog);
}
#endif /** end of WDT wrapper code */

View file

@ -0,0 +1,117 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xfsbl_misc_drivers.h
*
* This is the header file which contains declarations for wrapper functions
* for WDT, CSUDMA drivers
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 kc 10/21/13 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
#ifndef XFSBL_MISC_DRIVERS_H
#define XFSBL_MISC_DRIVERS_H
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xfsbl_hw.h"
/************************** Constant Definitions *****************************/
#ifdef XFSBL_WDT_PRESENT
#define XFSBL_WDT_DEVICE_ID (XPAR_XWDTPS_0_DEVICE_ID)
#define XFSBL_WDT_EXPIRE_TIME (100U)
#define XFSBL_WDT_CRV_SHIFT (12U)
#endif
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
#ifdef XFSBL_WDT_PRESENT
u32 XFsbl_InitWdt();
u32 XFsbl_ConvertTime_WdtCounter(u32 seconds);
#endif
/************************** Variable Definitions *****************************/
typedef struct {
u32 DeviceBaseAddress; /**< Flash device base address */
u32 (*DeviceInit) ();
/**< Function pointer for Device initialization code */
u32 (*DeviceCopy) (u32 SrcAddress, PTRSIZE DestAddress, u32 Length);
/**< Function pointer for device copy */
u32 (*DeviceRelease) ();
/**< Function pointer for device release */
} XFsblPs_DeviceOps;
/**
* SD driver functions
*/
#ifdef XFSBL_SD
u32 XFsbl_SdInit(void );
u32 XFsbl_SdCopy(u32 SrcAddress, PTRSIZE DestAddress, u32 Length);
u32 XFsbl_SdRelease(void );
#endif
/**
* NAND driver functions
*/
#ifdef XFSBL_NAND
u32 XFsbl_NandInit(void );
u32 XFsbl_NandCopy(u32 SrcAddress, PTRSIZE DestAddress, u32 Length);
u32 XFsbl_NandRelease(void );
#endif
#ifdef __cplusplus
}
#endif
#endif /* XFSBL_MISC_DRIVERS_H */

View file

@ -0,0 +1,159 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xfsbl_nand.c
*
* This is the file which contains nand related code for the FSBL.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 kc 04/21/14 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xfsbl_hw.h"
#ifdef XFSBL_NAND
#include "xnandps8.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
#define NAND_DEVICE_ID 0
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
XNandPs8_Config *Config;
XNandPs8 NandInstance; /* XNand Instance */
XNandPs8 *NandInstPtr = &NandInstance;
/*****************************************************************************/
/**
* This function is used to initialize the qspi controller and driver
*
* @param None
*
* @return None
*
*****************************************************************************/
u32 XFsbl_NandInit(void )
{
u32 Status = XFSBL_SUCCESS;
Config = XNandPs8_LookupConfig(NAND_DEVICE_ID);
if (Config == NULL) {
Status = XFSBL_ERROR_NAND_INIT;
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_NAND_INIT\r\n");
goto END;
}
/**
* Initialize the NAND flash driver.
*/
Status = (u32 )XNandPs8_CfgInitialize(NandInstPtr, Config,
Config->BaseAddress);
if (Status != XST_SUCCESS) {
Status = XFSBL_ERROR_NAND_INIT;
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_NAND_INIT\r\n");
goto END;
}
XFsbl_Printf(DEBUG_INFO,"Nand Init Success\r\n");
END:
return Status;
}
/*****************************************************************************/
/**
* This function is used to copy the data from NAND to destination
* address
*
* @param SrcAddress is the address of the NAND flash where copy should
* start from
*
* @param DestAddress is the address of the destination where it
* should copy to
*
* @param Length Length of the bytes to be copied
*
* @return
* - XFSBL_SUCCESS for successful copy
* - errors as mentioned in xfsbl_error.h
*
*****************************************************************************/
u32 XFsbl_NandCopy(u32 SrcAddress, PTRSIZE DestAddress, u32 Length)
{
u32 Status = XFSBL_SUCCESS;
Status = (u32 )XNandPs8_Read(NandInstPtr, (u64)SrcAddress, (u64)Length,
(u8 *) DestAddress);
if (Status != XST_SUCCESS) {
Status = XFSBL_ERROR_NAND_READ;
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_NAND_READ\r\n");
goto END;
}
END:
return Status;
}
/*****************************************************************************/
/**
* This function is used to release the nand settings
*
* @param None
*
* @return None
*
*****************************************************************************/
u32 XFsbl_NandRelease(void )
{
return XFSBL_SUCCESS;
}
#endif /* end of #ifdef XFSBL_NAND */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,640 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xfsbl_qspi.c
*
* This is the file which contains qspi related code for the FSBL.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 kc 10/21/13 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xfsbl_hw.h"
#include "xparameters.h"
#ifdef XFSBL_QSPI
#include "xqspips.h"
#include "xfsbl_qspi.h"
/************************** Constant Definitions *****************************/
/*
* The following constants map to the XPAR parameters created in the
* xparameters.h file. They are defined here such that a user can easily
* change all the needed parameters in one place.
*/
#define QSPI_DEVICE_ID XPAR_XQSPIPS_0_DEVICE_ID
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
void XFsbl_PrintArray (u32 DebugType, const u8 *Buf, u32 Len, const char *Str);
/************************** Variable Definitions *****************************/
static XQspiPs QspiInstance;
static XQspiPs *QspiInstancePtr;
static u32 QspiFlashSize=0;
static u32 QspiFlashMake=0;
static u32 ReadCommand=0;
/*
* The following variables are used to read and write to the eeprom and they
* are global to avoid having large buffers on the stack
*/
static u8 ReadBuffer[DATA_SIZE + DATA_OFFSET + DUMMY_SIZE];
static u8 WriteBuffer[DATA_OFFSET + DUMMY_SIZE];
/******************************************************************************
*
* This function reads serial FLASH ID connected to the SPI interface.
* It then deduces the make and size of the flash and obtains the
* connection mode to point to corresponding parameters in the flash
* configuration table. The flash driver will function based on this and
* it presently supports Micron and Spansion - 128, 256 and 512Mbit and
* Winbond 128Mbit
*
* @param none
*
* @return XST_SUCCESS if read id, otherwise XST_FAILURE.
*
* @note None.
*
******************************************************************************/
static u32 FlashReadID(void)
{
u32 Status = XFSBL_SUCCESS;
/*
* Read ID in Auto mode.
*/
WriteBuffer[COMMAND_OFFSET] = READ_ID_CMD;
WriteBuffer[ADDRESS_1_OFFSET] = 0x00; /* 3 dummy bytes */
WriteBuffer[ADDRESS_2_OFFSET] = 0x00;
WriteBuffer[ADDRESS_3_OFFSET] = 0x00;
Status = XQspiPs_PolledTransfer(QspiInstancePtr, WriteBuffer, ReadBuffer,
RD_ID_SIZE);
if (Status != XST_SUCCESS) {
Status = XFSBL_ERROR_QSPI_READ_ID;
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_QSPI_READ_ID\r\n");
goto END;
}
XFsbl_Printf(DEBUG_INFO,"Single Flash Information\r\n");
XFsbl_Printf(DEBUG_INFO,"FlashID=0x%x 0x%x 0x%x\r\n", ReadBuffer[1],
ReadBuffer[2],
ReadBuffer[3]);
/*
* Deduce flash make
*/
if (ReadBuffer[1] == MICRON_ID) {
QspiFlashMake = MICRON_ID;
XFsbl_Printf(DEBUG_INFO, "MICRON ");
} else if(ReadBuffer[1] == SPANSION_ID) {
QspiFlashMake = SPANSION_ID;
XFsbl_Printf(DEBUG_INFO, "SPANSION ");
} else if(ReadBuffer[1] == WINBOND_ID) {
QspiFlashMake = WINBOND_ID;
XFsbl_Printf(DEBUG_INFO, "WINBOND ");
} else {
Status = XFSBL_ERROR_UNSUPPORTED_QSPI;
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_UNSUPPORTED_QSPI\r\n");
goto END;
}
/*
* Deduce flash Size
*/
if (ReadBuffer[3] == FLASH_SIZE_ID_128M) {
QspiFlashSize = FLASH_SIZE_128M;
XFsbl_Printf(DEBUG_INFO, "128M Bits\r\n");
} else if (ReadBuffer[3] == FLASH_SIZE_ID_256M) {
QspiFlashSize = FLASH_SIZE_256M;
XFsbl_Printf(DEBUG_INFO, "256M Bits\r\n");
} else if (ReadBuffer[3] == FLASH_SIZE_ID_512M) {
QspiFlashSize = FLASH_SIZE_512M;
XFsbl_Printf(DEBUG_INFO, "512M Bits\r\n");
} else if (ReadBuffer[3] == FLASH_SIZE_ID_1G) {
QspiFlashSize = FLASH_SIZE_1G;
XFsbl_Printf(DEBUG_INFO, "1G Bits\r\n");
}else {
Status = XFSBL_ERROR_UNSUPPORTED_QSPI;
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_UNSUPPORTED_QSPI\r\n");
goto END;
}
END:
return Status;
}
/*****************************************************************************/
/**
* This function is used to initialize the qspi controller and driver
*
* @param None
*
* @return None
*
*****************************************************************************/
u32 XFsbl_Qspi24Init()
{
XQspiPs_Config *QspiConfig;
u32 Status = XFSBL_SUCCESS;
QspiInstancePtr = &QspiInstance;
/**
* Initialize the qspi driver
*/
/**
* Initialize the QSPI driver so that it's ready to use
*/
QspiConfig = XQspiPs_LookupConfig(QSPI_DEVICE_ID);
if (NULL == QspiConfig) {
Status = XFSBL_ERROR_QSPI_INIT;
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_QSPI_INIT\r\n");
goto END;
}
Status = XQspiPs_CfgInitialize(QspiInstancePtr, QspiConfig,
QspiConfig->BaseAddress);
if (Status != XST_SUCCESS) {
Status = XFSBL_ERROR_QSPI_INIT;
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_QSPI_INIT\r\n");
goto END;
}
/**
* Set the pre-scaler for QSPI clock
*/
Status = XQspiPs_SetClkPrescaler(QspiInstancePtr, XQSPIPS_CLK_PRESCALE_8);
if (Status != XST_SUCCESS) {
Status = XFSBL_ERROR_QSPI_INIT;
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_QSPI_INIT\r\n");
goto END;
}
/**
* Set Auto Start and Manual Chip select options and drive the
* HOLD_B high.
*/
Status = XQspiPs_SetOptions(QspiInstancePtr, XQSPIPS_FORCE_SSELECT_OPTION |
XQSPIPS_HOLD_B_DRIVE_OPTION);
if (Status != XST_SUCCESS) {
Status = XFSBL_ERROR_QSPI_INIT;
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_QSPI_INIT\r\n");
goto END;
}
/**
*
* configure the qspi in linear mode if running in XIP
* Configure the the qspi in IO mode
*/
switch (XPAR_PS8_QSPI_0_QSPI_MODE) {
case XQSPIPS_CONNECTION_MODE_SINGLE:
{
XFsbl_Printf(DEBUG_INFO,"QSPI is in single flash connection\r\n");
/**
* Single flash IO read
*/
XQspiPs_SetLqspiConfigReg(QspiInstancePtr,
SINGLE_QSPI_IO_CONFIG_QUAD_READ);
} break;
case XQSPIPS_CONNECTION_MODE_PARALLEL:
{
XFsbl_Printf(DEBUG_INFO,"QSPI is in Dual Parallel connection\r\n");
/**
* Dual parallel flash IO read
*/
XQspiPs_SetLqspiConfigReg(QspiInstancePtr,
DUAL_QSPI_PARALLEL_IO_CONFIG_QUAD_READ);
} break;
case XQSPIPS_CONNECTION_MODE_STACKED:
{
XFsbl_Printf(DEBUG_INFO,"QSPI is in Dual Stack connection\r\n");
/**
* Dual Stack flash IO read
*/
XQspiPs_SetLqspiConfigReg(QspiInstancePtr,
DUAL_QSPI_STACK_IO_CONFIG_READ);
}break;
default:
{
Status = XFSBL_ERROR_INVALID_QSPI_CONNECTION;
XFsbl_Printf(DEBUG_GENERAL,
"XFSBL_ERROR_INVALID_QSPI_CONNECTION\r\n");
goto END;
}break;
}
/**
* add code for 1x, 2x and 4x
*
*/
ReadCommand = QUAD_READ_CMD;
/**
* Assert the FLASH chip select.
*/
Status = XQspiPs_SetSlaveSelect(QspiInstancePtr);
if (Status != XST_SUCCESS) {
Status = XFSBL_ERROR_QSPI_INIT;
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_QSPI_INIT\r\n");
goto END;
}
/**
* Read Flash ID and extract Manufacture and Size information
*/
Status = FlashReadID();
if (Status != XFSBL_SUCCESS) {
goto END;
}
/**
* add code: For a Stacked connection, read second Flash ID
*/
if ((XPAR_PS8_QSPI_0_QSPI_MODE == XQSPIPS_CONNECTION_MODE_PARALLEL) ||
(XPAR_PS8_QSPI_0_QSPI_MODE == XQSPIPS_CONNECTION_MODE_STACKED) ) {
QspiFlashSize = 2 * QspiFlashSize;
}
END:
return Status;
}
/******************************************************************************
*
* This functions translates the address based on the type of interconnection.
* In case of stacked, this function asserts the corresponding slave select.
*
* @param Address which is to be accessed
*
* @return QspiAddr is the actual flash address to be accessed - for single
* it is unchanged; for stacked, the lower flash size is subtracted;
* for parallel the address is divided by 2.
*
* @note None.
*
*
******************************************************************************/
static u32 XFsbl_GetQspiAddr(u32 Address )
{
u32 LqspiCr=0;
u32 QspiAddr=0;
switch(XPAR_PS8_QSPI_0_QSPI_MODE) {
case XQSPIPS_CONNECTION_MODE_SINGLE:
QspiAddr = Address;
break;
case XQSPIPS_CONNECTION_MODE_STACKED:
/**
* Get the current LQSPI Config reg value
*/
LqspiCr = XQspiPs_GetLqspiConfigReg(QspiInstancePtr);
/* Select lower or upper Flash based on sector address */
if(Address > QspiFlashSize) {
/**
* Set selection to U_PAGE
*/
XQspiPs_SetLqspiConfigReg(QspiInstancePtr,
LqspiCr | XQSPIPS_LQSPI_CR_U_PAGE_MASK);
/**
* Subtract first flash size when accessing second flash
*/
QspiAddr = Address - QspiFlashSize;
}else{
/**
* Set selection to L_PAGE
*/
XQspiPs_SetLqspiConfigReg(QspiInstancePtr,
LqspiCr & (~XQSPIPS_LQSPI_CR_U_PAGE_MASK));
QspiAddr = Address;
}
/**
* Assert the Flash chip select.
*/
XQspiPs_SetSlaveSelect(QspiInstancePtr);
break;
case XQSPIPS_CONNECTION_MODE_PARALLEL:
/**
* The effective address in each flash is the actual
* address / 2
*/
QspiAddr = Address / 2;
break;
default:
/* RealAddr wont be assigned in this case; */
break;
}
return(QspiAddr);
}
/******************************************************************************
*
* This functions selects the current bank
*
* @param QspiPtr is a pointer to the QSPI driver component to use.
* @param Pointer to the write buffer which contains data to be transmitted
* @param BankSel is the bank to be selected in the flash device(s).
*
* @return XST_SUCCESS if bank selected, otherwise XST_FAILURE.
*
* @note None.
*
*
******************************************************************************/
static int SendBankSelect(u32 BankSel)
{
u32 Status = XFSBL_SUCCESS;
u8 WriteEnableCmd = { WRITE_ENABLE_CMD };
/**
* Bank select commands for Micron and Spansion are different
*/
if(QspiFlashMake == MICRON_ID) {
/**
* For Micron command WREN should be sent first
* except for some specific feature set
*/
Status = XQspiPs_PolledTransfer(QspiInstancePtr, &WriteEnableCmd, NULL,
sizeof(WriteEnableCmd));
if (Status != XST_SUCCESS) {
Status = XFSBL_FAILURE;
goto END;
}
WriteBuffer[COMMAND_OFFSET] = EXTADD_REG_WR;
WriteBuffer[ADDRESS_1_OFFSET] = BankSel;
/**
* Send the Extended address register write command
* written, no receive buffer required
*/
Status = XQspiPs_PolledTransfer(QspiInstancePtr, WriteBuffer, NULL,
BANK_SEL_SIZE);
if (Status != XST_SUCCESS) {
Status = XFSBL_FAILURE;
goto END;
}
}
if(QspiFlashMake == SPANSION_ID) {
WriteBuffer[COMMAND_OFFSET] = BANK_REG_WR;
WriteBuffer[ADDRESS_1_OFFSET] = BankSel;
/**
* Send the Extended address register write command
* written, no receive buffer required
*/
Status = XQspiPs_PolledTransfer(QspiInstancePtr, WriteBuffer, NULL,
BANK_SEL_SIZE);
if (Status != XST_SUCCESS) {
Status = XFSBL_FAILURE;
goto END;
}
}
/* Winbond can be added here */
END:
return Status;
}
/*****************************************************************************/
/**
* This function is used to copy the data from QSPI flash to destination
* address
*
* @param SrcAddress is the address of the QSPI flash where copy should
* start from
*
* @param DestAddress is the address of the destination where it
* should copy to
*
* @param Length Length of the bytes to be copied
*
* @return
* - XFSBL_SUCCESS for successful copy
* - errors as mentioned in xfsbl_error.h
*
*****************************************************************************/
u32 XFsbl_Qspi24Copy(u32 SrcAddress, PTRSIZE DestAddress, u32 Length)
{
u32 Status = XFSBL_SUCCESS;
u32 QspiAddr=0;
u32 BankSel=0;
u32 RemainingBytes=0;
u32 OverHeadBytes=0;
u32 TransferBytes=0;
XFsbl_Printf(DEBUG_INFO,"QSPI Reading Src 0x%0lx, Dest %0lx, Length %0lx\r\n",
SrcAddress, DestAddress, Length);
/**
* Check the read length with Qspi flash size
*/
if ((SrcAddress + Length) > QspiFlashSize)
{
Status = XFSBL_ERROR_QSPI_LENGTH;
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_QSPI_LENGTH\r\n");
goto END;
}
/**
* Update no of bytes to be copied
*/
RemainingBytes = Length;
while(RemainingBytes != 0) {
/**
* Copy bytes in terms of 4K blocks from flash
*/
if (RemainingBytes > DATA_SIZE)
{
TransferBytes = DATA_SIZE;
} else {
TransferBytes = RemainingBytes;
}
/**
* Translate address based on type of connection
* If stacked assert the slave select based on address
*/
QspiAddr = XFsbl_GetQspiAddr((u32 )SrcAddress);
/**
* Select bank
* check logic for DualQspi
*/
if(QspiFlashSize > BANKSIZE) {
BankSel = QspiAddr/BANKSIZE;
Status = SendBankSelect(BankSel);
if (Status != XFSBL_SUCCESS) {
Status = XFSBL_ERROR_QSPI_READ;
XFsbl_Printf(DEBUG_GENERAL,
"XFSBL_ERROR_QSPI_READ\r\n");
goto END;
}
}
/**
* If data to be read spans beyond the current bank, then
* calculate Transfer Bytes in current bank. Else
* transfer bytes are same
* check logic for DualQspi
*/
if((QspiAddr & BANKMASK) != ((QspiAddr+TransferBytes) & BANKMASK)) {
TransferBytes = (QspiAddr & BANKMASK) + BANKSIZE - QspiAddr;
}
/**
* Setup the read command with the specified address and data for the
* Flash
*/
WriteBuffer[COMMAND_OFFSET] = ReadCommand;
WriteBuffer[ADDRESS_1_OFFSET] = (u8)((QspiAddr & 0xFF0000) >> 16);
WriteBuffer[ADDRESS_2_OFFSET] = (u8)((QspiAddr & 0xFF00) >> 8);
WriteBuffer[ADDRESS_3_OFFSET] = (u8)(QspiAddr & 0xFF);
if ((ReadCommand == FAST_READ_CMD) || (ReadCommand == DUAL_READ_CMD) ||
(ReadCommand == QUAD_READ_CMD))
{
OverHeadBytes = OVERHEAD_SIZE + DUMMY_SIZE;
} else {
OverHeadBytes = OVERHEAD_SIZE;
}
/**
* Send the read command to the Flash to read the specified number
* of bytes from the Flash, send the read command and address and
* receive the specified number of bytes of data in the data buffer
*/
Status = XQspiPs_PolledTransfer(QspiInstancePtr, WriteBuffer,
ReadBuffer,TransferBytes + OverHeadBytes);
if (Status != XST_SUCCESS) {
Status = XFSBL_ERROR_QSPI_READ;
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_QSPI_READ\r\n");
goto END;
}
/**
* remove if not required
*/
XFsbl_PrintArray(DEBUG_DETAILED, ReadBuffer,
TransferBytes + OverHeadBytes, "QSPI READ DATA");
/**
* Moving the data from local buffer to DDR destination address
*/
XFsbl_MemCpy((u8 *)DestAddress, &ReadBuffer[OverHeadBytes],
TransferBytes);
XFsbl_Printf(DEBUG_INFO,".");
XFsbl_Printf(DEBUG_DETAILED,
"QSPI Read Src 0x%0lx, Dest %0lx, Length %0lx\r\n",
QspiAddr, DestAddress, TransferBytes);
/**
* Update the variables
*/
RemainingBytes -= TransferBytes;
DestAddress += TransferBytes;
SrcAddress += TransferBytes;
}
END:
return Status;
}
/*****************************************************************************/
/**
* This function is used to release the Qspi settings
*
* @param None
*
* @return None
*
*****************************************************************************/
u32 XFsbl_Qspi24Release()
{
u32 Status = XFSBL_SUCCESS;
return Status;
}
#endif /* endof XFSBL_QSPI */

View file

@ -0,0 +1,193 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xfsbl_qspi.h
*
* This is the header file which contains qspi declarations for the FSBL.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 kc 10/21/13 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
#ifndef XFSBL_QSPI_H
#define XFSBL_QSPI_H
#ifdef __cplusplus
extern "C" {
#endif
/***************************** Include Files *********************************/
#include "xil_types.h"
#include "xfsbl_hw.h"
#ifdef XFSBL_QSPI
/************************** Constant Definitions *****************************/
/*
* The following constants define the commands which may be sent to the FLASH
* device.
*/
#define FAST_READ_CMD (0x0BU)
#define DUAL_READ_CMD (0x3BU)
#define QUAD_READ_CMD (0x6BU)
#define READ_ID_CMD (0x9FU)
#define WRITE_ENABLE_CMD (0x06U)
#define BANK_REG_RD (0x16U)
#define BANK_REG_WR (0x17U)
/* Bank register is called Extended Address Reg in Micron */
#define EXTADD_REG_RD (0xC8U)
#define EXTADD_REG_WR (0xC5U)
#define COMMAND_OFFSET (0U) /* FLASH instruction */
#define ADDRESS_1_OFFSET (1U) /* MSB byte of address to read or write */
#define ADDRESS_2_OFFSET (2U) /* Middle byte of address to read or write */
#define ADDRESS_3_OFFSET (3U) /* LSB byte of address to read or write */
#define DATA_OFFSET (4U) /* Start of Data for Read/Write */
#define DUMMY_OFFSET (4U) /* Dummy byte offset for fast, dual and quad
reads */
#define DUMMY_SIZE (1U) /* Number of dummy bytes for fast, dual and
quad reads */
#define RD_ID_SIZE (4U) /* Read ID command + 3 bytes ID response */
#define BANK_SEL_SIZE (2U) /* BRWR or EARWR command + 1 byte bank value */
#define WRITE_ENABLE_CMD_SIZE (1U) /* WE command */
/*
* The following constants specify the extra bytes which are sent to the
* FLASH on the QSPI interface, that are not data, but control information
* which includes the command and address
*/
#define OVERHEAD_SIZE (4U)
/*
* The following constants specify the max amount of data and the size of the
* the buffer required to hold the data and overhead to transfer the data to
* and from the FLASH.
*/
#define DATA_SIZE (4096U)
/*
* The following defines are for dual flash interface.
*/
#define LQSPI_CR_FAST_QUAD_READ (0x0000006BU) /* Fast Quad Read output */
#define LQSPI_CR_1_DUMMY_BYTE (0x00000100U) /* 1 Dummy Byte between
address and return data */
#define SINGLE_QSPI_IO_CONFIG_QUAD_READ (LQSPI_CR_1_DUMMY_BYTE | \
LQSPI_CR_FAST_QUAD_READ)
#define DUAL_QSPI_PARALLEL_IO_CONFIG_QUAD_READ \
(XQSPIPS_LQSPI_CR_TWO_MEM_MASK | \
XQSPIPS_LQSPI_CR_SEP_BUS_MASK | \
LQSPI_CR_1_DUMMY_BYTE | \
LQSPI_CR_FAST_QUAD_READ)
#define DUAL_QSPI_STACK_IO_CONFIG_READ (XQSPIPS_LQSPI_CR_TWO_MEM_MASK | \
LQSPI_CR_1_DUMMY_BYTE | \
LQSPI_CR_FAST_QUAD_READ)
/**
* Flash connection type as defined in PCW
*/
#define FLASH_SIZE_16MB (0x1000000U)
#define BANKSIZE (FLASH_SIZE_16MB)
/*
* Bank mask
*/
#define BANKMASK (0xF000000U)
/*
* Identification of Flash
* Micron:
* Byte 0 is Manufacturer ID;
* Byte 1 is first byte of Device ID - 0xBB or 0xBA
* Byte 2 is second byte of Device ID describes flash size:
* 128Mbit : 0x18; 256Mbit : 0x19; 512Mbit : 0x20
* Spansion:
* Byte 0 is Manufacturer ID;
* Byte 1 is Device ID - Memory Interface type - 0x20 or 0x02
* Byte 2 is second byte of Device ID describes flash size:
* 128Mbit : 0x18; 256Mbit : 0x19; 512Mbit : 0x20
*/
#define MICRON_ID (0x20U)
#define SPANSION_ID (0x01U)
#define WINBOND_ID (0xEFU)
#define FLASH_SIZE_ID_128M (0x18U)
#define FLASH_SIZE_ID_256M (0x19U)
#define FLASH_SIZE_ID_512M (0x20U)
#define FLASH_SIZE_ID_1G (0x21U)
/*
* Size in bytes
*/
#define FLASH_SIZE_128M (0x1000000U)
#define FLASH_SIZE_256M (0x2000000U)
#define FLASH_SIZE_512M (0x4000000U)
#define FLASH_SIZE_1G (0x8000000U)
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
u32 XFsbl_Qspi24Init(void );
u32 XFsbl_Qspi24Copy(u32 SrcAddress, PTRSIZE DestAddress, u32 Length);
u32 XFsbl_Qspi24Release(void );
/************************** Variable Definitions *****************************/
#endif /* end of XFSBL_QSPI */
#ifdef __cplusplus
}
#endif
#endif /* XFSBL_QSPI_H */

View file

@ -0,0 +1,497 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
*******************************************************************************/
/*****************************************************************************/
/**
*
* @file xfsbl_rsa_sha.c
*
* This contains code for the RSA and SHA functionality.
* If the Hash type is SHA3 then CSU h/w will be used
* else we will use SoftSHA256 s/w library for SHA2-256.
* For RSA-4096 we will always use CSU h/w.
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 kc 07/22/14 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xfsbl_authentication.h"
#include "xfsbl_csu_dma.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
/************************** Variable Definitions *****************************/
static u32 XFsbl_Sha3Len;
/*****************************************************************************
*
* @param None
*
* @return None
*
******************************************************************************/
void XFsbl_Sha3Padd(u8 *Dst, u32 MsgLen)
{
/**
* SHA3 HASH value is not generated correctly
* when used 2nd time on REMUS 1.9
*/
XFsbl_MemSet(Dst, 0, MsgLen);
Dst[0] = 0x1;
Dst[MsgLen -1] |= 0x80;
}
/*****************************************************************************
*
* @param None
*
* @return None
*
******************************************************************************/
void XFsbl_Sha3Start(void)
{
XFsbl_Sha3Len = 0;
/**
* Reset SHA3 engine.
*/
XFsbl_Out32(CSU_SHA_RESET, CSU_SHA_RESET_RESET_MASK);
XFsbl_Out32(CSU_SHA_RESET, 0);
/**
* Configure the SSS for SHA3 hashing.
*/
XFsbl_SssSetup(XFsbl_SssInputSha3(XFSBL_CSU_SSS_SRC_SRC_DMA));
/**
* Start SHA3 engine.
*/
XFsbl_Out32(CSU_SHA_START, CSU_SHA_START_START_MSG_MASK);
}
/*****************************************************************************
*
* @param None
*
* @return None
*
******************************************************************************/
void XFsbl_Sha3Update(u8 * Data, u32 Size)
{
XFsbl_Sha3Len += Size;
XASSERT_VOID((Size & 3) == 0);
XFsbl_CsuDmaStart(XFSBL_CSU_DMA_SRC, (u32 )(PTRSIZE)Data, Size);
/* Checking the SHA3 done bit should be enough. */
XFsbl_CsuDmaWaitForDone(XFSBL_CSU_DMA_SRC);
}
/*****************************************************************************
*
* @param None
*
* @return None
*
******************************************************************************/
void XFsbl_Sha3WaitForDone(void)
{
volatile u32 Status;
do
{
Status = XFsbl_In32(CSU_SHA_DONE);
} while (CSU_SHA_DONE_SHA_DONE_MASK !=
(Status & CSU_SHA_DONE_SHA_DONE_MASK));
}
/*****************************************************************************
*
* @param None
*
* @return None
*
******************************************************************************/
void XFsbl_Sha3Finish(u8 *Hash)
{
u32 *HashPtr = (u32 *)Hash;
u32 PartialLen = XFsbl_Sha3Len % XFSBL_SHA3_BLOCK_LEN;
/**
* DT 780552 (SHA3 HASH value is not generated correctly
* when used 2nd time on REMUS 1.9)
*/
PartialLen = (PartialLen == 0)?(XFSBL_SHA3_BLOCK_LEN) :
(XFSBL_SHA3_BLOCK_LEN - PartialLen);
XFsbl_Sha3Padd(XFsbl_RsaSha3Array, PartialLen);
XFsbl_CsuDmaStart(XFSBL_CSU_DMA_SRC, (u32 )(PTRSIZE)XFsbl_RsaSha3Array,
PartialLen | XFSBL_CSU_DMA_SIZE_EOP);
/* Check the SHA3 DONE bit. */
XFsbl_Sha3WaitForDone();
/* If requested, read out the Hash in reverse order. */
if (Hash)
{
u32 Index = 0;
u32 Val = 0;
for (Index=0; Index < 12; Index++)
{
Val = XFsbl_In32(CSU_SHA_DIGEST_0 + (Index * 4));
HashPtr[11 - Index] = Val;
}
}
}
/*****************************************************************************
*
* @param None
*
* @return None
*
******************************************************************************/
void XFsbl_Sha3Digest(const u8 *In, const u32 Size, u8 *Out)
{
XFsbl_Sha3Start();
XFsbl_Sha3Update((u8 *)In, Size);
XFsbl_Sha3Finish(Out);
}
/*****************************************************************************
*
* @param None
*
* @return None
*
******************************************************************************/
static void XFsbl_RsaPutData(u32 * WrData, u8 RamOffset)
{
u32 Index = 0;
u32 DataOffset = 0;
u32 TmpIndex = 0;
u32 Data = 0;
/** Each of this loop will write 192 bits of data*/
for (DataOffset = 0; DataOffset < 22; DataOffset++)
{
for (Index = 0; Index < 6; Index++)
{
TmpIndex = (DataOffset*6) + Index;
/**
* DT 776670: CSU Boot ROM fails with error code 0x30E
* (RSA status register give done with error 0x5)
* Added this condition as we need only 4 bytes
* and rest of the data needs to be 0
*/
if(XFSBL_CSU_RSA_RAM_EXPO == RamOffset)
{
if(0 == TmpIndex )
{
Data = XFsbl_Htonl(*WrData);
}
else
{
Data = 0x0;
}
}
else
{
if(TmpIndex >=128)
{
Data = 0x0;
}
else
{
/**
* The RSA data in Image is in Big Endian.
* So reverse it before putting in RSA memory,
* becasue RSA h/w expects it in Little endian.
*/
Data = XFsbl_Htonl(WrData[127-TmpIndex]);
}
}
XFsbl_Out32((RSA_WR_DATA_0 + Index * 4), Data);
}
XFsbl_Out32(RSA_WR_ADDR, ((RamOffset * 22) + DataOffset));
}
}
/*****************************************************************************
*
* @param None
*
* @return None
*
******************************************************************************/
static void XFsbl_RsaGetData(u32 * RdData)
{
u32 Index = 0;
u32 DataOffset = 0;
int TmpIndex = 0;
/** Each of this loop will write 192 bits of data*/
for (DataOffset = 0; DataOffset < 22; DataOffset++)
{
XFsbl_Out32(RSA_RD_ADDR,
(XFSBL_CSU_RSA_RAM_RES_Y * 22) + DataOffset);
Index = (DataOffset == 0) ? 2: 0;
for (; Index < 6; Index++)
{
TmpIndex = 129 - ((DataOffset*6) + Index);
if(TmpIndex < 0)
{
break;
}
/**
* The Signature digest is compared in Big endian.
* So becasue RSA h/w results in Little endian,
* reverse it after reading it from RSA memory,
*/
RdData[TmpIndex] = XFsbl_Htonl(
XFsbl_In32(RSA_RD_DATA_0
+ (Index * 4)));
}
}
}
/*****************************************************************************
*
* @param u32 *Mod
*
* @return None
*
* @notes MINV is the 32-bit value of "-M mod 2**32"
* where M is LSB 32 bits of the original modulus
* DT 776670: CSU Boot ROM fails with error code 0x30E
* (RSA status register give done with error 0x5)
*
******************************************************************************/
static void XFsbl_Mod32Inverse(u32 *Mod)
{
/** Calculate the MINV*/
u8 Count = 0;
u32 ModVal = XFsbl_Htonl(Mod[127]);
u32 Inv = 2 - ModVal;
for (Count = 0; Count < 4; ++Count)
{
Inv = (Inv * (2- ( ModVal * Inv ) ) );
}
Inv = -Inv;
/** Put the value in MINV registers*/
XFsbl_Out32(RSA_CORE_MINV0, (Inv & 0xFF ));
XFsbl_Out32(RSA_CORE_MINV1, ((Inv >> 8) & 0xFF ));
XFsbl_Out32(RSA_CORE_MINV2, ((Inv >> 16) & 0xFF ));
XFsbl_Out32(RSA_CORE_MINV3, ((Inv >> 24) & 0xFF ));
}
/*****************************************************************************
*
* @param None
*
* @return None
*
******************************************************************************/
u32 XFsbl_RsaDecrypt(u8* EncText, u8* Mod, u8* ModExt, u8* ModExpo, u8* Result, u8 Reuse)
{
volatile u32 Status = XFSBL_SUCCESS;
u32 ErrorCode = XFSBL_SUCCESS;
/**
* Populate the RSA parameters in h/w.
*/
/**
* We will reuse the RSA config values,
* incase of FSBL Signature Authentication,
* because Boot header Signautre Authentication,
* also uses the same SPK Key.
*/
if(0 == Reuse)
{
/**
* DT 776670: CSU Boot ROM fails with error code 0x30E
* (RSA status register give done with error 0x5)
* Initialize Modular exponentiation
*/
XFsbl_RsaPutData((u32 *)ModExpo, XFSBL_CSU_RSA_RAM_EXPO);
/**
* Initialize Modular.
*/
XFsbl_RsaPutData((u32 *)Mod, XFSBL_CSU_RSA_RAM_MOD);
/**
* DT 776670: CSU Boot ROM fails with error code 0x30E
* (RSA status register give done with error 0x5)
* Initialize MINV values from Mod.
*/
XFsbl_Mod32Inverse((u32 *)Mod);
}
/**
* Initialize Modular extension (R*R Mod M)
*/
XFsbl_RsaPutData((u32 *)ModExt, XFSBL_CSU_RSA_RAM_RES_Y);
/**
* Initialize Digest
*/
XFsbl_RsaPutData((u32 *)EncText, XFSBL_CSU_RSA_RAM_DIGEST);
/**
* Start the RSA operation.
*/
XFsbl_Out32(RSA_CORE_CTRL, XFSBL_CSU_RSA_CONTROL_MASK);
/**
* Check and wait for status
*/
do
{
Status = XFsbl_In32(RSA_CORE_STATUS);
if(RSA_CORE_STATUS_ERROR_MASK ==
(Status & RSA_CORE_STATUS_ERROR_MASK))
{
ErrorCode = XFSBL_FAILURE;
goto END;
}
}while (RSA_CORE_STATUS_DONE_MASK !=
(Status & RSA_CORE_STATUS_DONE_MASK));
/**
* Copy the result
*/
XFsbl_RsaGetData((u32 *)Result);
END:
return ErrorCode;
}
/*****************************************************************************
*
* @param None
*
* @return None
*
******************************************************************************/
void XFsbl_ShaDigest(const u8 *In, const u32 Size, u8 *Out, u32 HashLen)
{
if(XFSBL_HASH_TYPE_SHA3 == HashLen)
{
XFsbl_Sha3Digest(In, Size, Out);
}
}
/*****************************************************************************
*
* @param None
*
* @return None
*
******************************************************************************/
void XFsbl_ShaStart( void * Ctx, u32 HashLen)
{
if(XFSBL_HASH_TYPE_SHA3 == HashLen)
{
XFsbl_Sha3Start();
}
}
/*****************************************************************************
*
* @param None
*
* @return None
*
******************************************************************************/
void XFsbl_ShaUpdate( void * Ctx, u8 * Data, u32 Size, u32 HashLen)
{
if(XFSBL_HASH_TYPE_SHA3 == HashLen)
{
XFsbl_Sha3Update(Data, Size);
}
}
/*****************************************************************************
*
* @param None
*
* @return None
*
******************************************************************************/
void XFsbl_ShaFinish( void * Ctx, u8 * Hash, u32 HashLen)
{
if(XFSBL_HASH_TYPE_SHA3 == HashLen)
{
XFsbl_Sha3Finish(Hash);
}
}

View file

@ -0,0 +1,189 @@
/******************************************************************************
*
* Copyright (C) 2015 Xilinx, Inc. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* Use of the Software is limited solely to applications:
* (a) running on a Xilinx device, or
* (b) that interact with a Xilinx device through a bus or interconnect.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* Except as contained in this notice, the name of the Xilinx shall not be used
* in advertising or otherwise to promote the sale, use or other dealings in
* this Software without prior written authorization from Xilinx.
*
******************************************************************************/
/*****************************************************************************/
/**
*
* @file xfsbl_sd.c
*
* This is the file which contains sd related code for the FSBL.
*
* <pre>
* MODIFICATION HISTORY:
*
* Ver Who Date Changes
* ----- ---- -------- -------------------------------------------------------
* 1.00 kc 04/21/14 Initial release
*
* </pre>
*
* @note
*
******************************************************************************/
/***************************** Include Files *********************************/
#include "xfsbl_hw.h"
#ifdef XFSBL_SD
#include "xparameters.h"
#include "ff.h"
/************************** Constant Definitions *****************************/
/**************************** Type Definitions *******************************/
/***************** Macros (Inline Functions) Definitions *********************/
/************************** Function Prototypes ******************************/
extern void XFsbl_MakeSdFileName(char *XFsbl_SdEmmcFileName, u32 MultibootReg);
/************************** Variable Definitions *****************************/
static FIL fil; /* File object */
static FATFS fatfs;
/*****************************************************************************/
/**
* This function is used to initialize the qspi controller and driver
*
* @param None
*
* @return None
*
*****************************************************************************/
u32 XFsbl_SdInit(void )
{
u32 Status = XFSBL_SUCCESS;
FRESULT rc;
char buffer[32];
char *boot_file = buffer;
u32 MultiBootOffset=0U;
/* Register volume work area, initialize device */
rc = f_mount(0, &fatfs);
XFsbl_Printf(DEBUG_INFO,"SD: rc= %.8x\n\r", rc);
if (rc != FR_OK) {
Status = XFSBL_ERROR_SD_INIT;
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_SD_INIT\n\r");
goto END;
}
/**
* Read the Multiboot Register
*/
MultiBootOffset = XFsbl_In32(CSU_CSU_MULTI_BOOT);
/**
* Create boot image name
*/
XFsbl_MakeSdFileName(boot_file, MultiBootOffset);
rc = f_open(&fil, boot_file, FA_READ);
if (rc) {
XFsbl_Printf(DEBUG_INFO,
"SD: Unable to open file %s: %d\n", boot_file, rc);
Status = XFSBL_ERROR_SD_F_OPEN;
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_SD_F_OPEN\n\r");
goto END;
}
END:
return Status;
}
/*****************************************************************************/
/**
* This function is used to copy the data from SD/eMMC to destination
* address
*
* @param SrcAddress is the address of the SD flash where copy should
* start from
*
* @param DestAddress is the address of the destination where it
* should copy to
*
* @param Length Length of the bytes to be copied
*
* @return
* - XFSBL_SUCCESS for successful copy
* - errors as mentioned in xfsbl_error.h
*
*****************************************************************************/
u32 XFsbl_SdCopy(u32 SrcAddress, PTRSIZE DestAddress, u32 Length)
{
u32 Status = XFSBL_SUCCESS;
FRESULT rc; /* Result code */
UINT br=0U;
rc = f_lseek(&fil, SrcAddress);
if (rc != 0) {
XFsbl_Printf(DEBUG_INFO,
"SD: Unable to seek to %x\n", SrcAddress);
Status = XFSBL_ERROR_SD_F_LSEEK;
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_SD_F_LSEEK\n\r");
goto END;
}
rc = f_read(&fil, (void*)DestAddress, Length, &br);
if (rc != 0) {
XFsbl_Printf(DEBUG_GENERAL,
"SD: f_read returned %d\r\n", rc);
Status = XFSBL_ERROR_SD_F_READ;
XFsbl_Printf(DEBUG_GENERAL,"XFSBL_ERROR_SD_F_READ\n\r");
goto END;
}
END:
return Status;
}
/*****************************************************************************/
/**
* This function is used to release the sd settings
*
* @param None
*
* @return None
*
*****************************************************************************/
u32 XFsbl_SdRelease(void )
{
(void )f_close(&fil);
return XFSBL_SUCCESS;
}
#endif /* end of XFSBL_SD */