summaryrefslogtreecommitdiff
path: root/cleopatre/u-boot-1.1.6/net
diff options
context:
space:
mode:
authorsave2009-07-27 12:49:47 +0000
committersave2009-07-27 12:49:47 +0000
commitb0c2bf496e10bd24e1a94b8021e1ad5528a834da (patch)
treedbca6e39a488966017b9ebed340f80024923a693 /cleopatre/u-boot-1.1.6/net
parent457a13107a3b0c89bff86fb827893ddd4231d498 (diff)
[CLEO][U-BOOT]SpidUpdate revue :
- NVRAM detection - Images selection with NVRAM parameters git-svn-id: svn+ssh://pessac/svn/cesar/trunk@5083 017c9cb6-072f-447c-8318-d5b54f68fe89
Diffstat (limited to 'cleopatre/u-boot-1.1.6/net')
-rw-r--r--cleopatre/u-boot-1.1.6/net/net.c17
-rw-r--r--cleopatre/u-boot-1.1.6/net/spidupd.c1239
-rw-r--r--cleopatre/u-boot-1.1.6/net/spidupd.h56
3 files changed, 771 insertions, 541 deletions
diff --git a/cleopatre/u-boot-1.1.6/net/net.c b/cleopatre/u-boot-1.1.6/net/net.c
index 05bbc1a407..2a16a02c6b 100644
--- a/cleopatre/u-boot-1.1.6/net/net.c
+++ b/cleopatre/u-boot-1.1.6/net/net.c
@@ -468,7 +468,7 @@ restart:
#if (CONFIG_COMMANDS & CFG_CMD_SPIDUPD)
case SPIDUPD:
- SpidupdStart();
+ SpidupdStart();
break;
#endif
default:
@@ -1204,7 +1204,7 @@ NetReceive(volatile uchar * inpkt, int len)
len -= E802_HDR_SIZE;
} else if (x != PROT_VLAN) { /* normal packet */
- if (x != PROT_SPIDUPD) {
+ if (x != PROT_SPIDUPD) {
ip = (IP_t *)(inpkt + ETHER_HDR_SIZE);
len -= ETHER_HDR_SIZE;
}
@@ -1512,21 +1512,20 @@ NetReceive(volatile uchar * inpkt, int len)
case PROT_SPIDUPD:
#ifdef ET_DEBUG
- puts ("Got SPIDUPD\n");
+ puts ("Got SPIDUPD\n");
#endif
/* We received packet from PC client.
- * in order to respod to it, we have to set
+ * in order to respond to it, we have to set
* the destination addr to the addr of that PC client */
memcpy (NetClientEther, ((MME_t *)NetRxPkt)->mme_src, 6);
/*
- * MME header OK. Pass the packet to the current handler.
+ * MME header OK. Pass the packet to the current handler.
* We do not use UDP ports, so they are set to 0
- */
- (*packetHandler)((uchar *)NetRxPkt, 0, 0, len);
- break;
+ */
+ (*packetHandler)((uchar *)NetRxPkt, 0, 0, len);
+ break;
}
-
}
diff --git a/cleopatre/u-boot-1.1.6/net/spidupd.c b/cleopatre/u-boot-1.1.6/net/spidupd.c
index 477c5b17bd..5b1106df87 100644
--- a/cleopatre/u-boot-1.1.6/net/spidupd.c
+++ b/cleopatre/u-boot-1.1.6/net/spidupd.c
@@ -26,188 +26,401 @@
#include <command.h>
#include <net.h>
#include <md5.h>
+#include <asm/arch/image_desc.h>
+#include <asm/arch/spc300_nvram.h>
#include "spidupd.h"
-#include "asm/arch-spc300/image_desc.h"
-#undef ET_DEBUG
-//#define ET_DEBUG
+/** Debug management */
+#undef ET_DEBUG
+//#define ET_DEBUG
-static spidcom_image_desc_t img_0_desc; /* in single-boot mode we use just img_0_desc */
-static spidcom_image_desc_t img_1_desc; /* needed for dual-boot mode */
-static spidcom_image_desc_t *hdr; /* global pointer on selected image descriptor */
-static unsigned char *upd_addr; /* addr on which we will load new image */
-
-#define IMG_0_ADDR (unsigned char *)0x00140000
-#define IMG_1_ADDR (unsigned char *)0x004a0000
-#define IMG_FLASH_SIZE 0x360000
+#ifdef ET_DEBUG
+#define TRACE(...) printf("SPiDUPD: " __VA_ARGS__)
+#else
+#define TRACE(...)
+#endif
-#define DUAL_BOOT
+/** Flash image status */
+#define BAD_MAGIC_NUMBER 1
+#define INDEX_NOT_VALID 2
+#define IMAGE_NOT_VALID 3
+#define WRONG_IMAGE_ARCH 4
+#define WRONG_IMAGE_TYPE 5
+#define UPD_NOT_FINISHED 6
+#define IMAGE_NOT_SUCCESS 7
+#define IMAGE_OK 8
+#define IMAGE_OK_ORIGIN 9
+
+/** Max flash images allowed */
+#define MAX_IMG 10
+/** Flash addresses of present images */
+static unsigned long img_addr[MAX_IMG] = {0};
+
+/** Size of a sImage type (Normal type */
+#define SIMG_FLASH_SIZE 0x360000
#if (CONFIG_COMMANDS & CFG_CMD_NET)
-#define TIMEOUT 1 /* Seconds to timeout for a lost pkt */
+/** Timeouts to stop Netloop */
+#define TIMEOUT 1 /* TO for a lost pkt in seconds */
#ifndef CONFIG_NET_RETRY_COUNT
-# define TIMEOUT_COUNT 0 /* # of timeouts before giving up */
+#define TIMEOUT_COUNT 0 /* TO before giving up */
#else
-# define TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT * 2)
+#define TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT * 2)
#endif
-#define FLASH_WRITE_TOUT 1*60 /* Writing Linux image to flash TO in seconds */
-
-
-static int SpidupdTimeoutCount;
-static int SpidupdState, NextSpidupdState; /* current and next state */
+/** Flash writing timeout */
+#define FLASH_WRITE_TOUT 1*60 /* TO in seconds */
+/** Different states of FSM */
#define STATE_WAIT_UPD_START 1
#define STATE_WAIT_UPD_TRANSFER 2
#define STATE_UPD_END 3
-#define SPIDUPD_BLOCK_SIZE 1024 /* default Spidupd block size */
-
+/** Informations about place to update image */
+struct update_place {
+ ulong flash_addr;
+ ulong ram_addr;
+ ulong index;
+ ulong nb_img;
+ ulong correct_img_exist;
+ ulong correct_type;
+ ulong correct_archi;
+ char versions[MAX_IMG][16];
+};
+
+/** Informations about image to update */
+struct update_image {
+ int num_rx_blk;
+ int len;
+};
+
+/** Processus management */
+struct update_process {
+ int state;
+ int next_state;
+ int modem_busy;
+ int timeout;
+ struct update_place *place;
+ struct update_image *image;
+ VsUpdStartCnf_t start_cnf;
+ VsUpdTransfCnf_t transfer_cnf;
+ VsUpdEndCnf_t end_cnf;
+};
+
+/** Global processus structure */
+struct update_process ctx;
+/** Global image structure */
+struct update_image g_upd_image;
+/** Global place structure */
+struct update_place g_upd_place;
+/** Global image desc structure */
+spidcom_image_desc_t g_img_desc;
+
+/** Reference to flash organization */
extern flash_info_t flash_info[];
-static int img_index = SPIDCOM_IMG_DESC_ORIGIN_INDEX; /* will hold img index */
-
-/* SPIDUPD message primitives */
-static VsUpdStartReq_t *vs_update_start_req;
-static VsUpdStartCnf_t *vs_update_start_cnf;
-static VsUpdTransfReq_t *vs_update_transfer_req;
-static VsUpdTransfCnf_t *vs_update_transfer_cnf;
-static VsUpdEndReq_t *vs_update_end_req;
-static VsUpdEndCnf_t *vs_update_end_cnf;
-
-static VsUpdStartCnf_t g_vs_update_start_cnf;
-static VsUpdTransfCnf_t g_vs_update_transfer_cnf;
-static VsUpdEndCnf_t g_vs_update_end_cnf;
-
-/* modem specific info */
-static int modem_busy = 0; /* update process in progress */
-static int received_block = 0; /* number of tha blocks we received */
-static int upd_img_len = 0; /* will hold the length of transfered image */
-
/**************************| Utility functions |***************************/
-/* cache flush */
-static void flushCaches(void)
+/**
+ * Flush Instruction and Data caches.
+ */
+static void flush_caches(void)
{
unsigned int c7format = 0;
__asm__ __volatile__(
"mcr p15, 0, %0, c7, c6, 0 @ invalidate caches \n\t"
:
- : "r" (c7format)
- : "memory");
+ : "r" (c7format)
+ : "memory");
}
-static int load_header(spidcom_image_desc_t *desc, char *addr)
+/**
+ * Copy the Image descriptor in RAM.
+ *
+ * \param addr source address of the descriptor.
+ * \param desc RAM address of the copy.
+ * \return error code.
+ */
+static int load_header(spidcom_image_desc_t *desc, uchar *addr)
{
- int use_spi_flash = 0;
-
- if ( IS_IN_SPI_RANGE(addr) )
- use_spi_flash = 1;
-
- if (use_spi_flash)
+ if(IS_IN_SPI_RANGE(addr))
{
-
- //printf ("\nLoading image header from SPI to RAM ... ");
-
- /* first read image header, to see what is the len of the image */
- if ( flash_read_spi ((unsigned char *)addr, (unsigned char *)desc, sizeof(spidcom_image_desc_t), 1, 0) != ERR_OK )
+ /* Source address is in flash */
+ if(flash_read_spi(addr, (unsigned char *)desc, sizeof(spidcom_image_desc_t), 1, 0) != ERR_OK)
{
- printf("ERROR : loading image from SPI flash failed.\n");
- return -1;
+ return -1;
}
- } /*IS_IN_SPI_RANGE(addr) */
- else /* we boot from SDRAM */
+ }
+ else
{
- memmove (desc, (char *)addr, sizeof(spidcom_image_desc_t));
+ /* Source is in RAM */
+ memmove(desc, addr, sizeof(spidcom_image_desc_t));
}
return 0;
}
-/*
- * MD5 functions
+/**
+ * Check Image descriptor to see if it is correct or not.
+ *
+ * \param desc Image descriptor pointer.
+ * \return Image status.
*/
+static int check_img(spidcom_image_desc_t *desc)
+{
+ if(strcmp(desc->magic, SPIDCOM_IMG_DESC_MAGIC))
+ {
+ return BAD_MAGIC_NUMBER;
+ }
+
+ if(desc->arch != SPIDCOM_IMG_DESC_SPC300)
+ {
+ return WRONG_IMAGE_ARCH;
+ }
+
+ if(desc->type != SPIDCOM_IMG_DESC_NORMAL_TYPE)
+ {
+ return WRONG_IMAGE_TYPE;
+ }
+
+ if(desc->index == SPIDCOM_IMG_DESC_ORIGIN_INDEX)
+ {
+ return IMAGE_OK_ORIGIN;
+ }
+
+ if(desc->is_not_update != 0)
+ {
+ return UPD_NOT_FINISHED;
+ }
+
+ if(desc->is_valid == 0)
+ {
+ return IMAGE_NOT_VALID;
+ }
+
+ if(desc->index == SPIDCOM_IMG_DESC_INVALID_INDEX)
+ {
+ return INDEX_NOT_VALID;
+ }
+
+ if(!desc->is_1st_boot && desc->is_not_success)
+ {
+ return IMAGE_NOT_SUCCESS;
+ }
-/* Prints a message digest in hexadecimal.
+ return IMAGE_OK;
+}
+
+/**
+ * Find Flash offset of image 0.
+ *
+ * \param bd board info structure.
+ * \return image 0 offset.
*/
-static void md5_print (md5_byte_t digest[16])
+static __inline__ ulong find_img_1st_offset(bd_t *bd)
{
- unsigned int i;
+ /* First image address is stored under NVRAM */
+ spc300_nvram_t *nvram = (spc300_nvram_t *)(bd->bi_nvram_addr);
- for (i = 0; i < 16; i++)
- printf ("%02x", digest[i]);
+ /* We can use SPI Direct Access because nb_images is a uint32_t */
+ return nvram->img_0_offset;
}
-/*Digests update image and prints the result.
+/**
+ * Find the number of allowed images in flash.
+ *
+ * \param bd board info structure.
+ * \return number of image allowed.
*/
-static void md5_image (md5_byte_t md5_sum[16])
+static __inline__ ulong find_nb_images(bd_t* bd)
{
- md5_state_t state;
+ /* Number of allowed images is stored under NVRAM */
+ spc300_nvram_t *nvram = (spc300_nvram_t *)(bd->bi_nvram_addr);
-#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
- ulong bdata = (ulong)UPD_IMG_RAM_ADDR;
- ulong edata = bdata + upd_img_len;
-#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
+ /* We can use SPI Direct Access because nb_images is a uint32_t */
+ return nvram->nb_images;
+}
- md5_init(&state);
+/**
+ * Find Flash images addresses of already present images.
+ *
+ * \param img_nb number of allowed images in flash.
+ * \param img_0_offset offset of flash images area.
+ * \param addrs addresses of found images.
+ * \return number of image found or -1 if error.
+ */
+static int find_images(ulong img_nb, ulong img_0_addr, ulong addrs[])
+{
+ flash_info_t *flinfo = &(flash_info[0]); /* we expect HW to have only one flash, thus only one flinfo */
+ char img_magic[8];
+ int i = 0;
+ int sect = 0;
- puts (" Verifying MD5 Checksum ... ");
+ /* just to be sure : there is only one img_nb address is img_0_addr */
+ if(img_nb == 1)
+ {
+ addrs[0] = img_0_addr;
+ return 1;
+ }
-#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
- while (bdata < edata)
+ /* Search for the "SPIDIMG\0" string on the beginning of the each sector */
+ for(sect=0 ; sect<flinfo->sector_count ; ++sect)
{
- ulong chunk = edata - bdata;
+ /* Sector lower than images area -> continue */
+ if(flinfo->start[sect] < img_0_addr)
+ continue;
- if (chunk > CHUNKSZ)
+ /* Copy beginning of the sector in local array variable */
+ if(flash_read_spi((unsigned char *)flinfo->start[sect], (unsigned char *)img_magic, 8, 1, 0) != ERR_OK)
{
- chunk = CHUNKSZ;
+ printf("Error (Flash Read).\n");
+ return -1;
}
- md5_append(&state, (const md5_byte_t *)bdata, chunk);
- bdata += chunk;
+ /* Compare this with magic word (for SPC300 that is "SPIDIMG\0") */
+ if(memcmp(img_magic, SPIDCOM_IMG_DESC_MAGIC, 8) != 0)
+ {
+ continue;
+ }
+ else
+ {
+ /* Found it */
+ addrs[i] = flinfo->start[sect];
- WATCHDOG_RESET();
- }
-#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
+ /* Number of images found, and index for next image */
+ i++;
- md5_append(&state, (const md5_byte_t *)UPD_IMG_RAM_ADDR, upd_img_len);
+ /* Check if we found all images */
+ if(i == img_nb)
+ break;
+ }
+ }/* for */
+ return i;
+}
-#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
+/**
+ * Choose the better update place.
+ *
+ * \param img_nb number of allowed images in flash.
+ * \param addrs addresses of found images.
+ * \param place update place information structure.
+ * \return error code.
+ */
+static int select_image(int img_nb, ulong img_0_addr, ulong addrs[], struct update_place *place)
+{
+ spidcom_image_desc_t *desc = &g_img_desc;
+ int img_state;
+ ulong min_index = 0xFFFFFFFF;
+ ulong max_index = 0;
+ int sel_img_ok = -1;
+ int sel_img_or = -1;
+ int sel_img_ko = -1;
+ int one_img_ok = 0;
+ int i, j;
+
+ place->correct_img_exist = 0;
+
+ /* Clear previous stored version */
+ for(i=0 ; i<MAX_IMG ; i++)
+ place->versions[i][0] = '\0';
+
+ for(i=0, j=0 ; i<img_nb ; i++)
+ {
+ /* Copy the descriptor to RAM because SPI direct allows only
+ * 32bits access */
+ load_header(desc, (uchar*)addrs[i]);
- md5_finish(&state, md5_sum);
+ /* Check flash Image */
+ img_state = check_img(desc);
- printf ("MD5 (Linux image) = ");
- md5_print (md5_sum);
- printf ("\n");
-}
+ TRACE("IMG_state[%d]=%x\n", i ,img_state);
-static void sprintf_hex(unsigned char * str, const unsigned char * ptr,
- int len, unsigned char delim)
-{
- static const unsigned char __hexdigits[] = "0123456789ABCDEF";
- int i, j=0;
- for(i=0; i<len; i++){
- if(i)str[j++]=delim;
- str[j++]=__hexdigits[ptr[i]>>4];
- str[j++]=__hexdigits[ptr[i]&0x0F];
- }
- str[j] = 0;
-}
-void print_ETHaddr (uchar *x)
-{
- unsigned char tmp[18];
+ switch(img_state)
+ {
+ case IMAGE_OK:
+ /* It's correct image */
+ one_img_ok++;
+ /* Smaller index -> select it */
+ if (desc->index <= min_index)
+ {
+ min_index = desc->index;
+ sel_img_ok = i;
+ }
+ /* Store max index */
+ if (desc->index > max_index)
+ {
+ max_index = desc->index;
+ }
+ /* Precise type and archi allowed */
+ place->correct_img_exist = 1;
+ place->correct_type = desc->type;
+ place->correct_archi = desc->arch;
+ /* Store the version */
+ strncpy(place->versions[j++], desc->version, 16);
+ break;
+
+ case IMAGE_OK_ORIGIN:
+ /* It's a JTAG image */
+ sel_img_or = i;
+ break;
- sprintf_hex(tmp, x, 6, ':');
- puts ((const char *)tmp);
+ default:
+ /* It's a corrupt image */
+ sel_img_ko = i;
+ }
+ }
+
+ if(one_img_ok)
+ {
+ /* at least one image OK present */
+ /* update index will be max + 1 */
+ place->index = max_index + 1;
+ }
+ else
+ {
+ /* No image OK present */
+ /* update index will be 0 */
+ place->index = 0;
+ }
+
+ if(sel_img_ko != -1)
+ {
+ place->flash_addr = (sel_img_ko * SIMG_FLASH_SIZE) + img_0_addr;
+ return 0;
+ }
+ else if(sel_img_ok != -1)
+ {
+ if(max_index == min_index)
+ {
+ /* there is only one image OK that will be overwritten */
+ /* update index will be 0 */
+ place->index = 0;
+ }
+ place->flash_addr = (sel_img_ok * SIMG_FLASH_SIZE) + img_0_addr;
+ return 0;
+ }
+ else if(sel_img_or != -1)
+ {
+ place->flash_addr = (sel_img_ok * SIMG_FLASH_SIZE) + img_0_addr;
+ return 0;
+ }
+ /* Never use */
+ return -1;
}
-static __inline__ int
-store_img (void)
+/**
+ * Store the new update image into the flash.
+ *
+ * \return error code.
+ */
+static int store_img(void)
{
- int rc = 0;
- flash_info_t * flinfo = &( flash_info[0] ); /* we expect HW to have only one flash, thus only one flinfo */
+ int rc = 0;
+ flash_info_t *flinfo = &(flash_info[0]); /* we expect HW to have only one flash, thus only one flinfo */
int i = 0;
ulong last_addr = 0;
+ struct update_image *image = ctx.image;
+ struct update_place *place = ctx.place;
/* Erase the flash */
/* In order to erase flash, we will use function flash_sect_erase (ulong addr_first, ulong addr_last),
@@ -217,20 +430,18 @@ store_img (void)
* last addr will be 49ffff (0x14000 + 0x35ffff), not 0x4a0000 (0x14000 + 0x360000)
*/
-
- if ( (ulong)upd_addr + IMG_FLASH_SIZE > flinfo->start[0] + flinfo->size )
+ if( place->flash_addr + image->len > flinfo->start[0] + flinfo->size )
{
- printf("No place in flash for writing the image -"
- "redefine image addr in flash or image size.\n");
+ printf("Error (Not enough place).\n");
return -1;
}
/* find the last_addr in the flash */
- while( flinfo->start[i] < (ulong)upd_addr + IMG_FLASH_SIZE && i < flinfo->sector_count)
+ while( flinfo->start[i] < place->flash_addr + image->len && i < flinfo->sector_count)
{
i++;
}
- if (i == flinfo->sector_count)
+ if(i == flinfo->sector_count)
{
last_addr = flinfo->start[0] + flinfo->size - 1; /* address of the last sector in flash */
}
@@ -239,32 +450,33 @@ store_img (void)
last_addr = flinfo->start[i] - 1;
}
- printf("Erasing the flash from the addr %#x to the addr %#x...\n", (ulong)upd_addr, last_addr );
+ TRACE("Erasing the flash from the addr %#x to the addr %#x...\n", place->flash_addr, last_addr);
- rc = flash_sect_erase( (ulong)upd_addr, last_addr );
- if (rc!=ERR_OK)
- {
- printf ("\n ");
- flash_perror (rc);
+ rc = flash_sect_erase(place->flash_addr, last_addr);
+ if(rc!=ERR_OK)
+ {
+ printf("Error (Flash Erase).\n");
+ flash_perror(rc);
return rc;
- }
- else
- {
- printf (" done.\n");
- }
+ }
+ else
+ {
+ TRACE("done.\n");
+ }
+ TRACE("Copy to flash...");
#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
{
size_t l = upd_img_len;
- void *to = (void *)upd_addr;
- void *from = (void *)UPD_IMG_RAM_ADDR;
+ void *to = (void *)place->flash_addr;
+ void *from = (void *)place->ram_addr;
- while (l > 0)
+ while(l > 0)
{
size_t tail = (l > CHUNKSZ) ? CHUNKSZ : l;
WATCHDOG_RESET();
- rc = flash_write (from, to, tail);
+ rc = flash_write(from, to, tail);
to += tail;
from += tail;
@@ -273,144 +485,211 @@ store_img (void)
}
#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
{
- rc = flash_write ( (char *)UPD_IMG_RAM_ADDR, (ulong)upd_addr, upd_img_len);
- putc ('\n');
+ rc = flash_write((char*)place->ram_addr, place->flash_addr, image->len);
+ TRACE("\n");
}
#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
- if (rc) {
- flash_perror (rc);
- printf ("\n ");
- }
+ if(rc)
+ {
+ flash_perror(rc);
+ printf("Error (Flash Write).\n");
+ }
return rc;
}
-static void SpidupdSend (void);
-static void SpidupdTimeout (void);
+/*
+ * MD5 functions
+ */
+#ifdef ET_DEBUG
+/**
+ * Print the MD5 Sum result.
+ *
+ * \param digest md5 to print.
+ */
+static void md5_print(md5_byte_t digest[16])
+{
+ unsigned int i;
-/**************************| Protocol functions |***************************/
+ for(i = 0; i < 16; i++)
+ printf("%02x", digest[i]);
+}
+#endif
-static void
-SpidupdSend (void)
+/**
+ * Calculate MD5 of an image.
+ *
+ * \param md5_sum md5 result.
+ */
+static void md5_image(md5_byte_t md5_sum[16])
{
- volatile uchar *pkt;
- volatile uchar *xp;
- int len = 0;
- volatile MME_t *s;
+ md5_state_t state;
+ struct update_image *image = ctx.image;
+ struct update_place *place = ctx.place;
- VsUpdStartCnf_t *p_start_cnf;
- VsUpdTransfCnf_t *p_transfer_cnf;
- VsUpdEndCnf_t *p_end_cnf;
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+ ulong bdata = place->ram_addr;
+ ulong edata = bdata + image->len;
+#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
+
+ md5_init(&state);
+
+ TRACE(" Verifying MD5 Checksum ... ");
+
+#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)
+ while (bdata < edata)
+ {
+ ulong chunk = edata - bdata;
+
+ if (chunk > CHUNKSZ)
+ {
+ chunk = CHUNKSZ;
+ }
+ md5_append(&state, (const md5_byte_t *)bdata, chunk);
+ bdata += chunk;
+
+ WATCHDOG_RESET();
+ }
+#else /* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */
+
+ md5_append(&state, (const md5_byte_t *)place->ram_addr, image->len);
+
+#endif /* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */
+
+ md5_finish(&state, md5_sum);
#ifdef ET_DEBUG
- printf ("Inside SpidupdSend()\n");
- printf ("SpidupdState = %d\n", SpidupdState);
+ printf("MD5 (Linux image) = ");
+ md5_print(md5_sum);
+ printf("\n");
#endif
+}
+
+
+/**************************| Protocol functions |***************************/
- /*
- * We will always be sending some sort of packet, so
- * cobble together the packet headers now.
- */
+static void SpidupdSend(void);
+static void SpidupdTimeout(void);
+
+/**
+ * Send a SPiDUpdate confirm packet.
+ */
+static void SpidupdSend(void)
+{
+ int len = 0;
+ int transfer_end = 0;
+ volatile uchar *pkt;
+ MME_t *mme;
+ VsUpdStartCnf_t *vs_update_start_cnf;
+ VsUpdTransfCnf_t *vs_update_transfer_cnf;
+ VsUpdEndCnf_t *vs_update_end_cnf;
+
+ /* Set structures pointers */
pkt = NetTxPacket;
- xp = pkt;
- NetSetEther (pkt, NetClientEther, PROT_SPIDUPD);
- s = (volatile MME_t *)pkt;
- s->mmv = MME_MMV;
+ mme = (MME_t *)pkt;
+ vs_update_start_cnf = (VsUpdStartCnf_t *)(mme+1);
+ vs_update_transfer_cnf = (VsUpdTransfCnf_t *)(mme+1);
+ vs_update_end_cnf = (VsUpdEndCnf_t *)(mme+1);
- switch (SpidupdState) {
- case STATE_WAIT_UPD_START:
- /* set mmtype to VS_UPDATE_START_CNF */
- s->mmtype = htommes(VS_UPDATE_START_CNF);
- /* skip the MME header */
- s++;
- pkt = (uchar *)s;
+ /* Set the MME version */
+ mme->mmv = MME_MMV;
- /* append the message */
- p_start_cnf = (VsUpdStartCnf_t *)pkt;
- p_start_cnf->start_update = vs_update_start_cnf->start_update;
+ /* Set MAC Address */
+ NetSetEther(pkt, NetClientEther, PROT_SPIDUPD);
- /* we finished with the message, skip it */
- p_start_cnf++;
- pkt = (uchar *)p_start_cnf;
+ TRACE("Inside SpidupdSend()\n");
+ TRACE("SpidupdState = %d\n", ctx.state);
- /* this is the end of packet, determine length */
- len = pkt - xp;
- break;
+ switch (ctx.state)
+ {
+ case STATE_WAIT_UPD_START:
+ /* Set mmtype to VS_UPDATE_START_CNF */
+ mme->mmtype = htommes(VS_UPDATE_START_CNF);
+
+ /* Append the message */
+ vs_update_start_cnf->start_update = ctx.start_cnf.start_update;
+
+ /* This is the end of packet, determine length */
+ len = ((ulong)vs_update_start_cnf - (ulong)pkt) + sizeof(VsUpdStartCnf_t);
+ break;
case STATE_WAIT_UPD_TRANSFER:
- if (NextSpidupdState == STATE_WAIT_UPD_TRANSFER)
+ if(ctx.next_state == STATE_WAIT_UPD_TRANSFER)
{
- /* set mmtype to VS_UPDATE_START_CNF */
- s->mmtype = htommes(VS_UPDATE_TRANSFER_CNF);
- /* skip the MME header */
- s++;
- pkt = (uchar *)s;
-
- /* append the message */
- p_transfer_cnf = (VsUpdTransfCnf_t *)pkt;
- p_transfer_cnf->ack = vs_update_transfer_cnf->ack;
- p_transfer_cnf->next_block = htommel(vs_update_transfer_cnf->next_block);
- /* we finished with the message, skip it */
- p_transfer_cnf++;
- pkt = (uchar *)p_transfer_cnf;
-
- /* this is the end of packet, determine length */
- len = pkt - xp;
+ /* Set mmtype to VS_UPDATE_START_CNF */
+ mme->mmtype = htommes(VS_UPDATE_TRANSFER_CNF);
+
+ /* Append the message */
+ vs_update_transfer_cnf->ack = ctx.transfer_cnf.ack;
+ vs_update_transfer_cnf->next_block = htommel(ctx.transfer_cnf.next_block);
+
+ /* This is the end of packet, determine length */
+ len = ((ulong)vs_update_transfer_cnf - (ulong)pkt) + sizeof(VsUpdTransfCnf_t);
}
- else if (NextSpidupdState == STATE_UPD_END)
+ else if(ctx.next_state == STATE_UPD_END)
{
- /* set mmtype to VS_UPDATE_START_CNF */
- s->mmtype = htommes(VS_UPDATE_END_CNF);
- /* skip the MME header */
- s++;
- pkt = (uchar *)s;
-
- /* append the message */
- p_end_cnf = (VsUpdEndCnf_t *)pkt;
- p_end_cnf->result = vs_update_end_cnf->result;
- /* we finished with the message, skip it */
- p_end_cnf++;
- pkt = (uchar *)p_end_cnf;
- /* this is the end of packet, determine length */
- len = pkt - xp;
+ /* Set mmtype to VS_UPDATE_START_CNF */
+ mme->mmtype = htommes(VS_UPDATE_END_CNF);
+
+ /* Append the message */
+ vs_update_end_cnf->result = ctx.end_cnf.result;
+
+ /* This is the end of packet, determine length */
+ len = ((ulong)vs_update_end_cnf - (ulong)pkt) + sizeof(VsUpdEndCnf_t);
+
+ transfer_end = 1;
}
else
{
/* WOW - How the hell did we get here ? */
- printf("Error - server in unknown state...\n");
+ printf("Error (Unknown State).\n");
NetState = NETLOOP_FAIL;
}
-
- break;
+ break;
default :
break;
- }
+ }
/* We sent a response - we can now change state */
- SpidupdState = NextSpidupdState;
+ ctx.state = ctx.next_state;
- /* Position to packet begining, and send packet */
- pkt = xp;
+ /* Send packet */
NetSendPacket(pkt, len);
+
+ if(transfer_end)
+ printf("Done.\n");
}
-/*
- * Handle a SPIDUPD received packet.
+/**
+ * Receive a SPiDUpdate request packet.
+ *
+ * \param pkt received packet pointer.
+ * \param dest destination MAC address.
+ * \param src source MAC address.
+ * \param len packet length.
*/
-static void
-SpidupdHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len)
+static void SpidupdHandler(uchar *pkt, unsigned dest, unsigned src, unsigned len)
{
- ushort proto;
- uchar * xp;
- MME_t *s;
-
- unsigned char md5_server[16];
- unsigned char md5_client[16];
-
- /* We received MME packet from PC client, reset the Netloop watchdog */
- NetSetTimeout (TIMEOUT * CFG_HZ, SpidupdTimeout);
+ int i;
+ MME_t *mme;
+ VsUpdStartReq_t *vs_update_start_req;
+ VsUpdTransfReq_t *vs_update_transfer_req;
+ VsUpdEndReq_t *vs_update_end_req;
+ uchar md5_server[16];
+ uchar md5_client[16];
+ struct update_image *image = ctx.image;
+ struct update_place *place = ctx.place;
+
+ /* We received MME packet from PC client, reset the NETLOOP Timeout */
+ NetSetTimeout(TIMEOUT * CFG_HZ, SpidupdTimeout);
+
+ /* Set structures pointers */
+ mme = (MME_t *)pkt;
+ vs_update_start_req = (VsUpdStartReq_t *)(mme+1);
+ vs_update_transfer_req = (VsUpdTransfReq_t *)(mme+1);
+ vs_update_end_req = (VsUpdEndReq_t *)(mme+1);
/*
* Server will now analyze the message and
@@ -420,345 +699,297 @@ SpidupdHandler (uchar * pkt, unsigned dest, unsigned src, unsigned len)
* 3) go to the next state
*/
- xp = pkt;
-
- /* warning: don't use increment (++) in ntohs() macros!! */
- s = (MME_t *)pkt;
- proto = s->mmtype;
-
- s++; /* skip the header */
- pkt = (uchar *)s;
-
- switch (mmetohs(proto))
+ switch( (ushort)(mmetohs(mme->mmtype)) )
{
- case VS_UPDATE_START_REQ:
-#ifdef ET_DEBUG
- printf("Got VS_UPDATE_START_REQ\n");
-#endif
- vs_update_start_req = (VsUpdStartReq_t *)pkt;
-
+ case VS_UPDATE_START_REQ:
+ TRACE("Got VS_UPDATE_START_REQ\n");
#ifdef ET_DEBUG
- {
- int i = 0;
+ {
+ int i = 0;
- puts("version = ");
- for (i=0; i<16; i++)
- {
- printf("%c", (vs_update_start_req->version)[i]);
- }
- printf("\n");
+ puts("version = ");
+ for (i=0; i<16; i++)
+ {
+ printf("%c", (vs_update_start_req->version)[i]);
}
-
- printf("arch = %#x\n", vs_update_start_req->arch);
- printf("upd_type = %#x\n", vs_update_start_req->upd_type);
+ printf("\n");
+ }
+ printf("arch = %#x\n", vs_update_start_req->arch);
+ printf("upd_type = %#x\n", vs_update_start_req->upd_type);
#endif
- if ( (SpidupdState == STATE_WAIT_UPD_START) && !modem_busy )
+ /* Check that no previous update is running */
+ if((ctx.state == STATE_WAIT_UPD_START) && !ctx.modem_busy)
+ {
+ /* defualt send cnf */
+ ctx.modem_busy = 1;
+ ctx.start_cnf.start_update = SPIDUPD_OK;
+ ctx.next_state = STATE_WAIT_UPD_TRANSFER;
+
+ /* shape the response to client */
+ if(place->correct_img_exist)
{
- /* shape the response to client */
- /* if we already have valid image, we do not want to update it with newer version */
- if ( hdr != NULL &&
- hdr->is_valid == 1 &&
- memcmp( vs_update_start_req->version, hdr->version, sizeof(hdr->version) ) == 0
- )
+ if(place->correct_archi != vs_update_start_req->arch)
{
- printf("FAILURE : udate firmware version is "
- "the same as the existing one.\n" );
-
- vs_update_start_cnf->start_update = SPIDUPD_BAD_VERSION;
+ /* Request bad architecture */
+ printf("Error (New image bad Architecture).\n");
+ ctx.modem_busy = 0;
+ ctx.start_cnf.start_update = SPIDUPD_BAD_ARCH;
+ ctx.next_state = STATE_WAIT_UPD_START;
+ break;
}
- else if ( hdr != NULL && vs_update_start_req->arch != hdr->arch )
+ if(place->correct_type != vs_update_start_req->upd_type)
{
- printf("FAILURE : bad udate firmware archtecture\n" );
- vs_update_start_cnf->start_update = SPIDUPD_BAD_ARCH;
+ /* Request doesn't concern a sImage */
+ printf("Error (New image bad type).\n" );
+ ctx.modem_busy = 0;
+ ctx.start_cnf.start_update = SPIDUPD_BAD_UPD_TYPE;
+ ctx.next_state = STATE_WAIT_UPD_START;
+ break;
}
- else if ( vs_update_start_req->upd_type != 0 )
- {
- printf("FAILURE : update firmware is not normal image. "
- "Update type not supported.\n" );
-
- vs_update_start_cnf->start_update = SPIDUPD_BAD_UPD_TYPE;
- }
- else
+ /* if we already have valid image with the same version, don't update it */
+ for(i=0 ; i<place->nb_img ; i++)
{
- /* no error - begin the transfer */
- modem_busy = 1;
- NextSpidupdState = STATE_WAIT_UPD_TRANSFER;
+ if(strcmp(place->versions[i], (char*)vs_update_start_req->version) == 0)
+ {
+ printf("Error (Same Version).\n" );
+ ctx.modem_busy = 0;
+ ctx.start_cnf.start_update = SPIDUPD_BAD_VERSION;
+ ctx.next_state = STATE_WAIT_UPD_START;
+ break;
+ }
}
}
- else
- {
- printf ("Server busy...\n");
- vs_update_start_cnf->start_update = SPIDUPD_MODEM_BUSY;
- }
+ }
+ else
+ {
+ printf("Error (Already in use).\n");
+ ctx.start_cnf.start_update = SPIDUPD_MODEM_BUSY;
+ }
+ break;
- break;
+ case VS_UPDATE_TRANSFER_REQ:
+ TRACE("Got VS_UPDATE_TRANSFER_REQ\n");
- case VS_UPDATE_TRANSFER_REQ:
-#ifdef ET_DEBUG
- printf("Got VS_UPDATE_TRANSFER_REQ\n");
-#endif
- vs_update_transfer_req = (VsUpdTransfReq_t *)pkt;
+ TRACE("received_block = %#x\n", image->num_rx_blk);
+ TRACE("block_id = %#x\n", mmetohl(vs_update_transfer_req->block_id) );
+ TRACE("length = %d\n", mmetohl(vs_update_transfer_req->length) );
-#ifdef ET_DEBUG
- printf("received_block = %#x\n", received_block);
- printf("block_id = %#x\n", mmetohl(vs_update_transfer_req->block_id) );
- printf("length = %d\n", mmetohl(vs_update_transfer_req->length) );
-#endif
+ if(ctx.state == STATE_WAIT_UPD_TRANSFER)
+ {
+ /* Block IDs are starting from 1.
+ * We are expecting to receive next block
+ * of the one that we received last time
+ */
+ if( mmetohl(vs_update_transfer_req->block_id) != image->num_rx_blk )
+ {
+ TRACE("FAILURE : Received block ID does not match expected.\n" );
+
+ ctx.transfer_cnf.ack = SPIDUPD_FAILURE;
+ ctx.transfer_cnf.next_block = image->num_rx_blk;
- if (SpidupdState == STATE_WAIT_UPD_TRANSFER)
+ }
+ else /* OK, we received block we expected */
{
- /* Block IDs are starting from 1.
- * We are expecting to receive next block
- * of the one that we received last time
- */
- if ( mmetohl(vs_update_transfer_req->block_id) != (received_block + 1) )
- {
- printf("FAILURE : Received block ID does not match expected.\n" );
+ /* give a small visual indication */
+ if((image->num_rx_blk % 50) == 0)
+ printf(".");
- vs_update_transfer_cnf->ack = SPIDUPD_FAILURE;
- vs_update_transfer_cnf->next_block = received_block + 1;
+ /* Put block in RAM */
+ memcpy((void*)(place->ram_addr + image->len),
+ vs_update_transfer_req->data,
+ vs_update_transfer_req->length);
- }
- else /* OK, we received block we expected */
- {
- /* give a small visual indication */
- if ( (received_block % 50) == 0 )
- printf("D");
- if ( (received_block != 0) && ( (received_block % 2500) == 0 ) )
- printf("\n");
- /* put block in RAM */
- memcpy ( UPD_IMG_RAM_ADDR + upd_img_len,
- vs_update_transfer_req->data,
- vs_update_transfer_req->length );
+ /* Increase transfered length */
+ image->len += mmetohl(vs_update_transfer_req->length);
+ /* we successfully received block, increment received counter */
+ image->num_rx_blk++;
- /* increase transfered length */
- upd_img_len += mmetohl(vs_update_transfer_req->length);
+ /* shape the response */
+ ctx.transfer_cnf.ack = SPIDUPD_SUCCESS;
+ ctx.transfer_cnf.next_block = image->num_rx_blk;
+ }
+ }
+ else
+ {
+ TRACE("Wrong message...\n");
+ }
- /* we sucesfully received block, increment received counter */
- received_block++;
+ /* We are not changing the state, we are still waiting for transfer */
+ ctx.next_state = STATE_WAIT_UPD_TRANSFER;
+ break;
- vs_update_transfer_cnf->ack = SPIDUPD_SUCCESS;
+ case VS_UPDATE_END_REQ:
+ TRACE("Got VS_UPDATE_END_REQ\n");
+ TRACE("|\n");
- /* REMEMBER: block IDs are starting from 1, not from 0.
- * That means that received_block number is also
- * ID of the last block received.
- */
- vs_update_transfer_cnf->next_block = received_block + 1;
- }
+ if (ctx.state == STATE_WAIT_UPD_TRANSFER)
+ {
+ /* Transfer is finished so calculate MD5 */
+ memcpy(md5_client, vs_update_end_req->md5_sum, 16);
+ md5_image((md5_byte_t *)md5_server);
+
+ if( memcmp(md5_server, md5_client, 16) != 0 )
+ {
+ /* Wrong MD5 */
+ printf("Error (MD5 Error).\n");
+ ctx.end_cnf.result = SPIDUPD_MD5_ERROR;
+
+ /* Abort the update */
+ NetState = NETLOOP_FAIL;
}
else
{
- printf ("Wrong message...\n");
- }
+ /* Correct MD5 */
+ TRACE("MD5 sum OK, will burn image...\n");
- /* and we are not changing the state, we are still waiting for transfer */
- NextSpidupdState = STATE_WAIT_UPD_TRANSFER;
+ NetSetTimeout((ulong)(FLASH_WRITE_TOUT * CFG_HZ), SpidupdTimeout);
- break;
+ /* We will start to write new image from RAM to FLASH.
+ * Set the index to correct value. */
+ ((spidcom_image_desc_t *)place->ram_addr)->index = place->index;
- case VS_UPDATE_END_REQ:
-#ifdef ET_DEBUG
- printf("Got VS_UPDATE_END_REQ\n");
-#endif
- vs_update_end_req = (VsUpdEndReq_t *)pkt;
-
- if (SpidupdState == STATE_WAIT_UPD_TRANSFER)
- {
- printf("|\n");
- memcpy (md5_client, vs_update_end_req->md5_sum, 16);
- md5_image( (md5_byte_t *)md5_server );
-
- if ( memcmp(md5_server, md5_client, 16) != 0 )
+ if(store_img() != ERR_OK)
{
- printf("Update failed : MD5 cehcksum differs.\n");
- vs_update_end_cnf->result = SPIDUPD_MD5_ERROR;
+ /* Error writing flash */
+ TRACE("Error.\nUpdate failure : image cannot be written to flash.\n");
+ ctx.end_cnf.result = SPIDUPD_FLASH_WRITE_ERROR;
+
+ /* Image on flash is corrupted! */
+ ((spidcom_image_desc_t *)place->ram_addr)->is_valid = 0;
+ flash_write( (char *)place->ram_addr, place->flash_addr, sizeof(spidcom_image_desc_t) );
- /* Abort the update */
+ /*
+ * We have no valid image anymore!
+ * Update failed.
+ */
NetState = NETLOOP_FAIL;
}
- else /* MD5 sum OK */
+ else
{
- printf("MD5 sum OK, will burn image...\n");
+ /* Flash write OK */
+ TRACE("Update image successfully written to flash.\n");
+ ctx.end_cnf.result = SPIDUPD_SUCCESS;
+ NetBootFileXferSize = image->len;
- /* We will start to write new image from SDRAM to FLASH.
- * Set the index to correct value. */
- ((spidcom_image_desc_t *)UPD_IMG_RAM_ADDR)->index = img_index;
-
- NetSetTimeout ((ulong)(FLASH_WRITE_TOUT * CFG_HZ), SpidupdTimeout);
- if ( store_img() != ERR_OK )
- {
- /* error writing flash */
- printf ("Update failure : image cannot be written to flash.\n");
- vs_update_end_cnf->result = SPIDUPD_FLASH_WRITE_ERROR;
-
- /* image on flash is corrupted! */
- ((spidcom_image_desc_t *)UPD_IMG_RAM_ADDR)->is_valid = 0;
- flash_write( (char *)UPD_IMG_RAM_ADDR, (ulong)upd_addr, sizeof(spidcom_image_desc_t) );
-
- /*
- * We have no valid image anymore!
- * Update failed.
- */
- NetState = NETLOOP_FAIL;
- }
- else /* flash write OK */
- {
- printf ("Update image successfully written to flash.\n");
- vs_update_end_cnf->result = SPIDUPD_SUCCESS;
- NetBootFileXferSize = upd_img_len;
-
- NetState = NETLOOP_SUCCESS;
- }
-
- /* We finished update :
- * re-write header, but with the normal state indication -
- * put is_update flag to 0, because update is finished
- * (it was put to 1 by default when image is generated) */
- ((spidcom_image_desc_t *)UPD_IMG_RAM_ADDR)->is_not_update = 0;
- flash_write( (char*)UPD_IMG_RAM_ADDR, (ulong)upd_addr, sizeof(spidcom_image_desc_t) );
+ NetState = NETLOOP_SUCCESS;
}
- NextSpidupdState = STATE_UPD_END;
+ /* We finished update :
+ * re-write header, but with the normal state indication -
+ * put is_update flag to 0, because update is finished
+ * (it was put to 1 by default when image is generated) */
+ ((spidcom_image_desc_t *)place->ram_addr)->is_not_update = 0;
+ flash_write( (char*)place->ram_addr, place->flash_addr, sizeof(spidcom_image_desc_t) );
}
- else
- {
- printf ("Wrong message...\n");
- }
- break;
- }
- /*
- * Acknowledge the block just received, which will prompt
- * the client for the next one.
- */
+ ctx.next_state = STATE_UPD_END;
+ }
+ else
+ {
+ TRACE("Wrong message...\n");
+ }
+ break;
+ }
- SpidupdSend ();
+ /* Acknowledge the block just received, which will prompt
+ * the client for the next one. */
+ SpidupdSend();
}
-static void
-SpidupdTimeout (void)
+/**
+ * Calculate timeout procedure.
+ */
+static void SpidupdTimeout(void)
{
- if (++SpidupdTimeoutCount > TIMEOUT_COUNT)
+ if(++ctx.timeout > TIMEOUT_COUNT)
{
+ printf("Timeout.\n");
- printf ("Timeout error : no response from the client.\n");
-
- /* TIMEOUT occured - go out of NETLOOP and notify the caller about failure */
+ /* TIMEOUT occurred.
+ * Go out of NETLOOP and notify the caller about failure */
NetState = NETLOOP_FAIL;
- } else
+ }
+ else
{
- puts ("T ");
- NetSetTimeout (TIMEOUT * CFG_HZ, SpidupdTimeout);
- SpidupdSend ();
- }
+ NetSetTimeout(TIMEOUT * CFG_HZ, SpidupdTimeout);
+ SpidupdSend();
+ }
}
-void
-SpidupdStart (void)
+/**
+ * Start SPiPUpdate procedure.
+ */
+void SpidupdStart(void)
{
- /* flush caches in the very begining */
- flushCaches();
+ DECLARE_GLOBAL_DATA_PTR;
+ ulong nb_img;
+ ulong img_0_addr;
+ int i;
- /* initialize global pointers to
- point to structures that will hold
- responses of the server */
- vs_update_start_cnf = &g_vs_update_start_cnf;
- vs_update_transfer_cnf = &g_vs_update_transfer_cnf;
- vs_update_end_cnf = &g_vs_update_end_cnf;
+ /* Flush caches just to be sure */
+ flush_caches();
+ puts("SPiDUpdate...");
-#if defined(CONFIG_NET_MULTI)
- printf ("Using %s device\n", eth_get_name());
-#endif
- puts ("SPIDUPD server now listening at address : "); print_ETHaddr (NetOurEther);
- putc ('\n');
- puts (">>> SPIDUPD server started <<<\n");
+ /* Clear an eventually previous call */
+ for(i=0 ; i<MAX_IMG ; i++)
+ img_addr[i] = 0;
- NetSetTimeout (TIMEOUT * CFG_HZ, SpidupdTimeout);
- NetSetHandler (SpidupdHandler);
+ /* Prepare Networking Handler and timeout */
+ NetSetTimeout(TIMEOUT * CFG_HZ, SpidupdTimeout);
+ NetSetHandler(SpidupdHandler);
- /* load headers */
- load_header(&img_0_desc, (char*)IMG_0_ADDR);
- load_header(&img_1_desc, (char*)IMG_1_ADDR);
+ /* Find number of allowed places under flash */
+ nb_img = find_nb_images(gd->bd);
-#ifdef DUAL_BOOT
- /* Select image for update. */
- if ( strcmp(img_0_desc.magic, SPIDCOM_IMG_DESC_MAGIC) != 0 )
- {
- puts ("IMG_0 not detected.\n");
- /* No IMG_0 present - we will update here independently if IMG_1 exist or not,
- because even if IMG_1 does not exist also, we will take IMG_0 addre for update */
- puts ("No bootable image present - selecting IMG_0.\n");
- hdr = NULL; /* mark that we have no image at this place */
- upd_addr = IMG_0_ADDR;
+ /* Find the first image offset under flash */
+ img_0_addr = PHYS_FLASH_SPI_1 + find_img_1st_offset(gd->bd);
+
+ /* Find addresses of already present images */
+ find_images(nb_img, img_0_addr, img_addr);
+
+ /* Find better place to update a new image */
+ select_image(nb_img, img_0_addr, img_addr, &g_upd_place);
+
+ /* Reset globals */
+ g_upd_place.nb_img = nb_img;
+ g_upd_place.ram_addr = (ulong)UPD_IMG_RAM_ADDR;
+
+ g_upd_image.len = 0;
+ g_upd_image.num_rx_blk = 1;
+
+ ctx.place = &g_upd_place;
+ ctx.image = &g_upd_image;
+ ctx.modem_busy = 0;
+ ctx.timeout = 0;
+ ctx.state = STATE_WAIT_UPD_START;
+ ctx.next_state = STATE_WAIT_UPD_START;
+
+#ifdef ET_DEBUG
+ printf("place.flash_addr=%x\n",g_upd_place.flash_addr);
+ printf("place.ram_addr=%x\n",g_upd_place.ram_addr);
+ printf("place.index=%d\n",g_upd_place.index);
+ printf("place.nb_img=%d\n",g_upd_place.nb_img);
+ printf("place.c_img_exist=%d\n",g_upd_place.correct_img_exist);
+ printf("place.c_type=%x\n",g_upd_place.correct_type);
+ printf("place.c_archi=%x\n",g_upd_place.correct_archi);
- if ( strcmp(img_1_desc.magic, SPIDCOM_IMG_DESC_MAGIC) != 0 )
- {
- img_index = img_1_desc.index + 1;
- }
- else
- {
- img_index = 0;
- }
- }
- else /* IMG_0 is OK */
{
- puts ("IMG_0 already exists. Checking for IMG_1...\n");
- if ( strcmp(img_1_desc.magic, SPIDCOM_IMG_DESC_MAGIC) != 0 )
+ int i;
+ printf("Versions:\n");
+ for(i=0 ; i<MAX_IMG ; i++)
{
- /* IMG_1 does not exist, so we will put update to this place */
- puts ("IMG_1 is does not exist - selecting this place for update.\n");
- hdr = NULL; /* mark that we have no image at this place */
- upd_addr = IMG_1_ADDR;
- img_index = img_0_desc.index + 1;
+ printf("%s\n", g_upd_place.versions[i]);
}
- else /* both images are OK => compare the indexes */
- {
- if ( img_0_desc.index > img_1_desc.index )
- {
- hdr = &img_0_desc;
- upd_addr = IMG_0_ADDR;
- img_index = img_0_desc.index + 1;
- printf ("Selected IMG_0 for update.\n");
- }
- else
- {
- hdr = &img_1_desc;
- upd_addr = IMG_1_ADDR;
- img_index = img_1_desc.index + 1;
- printf ("Selected IMG_1 for update.\n");
- }
- }
- }
-#else /* single boot */
- /* we have only one image placeholder, but check if there is already one image there */
- if ( strcmp(img_0_desc.magic, SPIDCOM_IMG_DESC_MAGIC) != 0 )
- {
- puts ("IMG_0 not present.\n");
- hdr = NULL; /* mark that we have no image at this place */
}
- else
- {
- hdr = &img_0_desc;
- }
- upd_addr = IMG_0_ADDR;
-
-#endif /* DUAL_BOOT */
-
- /* reset globals */
- modem_busy = 0;
- upd_img_len = 0;
- received_block = 0;
-
- SpidupdTimeoutCount = 0;
- SpidupdState = STATE_WAIT_UPD_START;
- NextSpidupdState = STATE_WAIT_UPD_START;
+#endif
}
#endif /* CFG_CMD_NET */
+
diff --git a/cleopatre/u-boot-1.1.6/net/spidupd.h b/cleopatre/u-boot-1.1.6/net/spidupd.h
index 535ad23640..b36e1852de 100644
--- a/cleopatre/u-boot-1.1.6/net/spidupd.h
+++ b/cleopatre/u-boot-1.1.6/net/spidupd.h
@@ -18,7 +18,7 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
- * Author(s):
+ * Author(s):
* Drasko DRASKOVIC, drasko.draskovic@spidcom.com
*/
@@ -45,7 +45,7 @@
#define VS_UPDATE_END 0xA308
/* information about REQ, CNF IND or RSP is held in two LSBs */
-#define VS_UPDATE_START_REQ (VS_UPDATE_START | 0x0)
+#define VS_UPDATE_START_REQ (VS_UPDATE_START | 0x0)
#define VS_UPDATE_START_CNF (VS_UPDATE_START | 0x1)
#define VS_UPDATE_TRANSFER_REQ (VS_UPDATE_TRANSFER | 0x0)
#define VS_UPDATE_TRANSFER_CNF (VS_UPDATE_TRANSFER | 0x1)
@@ -53,47 +53,47 @@
#define VS_UPDATE_END_CNF (VS_UPDATE_END | 0x1)
#define VS_UPDATE_END_IND (VS_UPDATE_END | 0x2)
-/*
- * SPIDUPD Primitive types
+/*
+ * SPIDUPD Primitive types
*/
-typedef struct
+typedef struct
{
- unsigned char version[16]; /* version string of the fw to send */
- unsigned char arch; /* modem arch type; default: 0 (spc300) */
- unsigned char upd_type; /* update type; default: 0 for normal image */
+ unsigned char version[16]; /* version string of the fw to send */
+ unsigned char arch; /* modem arch type; default: 0 (spc300) */
+ unsigned char upd_type; /* update type; default: 0 for normal image */
} __attribute__ ((__packed__)) VsUpdStartReq_t;
-typedef struct
+typedef struct
{
- unsigned char start_update; /* 0 - success, 0x1..0x5 - error messages */
+ unsigned char start_update; /* 0 - success, 0x1..0x5 - error messages */
} __attribute__ ((__packed__)) VsUpdStartCnf_t;
-typedef struct
+typedef struct
{
- unsigned int block_id; /* block ID of data to be sent */
- unsigned int length; /* length of data to be sent */
+ unsigned int block_id; /* block ID of data to be sent */
+ unsigned int length; /* length of data to be sent */
unsigned char data[MAX_MME_SIZE - 8]; /* padded data (for min size of eth packet) */
} __attribute__ ((__packed__)) VsUpdTransfReq_t;
-typedef struct
+typedef struct
{
- unsigned char ack; /* 0 - success, 0x1 - failure */
- unsigned int next_block; /* next block ID that server expects */
+ unsigned char ack; /* 0 - success, 0x1 - failure */
+ unsigned int next_block; /* next block ID that server expects */
} __attribute__ ((__packed__)) VsUpdTransfCnf_t;
-typedef struct
+typedef struct
{
- unsigned char md5_sum[16]; /* 0 - success, 0x1 - failure */
+ unsigned char md5_sum[16]; /* 0 - success, 0x1 - failure */
} __attribute__ ((__packed__)) VsUpdEndReq_t;
-typedef struct
+typedef struct
{
- unsigned char result; /* 0 - success, 0x1 - failure */
+ unsigned char result; /* 0 - success, 0x1 - failure */
} __attribute__ ((__packed__)) VsUpdEndCnf_t;
-typedef struct
+typedef struct
{
- unsigned char result; /* 0 - success, 0x1..0x2 - error messages */
+ unsigned char result; /* 0 - success, 0x1..0x2 - error messages */
} __attribute__ ((__packed__)) VsUpdEndInd_t;
@@ -105,8 +105,8 @@ typedef struct
#define SPIDUPD_BAD_UPD_TYPE 0x03
#define SPIDUPD_MODEM_BUSY 0x04
-/* tansfer_cnf and end_cnf */
-#define SPIDUPD_SUCCESS 0x00
+/* transfer_cnf and end_cnf */
+#define SPIDUPD_SUCCESS 0x00
#define SPIDUPD_FAILURE 0x01
/* end_cnf */
@@ -123,14 +123,14 @@ typedef struct
* Global functions and variables.
*/
-/*
+/*
*define an address in RAM where we will put update image that is coming
* from PC client. After download, image will be written to flash
*/
-#define UPD_IMG_RAM_ADDR ( (unsigned char *)0x40100000 )
-
+#define UPD_IMG_RAM_ADDR ( (unsigned char *)0x40100000 )
+
/* spidupd.c */
-extern void SpidupdStart (void); /* Begin SPIDUPD get */
+extern void SpidupdStart (void); /* Begin SPIDUPD get */
/**********************************************************************/