2 * Initialization and support routines for self-booting
5 * Copyright 2004, Broadcom Corporation
8 * THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY
9 * KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM
10 * SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
11 * FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE.
27 /* Cache and line sizes */
28 static uint icache_size
, ic_lsize
, dcache_size
, dc_lsize
;
31 _change_cachability(uint32 cm
)
35 c0reg
= MFC0(C0_CONFIG
, 0);
36 c0reg
&= ~CONF_CM_CMASK
;
37 c0reg
|= (cm
& CONF_CM_CMASK
);
38 MTC0(C0_CONFIG
, 0, c0reg
);
39 prid
= MFC0(C0_PRID
, 0);
40 if ((prid
& (PRID_COMP_MASK
| PRID_IMP_MASK
)) ==
41 (PRID_COMP_BROADCOM
| PRID_IMP_BCM3302
)) {
42 c0reg
= MFC0(C0_BROADCOM
, 0);
43 /* Enable icache & dcache */
44 c0reg
|= BRCM_IC_ENABLE
| BRCM_DC_ENABLE
;
45 MTC0(C0_BROADCOM
, 0, c0reg
);
48 static void (*change_cachability
)(uint32
);
54 uint start
, end
, size
, lsize
;
56 /* Save cache config */
57 config1
= MFC0(C0_CONFIG
, 1);
59 icache_probe(config1
, &size
, &lsize
);
63 dcache_probe(config1
, &size
, &lsize
);
67 /* If caches are not in the default state then
68 * presume that caches are already init'd
70 if ((MFC0(C0_CONFIG
, 0) & CONF_CM_CMASK
) != CONF_CM_UNCACHED
) {
78 end
= (start
+ icache_size
);
82 cache_op(start
, Index_Store_Tag_I
);
88 end
= (start
+ dcache_size
);
92 cache_op(start
, Index_Store_Tag_D
);
96 /* Must be in KSEG1 to change cachability */
97 change_cachability
= (void (*)(uint32
)) KSEG1ADDR(_change_cachability
);
98 change_cachability(CONF_CM_CACHABLE_NONCOHERENT
);
102 #define BCM4710_DUMMY_RREG() (((sbconfig_t *)(KSEG1ADDR(SB_ENUM_BASE + SBCONFIGOFF)))->sbimstate)
110 end
= start
+ dcache_size
;
112 while (start
< end
) {
113 BCM4710_DUMMY_RREG();
114 cache_op(start
, Index_Writeback_Inv_D
);
125 end
= start
+ icache_size
;
127 while (start
< end
) {
128 cache_op(start
, Index_Invalidate_I
);
135 struct serial_struct
{
136 unsigned char *reg_base
;
137 unsigned short reg_shift
;
142 static struct serial_struct min_uart
;
144 #define LOG_BUF_LEN (1024)
145 #define LOG_BUF_MASK (LOG_BUF_LEN-1)
146 static char log_buf
[LOG_BUF_LEN
];
147 static unsigned long log_start
;
151 serial_in(struct serial_struct
*info
, int offset
)
153 return ((int)R_REG(NULL
, (uint8
*)(info
->reg_base
+ (offset
<< info
->reg_shift
))));
157 serial_out(struct serial_struct
*info
, int offset
, int value
)
159 W_REG(NULL
, (uint8
*)(info
->reg_base
+ (offset
<< info
->reg_shift
)), value
);
160 *((volatile unsigned int *) KSEG1ADDR(SB_ENUM_BASE
));
170 /* Store in log buffer */
171 *((char *) KSEG1ADDR(&log_buf
[log_start
])) = (char) c
;
172 log_start
= (log_start
+ 1) & LOG_BUF_MASK
;
175 if (!min_uart
.reg_base
)
178 while (!(serial_in(&min_uart
, UART_LSR
) & UART_LSR_THRE
));
179 serial_out(&min_uart
, UART_TX
, c
);
182 /* assert & debugging */
186 assfail(char *exp
, char *file
, int line
)
188 printf("ASSERT %s file %s line %d\n", exp
, file
, line
);
190 #endif /* BCMDBG_ASSERT */
192 /* general purpose memory allocation */
194 extern char text_start
[], text_end
[];
195 extern char data_start
[], data_end
[];
196 extern char bss_start
[], bss_end
[];
198 static ulong free_mem_ptr
= 0;
199 static ulong free_mem_ptr_end
= 0;
208 printf("Malloc error");
209 if (free_mem_ptr
== 0)
210 printf("Memory error");
213 free_mem_ptr
= (free_mem_ptr
+ 3) & ~3;
215 p
= (void *) free_mem_ptr
;
216 free_mem_ptr
+= size
;
218 if (free_mem_ptr
>= free_mem_ptr_end
)
219 printf("Out of memory");
230 /* microsecond delay */
232 /* Default to 125 MHz */
233 static unsigned long cpu_clock
= 125000000;
238 __asm__
__volatile__(
240 "1:\tbnez\t%0,1b\n\t"
252 loops
= cpu_clock
/ 5;
257 /* No trap handling in self-decompressing boots */
258 extern void trap_init(void);
267 serial_add(void *regs
, uint irq
, uint baud_base
, uint reg_shift
)
271 if (min_uart
.reg_base
)
274 min_uart
.reg_base
= regs
;
276 min_uart
.baud_base
= baud_base
/ 16;
277 min_uart
.reg_shift
= reg_shift
;
279 /* Set baud and 8N1 */
280 quot
= (min_uart
.baud_base
+ 57600) / 115200;
281 serial_out(&min_uart
, UART_LCR
, UART_LCR_DLAB
);
282 serial_out(&min_uart
, UART_DLL
, quot
& 0xff);
283 serial_out(&min_uart
, UART_DLM
, quot
>> 8);
284 serial_out(&min_uart
, UART_LCR
, UART_LCR_WLEN8
);
286 /* According to the Synopsys website: "the serial clock
287 * modules must have time to see new register values
288 * and reset their respective state machines. This
289 * total time is guaranteed to be no more than
290 * (2 * baud divisor * 16) clock cycles of the slower
291 * of the two system clocks. No data should be transmitted
292 * or received before this maximum time expires."
304 /* Disable interrupts */
305 c0reg
= MFC0(C0_STATUS
, 0);
307 MTC0(C0_STATUS
, 0, c0reg
);
310 sbh
= sb_kattach(SB_OSH
);
312 sb_mips_init(sbh
, 0);
313 sb_serial_init(sbh
, serial_add
);
316 free_mem_ptr
= (ulong
) bss_end
;
317 free_mem_ptr_end
= ((ulong
)&c0reg
) - 8192; /* Enough stack? */
319 return ((void *)sbh
);
322 /* translate bcmerros */
324 osl_error(int bcmerror
)