source: svn/trunk/newcon3bcm2_21bu/dta/src/bootloader/s2_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: 8.2 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: Stage 2 C entry point.
15 *
16 * Revision History:
17 *
18 * $brcm_Log: $
19 *
20 *
21 ***************************************************************************/
22#include "bstd.h"
23#include "image_selector.h"
24#include "ramheader.h"
25
26#define KSEG0_KSEG1(x) ((0x20000000) | (unsigned long)(x))
27#if defined(RSA_BITS)
28#define SIGNATURE_SIZE (RSA_BITS/8)
29#else
30#define SIGNATURE_SIZE 0x80
31#endif
32
33#define XPT_OTP_MC1_BASE 0xb053802c
34
35/* starting location of bootloader in flash */
36extern unsigned int flash_start;
37/* combined size of stage 1 and 2 bootloaders */
38extern unsigned int _bootloader_size;
39
40/* write character on serial port */
41extern void _writeasm(int c);
42/* copy memory block from word aligned src to word aligned destination
43   with word aligned size. All pointer and size must be 4 bytes aligned */
44extern void aligned_copy(void * src, void * dst, unsigned int n);
45extern void clear_all_d_cache(void);
46extern void invalidate_all_i_cache(void);
47
48/* constants and static data */
49const unsigned int stage3_vma = 0x80000000;
50const unsigned int scm_vma = 0x80016000;
51#if 1
52const unsigned int scm_key[0x100/4] = 
53{
54    0xbb4b3dac,0xaad0a0f7,0x69efdb63,0x0f0cf45d,
55    0xa8bee481,0xdae2ced3,0xb2a35773,0xb859cb6d,
56    0xc42a5f7d,0x0b02b5a6,0x40e81bde,0x592afa2c,
57    0xc6b0f440,0xc27adc14,0xa499709b,0xc6c06c05,
58    0x7fc11902,0xbcc63a02,0x68f07420,0xa701267f,
59    0xee6db3b1,0x7d563cd6,0xf749d20a,0x38f546f8,
60    0x805bbc09,0xa184b617,0xd1d2f5d7,0xe20de8be,
61    0x84b471a7,0x8d57e5f5,0x7d3cec98,0x290f3ad1,
62    0x1e6dbfa9,0x5e28a674,0xf02d0afc,0xe8f90d41,
63    0x033c6fd2,0x2b02f77d,0xcfe718af,0x0741699b,
64    0x4c933cba,0x71135d5e,0x3016bb7a,0x449efe72,
65    0xbfdd6f79,0x5849551a,0xa6e38ac3,0x9d74c7aa,
66    0xc6a3eb11,0xa20d3d63,0x55d74702,0xdaa1bd7c,
67    0x8af2ab33,0x694ba3bf,0xbd39dd1e,0x4b371322,
68    0x4593bf32,0x037837ba,0x1c854644,0xd6815619,
69    0x0e9720de,0xea891def,0x4bffc70f,0x1c1b92a7,
70};
71#else
72const unsigned int scm_key[0x100/4] = 
73{
74    /* test public key generated from privkey2048.pem */
75     0xc743ee55,0xb3143b8d,0xb427ecb5,0xf31cc652,
76     0x3760d7d7,0xb1c8a2b7,0x4f853b90,0x9ae6fba0,
77     0x6d750313,0x33bfb2d9,0x5fb5e078,0xe65b01ce,
78     0xab976eb2,0x1cab3054,0x807b0111,0x9758d712,
79     0x315760c5,0x4312a951,0xea31d43f,0xdaee15ff,
80     0xfb432017,0x54d4762d,0x191b4950,0x95ed9b0c,
81     0xe89b47b7,0xb3c41116,0x9b294f0e,0xb84662cb,
82     0x63405466,0x49b70d4d,0x69fff19f,0x4804b8e0,
83     0x080965f5,0xe8765ab5,0xf5dbbf20,0xdd70df30,
84     0xf51644a3,0x900eba4d,0x1e9a9670,0x60518e67,
85     0x3a1038cb,0xb8fe6752,0x75b86eff,0x107a9a47,
86     0xcce14416,0x7d47ffd8,0xdd30fcfc,0x79b30b7c,
87     0xa2ba451c,0x0716442e,0x2d912f8a,0x6a31e3fc,
88     0x92bf8d4c,0x24112f41,0xaf6bc6b1,0x3b9a1925,
89     0x87a104f2,0x2e1793c2,0x79e7c4d7,0x535b8cbe,
90     0xe6f4debd,0xbaf2a446,0x8a4d7c5d,0x22508e73,
91};
92#endif
93
94extern unsigned int key1[];
95unsigned int key1_copy[SIGNATURE_SIZE/4];
96
97#define OTP_MID() (((*(uint32_t*)XPT_OTP_MC1_BASE) >> 18) | ((*(uint32_t*)(XPT_OTP_MC1_BASE + 4)) << (32 - 18)))
98
99/* forward declarations */
100int signature_check(unsigned long in, unsigned long size, unsigned long signature, unsigned long public_key);
101void invoke_dsp_loader(void);
102void print_string(char *s);
103
104void bootloader_main(void)
105{   
106    unsigned int * stage3_start;
107    unsigned int stage3_size;
108    unsigned int oem_key;
109    unsigned int oem_mid;
110    unsigned int signature;
111
112    print_string("\r\nS2 " __DATE__":" __TIME__ "\r\n");
113//    __asm__("1: b 1b; nop;");
114    invoke_dsp_loader();
115
116
117    stage3_start = (unsigned int *)((unsigned int)&_bootloader_size + (unsigned int)&flash_start + SIGNATURE_SIZE);
118    stage3_size = *(stage3_start + 4) + SIGNATURE_SIZE;
119    aligned_copy(stage3_start, (void*)stage3_vma, stage3_size);
120
121    aligned_copy(key1, key1_copy, SIGNATURE_SIZE);
122    oem_key = stage3_vma + 0x400; /* key offset in the image */
123    oem_mid = oem_key + 0x100;
124    signature = oem_mid + 0x40;
125    /* authenticate key */
126    oem_mid = *((unsigned int*)oem_mid);
127    if(OTP_MID() != oem_mid){
128        _writeasm('m');
129        /* market id check failed, make sure chip is secure */
130        if(4 == ((*(uint32_t*)XPT_OTP_MC1_BASE) & 4))
131            __asm__("wait ; 1: b 1b ; nop ;");
132       
133    }
134    if(0 != signature_check((unsigned long)oem_key, (SIGNATURE_SIZE+0x40), signature, (unsigned long)key1_copy)){
135        _writeasm('k');
136        /* signature check failed, make sure chip is secure */
137        if(4 == ((*(uint32_t*)XPT_OTP_MC1_BASE) & 4))
138            __asm__("wait ; 1: b 1b ; nop ;");
139    }
140    /* authenticate s3 with oem key */
141    stage3_size -= SIGNATURE_SIZE;
142    signature = stage3_vma + stage3_size;
143    if(0 != signature_check((unsigned long)stage3_vma, stage3_size, signature, (unsigned long)oem_key)){
144        _writeasm('b');
145        /* signature check failed, make sure chip is secure */
146        if(4 == ((*(uint32_t*)XPT_OTP_MC1_BASE) & 4))
147            __asm__("wait ; 1: b 1b ; nop ;");
148    }
149   
150    clear_all_d_cache();
151    invalidate_all_i_cache();
152
153    ((void (*)(void))stage3_vma)();
154}
155
156/* watchdog signature DLWD */
157#define WD_SIGNATURE 0x444C5744
158/* watchdog timeout 5 seconds */
159#define WD_TIMEOUT 0x80befc0
160/* watchdog singature register. LMC_CORE.SCB_DATA[10] */
161#define WD_SIGNATURE_REG 0xB0340928
162#define WD_TIMEOUT_REG 0xB04066E8
163#define WD_WDCMG_REG 0xB04066EC
164#define WD_WDCRS_REG 0xB04066F4
165
166/*
167   Steps:
168   - check if rebooted from watchdog
169   - if did check if watchdog was from dsp loader
170   - find active image
171   - find scm in the active image
172   - compute size of scm including header and signature
173   - copy scm with header and signature in to ram
174   - authenticate scm
175   - setup watchdog
176   - run scm loader
177   - clear watchdog
178 */
179void invoke_dsp_loader(void)
180{
181    void * image;
182    void * image_ram;
183    scm_info_header_t * sh;
184    unsigned long size;
185    unsigned long scm_sig;
186    uint32_t val;
187   
188    /* check if we got here after watchdog fired */
189    val = *(uint32_t*)WD_WDCRS_REG;
190    if(1 == val){
191        val = *(uint32_t*)WD_SIGNATURE_REG;
192        if(WD_SIGNATURE == val){
193            *(uint32_t*)WD_SIGNATURE_REG = 0;
194            /* just return if WD is fired and let second stage select another
195               image */
196            goto ExitFunc;
197        }
198    }
199    image = active_image_address();
200
201    image = dsp_loader_address(image);
202    if(NULL == image){
203        goto ExitFunc;
204    }
205    sh = (scm_info_header_t *) image;
206    size = sh->image_size + sizeof(scm_info_header_t) + SIGNATURE_SIZE;
207    if(0x20000 < size){
208        /* size is too large */
209        goto ExitFunc;
210    }
211    image_ram = (void *)(scm_vma - sizeof(scm_info_header_t));
212    aligned_copy(image, image_ram, size);
213    /* adjust size for authentication */
214    size -= SIGNATURE_SIZE;
215    scm_sig = (unsigned long)image_ram + size;
216    if(0 != signature_check((unsigned long)image_ram, size, scm_sig, (unsigned long)scm_key)){
217        print_string("Dsp loader invalid.\n\r");
218        /* signature check failed, make sure chip is secure */
219        if(4 == ((*(uint32_t*)XPT_OTP_MC1_BASE) & 4))
220            goto ExitFunc;
221        /* if chip is not secure contunue with scm loading */
222    }
223
224    print_string("Loading dsp...");
225    /* setup and start WD */
226    *(uint32_t*)WD_SIGNATURE_REG = WD_SIGNATURE;
227    *(uint32_t*)WD_TIMEOUT_REG = WD_TIMEOUT;
228    *(uint32_t*)WD_WDCMG_REG = 0xff00;
229    *(uint32_t*)WD_WDCMG_REG = 0x00ff;
230
231    clear_all_d_cache();
232    invalidate_all_i_cache();
233    /* invoke scm loader */
234    ((void (*)(void))scm_vma)();
235    /* stop WD */
236    *(uint32_t*)WD_SIGNATURE_REG = 0;
237    *(uint32_t*)WD_WDCMG_REG = 0xee00;
238    *(uint32_t*)WD_WDCMG_REG = 0x00ee;   
239    print_string("done\n\r");
240ExitFunc:
241    return;
242}
243
244void print_string(char *s)
245{
246    while (*s)
247    {
248        _writeasm(*s++);
249    }
250    return;
251}
252
253
254#include "signature.c"
255
256/* Please do not remove! */
257/* Local Variables: */
258/* mode: C */
259/* indent-tabs-mode: nil */
260/* End: */
Note: See TracBrowser for help on using the repository browser.