diff options
author | Stephan Broyles <sbroyles@us.ibm.com> | 2014-11-05 19:09:37 -0600 |
---|---|---|
committer | Stephan Broyles <sbroyles@us.ibm.com> | 2014-11-05 19:22:32 -0600 |
commit | 9976c207cdb20871880bd2f4cf123cf4cb6a8b0f (patch) | |
tree | 1cf9ed8f23085e6fe3e0e6046fc30dcb7e02ccf2 /src/occBootLoader | |
parent | 2f8ce357b89d361b5091d88aea91416011b73ccb (diff) | |
download | talos-occ-9976c207cdb20871880bd2f4cf123cf4cb6a8b0f.tar.gz talos-occ-9976c207cdb20871880bd2f4cf123cf4cb6a8b0f.zip |
Added remaining occ files.
Change-Id: I91a748d3dcf3161a6a3eedcb376fcaf1e4dfe655
Diffstat (limited to 'src/occBootLoader')
-rwxr-xr-x | src/occBootLoader/Makefile | 90 | ||||
-rwxr-xr-x | src/occBootLoader/bootInit.S | 234 | ||||
-rwxr-xr-x | src/occBootLoader/bootMain.c | 308 | ||||
-rwxr-xr-x | src/occBootLoader/bootMain.h | 102 | ||||
-rwxr-xr-x | src/occBootLoader/bootfiles.mk | 28 | ||||
-rwxr-xr-x | src/occBootLoader/imageHdrScript.c | 877 | ||||
-rwxr-xr-x | src/occBootLoader/linkboot.cmd | 117 | ||||
-rw-r--r-- | src/occBootLoader/occLinkInputFile | 1 |
8 files changed, 1757 insertions, 0 deletions
diff --git a/src/occBootLoader/Makefile b/src/occBootLoader/Makefile new file mode 100755 index 0000000..a9446b3 --- /dev/null +++ b/src/occBootLoader/Makefile @@ -0,0 +1,90 @@ +# @file Makefile +# +# @brief bootloader Makefile +# + +# @page ChangeLogs Change Logs +# @section Makefile +# @verbatim +# +# +# Change Log ****************************************************************** +# Flag Defect/Feature User Date Description +# ------ -------------- ---------- ------------ ----------- +# @pb000 pbavari 07/01/2011 Created +# @pb001 pbavari 07/16/2011 Changed to combine image +# as separate command +# @pb006 pbavari 09/16/2011 Display size support +# @pb004 pbavari 09/20/2011 Added occ/ in include path +# @pb007 pbavari 09/29/2011 Added ppc405 in include path +# @rc003 rickylie 02/03/2012 Verify & Clean Up OCC Headers & Comments +# +# @endverbatim +# + +# >> gitprep +ifndef ROOTPATH +ROOTPATH = $(shell pwd)/../ +export OCCROOT = $(ROOTPATH) +endif +# << gitprep + +#******************************************************************************* +# mk variable Declaration +#******************************************************************************* +OCC = ../occ +BOOTLOADER = . +SSX = ../ssx +#******************************************************************************* +# Includes +#******************************************************************************* +include bootfiles.mk +include ../ssx/pgp/ssx.mk + +INCLUDES = -I. -I$(SSX)/ppc32 -I$(SSX)/pgp -I$(OCC)/incl -I$(OCC)/ \ + -I$(SSX)/ppc405 + +#******************************************************************************* +# Flags +#******************************************************************************* +OBJECTS = ${BOOTLOADER_OBJECTS} +EXECUTABLE = bootloader +imageHdrScript = imageHdrScript +imageHdrScript_CC = gcc + +#D = -DSIMICS_MAGIC_PANIC=1 \ + -DINITIALIZE_SIMICS_IO=1 + +DEFS += $(D) + +#******************************************************************************* +# Compilation +#******************************************************************************* + +all: ${BOOTLOADER_OBJECTS} imageHdrScript + $(CPP) -P $(DEFS) < linkboot.cmd > linkscript + # >> gitprep + # Add missing link and objcopy flags + $(LD) ${BOOTLOADER_OBJECTS} \ + -Tlinkscript $(LDFLAGS) -zmuldefs -Map $(EXECUTABLE).map -melf32ppc --oformat=elf32-powerpc -Bstatic -o \ + $(EXECUTABLE).out + $(OBJCOPY) -I elf32-powerpc -O binary $(EXECUTABLE).out $(EXECUTABLE).bin + # << gitprep + $(OBJDUMP) -d $(EXECUTABLE).out > $(EXECUTABLE).dis + $(BOOTLOADER)/$(imageHdrScript) $(EXECUTABLE).bin t1 + +.PHONY : combineImage +combineImage: + $(BOOTLOADER)/imageHdrScript $(EXECUTABLE).bin combineImage + $(BOOTLOADER)/imageHdrScript $(EXECUTABLE).out displaySize + +imageHdrScript: imageHdrScript.c + $(imageHdrScript_CC) $(LDFLAGS) -I$(BOOTLOADER) -I$(OCC)/incl -I$(OCC)/ \ + imageHdrScript.c -o $@ + +#******************************************************************************* +# Clean +#******************************************************************************* +clean: + rm -f *.o *.d *.out *.bin *.srec *.dis *.map linkscript imageHdrScript + rm -rf $(EXECUTABLE) $(IMAGE_FILE) diff --git a/src/occBootLoader/bootInit.S b/src/occBootLoader/bootInit.S new file mode 100755 index 0000000..9f4c104 --- /dev/null +++ b/src/occBootLoader/bootInit.S @@ -0,0 +1,234 @@ +# ***************************************************************************** +# @file bootInit.S +# @brief OCC boot loader initialization +# + +# ***************************************************************************** +# +# @page ChangeLogs Change Logs +# @section bootInit.S BOOTINIT.S +# @verbatim +# +# Flag Def/Fea Userid Date Description +# ------- ---------- -------- ---------- ---------------------------------- +# @pb000 pbavari 06/21/2011 Created +# @pb007 pbavari 09/29/2011 Added trap if reset was due to +# watchdog timer +# @rc003 rickylie 02/03/2012 Verify & Clean Up OCC Headers & Comments +# @th00c thallet 03/02/2012 DCCR was getting loaded with incorret imm +# +# @endverbatim +# +# ***************************************************************************** + +/*****************************************************************************/ +// Includes +/*****************************************************************************/ +#include "bootMain.h" +#include "ppc32_asm.h" +#include "ppc405_spr.h" +/*****************************************************************************/ + +/*****************************************************************************/ +// Functions +/*****************************************************************************/ +# Function Specification ****************************************************** +# +# Name: boot_low_level_init +# +# Description: Low level boot initialization +# +# Flow: 06/22/2011 FN= ?? +# +# End Function Specification ************************************************** + +.global_function __boot_low_level_init + +__boot_low_level_init: + + +#enable machine check exception +# initialize exception vector prefix to zero +# enable machine check (19th bit) + +li %r3, 0 +mtevpr %r3 +_liwa %r4, MACHINE_CHECK_ENABLE +mtmsr %r4 + +// Check if TSR[WSR] indicates that reset was due to watchdog, +// then initialize external debug event and trap(halt). Otherwise +// continue normally. Setting up external debug event will set FIR bits on halt +mftsr %r3 +_liwa %r4, ( TSR_WRS_CHIP | TSR_WRS_CORE | TSR_WRS_SYSTEM ) +AND %r5, %r3, %r4 +li %r4, 0 +cmp 0, 0, %r4, %r5 +beq skip_wd_reset_trap + +// Initialize external debug event before doing trap +_liwa %r3, (DBCR0_EDM | DBCR0_TDE | DBCR0_FT ) +mtdbcr0 %r3 +tw 31,0,0 + +skip_wd_reset_trap: + +# enable write back data cache and instruction cache +# enable write back data for 0x80000000. Note:write-back=0,write-through=1 +# Data cache enabled for 0x80000000. Bit 16 going left-right. 1=enable,0=disable +# enable instruction cache for 0x80000000. Bit 16 going left-right. +# 1= enable, 0 = disable + +li %r3, 0 +mtdcwr %r3 +_liw %r3, DATA_CACHE_BLOCK_ENABLE +mtdccr %r3 +mticcr %r3 + +dcache_invalidate: + ## We loop through addresses 0 ... (DCACHE_SIZE / DCACHE_WAYS) - 1 + ## invalidating the D-Cache. The dccci instruction on the 405 + ## invalidates both ways. Added: @th00c + + li %r3, 0 + _liwa %r4, (DATA_CACHE_LINES / 2) + mtctr %r4 + +1: + dccci %r0, %r3 + addi %r3, %r3, CACHE_LINE_SIZE + bdnz 1b + + sync + +# fill in 16K with zero for the data cache +# set counter to loop for number of data cache lines + +_liw %r3, 0 +_liwa %r5, DATA_CACHE_BLOCK_ADDR +_liwa %r4, DATA_CACHE_LINES +mtctr %r4 + +dcbz_loop: + + dcbz %r5, %r3 + addi %r3, %r3, CACHE_LINE_SIZE + bdnz dcbz_loop + + +# calculate writable data section start address +# start_addr + readonly_size = writable data section address +# load start address into r5 +# load readonly size address into r4 +# add contents of r5 and r4 and put into r3 +# r3 now has source address +# load address of size of the data to be copied into r4 +# load destination address into r5 +# store number of word trasfers in r4 +# set counter to r4 content +# NOTE: (-4) for the source and destination address is done because +# in the loop 4 is added to get to the correct address. + +_liw %r5, (__START_ADDR__ - 4) +_liw %r4, __READ_ONLY_DATA_LEN__ +add %r3, %r5, %r4 +_liw %r4, __WRITEABLE_DATA_LEN__ +_liw %r5, (__WRITEABLE_DATA_ADDR__ - 4) +_liw %r6, 2 +srw %r4, %r4, %r6 + +# Compare r4 and r6. If equal then skip_loop. Else execute copy_loop +_liw %r6, 0 +cmp 0, 0, %r4, %r6 +beq skip_loop +mtctr %r4 +copy_loop: + + lwzu %r4, 4(%r3) + stwu %r4, 4(%r5) + bdnz copy_loop + +skip_loop: + +# set up EABI constant registers r2,r13 + +_liw %r2, _SDA2_BASE_ +_liw %r13, _SDA_BASE_ + +# set up stack pointer - register r1 + +_liwa %r1, STACK_POINTER_ADDR + +# jump to main + +b main + +# function clean up and return + +.epilogue __boot_low_level_init + +# vector section + +.section .vectors_0000, "a", @progbits + .global __vectors_0000 + +__vectors_0000: + + + .section .vectors_0100, "ax", @progbits + .global __vectors_0100 + +__vectors_0100: + +# Trap instruction +tw 31,0,0 + + .section .vectors_0200, "ax", @progbits + .global __vectors_0200 + +__vectors_0200: + +# Trap instruction +tw 31,0,0 + + .section .vectors_0300, "ax", @progbits + .global __vectors_0300 + +__vectors_0300: + +# Trap instruction +tw 31,0,0 + + .section .vectors_0400, "ax", @progbits + .global __vectors_0400 + +__vectors_0400: + +# Trap instruction +tw 31,0,0 + + .section .vectors_0500, "ax", @progbits + .global __vectors_0500 + +__vectors_0500: + +# Trap instruction +tw 31,0,0 + + .section .vectors_0600, "ax", @progbits + .global __vectors_0600 + +__vectors_0600: + +# Trap instruction +tw 31,0,0 + + + .section .vectors_0700, "ax", @progbits + .global __vectors_0700 + +__vectors_0700: + +# Trap instruction +tw 31,0,0 + diff --git a/src/occBootLoader/bootMain.c b/src/occBootLoader/bootMain.c new file mode 100755 index 0000000..10df75f --- /dev/null +++ b/src/occBootLoader/bootMain.c @@ -0,0 +1,308 @@ +/****************************************************************************** +// @file bootMain.c +// @brief OCC boot loader main +*/ +/****************************************************************************** + * + * @page ChangeLogs Change Logs + * @section bootMain.c BOOTMAIN.C + * @verbatim + * + * Flag Def/Fea Userid Date Description + * ------- ---------- -------- ---------- ---------------------------------- + * @pb000 pbavari 06/22/2011 Created + * @dw000 dwoodham 12/12/2011 Update call to IMAGE_HEADER macro + * @rc003 rickylie 02/03/2012 Verify & Clean Up OCC Headers & Comments + * @th00c thallet 03/02/2012 VPO Changes to 405 Caching + * @sb000 905048 sbroyles 10/28/2013 Add tags for code cleanup, + * see RTC task 73327. +* @sb001 906184 sbroyles 11/11/2013 Resolve fix tags + * @endverbatim + * + *///*************************************************************************/ + +//************************************************************************* +// Includes +//************************************************************************* +#include <bootMain.h> // boot loader defines +#include <pgp_common.h> // Nest frequency constant +#include <stddef.h> // offsetof + +//************************************************************************* +// Externs +//************************************************************************* +extern void __boot_low_level_init; + +//************************************************************************* +// Image header +//************************************************************************* +//@dw001c - added arg: idNum = ID_NUM_INVALID +IMAGE_HEADER (G_bootImageHdr,__boot_low_level_init,BOOT_LOADER_ID, + ID_NUM_INVALID); + +//************************************************************************* +// Macros +//************************************************************************* + +//************************************************************************* +// Defines/Enums +//************************************************************************* + +//************************************************************************* +// Structures +//************************************************************************* + +//************************************************************************* +// Globals +//************************************************************************* + +//************************************************************************* +// Function Prototypes +//************************************************************************* +//Forward declaration +uint32_t boot_test_sram(); +uint32_t boot_load_image(const imageHdr_t * i_hdrAddr); +uint32_t calChecksum(const uint32_t i_startAddr,const uint32_t i_sz ); + +//************************************************************************* +// Functions +//************************************************************************* + +// Function Specification +// +// Name: boot_main +// +// Description: boot main will test SRAM, copy main application image from +// main memory to SRAM, validate checksum and calls ssx_boot. +// +// Flow: 06/22/2011 FN= boot_main +// +// End Function Specification +void main() +{ + uint32_t l_rc = 0; + // set checkpoint to boot test SRAM + WRITE_TO_SPRG0(BOOT_TEST_SRAM_CHKPOINT); + +#ifndef VPO + // @th00c - This is ifdef'd out b/c it takes too long to run in VPO + // Test SRAM + l_rc = boot_test_sram(); +#endif + + // If failed to test SRAM, write failed return code to SPRG1 and halt + if( 0 != l_rc ) + { + WRITE_TO_SPRG1_AND_HALT(l_rc); + } + + // set imageHdr_t pointer to point to boot image header to get to boot + // image size. This way we can get to main application image header. + imageHdr_t *l_hdrPtr = (imageHdr_t*)(G_bootImageHdr.start_addr + + G_bootImageHdr.image_size ); + + // set checkpoint to boot load main application image to SRAM + WRITE_TO_SPRG0(BOOT_LOAD_IMAGE_CHKPOINT ); + + // Load main application image to SRAM including main application header + l_rc = boot_load_image(l_hdrPtr); + + // If failed to load image, write failed return code to SPRG1 and halt + if( 0 != l_rc ) + { + WRITE_TO_SPRG1_AND_HALT(l_rc); + } + + // set checkpoint to calculate checksum + WRITE_TO_SPRG0(BOOT_CALCULTE_CHKSUM_CHKPOINT); + + // calculate checksum for the SRAM main application image + uint32_t l_checksum = calChecksum(l_hdrPtr->start_addr, + l_hdrPtr->image_size); + + // If checksum does not match, store bad checksum into SPRG1 and halt + if( l_checksum != l_hdrPtr->checksum) + { + WRITE_TO_SPRG1_AND_HALT(l_checksum); + } + + // set checkpoint to get nest frequency + WRITE_TO_SPRG0(BOOT_GET_NEST_FREQ_CHKPOINT); + + // @sb001 Remove this local. + //uint32_t l_nestFreq = 2400000; + + // set checkpoint to call to SSX_BOOT + WRITE_TO_SPRG0(BOOT_SSX_BOOT_CALL_CHKPOINT); + + // Invalidate Data Cache before calling __ssx_boot() + //dcache_invalidate_all(); // @th00c + + // create function pointer pointing to main application header entry point + // address. This is similar to jump/branch to address in assembly + + // @sb001 Don't pass l_nestFreq anymore, ssx boot code isn't reading it. + //void (*execute_ssx_boot)(uint32_t) = (void (*)(uint32_t)) l_hdrPtr->ep_addr; + //(*execute_ssx_boot)(l_nestFreq); + void (*execute_ssx_boot)(void) = (void (*)(void)) l_hdrPtr->ep_addr; + (*execute_ssx_boot)(); + + // set checkpoint to return from ssx_boot. This should never happen so + // halt at this point. + WRITE_TO_SPRG0(BOOT_SSX_RETURNED_CHKPOINT); + WRITE_TO_SPRG1_AND_HALT(l_hdrPtr->ep_addr); + +} + +// Function Specification +// +// Name: calChecksum +// +// Description: Calculate checksum starting at given address and given size +// bytes. Skip checksum field in the imageHdr_t while calculating +// checksum +// +// Flow: None FN= None +// +// End Function Specification + +uint32_t calChecksum(const uint32_t i_startAddr,const uint32_t i_sz ) +{ + uint32_t l_checksum = 0; + uint32_t l_counter = 0; + uint8_t * l_srcPtr = (uint8_t *) (i_startAddr); + + while (l_counter < i_sz ) + { + l_checksum += (*(l_srcPtr + l_counter)); + l_counter = l_counter + 1; + if( l_counter == (uint32_t)(offsetof(imageHdr_t,checksum))) + { + l_counter = ((uint32_t)(offsetof(imageHdr_t,checksum)) + + sizeof(G_bootImageHdr.checksum)); + } + } + + return l_checksum; +} + +// Function Specification +// +// Name: boot_load_image +// +// Description: This function copies main application image from main memory +// to SRAM +// +// +// Flow: 06/22/2011 FN= boot_load_image +// +// End Function Specification + +uint32_t boot_load_image(const imageHdr_t * i_hdrAddr ) +{ + uint32_t l_rc = 0x0; + uint32_t l_mainAppDestRang = (i_hdrAddr->start_addr) + + (i_hdrAddr->image_size-1); + + // Make sure main application destination rang address falls within SRAM + // range. + if( ( l_mainAppDestRang < SRAM_START_ADDRESS) || + (l_mainAppDestRang > SRAM_END_ADDRESS )) + { + // Return destination rang address if address is out of range and + // address is not zero. If address is zero, then return eye-catcher + // address. + if( l_mainAppDestRang != 0 ) + { + l_rc = l_mainAppDestRang; + } + else + { + l_rc = EYE_CATCHER_ADDRESS; + } + } + //Make sure main application start address falls within SRAM range + else if ((i_hdrAddr->start_addr < SRAM_START_ADDRESS) || + (i_hdrAddr->start_addr > SRAM_END_ADDRESS)) + { + // Return start address if address is out of range and + // address is not zero. If address is zero, then return eye-catcher + // address. + if( i_hdrAddr->start_addr != 0 ) + { + l_rc = i_hdrAddr->start_addr; + } + else + { + l_rc = EYE_CATCHER_ADDRESS; + } + } + else + { + // At this point we know that main application destination address + // is within SRAM range. + // Now copy main application header specified + // size of data from main memory to main application header specified + // start address. + uint8_t * l_srcPtr = (uint8_t *) (i_hdrAddr); + uint8_t * l_destPtr = (uint8_t *) (i_hdrAddr->start_addr); + uint32_t l_numWords = i_hdrAddr->image_size; + + while (l_numWords != 0 ) + { + *l_destPtr = *l_srcPtr; + l_destPtr++; + l_srcPtr++; + l_numWords = l_numWords - 1; + } + } + + return l_rc; +} + + +// Function Specification +// +// Name: boot_test_sram +// +// Description: This function tests SRAM by writing some bit pattern and +// verifying it back through read +// +// +// Flow: 06/22/2011 FN= boot_test_sram +// +// End Function Specification + +uint32_t boot_test_sram() +{ + uint32_t l_rc = 0; + + // Point start to SRAM start address + uint32_t * l_startPtr = (uint32_t *) SRAM_TEST_START_ADDRESS; + + // Copy bit pattern from start until SRAM end address + while( (uint32_t)l_startPtr < SRAM_TEST_END_ADDRESS ) + { + *l_startPtr = SRAM_TEST_BIT_PATTERN; + l_startPtr++; + } + + // Reset start pointer to point to SRAM start Address + l_startPtr = (uint32_t *) SRAM_TEST_START_ADDRESS; + + //Read and verify bit pattern that was written. If pattern does not match, + // return address that failed to match the pattern. + while( (uint32_t)l_startPtr < SRAM_TEST_END_ADDRESS ) + { + if( (*l_startPtr) != SRAM_TEST_BIT_PATTERN) + { + l_rc = (uint32_t)l_startPtr; + break; + } + l_startPtr++; + } + + return l_rc; +} + + diff --git a/src/occBootLoader/bootMain.h b/src/occBootLoader/bootMain.h new file mode 100755 index 0000000..0d836c5 --- /dev/null +++ b/src/occBootLoader/bootMain.h @@ -0,0 +1,102 @@ +/****************************************************************************** +// @file bootMain.h +// @brief OCC boot loader main defines +*/ +/****************************************************************************** + * + * @page ChangeLogs Change Logs + * @section bootMain.h BOOTMAIN.H + * @verbatim + * + * Flag Def/Fea Userid Date Description + * ------- ---------- -------- ---------- ---------------------------------- + * @pb000 pbavari 06/22/2011 Created + * @rc003 rickylie 02/03/2012 Verify & Clean Up OCC Headers & Comments + * @ai007 ailutsar 12/10/2012 Change OCC Image Header to reserve 64 bytes + * for SRAM Repair instead of 16 + * @th030 thallet 02/03/2013 Need to reserve last 1kB for PORE-SLW + * + * @endverbatim + * + *///*************************************************************************/ + +#ifndef _bootMain_h +#define _bootMain_h + +//************************************************************************* +// Includes +//************************************************************************* +#ifndef __ASSEMBLER__ +#include <common_types.h> // defines imageHdr_t and other types +#endif /* __ASSEMBLER__ */ + +//************************************************************************* +// Externs +//************************************************************************* + +//************************************************************************* +// Macros +//************************************************************************* + +//************************************************************************* +// Defines/Enums +//************************************************************************* +#define MACHINE_CHECK_ENABLE 0x00001000 +#define DATA_CACHE_BLOCK_ENABLE 0x00008000 +#define DATA_CACHE_BLOCK_ADDR 0x80000000 +#define DATA_CACHE_SIZE (16 * 1024) +#define CACHE_LINE_SIZE 32 +#define DATA_CACHE_LINES (DATA_CACHE_SIZE/CACHE_LINE_SIZE) + +// Data cache address + 8K +#define STACK_POINTER_ADDR ( DATA_CACHE_BLOCK_ADDR + 0x2000) + +#ifndef __ASSEMBLER__ + +typedef enum CHKPOINT +{ + BOOT_TEST_SRAM_CHKPOINT = 0x00000001, + BOOT_LOAD_IMAGE_CHKPOINT = 0x00000002, + BOOT_CALCULTE_CHKSUM_CHKPOINT= 0x00000003, + BOOT_GET_NEST_FREQ_CHKPOINT = 0x00000004, + BOOT_SSX_BOOT_CALL_CHKPOINT = 0x00000005, + BOOT_SSX_RETURNED_CHKPOINT = 0x00000006 +}CHKPOINT; + +#endif /* __ASSEMBLER__ */ + +#define SRAM_TEST_START_ADDRESS 0xFFF80040 // @ai007c +#define SRAM_START_ADDRESS 0xFFF80000 +#define SRAM_TEST_END_ADDRESS 0xFFFFFBFF // @th030c +#define SRAM_END_ADDRESS 0xFFFFFFFF +#define SRAM_TEST_BIT_PATTERN 0xA5A5A5A5 +#define EYE_CATCHER_ADDRESS 0x1234ABCD + +#define BOOT_LOADER_ID "OCC Boot Image\0" + +// Define to write val to SPRG0 register +#define WRITE_TO_SPRG0(val) \ + ({__asm__ __volatile__ ("mtsprg0 %0;" ::"r"(val));}) + +#define WRITE_TO_SPRG1_AND_HALT(rc) \ + ({__asm__ __volatile__ ( "mtsprg1 %0;" "tw 31,0,0;": : "r" (rc));}) + +//************************************************************************* +// Structures +//************************************************************************* + +//************************************************************************* +// Globals +//************************************************************************* + +//************************************************************************* +// Function Prototypes +//************************************************************************* + +//************************************************************************* +// Functions +//************************************************************************* + +#endif // _bootMain_h + + diff --git a/src/occBootLoader/bootfiles.mk b/src/occBootLoader/bootfiles.mk new file mode 100755 index 0000000..f7b2cbc --- /dev/null +++ b/src/occBootLoader/bootfiles.mk @@ -0,0 +1,28 @@ +# @file libofiles.mk +# +# @brief mk for libssx.a object files +# +# @page ChangeLogs Change Logs +# @section ofiles.mk +# @verbatim +# +# +# Change Log ****************************************************************** +# Flag Defect/Feature User Date Description +# ------ -------------- ---------- ------------ ----------- +# @pb00E pbavari 03/28/2012 Makefile ODE support +# @rc004 882410 rickylie 05/10/2013 Pin OCC Firmware Level to an Address in Lid +# +# @endverbatim +# +########################################################################## +# INCLUDES +########################################################################## +C-SOURCES = bootMain.c ../occ/occbuildname.c +S-SOURCES = bootInit.S ../ssx/ppc32/savegpr.S + +BOOTLOADER_OBJECTS = $(C-SOURCES:.c=.o) $(S-SOURCES:.S=.o) + + + + diff --git a/src/occBootLoader/imageHdrScript.c b/src/occBootLoader/imageHdrScript.c new file mode 100755 index 0000000..77bb134 --- /dev/null +++ b/src/occBootLoader/imageHdrScript.c @@ -0,0 +1,877 @@ +/****************************************************************************** +// @file imageHdrScript.c +// @brief Helper script to fix image header fields and other image related +// support +*/ +/****************************************************************************** + * + * @page ChangeLogs Change Logs + * @section imageHdrScript.c IMAGEHDRSCRIPT.C + * @verbatim + * + * Flag Def/Fea Userid Date Description + * ------- ---------- -------- ---------- ---------------------------------- + * @pb000 pbavari 06/28/2011 Created + * @pb001 pbavari 07/21/2011 Changed the way image is being + * combined to support applet images + * @pb006 pbavari 09/16/2011 Display object size support + * @pb00A pbavari 11/17/2011 Added check for 128 bytes + * alignment for image size. + * @rc003 rickylie 02/03/2012 Verify & Clean Up OCC Headers & Comments + * @pb010 D856284 pbavari 10/05/2012 Fix displaySize option + * @ai004 ailutsar 11/06/2012 Improvement for imageHdrScript help text + * + * @endverbatim + * + *///*************************************************************************/ + +//************************************************************************* +// Includes +//************************************************************************* +#include <sys/types.h> +#include <stdio.h> +#include <stdlib.h> +#include <common_types.h> +#include <stddef.h> +#include <string.h> + +//************************************************************************* +// Externs +//************************************************************************* + +//************************************************************************* +// Macros +//************************************************************************* + +//************************************************************************* +// Defines/Enums +//************************************************************************* +#define CHECKSUM_FIELD_OFFSET offsetof(imageHdr_t, checksum) +#define CHECKSUM_FIELD_LEN 4 +#define IMAGE_SZ_FIELD_OFFSET offsetof(imageHdr_t, image_size) +#define IMAGE_SZ_FIELD_LEN 4 +#define FAILURE_RC -1 +#define SUCCESS_RC 0 +#define EP_BRANCH_INST_LEN 4 +#define EP_BRANCH_INST_OFFSET offsetof(imageHdr_t, ep_branch_inst) +#define ADDRESS_OFFSET offsetof(imageHdr_t, ep_addr) +#define ADDRESS_LEN 4 +#define VERSION_OFFSET offsetof(imageHdr_t, version) +#define VERSION_LEN 4 +#define ID_STR_OFFSET offsetof(imageHdr_t, image_id_str) +#define ID_STR_LEN IMAGE_ID_STR_SZ +#define ADDRESS_MASK 0x03FFFFFC +#define BRANCH_MASK 0x48000002 +#define DUMP_HDR_STR "dumpHdr" +#define COMBINE_IMAGE_STR "combineImage" + +// >> gitprep +#define FILE_TO_WRITE_ODE "/obj/ppc/occc/405/image.bin" +#define FILE_TO_WRITE_GNU "image.bin" +// << gitprep + +//@pb006a - start +#define DISPLAY_SIZE "displaySize" +#define READELF_CMD "readelf -S " +#define PIPE_CMD " > elfdata " +#define ELF_FILE "elfdata" +#define ELF_FILE_REMOVE_CMD "rm elfdata" +//@pb006a - end + +//************************************************************************* +// Structures +//************************************************************************* + +//************************************************************************* +// Globals +//************************************************************************* + +//************************************************************************* +// Function Prototypes +//************************************************************************* + +//************************************************************************* +// Functions +//************************************************************************* + +//@pb006a +// Function Specification +// +// Name: displaySize +// +// Description: Display size of the object file +// +// Flow: FN=None +// +// End Function Specification +int displaySize(char * i_file) +{ + int l_rc = SUCCESS_RC; + unsigned long int l_size = 0; + FILE * l_file = NULL; + int l_delfile = 0; + do + { + // create command for the system call to display size using + // readelf tool and copy output into different file for parsing later. + if( i_file != NULL) + { + l_size = strlen(i_file); + } + l_size += strlen(READELF_CMD); + l_size += strlen(PIPE_CMD); + char l_cmd[l_size+1]; + unsigned long int l_cnt = strlen(READELF_CMD); + strncpy(l_cmd,READELF_CMD,l_cnt); + strncpy(&l_cmd[l_cnt],i_file,strlen(i_file)); + l_cnt += strlen(i_file); + strncpy(&l_cmd[l_cnt],PIPE_CMD,strlen(PIPE_CMD)); + l_cnt += strlen(PIPE_CMD); + l_cmd[l_cnt] = '\0'; + // do system call + system (l_cmd ); + // set to indicate delete temporary file + l_delfile = 1; + // Open the file that was written with the system call for + // reading + l_file = fopen(ELF_FILE, "r"); + + if( NULL == l_file) + { + printf("Failed to open file %s for reading\n",ELF_FILE); + l_rc = FAILURE_RC; + break; + } + // seek to end to get size of file + l_rc = fseek(l_file, 0, SEEK_END); + + if( l_rc != 0) + { + printf("Failed to seek end of the file: %s,rc: %d\n", + i_file,l_rc); + l_rc = FAILURE_RC; + break; + } + // get size + l_size = ftell(l_file); + + //Now seek back to the beginning to start parsing + l_rc = fseek(l_file, 0, SEEK_SET); + + if( l_rc != 0) + { + printf("Failed to seek start after getting size of the file: %s, " + "rc: %d\n",i_file,l_rc); + l_rc = FAILURE_RC; + break; + } + + // parse data and display size + char l_data[l_size]; + unsigned long int l_totalSz = 0; + char * l_str = NULL; + printf("===========================================================\n"); + printf("Size display for %s:\n", i_file); + printf("%-25.25s : Address : Size \n","Section"); + printf("===========================================================\n"); + while (fgets(l_data,l_size,l_file) != NULL) + { + // Ignore lines that does not have BITS in them + if(strstr(l_data,"BITS") != NULL) + { + // If there is word debug on the line then we are done parsing + if(strstr(l_data,"debug") != NULL) + { + break; + } + //@pb010a - start + l_str = NULL; + // We need to parse 2 different options: + // 1) [ X] and 2) [XX] Where X is number. + // Example of data: + // Num Section Type Addr offset Size + // [ 9] .linear_wr PROGBITS ffff6000 046000 001000 00 WA 0 0 1 + // [10] .linear_rd PROGBITS ffff7000 047000 001000 00 WA 0 0 1 + // We are interested in Section, Address, offset and size. + // Everything else we can ignore. So for ease of parsing, + // ignore everything until first "]". + l_str = strstr(l_data,"]"); + if( NULL != l_str ) + { + char l_str1[l_size]; + char l_sec[l_size]; + unsigned long int l_addr = 0; + unsigned long int l_offset = 0; + unsigned long int l_size = 0; + sscanf(l_str,"%s %s %s %x %x %x ",l_str1,l_sec, + l_str1,&l_addr,&l_offset,&l_size); + printf("%-25.25s : 0x%08x : %d\t(HEX: %x ) \n",l_sec, + l_addr,(int)l_size,l_size); + l_totalSz += l_size; + } + //@pb010a - end + } + } // end while loop + printf("===========================================================\n"); + printf("%-25.25s : : %d\t(HEX: %x ) \n","Total", + (int)l_totalSz,l_totalSz); + printf("===========================================================\n"); + + }while(0); + + // Close file if it was open + if( l_file != NULL) + { + int l_rc2 = fclose( l_file); + + if( l_rc2 != 0) + { + printf("Failed to close destination file: rc: %d\n",l_rc2); + } + } + + if( l_delfile == 1) + { + // remove temporary file + system(ELF_FILE_REMOVE_CMD); + } + + return l_rc; +} + + +// Function Specification +// +// Name: combineImage +// +// Description: Append input image to $sb/src/image.bin +// +// Flow: FN=None +// +// End Function Specification +int combineImage(char * i_file1) +{ + FILE * l_file1 = NULL; + FILE * l_file2 = NULL; + FILE * l_file = NULL; + int l_rc = SUCCESS_RC; + unsigned long int l_size = 0; + // >> gitprep + bool l_odeBuild = TRUE; + // << gitprep + + do + { + char * l_sbPath = getenv("SANDBOXBASE"); + if( l_sbPath != NULL) + { + l_size = strlen(l_sbPath); + // >> gitprep + l_size += strlen(FILE_TO_WRITE_ODE); + // << gitprep + } + else + { + // >> gitprep + l_sbPath = getenv("OCCROOT"); + if(l_sbPath != NULL) + { + l_size = strlen(l_sbPath); + l_size += strlen(FILE_TO_WRITE_GNU); + l_odeBuild = FALSE; + } + else + { + printf("Failed to get either SANDBOXBASE or OCCROOT environment variables\n"); + l_rc = FAILURE_RC; + break; + } + // << gitprep + } + char l_fileToWrite[l_size+1]; + strncpy(l_fileToWrite,l_sbPath,strlen(l_sbPath)); + + // >> gitprep + if ( TRUE == l_odeBuild ) + { + strncpy(&l_fileToWrite[strlen(l_sbPath)],FILE_TO_WRITE_ODE,strlen(FILE_TO_WRITE_ODE)); + } + else + { + strncpy(&l_fileToWrite[strlen(l_sbPath)],FILE_TO_WRITE_GNU,strlen(FILE_TO_WRITE_GNU)); + } + // << gitprep + l_fileToWrite[l_size] = '\0'; + // >> gitprep + printf("l_fileToWrite: %s\t\tl_sbPath: %s\n", l_fileToWrite, l_sbPath); + // << gitprep + // Open the file1 + l_file1 = fopen(i_file1, "r"); + + if( NULL == l_file1) + { + printf("Failed to open file %s for reading\n",i_file1); + l_rc = FAILURE_RC; + break; + } + + // Open the destination file + l_file = fopen(l_fileToWrite, "a"); + + if( NULL == l_file) + { + printf("Failed to open file %s for reading\n",l_fileToWrite); + l_rc = FAILURE_RC; + break; + } + + // get size of file1 + l_rc = fseek(l_file1, 0, SEEK_END); + + if( l_rc != 0) + { + printf("Failed to seek end of the file: %s,rc: %d\n", + i_file1,l_rc); + l_rc = FAILURE_RC; + break; + } + + unsigned long int l_sz1 = ftell(l_file1); + + //Now seek back to the beginning + l_rc = fseek(l_file1, 0, SEEK_SET); + + if( l_rc != 0) + { + printf("Failed to seek start after getting size of the file: %s, " + "rc: %d\n",i_file1,l_rc); + l_rc = FAILURE_RC; + break; + } + + // Read full file into buffer + unsigned int l_data[l_sz1]; + size_t l_readSz = fread(&l_data[0], 1, l_sz1, l_file1); + + if( l_readSz != l_sz1) + { + printf("Failed to read file: %s,readSz: 0x%x,l_sz: 0x%x\n", + i_file1,l_readSz,l_sz1); + l_rc = -1; + break; + } + + // Write file1 data to destination file + size_t l_writeSz = fwrite( l_data,1,l_sz1,l_file); + + if( l_writeSz != l_sz1) + { + printf("Error writing data. Written Sz :0x%x,Expected Sz:0x%x\n", + l_writeSz,l_sz1); + l_rc = FAILURE_RC; + } + + }while(0); + + // Close file1 if it was open + if( l_file1 != NULL) + { + int l_rc2 = fclose( l_file1); + + if( l_rc2 != 0) + { + printf("Failed to close file: %s,rc: %d\n", i_file1,l_rc2); + } + } + + // Close destination file if it was open + if( l_file != NULL) + { + int l_rc2 = fclose( l_file); + + if( l_rc2 != 0) + { + printf("Failed to close destination file: rc: %d\n",l_rc2); + } + } + + return l_rc; +} + + +// Function Specification +// +// Name: dumpHdr +// +// Description: Dump image header +// +// Flow: FN=None +// +// End Function Specification +int dumpHdr(char * i_fileStr) +{ + FILE * l_filePtr = NULL; + int l_rc = SUCCESS_RC; + do + { + // Open the file + l_filePtr = fopen(i_fileStr, "rb"); + + if( NULL == l_filePtr) + { + printf("Failed to open file %s for reading\n",i_fileStr); + l_rc = FAILURE_RC; + break; + } + // file is open now + // get the file size + l_rc = fseek(l_filePtr, 0, SEEK_END); + + if( l_rc != 0) + { + printf("Failed to seek end of the file: %s,rc: %d\n", + i_fileStr,l_rc); + l_rc = FAILURE_RC; + break; + } + + unsigned long int l_sz = ftell(l_filePtr); + + //Now seek back to the beginning + l_rc = fseek(l_filePtr, 0, SEEK_SET); + + if( l_rc != 0) + { + printf("Failed to seek start after getting size of the file: %s, " + "rc: %d\n",i_fileStr,l_rc); + l_rc = FAILURE_RC; + break; + } + + l_sz = sizeof(imageHdr_t); + + // Read header from the file + unsigned int l_hdrPtr[l_sz]; + size_t l_readSz = fread(&l_hdrPtr[0], 1, l_sz, l_filePtr); + + if( l_readSz != l_sz) + { + printf("Failed to read file: %s,readSz: 0x%x,l_sz: 0x%x\n", + i_fileStr,l_readSz,l_sz); + l_rc = -1; + break; + } + + printf("==========================================================\n"); + printf("SRAM Repair Reserved:\t "); + unsigned int idx = 0; + for(idx = 0; idx < SRAM_REPAIR_RESERVE_SZ/4; idx++) + { + printf("0x%08X ",htonl(l_hdrPtr[idx]) ); + } + printf("\n"); + printf("ep_branch_inst:\t\t 0x%08x\n",htonl( l_hdrPtr[idx++])); + printf("halt_inst:\t\t 0x%x\n",htonl( l_hdrPtr[idx++])); + printf("image_size:\t\t 0x%08x \n", htonl( l_hdrPtr[idx++])); + printf("start_addr:\t\t 0x%08x\n",htonl( l_hdrPtr[idx++])); + printf("readonly_size:\t\t 0x%08x \n",htonl( l_hdrPtr[idx++])); + printf("boot_writeable_addr:\t 0x%08x\n",htonl( l_hdrPtr[idx++])); + printf("boot_writeable_size:\t 0x%08x \n",htonl( l_hdrPtr[idx++])); + printf("zero_data_addr:\t\t 0x%08x\n", htonl( l_hdrPtr[idx++])); + printf("zero_data_size:\t\t 0x%08x \n", htonl( l_hdrPtr[idx++])); + printf("ep_addr:\t\t 0x%08x\n", htonl( l_hdrPtr[idx++])); + printf("checksum:\t\t 0x%08x\n", htonl( l_hdrPtr[idx++])); + printf("version:\t\t %.*s\n", VERSION_LEN,(char*)&l_hdrPtr[idx++]); + printf("image_id_str:\t\t %s\n",(char*)(&l_hdrPtr[idx])); + idx += (IMAGE_ID_STR_SZ/4); + unsigned int i = 0; + printf("Reserved:\t\t "); + for(i = 0; i < RESERVED_SZ/4; i++) + { + printf("0x%08X ",htonl(l_hdrPtr[idx++]) ); + } + printf("\n"); + printf("==========================================================\n"); + + }while(0); + + // Close file if open + if( l_filePtr != NULL) + { + int l_rc2 = fclose( l_filePtr); + + if( l_rc2 != 0) + { + printf("Failed to close file: %s,rc: %d\n", i_fileStr,l_rc2); + } + } + + return l_rc; +} + + +// Function Specification +// +// Name: calImageChecksum +// +// Description: calculate image checksum +// +// Flow: FN=None +// +// End Function Specification +unsigned long int calImageChecksum(FILE * i_filePtr) +{ + unsigned long int l_checksum = 0; + + unsigned long int l_counter = 0; + int l_val = fgetc(i_filePtr); + + while( l_val != EOF) + { + l_checksum += l_val; + l_counter += 1; + // Skip checksum field + if( l_counter == CHECKSUM_FIELD_OFFSET) + { + while( l_counter != (CHECKSUM_FIELD_OFFSET + CHECKSUM_FIELD_LEN)) + { + l_counter++; + l_val = fgetc(i_filePtr); + } + } + l_val = fgetc(i_filePtr); + } + + // >> gitprep + fprintf(stdout,"Checksum: 0x%08X\t\tSize: 0x%08X\n", l_checksum, l_counter); + // << gitprep + return l_checksum; +} + + +// Function Specification +// +// Name: write +// +// Description: Write given data to file at given offset +// +// Flow: FN=None +// +// End Function Specification +int write(FILE * i_filePtr, + const void * i_dataPtr, + const unsigned long int i_dataSz, + const unsigned long int i_dataOffset) +{ + int l_rc = SUCCESS_RC; + + l_rc = fseek(i_filePtr, i_dataOffset, SEEK_SET); + + if( l_rc != 0) + { + printf("Failed to seek offset: [0x%x] while writing to file,rc: %d\n", + i_dataOffset,l_rc); + l_rc = FAILURE_RC; + } + else + { + size_t l_writeSz = fwrite( i_dataPtr,1,i_dataSz,i_filePtr); + + if( l_writeSz != i_dataSz) + { + printf("Error writing data. Written Sz :0x%x,Expected Sz:0x%x\n", + l_writeSz,i_dataSz); + l_rc = FAILURE_RC; + } + } + + return l_rc; +} + + +// Function Specification +// +// Name: printHelp +// +// Description: script usage +// +// Flow: FN=None +// +// End Function Specification +void printHelp() +{ + // @ai004M + printf("Script Usage: imageHdrScript [FILE] [OPTIONS]\n\n"); + + printf("This OCC Image Header Script is used for handling different image header\n"); + printf("fields and combining different OCC images into single image.\n"); + // >> gitprep + if ( NULL != getenv("SANDBOXBASE") ) + { + printf("The path to target image is $SANDBOXBASE%s\n\n", FILE_TO_WRITE_ODE); + } + else + { + printf("The path to target image is $OCCROOT%s\n\n", FILE_TO_WRITE_GNU); + } + // << gitprep + printf("Option for ELF executable file (file type: *.out):\n"); + printf(" displaySize check section sizes in input file\n"); + printf("Options for binary image file (file type: *.bin):\n"); + printf(" combineImage append input image to the target image\n"); + printf(" dumpHdr dump values of each header field in input image\n\n"); + + printf("If the option string is not equal to \"combineImage\", \"displaySize\", or\n"); + printf("\"dumpHdr\", the script will use that string as image version, and start to\n"); + printf("check/update image header fields.\n"); + printf("Example:\n"); + printf(" imageHdrScript IMAGE_FILE VERSION_STRING\n"); + printf(" imageHdrScript IMAGE_FILE VERSION_STRING ID_STRING\n"); +} + + +// Function Specification +// +// Name: main +// +// Description: main for the script +// +// Flow: FN=None +// +// End Function Specification +int main(int argc, char* argv[]) +{ + FILE * l_filePtr = NULL; + int l_rc = SUCCESS_RC; + + do + { + if( argc <= 2) + { + printHelp(); + l_rc = FAILURE_RC; + break; + } + + if( (strcmp(argv[2],DUMP_HDR_STR)== 0)) + { + printf("Dump Image Header\n"); + l_rc = dumpHdr(argv[1]); + + if( l_rc != 0) + { + printf("Problem dumping header for file: %s,rc: %d\n", + argv[1],l_rc); + l_rc = FAILURE_RC; + } + break; + } + + if( (argc > 2) && (strcmp(argv[2],COMBINE_IMAGE_STR)== 0)) + { + printf("Combining image from file: %s\n",argv[1]); + l_rc = combineImage(argv[1]); + + if( l_rc != 0) + { + printf("Problem combining image: rc: %d\n",l_rc); + l_rc = FAILURE_RC; + } + break; + } + //@pb006a - display size + if( (argc > 2) && (strcmp(argv[2],DISPLAY_SIZE)== 0)) + { + l_rc = displaySize(argv[1]); + + if( l_rc != 0) + { + printf("Problem displaying size: rc: %d\n",l_rc); + l_rc = FAILURE_RC; + } + break; + } + + // At this point we know there is atleast 1 argument to the program + + // Open the file + l_filePtr = fopen(argv[1], "r+"); + + if( NULL == l_filePtr) + { + printf("Failed to open file %s for reading and writing\n",argv[1]); + l_rc = FAILURE_RC; + break; + } + // file is open now + // get the file size + l_rc = fseek(l_filePtr, 0, SEEK_END); + + if( l_rc != 0) + { + printf("Failed to seek end of the file: %s, rc: %d\n",argv[1],l_rc); + l_rc = FAILURE_RC; + break; + } + + unsigned long int l_sz = ftell(l_filePtr); + + if( l_sz % 128 != 0) + { + printf("Image size:[%d] in file: [%s] is not 128-byte aligned\n", + l_sz,argv[1]); + l_rc = FAILURE_RC; + break; + } + + //Now seek back to the beginning + l_rc = fseek(l_filePtr, 0, SEEK_SET); + + if( l_rc != 0) + { + printf("Failed to seek start after getting size of the file: %s, " + "rc: %d\n",argv[1],l_rc); + l_rc = FAILURE_RC; + break; + } + + l_sz = htonl(l_sz); + + // Write image size to the image header + l_rc = write(l_filePtr, &l_sz, IMAGE_SZ_FIELD_LEN,IMAGE_SZ_FIELD_OFFSET); + + if( l_rc != 0) + { + printf("Failed to write image size in the file: %s, " + "rc: %d,l_sz: 0x%x,IMAGE_SZ_FIELD_LEN: %d, " + "IMAGE_SZ_FIELD_OFFSET: %d\n",argv[1],l_rc, + IMAGE_SZ_FIELD_LEN,IMAGE_SZ_FIELD_OFFSET); + l_rc = FAILURE_RC; + break; + + } + + // Write image version + unsigned long int l_version = 0; + sprintf((char*)&l_version, "%s",argv[2]); + l_rc = write(l_filePtr, &l_version, VERSION_LEN, VERSION_OFFSET); + + if( l_rc != 0) + { + printf("Failed to write version in the file: %s, " + "rc: %d,l_sz: 0x%x,: VERSION_LEN: %d, " + "VERSION_OFFSET: %d\n",VERSION_LEN,l_rc, + VERSION_LEN,VERSION_OFFSET); + l_rc = FAILURE_RC; + break; + + } + + // If user has passed in image id string, write it to the image + if( argc > 3) + { + l_rc = write(l_filePtr, argv[3], ID_STR_LEN, ID_STR_OFFSET); + + if( l_rc != 0) + { + printf("Failed to write id_str in the file: %s, " + "rc: %d,l_sz: 0x%x,: ID_STR_LEN: %d, " + "ID_STR_OFFSET: %d\n",argv[1],l_rc, + ID_STR_LEN,ID_STR_OFFSET); + l_rc = FAILURE_RC; + break; + + } + } + + //Now seek to the ep_address field + l_rc = fseek(l_filePtr, ADDRESS_OFFSET, SEEK_SET); + + if( l_rc != 0) + { + printf("Failed to seek ep_address offset: 0x%x of the file: %s, " + "rc: %d\n",ADDRESS_OFFSET,argv[1],l_rc); + l_rc = FAILURE_RC; + break; + } + unsigned long int l_addr = 0; + // read ep_addr field + size_t l_readSz = fread(&l_addr, 1, ADDRESS_LEN, l_filePtr); + + if( l_readSz != ADDRESS_LEN) + { + printf("Failed to read address for ep_branch calculation.file: %s, " + "readSz: 0x%x,ADDRESS_LEN: 0x%x\n",argv[1],l_readSz, + ADDRESS_LEN); + l_rc = FAILURE_RC; + break; + } + + // calculate branch instruction to that address and write to + // ep_branch_inst field in the image header + l_addr = ntohl(l_addr); + l_addr &= ADDRESS_MASK; + l_addr |= BRANCH_MASK; + + l_addr = htonl(l_addr); + + l_rc = write(l_filePtr, &l_addr, EP_BRANCH_INST_LEN, + EP_BRANCH_INST_OFFSET); + + if( l_rc != 0) + { + printf("Failed to write ep_branch_inst in the file: %s, " + "rc: %d,l_sz: 0x%x,: EP_BRANCH_INST_LEN: %d, " + "EP_BRANCH_INST_OFFSET: %d\n",argv[1],l_rc, + EP_BRANCH_INST_LEN,EP_BRANCH_INST_OFFSET); + l_rc = FAILURE_RC; + break; + + } + + //Now seek back to the beginning for calculating checksum + l_rc = fseek(l_filePtr, 0, SEEK_SET); + + if( l_rc != 0) + { + printf("Failed to seek start before checksum calculation.file: %s," + "rc: %d\n",argv[1],l_rc); + l_rc = FAILURE_RC; + break; + } + + // calculate checksum + unsigned long int l_checksum = calImageChecksum(l_filePtr); + + l_checksum = htonl(l_checksum); + + // Write checksum + l_rc = write(l_filePtr, &l_checksum,CHECKSUM_FIELD_LEN, + CHECKSUM_FIELD_OFFSET); + + if( l_rc != 0) + { + printf("Failed to write image size in the file: %s, " + "rc: %d,l_sz: 0x%x,IMAGE_SZ_FIELD_LEN: %d, " + "IMAGE_SZ_FIELD_OFFSET: %d\n",argv[1],l_rc, + CHECKSUM_FIELD_LEN,CHECKSUM_FIELD_OFFSET); + l_rc = FAILURE_RC; + break; + } + + }while(0); + + // Close file if open + if( l_filePtr != NULL) + { + int l_rc2 = fclose( l_filePtr); + + if( l_rc2 != 0) + { + printf("Failed to close file: %s,rc: %d\n", argv[1],l_rc2); + } + } + + + return l_rc; +} diff --git a/src/occBootLoader/linkboot.cmd b/src/occBootLoader/linkboot.cmd new file mode 100755 index 0000000..544240e --- /dev/null +++ b/src/occBootLoader/linkboot.cmd @@ -0,0 +1,117 @@ + +// $Id$ + + +// This linker script for the OCC Firmware boot loader. This +// script is processed through the C proprocessor to create +// configuration-dependent images. +// This creates image that is 4 byte aligned. + +#ifdef OCCMK +INCLUDE occLinkInputFile +#endif + +#define BOOT_IMAGE_START_ADDR 0x00000000 +#define BOOT_VECTORS 0x00000000 +#define BOOT_VECTORS_SIZE 0x00000740 +#define BOOT_BUILDNAME_ADDR (BOOT_IMAGE_START_ADDR + BOOT_VECTORS_SIZE) +#define WRITE_DATA_SEC_ADDR 0x80000000 +#define BYTE_ALIGN 128 +#define pack_0000 bootMain.o(imageHeader) + +MEMORY +{ + writeableMem : ORIGIN = WRITE_DATA_SEC_ADDR, LENGTH = 0x4000 +} + +SECTIONS +{ + . = BOOT_IMAGE_START_ADDR; + . = BOOT_VECTORS; + + __START_ADDR__ = .; + + //////////////////////////////// + // start read-only section + //////////////////////////////// + + //////////////////////////////// + // exception/vector section + //////////////////////////////// + + .exceptions . : { + ___vectors = .; + bootInit.o(.vectors_0000) + pack_0000 + . = ___vectors + 0x0100; + bootInit.o(.vectors_0100) + . = ___vectors + 0x0200; + bootInit.o(.vectors_0200) + . = ___vectors + 0x0300; + bootInit.o(.vectors_0300) + . = ___vectors + 0x0400; + bootInit.o(.vectors_0400) + . = ___vectors + 0x0500; + bootInit.o(.vectors_0500) + . = ___vectors + 0x0600; + bootInit.o(.vectors_0600) + . = ___vectors + 0x0700; + bootInit.o(.vectors_0700) + } + + //////////////////////////////// + // buildname section 4 byte aligned + //////////////////////////////// + . = BOOT_BUILDNAME_ADDR; + .buildname . : { *(.buildname) } + + //////////////////////////////// + // text section 4 byte aligned, follows buildname section + //////////////////////////////// + // >> gitprep + .text . : { *(.text) *(.text.*) . = ALIGN(BYTE_ALIGN);} + // << gitprep + //////////////////////////////// + // SDA2 section 4 byte aligned + //////////////////////////////// + + _SDA2_BASE_ = .; + .sdata2 . : { *(.sdata2) . = ALIGN(BYTE_ALIGN); } + .sbss2 . : { *(.sbss2) . = ALIGN(BYTE_ALIGN);} + + .rodata . : { *(.rodata*) *(.got2) . = ALIGN(BYTE_ALIGN);} + + __READ_ONLY_DATA_LEN__ = . - BOOT_IMAGE_START_ADDR ; + __WRITEABLE_ADDR__ = .; + + //////////////////////////////// + // start writeable section has different vritual and loadable memory address + //////////////////////////////// + __WRITEABLE_DATA_ADDR__ = WRITE_DATA_SEC_ADDR; + __CURADDR__ = WRITE_DATA_SEC_ADDR; + + //////////////////////////////// + // read-write section + //////////////////////////////// + .rela __CURADDR__ : AT(__WRITEABLE_ADDR__ ) { *(.rela*) . = ALIGN(BYTE_ALIGN);} > writeableMem + __CURADDR__ = __CURADDR__ + SIZEOF(.rela); + .rwdata __CURADDR__ : AT(__WRITEABLE_ADDR__ + SIZEOF(.rela)) { *(.data) *(.bss) *(COMMON) . = ALIGN(BYTE_ALIGN);} > writeableMem + __CURADDR__ = __CURADDR__ + SIZEOF(.rwdata); + + //////////////////////////////// + // SDA section + //////////////////////////////// + _SDA_BASE_ = __CURADDR__; + .sdata __CURADDR__ : AT(__WRITEABLE_ADDR__ + SIZEOF(.rela) + SIZEOF(.rwdata)) { *(.sdata) . = ALIGN(BYTE_ALIGN);} > writeableMem + __CURADDR__ = __CURADDR__ + SIZEOF(.sdata); + .sbss (__CURADDR__) : AT( __WRITEABLE_ADDR__ + SIZEOF(.rela) + SIZEOF(.rwdata) + SIZEOF(.sdata) ) { *(.sbss) . = ALIGN(BYTE_ALIGN); } > writeableMem + __CURADDR__ = __CURADDR__ + SIZEOF(.sbss); + + //////////////////////////////// + // writeable section length is all writeable section except .sbss as + // .sbss section is not showing up in the binary unless there is some data + // in the section below it. Thus it is left at the end to get same + // behavior all the time. + //////////////////////////////// + __WRITEABLE_DATA_LEN__ = (__WRITEABLE_ADDR__ + SIZEOF(.sdata) + SIZEOF(.rela) + SIZEOF(.rwdata)) - __WRITEABLE_ADDR__; +} diff --git a/src/occBootLoader/occLinkInputFile b/src/occBootLoader/occLinkInputFile new file mode 100644 index 0000000..6fe2f9a --- /dev/null +++ b/src/occBootLoader/occLinkInputFile @@ -0,0 +1 @@ +INPUT ( bootMain.o ../occ/occbuildname.o bootInit.o ../ssx/ppc32/savegpr.o ) |