source: svn/trunk/newcon3bcm2_21bu/dta/src/jflu/jflu.c @ 53

Last change on this file since 53 was 2, checked in by jglee, 11 years ago

first commit

  • Property svn:executable set to *
File size: 7.2 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2011, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: $
11 * $brcm_Revision: $
12 * $brcm_Date: $
13 *
14 * Module Description: Jtag flash programming module. This module is
15 * concatenated with compressed flash image and used to update flash
16 * using EJTAG connection. This module must be used when bootloader already
17 * in flash or memory is initialized using some other method like BBS script.
18 *
19 * Revision History:
20 *
21 * $brcm_Log: $
22 *
23 *
24 ***************************************************************************/
25
26#include "fast_heap.h"
27#include "zlib.h"
28#include "bchp_rdc.h"
29#include "bchp_sun_top_ctrl.h"
30#include "jflu_spi.h"
31
32#define RAM_TEXT_BASE 0x80016000
33#define RAM_TEXT_SIZE 0x01000000
34
35/**
36   The utility now supports programming any binary at a specified offset.
37   The offset and a magic number must be written the respective registers
38   before the _jflu binary runs. This can be done with a simple gdb
39   script or a simple bbs script. The magic number must be programmed in
40   the OFFSET_MAGIC_REG and the offset itself must be programmed in to
41   the OFFSET_REG. The magic number value is 0x4f464653 (OFFS). Code will
42   first look at presence of magic number in the register and if it is
43   present, code will apply the offset. If magic number is not present,
44   the offset will be 0.
45 */
46#define OFFSET_MAGIC 0x4f464653
47#define OFFSET_MAGIC_REG BCHP_RDC_scratch_i_ARRAY_BASE
48#define OFFSET_REG (BCHP_RDC_scratch_i_ARRAY_BASE + 4)
49#define REG_BASE 0xb0000000
50#define ReadReg32(reg) (*((volatile uint32_t *)((unsigned int)(reg) + REG_BASE)))
51#define WriteReg32(reg, data) (*((volatile uint32_t *)((unsigned int)(reg) + REG_BASE)) = (data))
52
53extern void clear_all_d_cache(void);
54extern void invalidate_all_i_cache(void);
55/* output character on serial port */
56extern void _writeasm(unsigned int a);
57extern void udelay(int microseconds);
58
59static int decompress(unsigned char *in_buf, unsigned int in_size, unsigned char * out_buf, unsigned int out_size);
60
61void update_flash(unsigned int offset, unsigned char * data, int data_size);
62void jflu_chip_reset(void);
63
64extern unsigned int comp_size;
65extern unsigned int _edata;
66extern unsigned int _end;
67
68void strout(char *s)
69{
70    while (*s)
71    {
72        _writeasm(*s++);
73    }
74    return;
75}
76
77
78void *memset(void *dest,int c,size_t count)
79{
80    uint8_t *d = dest;
81    for(;count>0;count--) {
82        *d++ = c;
83    }
84    return dest;
85}
86
87int decompress(unsigned char *in_buf, unsigned int in_size, unsigned char * out_buf, unsigned int out_size)
88{
89    z_stream strm;
90    int ret;
91
92    memset(&strm,0,sizeof(strm));
93    strm.avail_in = in_size;
94    strm.next_in = in_buf;
95    strm.avail_out = out_size;
96    strm.next_out = out_buf;
97    ret = inflateInit2(&strm, 15+32);
98    if (ret == Z_OK)
99    {
100        ret = inflate(&strm, Z_FINISH);
101        inflateEnd(&strm);
102        if ((ret == Z_STREAM_END) || (ret == Z_OK))
103        {
104            return strm.total_out;
105        }
106        else if (ret > 0)
107        {
108            return -ret;
109        }
110    }
111    return ret;
112}
113
114void bcm_main(void)
115{
116    unsigned char * compressed_image;
117    unsigned int compressed_size;
118    int dlen;                   /* decompressed length */
119    unsigned char * ddata;      /* decompressed data */
120    unsigned int flash_offset;
121
122    fast_heap_init((unsigned long)&_end);
123
124    compressed_image = (unsigned char *) &_edata;
125    compressed_size = (unsigned int) &comp_size;
126    ddata = (unsigned char *) RAM_TEXT_BASE;
127    strout("\r\n\r\n");
128    strout("Decompressing flash image ... ");
129    dlen = decompress(compressed_image, compressed_size, ddata, RAM_TEXT_SIZE);
130    /* we got decompressed image at RAM_TEXT_BASE location and size of the
131       image is in dlen. */
132    if(0 < dlen){
133        strout("OK\r\n");
134    }else{
135        strout("Fail\r\n");
136        goto ExitFunc;
137    }
138    flash_offset = ReadReg32(OFFSET_MAGIC_REG);
139    if(OFFSET_MAGIC == flash_offset){
140        strout("Writing at specified offset ...\r\n");
141        flash_offset = ReadReg32(OFFSET_REG);
142    }else{
143        strout("Writing at default offset ...\r\n");
144        flash_offset = 0;
145    }
146    update_flash(flash_offset, ddata, dlen);
147    udelay(2000000);
148    jflu_chip_reset();
149ExitFunc:
150    while(1);
151}
152
153spi_flash_t fl;
154char indicator1[4] = "|/-\\";
155
156void update_flash(unsigned int offset, unsigned char * data, int data_size)
157{
158    int res;
159    int sector_count;
160    unsigned int curr_offset;
161    int i, in;
162    unsigned char * page_data;
163    int remaining_size;
164    int block_size;
165
166    jflu_spi_init(&fl);
167    res = jflu_spi_identify(&fl);
168    if(SPI_OK != res){
169        strout("Unable to identify SPI flash.\n\r");
170        goto ExitFunc;
171    }
172    sector_count = data_size / fl.sector_size;
173    if(data_size % fl.sector_size){
174        sector_count += 1;
175    }
176    /* erase sectors */
177    curr_offset = offset;
178    in = 0;
179    strout("Erasing ... ");
180    for(i = 0; i < sector_count; i++){
181        res = jflu_spi_sector_erase(&fl, curr_offset);
182        _writeasm(indicator1[in]);
183        _writeasm('\b');
184        in++; in &= 3;
185        if(SPI_OK != res){
186            strout("Unable to erase sector.\n\r");
187            goto ExitFunc;
188        }
189        curr_offset += fl.sector_size;
190    }
191    strout("Done\n\r");
192    curr_offset = offset;
193    page_data = data;
194    remaining_size = data_size;
195    in = 0;
196    strout("Writing ... ");
197    while(remaining_size > 0){
198        if(remaining_size > fl.page_size){
199            block_size = fl.page_size;
200        }else{
201            block_size = remaining_size;
202        }
203        res = jflu_spi_page_program(&fl, curr_offset, page_data, block_size);
204        if(SPI_OK != res){
205            strout("Unable to program page.\n\r");
206            goto ExitFunc;
207        }
208        if(curr_offset % 0x8000){
209            _writeasm(indicator1[in]);
210            _writeasm('\b');
211            in++; in &= 3;
212        }
213        remaining_size -= block_size;
214        page_data = page_data + block_size;
215        curr_offset += block_size;
216    }
217    strout("Done\n\r");
218ExitFunc:
219    return;
220}
221
222void jflu_chip_reset(void)
223{
224        uint32_t value;
225#if (BCHP_CHIP == 7550)
226        value = ReadReg32(BCHP_SUN_TOP_CTRL_RESET_CTRL);
227        value |= 0x8;               /* master_reset_en */
228        WriteReg32(BCHP_SUN_TOP_CTRL_RESET_CTRL, value);
229        value = ReadReg32(BCHP_SUN_TOP_CTRL_SW_RESET);
230        value |= 0x80000000;        /* chip_master_reset */
231        WriteReg32(BCHP_SUN_TOP_CTRL_SW_RESET, value);
232#endif
233#if (BCHP_CHIP == 7552)
234    value = ReadReg32(BCHP_SUN_TOP_CTRL_RESET_SOURCE_ENABLE);
235    value |= BCHP_SUN_TOP_CTRL_RESET_SOURCE_ENABLE_sw_master_reset_enable_MASK;
236    WriteReg32(BCHP_SUN_TOP_CTRL_RESET_SOURCE_ENABLE, value);
237    value = ReadReg32(BCHP_SUN_TOP_CTRL_SW_MASTER_RESET);
238    value |= BCHP_SUN_TOP_CTRL_SW_MASTER_RESET_chip_master_reset_MASK;
239    WriteReg32(BCHP_SUN_TOP_CTRL_SW_MASTER_RESET, value);
240#endif
241}
242
243/* Please do not remove! */
244/* Local Variables: */
245/* mode: C */
246/* indent-tabs-mode: nil */
247/* End: */
Note: See TracBrowser for help on using the repository browser.