Path: blob/master/arch/blackfin/mach-common/head.S
10817 views
/*1* Common Blackfin startup code2*3* Copyright 2004-2008 Analog Devices Inc.4*5* Licensed under the GPL-2 or later.6*/78#include <linux/linkage.h>9#include <linux/init.h>10#include <asm/blackfin.h>11#include <asm/thread_info.h>12#include <asm/trace.h>13#include <asm/asm-offsets.h>1415__INIT1617ENTRY(__init_clear_bss)18r2 = r2 - r1;19cc = r2 == 0;20if cc jump .L_bss_done;21r2 >>= 2;22p1 = r1;23p2 = r2;24lsetup (1f, 1f) lc0 = p2;251: [p1++] = r0;26.L_bss_done:27rts;28ENDPROC(__init_clear_bss)2930ENTRY(__start)31/* R0: argument of command line string, passed from uboot, save it */32R7 = R0;3334/* Enable Cycle Counter and Nesting Of Interrupts */35#ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES36R0 = SYSCFG_SNEN;37#else38R0 = SYSCFG_SNEN | SYSCFG_CCEN;39#endif40SYSCFG = R0;4142/* Optimization register tricks: keep a base value in the43* reserved P registers so we use the load/store with an44* offset syntax. R0 = [P5 + <constant>];45* P5 - core MMR base46* R6 - 047*/48r6 = 0;49p5.l = 0;50p5.h = hi(COREMMR_BASE);5152/* Zero out registers required by Blackfin ABI */5354/* Disable circular buffers */55L0 = r6;56L1 = r6;57L2 = r6;58L3 = r6;5960/* Disable hardware loops in case we were started by 'go' */61LC0 = r6;62LC1 = r6;6364/*65* Clear ITEST_COMMAND and DTEST_COMMAND registers,66* Leaving these as non-zero can confuse the emulator67*/68[p5 + (DTEST_COMMAND - COREMMR_BASE)] = r6;69[p5 + (ITEST_COMMAND - COREMMR_BASE)] = r6;70CSYNC;7172trace_buffer_init(p0,r0);7374/* Turn off the icache */75r1 = [p5 + (IMEM_CONTROL - COREMMR_BASE)];76BITCLR (r1, ENICPLB_P);77[p5 + (IMEM_CONTROL - COREMMR_BASE)] = r1;78SSYNC;7980/* Turn off the dcache */81r1 = [p5 + (DMEM_CONTROL - COREMMR_BASE)];82BITCLR (r1, ENDCPLB_P);83[p5 + (DMEM_CONTROL - COREMMR_BASE)] = r1;84SSYNC;8586/* in case of double faults, save a few things */87p0.l = _init_retx;88p0.h = _init_retx;89R0 = RETX;90[P0] = R0;9192#ifdef CONFIG_DEBUG_DOUBLEFAULT93/* Only save these if we are storing them,94* This happens here, since L1 gets clobbered95* below96*/97GET_PDA(p0, r0);98r5 = [p0 + PDA_DF_RETX];99p1.l = _init_saved_retx;100p1.h = _init_saved_retx;101[p1] = r5;102103r5 = [p0 + PDA_DF_DCPLB];104p1.l = _init_saved_dcplb_fault_addr;105p1.h = _init_saved_dcplb_fault_addr;106[p1] = r5;107108r5 = [p0 + PDA_DF_ICPLB];109p1.l = _init_saved_icplb_fault_addr;110p1.h = _init_saved_icplb_fault_addr;111[p1] = r5;112113r5 = [p0 + PDA_DF_SEQSTAT];114p1.l = _init_saved_seqstat;115p1.h = _init_saved_seqstat;116[p1] = r5;117#endif118119/* Initialize stack pointer */120sp.l = _init_thread_union + THREAD_SIZE;121sp.h = _init_thread_union + THREAD_SIZE;122fp = sp;123usp = sp;124125#ifdef CONFIG_EARLY_PRINTK126call _init_early_exception_vectors;127r0 = (EVT_IVHW | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU);128sti r0;129#endif130131r0 = r6;132/* Zero out all of the fun bss regions */133#if L1_DATA_A_LENGTH > 0134r1.l = __sbss_l1;135r1.h = __sbss_l1;136r2.l = __ebss_l1;137r2.h = __ebss_l1;138call __init_clear_bss139#endif140#if L1_DATA_B_LENGTH > 0141r1.l = __sbss_b_l1;142r1.h = __sbss_b_l1;143r2.l = __ebss_b_l1;144r2.h = __ebss_b_l1;145call __init_clear_bss146#endif147#if L2_LENGTH > 0148r1.l = __sbss_l2;149r1.h = __sbss_l2;150r2.l = __ebss_l2;151r2.h = __ebss_l2;152call __init_clear_bss153#endif154r1.l = ___bss_start;155r1.h = ___bss_start;156r2.l = ___bss_stop;157r2.h = ___bss_stop;158call __init_clear_bss159160/* Put The Code for PLL Programming and SDRAM Programming in L1 ISRAM */161call _bfin_relocate_l1_mem;162163#ifdef CONFIG_ROMKERNEL164call _bfin_relocate_xip_data;165#endif166167#ifdef CONFIG_BFIN_KERNEL_CLOCK168/* Only use on-chip scratch space for stack when absolutely required169* to avoid Anomaly 05000227 ... we know the init_clocks() func only170* uses L1 text and stack space and no other memory region.171*/172# define KERNEL_CLOCK_STACK (L1_SCRATCH_START + L1_SCRATCH_LENGTH - 12)173sp.l = lo(KERNEL_CLOCK_STACK);174sp.h = hi(KERNEL_CLOCK_STACK);175call _init_clocks;176sp = usp; /* usp hasn't been touched, so restore from there */177#endif178179/* This section keeps the processor in supervisor mode180* during kernel boot. Switches to user mode at end of boot.181* See page 3-9 of Hardware Reference manual for documentation.182*/183184/* EVT15 = _real_start */185186p1.l = _real_start;187p1.h = _real_start;188[p5 + (EVT15 - COREMMR_BASE)] = p1;189csync;190191#ifdef CONFIG_EARLY_PRINTK192r0 = (EVT_IVG15 | EVT_IVHW | EVT_IRPTEN | EVT_EVX | EVT_NMI | EVT_RST | EVT_EMU) (z);193#else194r0 = EVT_IVG15 (z);195#endif196sti r0;197198raise 15;199#ifdef CONFIG_EARLY_PRINTK200p0.l = _early_trap;201p0.h = _early_trap;202#else203p0.l = .LWAIT_HERE;204p0.h = .LWAIT_HERE;205#endif206reti = p0;207#if ANOMALY_05000281208nop; nop; nop;209#endif210rti;211212.LWAIT_HERE:213jump .LWAIT_HERE;214ENDPROC(__start)215216/* A little BF561 glue ... */217#ifndef WDOG_CTL218# define WDOG_CTL WDOGA_CTL219#endif220221ENTRY(_real_start)222/* Enable nested interrupts */223[--sp] = reti;224225/* watchdog off for now */226p0.l = lo(WDOG_CTL);227p0.h = hi(WDOG_CTL);228r0 = 0xAD6(z);229w[p0] = r0;230ssync;231232/* Pass the u-boot arguments to the global value command line */233R0 = R7;234call _cmdline_init;235236sp += -12 + 4; /* +4 is for reti loading above */237call _init_pda238sp += 12;239jump.l _start_kernel;240ENDPROC(_real_start)241242__FINIT243244245