source: svn/trunk/newcon3bcm2_21bu/dta/src/bootloader/bl_main.c @ 2

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

1.phkim

  1. revision copy newcon3sk r27
  • Property svn:executable set to *
File size: 10.6 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2003-2010, 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:
15 *
16 * Revision History:
17 *
18 * $brcm_Log: $
19 *
20 *
21 ***************************************************************************/
22
23#include "fast_heap.h"
24#include "memc_access.h"
25#undef print_string
26#include "xmodem.h"
27#include "zlib.h"
28#include "bchp_sun_top_ctrl.h"
29#include "ramheader.h"
30
31#include "bchp_vcxo_ctl_config_fsm.h"
32#include "bchp_bspi.h"
33
34#define HEAP_START_ADDRESS ((unsigned long)&(_end))
35/* allow up to 3 mb comressed image */
36#define COMPRESSED_BUFFER_SIZE 0x300000
37#define BL_UART UARTA
38
39#define RAM_TEXT_BASE 0x80016000
40#define RAM_TEXT_SIZE (0x01000000 - 0x16000)
41
42#define XPT_OTP_MC1_BASE 0xb053802c
43#if defined(RSA_BITS)
44#define SIGNATURE_SIZE (RSA_BITS/8)
45#else
46#define SIGNATURE_SIZE 0x80
47#endif
48
49
50extern void clear_all_d_cache(void);
51extern void invalidate_all_i_cache(void);
52/* copy memory block from word aligned src to word aligned destination
53   with word aligned size. All pointer and size must be 4 bytes aligned */
54extern void aligned_copy(void * src, void * dst, unsigned int n);
55
56static int decompress(unsigned char *in_buf, unsigned int in_size, unsigned char * out_buf, unsigned int out_size);
57static void run_compressed(unsigned char * data, unsigned int len);
58static unsigned char * skip_headers(unsigned char * image);
59static int authenticate_image(unsigned char * image);
60static unsigned int image_size(unsigned char * image);
61
62extern unsigned int _ram_image_start;
63extern unsigned int _end;
64extern unsigned int __start_s3;
65
66void print_string(char *s)
67{
68    while (*s)
69    {
70        print_char(*s++);
71    }
72    return;
73}
74
75void *memset(void *dest,int c,size_t count)
76{
77    uint8_t *d = dest;
78    for(;count>0;count--) {
79        *d++ = c;
80    }
81    return dest;
82}
83
84void bootloader_main(void)
85{
86    unsigned char * compressed_image;
87    unsigned char * compressed_flash;
88    int rc;
89    unsigned int * boot_mode;
90    unsigned int * addr;
91    unsigned int val;
92       
93    print_string("\r\nS3 " __DATE__":" __TIME__ "\r\n");
94    fast_heap_init(HEAP_START_ADDRESS);
95    boot_mode = (unsigned int *)(0xB0000000 + BCHP_SUN_TOP_CTRL_UNCLEARED_SCRATCH);
96    /* set spi flash clock */
97    addr = (unsigned int *)(0xB0000000 + BCHP_VCXO_CTL_CONFIG_FSM_PLL_NEXT_CFG_3A);
98    val = *addr;
99   
100    /*
101       possible flash speeds in MHz:
102       0x0b00:118, 0x2B00:32.4, 0x1200:72, 0x0c00:108, 0x0a00:129.6,
103       0x0900:144, 0x0800:162
104     */
105    val = (val & 0xFFFF00FF) | 0x1200 | 0x80000000;
106    *addr = val;
107    addr = (unsigned int *)(0xB0000000 + BCHP_VCXO_CTL_CONFIG_FSM_PLL_UPDATE);
108    //val = *addr;
109    //val |= 1;
110    *addr = 1;
111    /* set flash to dual mode */
112    addr = (unsigned int *)(0xB0000000 + BCHP_BSPI_STRAP_OVERRIDE_CTRL);
113    val = 0x3;
114    *addr = val;
115
116    /* GPIO 100 PAD CTRL */
117    /* set it in bootloader instead to avoid pop sound when enable the Raptor */
118    addr = (unsigned int *)(0xB0000000 | BCHP_SUN_TOP_CTRL_PIN_MUX_PAD_CTRL_8);
119        val = *addr;
120    val &= ~(BCHP_SUN_TOP_CTRL_PIN_MUX_PAD_CTRL_8_gpio_100_pad_ctrl_MASK);
121    val |= (BCHP_SUN_TOP_CTRL_PIN_MUX_PAD_CTRL_8_gpio_100_pad_ctrl_PULL_UP << BCHP_SUN_TOP_CTRL_PIN_MUX_PAD_CTRL_8_gpio_100_pad_ctrl_SHIFT);
122        *addr = val;
123
124try_again:
125    compressed_image = malloc(COMPRESSED_BUFFER_SIZE);
126//    __asm__("1: b 1b; nop;");
127    if(0xff == (*boot_mode & 0xff)){
128        print_string("Use xmodem send to send image: ");
129        rc = xmodem_receive(BL_UART, compressed_image);
130        sleep(SLEEP_1_SEC);
131    }else{
132        flash_map_info_t *fmap;
133        unsigned int isize;
134
135        print_string("\r\nAuthenticating DTA code...");
136        fmap = (flash_map_info_t *)((unsigned int)&__start_s3 + 20);
137        if(fmap->fmap_magic == FMAP_MAGIC){
138            compressed_flash = (unsigned char *)(fmap->image0_offset + FLASH_BASE);
139        }else{
140            compressed_flash = (unsigned char *)&_ram_image_start;
141        }
142        /* for sharf we must copy code to ram as sharf can not read from bspi */
143        isize = image_size(compressed_flash);
144        if(0 != isize)
145            aligned_copy(compressed_flash, compressed_image, isize);
146//        __asm__("1: b 1b; nop;");
147        rc = authenticate_image(compressed_image);
148        /* process result of the authentication here */
149        if(0 == rc){
150            rc = COMPRESSED_BUFFER_SIZE;
151        }else{
152            rc = -1;
153            if(((*(uint32_t*)XPT_OTP_MC1_BASE) & 4) == 0){
154                print_char('-');
155                rc = COMPRESSED_BUFFER_SIZE;
156            }
157        }
158    }
159    if(0 < rc){
160        print_string("OK\r\n");
161        compressed_image = skip_headers(compressed_image);
162        if(NULL != compressed_image)
163            run_compressed(compressed_image, rc);
164    }else{
165        print_string("FAILED\r\n");
166        __asm__("wait");
167    }
168
169        /* This is for debugging and development only, production bootloader should reboot */
170    fast_heap_init(HEAP_START_ADDRESS);
171    *boot_mode = 0xff;
172        goto try_again;
173}
174
175typedef void (*entry_t)(void);
176
177void run_compressed(unsigned char * data, unsigned int len)
178{
179    int rc;
180    unsigned char * text;
181    entry_t entry;
182
183    text = (unsigned char *)RAM_TEXT_BASE;
184    print_string("Decompressing...");
185    rc = decompress(data, len, text, RAM_TEXT_SIZE);
186    if(rc > 0){
187        print_string("OK\r\n");
188        clear_all_d_cache();
189        invalidate_all_i_cache();
190        entry = (entry_t) RAM_TEXT_BASE;
191        entry();
192    }else{
193        print_string("DECOMPRESS FAILED\r\n");
194    }
195}
196
197int decompress(unsigned char *in_buf, unsigned int in_size, unsigned char * out_buf, unsigned int out_size)
198{
199    z_stream strm;
200    int ret;
201
202    memset(&strm,0,sizeof(strm));
203    strm.avail_in = in_size;
204    strm.next_in = in_buf;
205    strm.avail_out = out_size;
206    strm.next_out = out_buf;
207    ret = inflateInit2(&strm, 15+32);
208    if (ret == Z_OK)
209    {
210        ret = inflate(&strm, Z_FINISH);
211        inflateEnd(&strm);
212        if ((ret == Z_STREAM_END) || (ret == Z_OK))
213        {
214            return strm.total_out;
215        }
216        else if (ret > 0)
217        {
218            return -ret;
219        }
220    }
221    return ret;
222}
223
224#define ZID1 0x1f
225#define ZID2 0x8b
226
227/*
228  We have 2 headers to skip from compressed data, boot order header and
229  application header, to get to the compressed data.
230 */
231unsigned char * skip_headers(unsigned char * image)
232{
233    unsigned char * data;
234    boot_header_t * bh;
235    application_info_header_t * ah;
236    unsigned int offset;
237
238    data = NULL;
239    offset = 0;
240    if((ZID1 == image[0]) && (ZID2 == image[1])){
241        /* image pointing to zlib data */
242        data = image;
243        goto ExitFunc;
244    }
245    bh = (boot_header_t*)image;
246    if(CHIP_ID == bh->chip_id){
247        /* skip boot header if found */
248        offset = sizeof(boot_header_t);
249    }
250    ah = (application_info_header_t *)(&image[offset]);
251    if((CHIP_ID != ah->chip_id) || (DTA_MAGIC != ah->dta_magic)){
252        /* app header or boot header not found */
253        goto ExitFunc;
254    }
255    offset += sizeof(application_info_header_t);
256    if((ZID1 == image[offset]) && (ZID2 == image[offset+1])){
257        /* image pointing to zlib data */
258        data = &image[offset];
259    }
260
261ExitFunc:
262    return data;
263}
264
265#include "signature.c"
266
267extern unsigned int oem_key[];
268
269/* my test key generated from privkey2048.pem */
270unsigned long broadcom_test_key2[] = {
271    0xc743ee55,0xb3143b8d,0xb427ecb5,0xf31cc652,
272    0x3760d7d7,0xb1c8a2b7,0x4f853b90,0x9ae6fba0,
273    0x6d750313,0x33bfb2d9,0x5fb5e078,0xe65b01ce,
274    0xab976eb2,0x1cab3054,0x807b0111,0x9758d712,
275    0x315760c5,0x4312a951,0xea31d43f,0xdaee15ff,
276    0xfb432017,0x54d4762d,0x191b4950,0x95ed9b0c,
277    0xe89b47b7,0xb3c41116,0x9b294f0e,0xb84662cb,
278    0x63405466,0x49b70d4d,0x69fff19f,0x4804b8e0,
279    0x080965f5,0xe8765ab5,0xf5dbbf20,0xdd70df30,
280    0xf51644a3,0x900eba4d,0x1e9a9670,0x60518e67,
281    0x3a1038cb,0xb8fe6752,0x75b86eff,0x107a9a47,
282    0xcce14416,0x7d47ffd8,0xdd30fcfc,0x79b30b7c,
283    0xa2ba451c,0x0716442e,0x2d912f8a,0x6a31e3fc,
284    0x92bf8d4c,0x24112f41,0xaf6bc6b1,0x3b9a1925,
285    0x87a104f2,0x2e1793c2,0x79e7c4d7,0x535b8cbe,
286    0xe6f4debd,0xbaf2a446,0x8a4d7c5d,0x22508e73,
287};
288
289
290#define KSEG0_KSEG1(x) ((0x20000000) | (unsigned long)(x))
291unsigned int app_signature[SIGNATURE_SIZE/4];
292unsigned int key1_copy[SIGNATURE_SIZE/4];
293
294int authenticate_image(unsigned char * image)
295{
296    void * app_signature_address;
297    boot_header_t * bh;
298    application_info_header_t * ah;
299    unsigned int offset;
300    int rc;
301    unsigned long signed_size;
302
303    /* by default authentication fails */
304    rc = 1;
305    offset = 0;
306
307    bh = (boot_header_t*)image;
308    if(CHIP_ID == bh->chip_id){
309        /* skip boot header if found */
310        offset = sizeof(boot_header_t);
311    }
312    ah = (application_info_header_t *)(&image[offset]);
313    if((CHIP_ID != ah->chip_id) || (DTA_MAGIC != ah->dta_magic)){
314        /* app header or boot header not found */
315        goto ExitFunc;
316    }
317    /* ah now points to application image */
318    /* find signature address. image size does not include header */
319    signed_size = sizeof(application_info_header_t) + ah->image_size;
320    app_signature_address = (void *)((unsigned int)ah + signed_size);
321    aligned_copy(app_signature_address, app_signature, SIGNATURE_SIZE);
322//    aligned_copy(oem_key, key1_copy, SIGNATURE_SIZE);
323    aligned_copy(broadcom_test_key2, key1_copy, SIGNATURE_SIZE);
324    rc = signature_check((unsigned long)ah, signed_size, (unsigned long)app_signature, (unsigned long)key1_copy);
325ExitFunc:
326    return rc;
327}
328
329unsigned int image_size(unsigned char * image)
330{
331    boot_header_t * bh;
332    application_info_header_t * ah;
333    unsigned int offset;
334    unsigned int isize;
335
336    isize = 0;
337    offset = 0;
338    bh = (boot_header_t*)image;
339    if(CHIP_ID == bh->chip_id){
340        /* skip boot header if found */
341        offset = sizeof(boot_header_t);
342    }
343    ah = (application_info_header_t *)(&image[offset]);
344    if((CHIP_ID != ah->chip_id) || (DTA_MAGIC != ah->dta_magic)){
345        /* app header or boot header not found */
346        goto ExitFunc;
347    }
348    /* ah now points to application image */
349    offset += sizeof(application_info_header_t);
350    /* image size does not include headers, signature */
351    isize = offset + ah->image_size + SIGNATURE_SIZE;
352ExitFunc:
353    return isize;
354}
355
356/* Please do not remove! */
357/* Local Variables: */
358/* mode: C */
359/* indent-tabs-mode: nil */
360/* End: */
Note: See TracBrowser for help on using the repository browser.