/*************************************************************************** * Copyright (c) 2003-2008, Broadcom Corporation * All Rights Reserved * Confidential Property of Broadcom Corporation * * THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE * AGREEMENT BETWEEN THE USER AND BROADCOM. YOU HAVE NO RIGHT TO USE OR * EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT. * * $brcm_Workfile: $ * $brcm_Revision: $ * $brcm_Date: $ * * Module Description: write image to flash. * * Revision History: * * $brcm_Log: $ * * ***************************************************************************/ #include "bstd.h" #include "bdbg.h" #include "image_recv.h" #include "ram_header.h" BDBG_MODULE(image_write); /* JPF TODO Fix up for non_ucos environments */ static unsigned int s_static_values[128] = { DEF_VERSION, DEF_VERSION,0 }; #define RAM_DISPATCH_BASE (&s_static_values[1]) #define ROM_TEXT_BASE (unsigned int)(&s_static_values[2]) #define FLASH_BASE (unsigned int)(&s_static_values[3]) unsigned int ram0_start_address = (unsigned int)(&s_static_values[4]); unsigned int ram1_start_address = (unsigned int)(&s_static_values[5]); /* return value when image autheticated successfuly else value is 0 */ #define BCM_MAIN_PASSED 0x5abf632d /* 0x1dc8 is offset or authenticate_ram function from the start of main function or start of security image, when security image is built in release mode. 0x2230 is the same offset when image is build in debug mode. SECURE_BASE depends on where security rom is placed. */ #define SECURE_BASE 0x9fc7c000 #define AUTHENTICATE_RAM ((authenticate_t)(SECURE_BASE + 0x1dc8)) typedef unsigned long (*authenticate_t)(unsigned long image_addr, unsigned long image_size, unsigned long signature_addr, unsigned long pubkey_idx); #if defined(DUMMY_AUTHENTICATE) #undef AUTHENTICATE_RAM #define AUTHENTICATE_RAM(x1, x2, x3, x4) BCM_MAIN_PASSED #endif #define RUNNING_TIME_STAMP (*(unsigned long*)(RAM_DISPATCH_BASE-4)) extern void flash_install(uint32_t base, uint32_t offset, uint8_t * data, size_t len); static unsigned long authenticate_code(struct identifying_data6_t * code); bresult image_write(struct image_t * image) { struct identifying_data6_t * ram0; struct identifying_data6_t * ram1; struct identifying_data6_t * new_ram; uint32_t ram_offset; /* find running image */ ram0 = (struct identifying_data6_t *)&ram0_start_address; ram1 = (struct identifying_data6_t *)&ram1_start_address; if(RUNNING_TIME_STAMP == ram0->signing_time){ ram_offset = (unsigned long)ram1 - ROM_TEXT_BASE; }else if(RUNNING_TIME_STAMP == ram1->signing_time){ ram_offset = (unsigned long)ram0 - ROM_TEXT_BASE; }else{ ram_offset = (unsigned long)ram1 - ROM_TEXT_BASE; } new_ram = (struct identifying_data6_t *)image->data; if ((ram0->signing_time == new_ram->signing_time) || (ram1->signing_time == new_ram->signing_time)) { BDBG_WRN(("image already in flash")); return berr_same_version; } if(BCM_MAIN_PASSED != authenticate_code(new_ram)){ BDBG_WRN(("authentication failed")); return berr_verification_falure; } BDBG_WRN(("writing at 0x%x", ram_offset)); #if 0 /* JPF TODO */ flash_install(FLASH_BASE, ram_offset, image->data, image->size); #endif return b_ok; } unsigned long authenticate_code(struct identifying_data6_t * code) { unsigned long res; unsigned long code_address; unsigned long code_size; unsigned long signature_address; unsigned long key_idx; res = 0; if(1 != code->key_identifier_flag){ goto ExitFunc; } code_address = (unsigned long)code; code_size = code->length - 128; signature_address = (unsigned long)code + code->signature_index; key_idx = code->key_identifier[0]; if(0x40 > code_size){ goto ExitFunc; } if ((0 < key_idx) && (16 > key_idx)) { res = AUTHENTICATE_RAM(code_address, code_size, signature_address, key_idx); } ExitFunc: return res; }