Fix infinite loop in SendResp_upnphttp()
[tomato.git] / release / src / shared / boot.S
bloba452d6bf86802547769308b0d2e38c23874de274
1 /*
2  * BCM947XX Boot code for standalone apps.
3  *
4  * Code should be position-independent until it copies itself to SDRAM.
5  *
6  * Copyright 2004, Broadcom Corporation
7  * All Rights Reserved.
8  * 
9  * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
10  * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
11  * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
12  * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
13  *
14  * $Id$
15  */
17 #include "mipsinc.h"
18 #include "sbconfig.h"
19 #include "sbchipc.h"
20 #include "bcmdevs.h"
22         .text
23         LEAF(startup)
24         .set    noreorder
27         li      a0,KSEG1ADDR(SB_ENUM_BASE)
29         # XXX: the following code snipet sets clk frequency to 200M
30         # correct pll clk freq to real speed in the 5350 case.
31         # unless its vsim which we detect as pkg option 1 (should be 0xe)
32         # It is Ugly...but
33         li      a3,BCM5350_CHIP_ID              # 5350 ChipID
34         lw      t1,CC_CHIPID(a0)                # ChipID register
35         li      t2,CID_ID_MASK                  # chip id is bit 0-15
36         and     t2,t1,t2
37         bne     t2,a3,2f                        # if not 5350 then skip
38         nop
39         
40         li      t2,CID_PKG_MASK                 # if it is a vsim 5350, also skip
41         and     t2,t1,t2
42         li      a3,(HDLSIM5350_PKG_ID << CID_PKG_SHIFT)
43         beq     t2,a3,2f                        # if pkg opt 1 then skip
44         nop
46         li      a3,CLKC_5350_N
47         lw      t1,CC_CLKC_N(a0)
48         beq     a3,t1,2f                        # move ahead if clk freq set correctly
49         nop
50         sw      a3,CC_CLKC_N(a0)                # set control N1 to select 6
51         li      t1,1
52         sw      t1,CC_WATCHDOG(a0)              # set WatchDog Reset
53 1:      b       1b
54         nop
57 #ifdef  BCM5354
58         lw      t1,CC_CHIPID(a0)                # ChipID register
59         li      t2,CID_ID_MASK                  # chip id is bit 0-15
60         li      a3,BCM5354_CHIP_ID              # 5354 ChipID
61         and     t2,t1,t2
62         bne     t2,a3,ramcheck                  # if not 5354 then skip
63         nop
65         li      t2,0x1                          # Need define
66         sw      t2,PMU_REG_CONTROL_ADDR(a0)
67         li      t3,0x6800000                    # Should only affect the switch bits
68         sw      t3,PMU_REG_CONTROL_DATA(a0)
69         
70         /* 
71          * Trim the output voltage of the 1.2V BB switcher and 2.5V
72          * regulator to the correct value.
73          */
74         li      t2,0x0
75         sw      t2,PMU_REG_CONTROL_ADDR(a0)
76         li      t3,0x2000                       # Reduce the output voltage of
77         sw      t3,PMU_REG_CONTROL_DATA(a0)     # BB switcher to get 1.2V
78         li      t2,0x3
79         sw      t2,PMU_REG_CONTROL_ADDR(a0)
80         li      t3,0x02000000                   # Increase the output voltage
81         sw      t3,PMU_REG_CONTROL_DATA(a0)     # of VDDP LDO to get 2.5V
83         lw      t2,PMU_CTL(a0)                  # Check if PLL has been programmed
84         andi    t2,t2,PCTL_XTALFREQ_MASK
85         bnez    t2,3f                           # Yup, leave it alone
86         nop
87         li      t2,0x7ffff                      # Should only turn off the PLL bit
88         sw      t2,PMU_MIN_RES_MASK(a0)         # Disable base band PLL
89         sw      t2,PMU_MAX_RES_MASK(a0)
90         nop
92         /* Init code for FF4 space without TLB, enabling RAC */
93 3:      li      t0,0x1fa0000c                   # Set up CBR to 0x1fax_xxxx
94         mtc0    t0,$22,6
95         li      t1,0x1fa00000
96         lw      t2,0x14(t1)
97         or      t3,t2,0xc0000000                # enable ffxx_xxxx space # without programming TLB
98         sw      t3,0x14(t1) 
99         li      t0,0xff40000c                   # change CBR to ff4x_xxxx
100         mtc0    t0,$22,6
101 #endif  /* BCM5354 */
103 ramcheck:
104         /* Check if we booted from SDRAM */
105         bal     1f
106         nop
107 1:      li      t0,PHYSADDR_MASK
108         and     t0,t0,ra
109         li      t1,SB_FLASH1
110         bge     t0,t1,inflash
111         nop
113         /* Call draminit to size memory */
114         jal     board_draminit
115         nop
116         b       setsp
117         nop
119 inflash:
120         /* Is this chipc rev 11 or 12 and a serial flash? */
121         li      t0,KSEG1ADDR(SB_ENUM_BASE)
122         lw      t1,(SBCONFIGOFF + SBIDHIGH)(t0)
123         and     t2,t1,SBIDH_CC_MASK
124         srl     t2,t2,SBIDH_CC_SHIFT
125         bne     t2,SB_CC,checkcon               /* Not chipc */
126         nop
127         and     t2,t1,SBIDH_RC_MASK
128         and     t3,t1,SBIDH_RCE_MASK
129         srl     t3,t3,SBIDH_RCE_SHIFT
130         or      t2,t3
131         ble     t2,10,checkcon                  /* ccrev <= 10 */
132         nop
133         bge     t2,13,checkcon                  /* ccrev >= 13 */
134         nop
135         lw      t0,CC_CAPABILITIES(t0)
136         and     t0,t0,CC_CAP_FLASH_MASK
137         beq     t0,SFLASH_AT,switchkseg0        /* Atmel sflash */
138         nop
139         beq     t0,SFLASH_ST,switchkseg0        /* ST sflash */
140         nop
143 checkcon:
144         /* Check if the caches are already on */
145         mfc0    t0,C0_CONFIG
146         and     t0,CONF_CM_CMASK
147         beq     t0,CONF_CM_UNCACHED,initcaches
148         nop
150         b       switchkseg0
151         nop
153 initcaches:
154         /* Turn on the caches in the CP0 register */
155         mfc0    t0,C0_DIAGNOSTIC
156         or      t0,(BRCM_IC_ENABLE | BRCM_DC_ENABLE) /* Enable both I$ and D$ */
157         mtc0    t0,C0_DIAGNOSTIC
160 1:      /* Get cache sizes */
161         .set    mips32
162         mfc0    s0,C0_CONFIG,1
163         .set    mips0
165         li      s1,CONF1_DL_MASK
166         and     s1,s0
167         beq     s1,zero,nodc
168         nop
170         srl     s1,CONF1_DL_SHIFT
171         li      t0,CONF1_DL_BASE
172         sll     s1,t0,s1                /* s1 has D$ cache line size */
174         li      s2,CONF1_DA_MASK
175         and     s2,s0
176         srl     s2,CONF1_DA_SHIFT
177         addiu   s2,CONF1_DA_BASE        /* s2 now has D$ associativity */
179         li      t0,CONF1_DS_MASK
180         and     t0,s0
181         srl     t0,CONF1_DS_SHIFT
182         li      s3,CONF1_DS_BASE
183         sll     s3,s3,t0                /* s3 has D$ sets per way */
185         multu   s2,s3                   /* sets/way * associativity */
186         mflo    t0                      /* total cache lines */
188         multu   s1,t0                   /* D$ linesize * lines */
189         mflo    s2                      /* s2 is now D$ size in bytes */
191         /* Initilize the D$: */
192         mtc0    zero,C0_TAGLO
193         mtc0    zero,C0_TAGHI
195         li      t0,KSEG0                /* Just an address for the first $ line */
196         addu    t1,t0,s2                /*  + size of cache == end */
198         .set    mips3
199 1:      cache   Index_Store_Tag_D,0(t0)
200         .set    mips0
201         bne     t0,t1,1b
202         addu    t0,s1
204 nodc:
205         /* Now we get to do it all again for the I$ */
207         li      t0,CONF1_IL_MASK
208         and     t0,s0
209         beq     t0,zero,noic
210         nop
212         srl     t0,CONF1_IL_SHIFT
213         li      s3,CONF1_IL_BASE
214         sll     s3,t0                   /* s3 has I$ cache line size */
216         li      t0,CONF1_IA_MASK
217         and     t0,s0
218         srl     t0,CONF1_IA_SHIFT
219         addiu   s4,t0,CONF1_IA_BASE     /* s4 now has I$ associativity */
221         li      t0,CONF1_IS_MASK
222         and     t0,s0
223         srl     t0,CONF1_IS_SHIFT
224         li      s5,CONF1_IS_BASE
225         sll     s5,t0                   /* s5 has I$ sets per way */
227         multu   s4,s5                   /* sets/way * associativity */
228         mflo    t0                      /* s4 is not total cache lines */
230         multu   s3,t0                   /* I$ linesize * lines */
231         mflo    s4                      /* s4 is cache size in bytes */
233         /* Initilize the I$: */
234         mtc0    zero,C0_TAGLO
235         mtc0    zero,C0_TAGHI
237         li      t0,KSEG0                /* Just an address for the first $ line */
238         addu    t1,t0,s4                /*  + size of cache == end */
240         .set    mips3
241 1:      cache   Index_Store_Tag_I,0(t0)
242         .set    mips0
243         bne     t0,t1,1b
244         addu    t0,s1
246 noic:   
247         /* Caches initialized, change cacheability */
248         mfc0    t0,C0_CONFIG
249         and     t0,~CONF_CM_CMASK
250         or      t0,CONF_CM_CACHABLE_NONCOHERENT
251         mtc0    t0,C0_CONFIG
252         nop
254 switchkseg0:
255         /* And now jump to KSEG0 */
256         li      t0,KSEG1ADDR(SB_FLASH1)
257         la      t1,text_start
258         la      t2,initdram
259         sub     t0,t0,t1
260         add     t2,t2,t0
261         and     t2,PHYSADDR_MASK
262         or      t2,KSEG0
263         jr      t2
264         nop
266 initdram:
267         /* Initialize SDRAM */
268         li      t0,KSEG0ADDR(SB_FLASH1)
269         la      t1,text_start
270         la      t2,board_draminit
271         sub     t0,t0,t1
272         add     t2,t2,t0
273         jalr    t2
274         nop
276         /* v0 now contains memory size in bytes */
278         /* Copy self to SDRAM */
279 #ifdef  CONFIG_XIP
280         la      a0,text_end
281         la      a1,data_start
282         la      a2,input_data
283 #else
284         li      a0,KSEG0ADDR(SB_FLASH1)
285         la      a1,text_start
286         and     a1,PHYSADDR_MASK        /* Uncached writes to avoid a flush */
287         or      a1,KSEG1
288         la      a2,_end
289         and     a2,PHYSADDR_MASK
290         or      a2,KSEG1
291 #endif
292 1:      lw      t0,0(a0)
293         sw      t0,0(a1)
294         add     a0,4
295         add     a1,4
296         blt     a1,a2,1b
297         nop
298         b       setsp
299         nop
301         /* Black hole for traps with BEV on */
302         .org    0x380
303 bevtrap: nop
304         nop
305         .set    mips32
306         wait
307         .set    mips0
308         nop
309         nop
310         b       bevtrap
311         nop
313         /* Record the size of the binary */
314         .org    BISZ_OFFSET
315         .word   BISZ_MAGIC
316         .word   text_start
317         .word   text_end
318         .word   data_start
319         .word   data_end
320         .word   bss_start
321         .word   bss_end
322         .word   _end
324         /* Embedded NVRAM */
325         .balign 0x400   
326         .globl  embedded_nvram
327 embedded_nvram:
328         .fill   0x100,4,~(0x48534c46)
330 setsp:
331         /* Record the memory size */
332         la      t0,_memsize
333         sw      v0,0(t0)
335         /* Set up stack pointer */
336         or      v0,KSEG0
337         sub     sp,v0,4
339         /* Clear BSS */ 
340         la      a0,bss_start
341         la      a1,bss_end
342 1:      sw      zero,0(a0)
343         addi    a0,a0,4
344         blt     a0,a1,1b
345         nop
347         /* Setup trap handlers */
348 #ifdef CONFIG_XIP
349         li      t0,KSEG0ADDR(SB_FLASH1)
350         la      t1,text_start
351         la      t2,trap_init
352         sub     t0,t0,t1
353         add     t2,t2,t0
354         jalr    t2
355         nop
356 #else
357         la      t0,trap_init
358         jalr    t0
359         nop
360 #endif
362         /* Jump to C */
363         la      t0,c_main
364         jal     t0
365         move    a0,ra
367         /* In case c_main returns */
368 theend: nop
369         nop
370         .set    mips32
371         wait
372         .set    mips0
373         nop
374         nop
375         b       theend
376         nop
378         .set reorder
379         END(startup)
381         .data
382         .globl  _memsize
383 _memsize:
384         .word   0