diff options
author | Mike Frysinger <vapier@gentoo.org> | 2011-02-02 21:16:44 -0500 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2011-03-18 04:01:04 -0400 |
commit | 511cdcc50031eacd88cc70351da54beebff515e2 (patch) | |
tree | 7c36d07340e6cbf03c3832b932fc259e0b34c2bf /arch/blackfin/mach-common | |
parent | c6345ab1a3d17f4b6c80ac79d7fb0f006b32fdaa (diff) |
Blackfin: optimize startup code
Take advantage of more Blackfin-specific insns, and only initialize
registers required by the ABI.
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch/blackfin/mach-common')
-rw-r--r-- | arch/blackfin/mach-common/head.S | 110 |
1 files changed, 41 insertions, 69 deletions
diff --git a/arch/blackfin/mach-common/head.S b/arch/blackfin/mach-common/head.S index 4391621d9048..581e2b0a71ac 100644 --- a/arch/blackfin/mach-common/head.S +++ b/arch/blackfin/mach-common/head.S | |||
@@ -31,6 +31,7 @@ ENDPROC(__init_clear_bss) | |||
31 | ENTRY(__start) | 31 | ENTRY(__start) |
32 | /* R0: argument of command line string, passed from uboot, save it */ | 32 | /* R0: argument of command line string, passed from uboot, save it */ |
33 | R7 = R0; | 33 | R7 = R0; |
34 | |||
34 | /* Enable Cycle Counter and Nesting Of Interrupts */ | 35 | /* Enable Cycle Counter and Nesting Of Interrupts */ |
35 | #ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES | 36 | #ifdef CONFIG_BFIN_SCRATCH_REG_CYCLES |
36 | R0 = SYSCFG_SNEN; | 37 | R0 = SYSCFG_SNEN; |
@@ -38,76 +39,49 @@ ENTRY(__start) | |||
38 | R0 = SYSCFG_SNEN | SYSCFG_CCEN; | 39 | R0 = SYSCFG_SNEN | SYSCFG_CCEN; |
39 | #endif | 40 | #endif |
40 | SYSCFG = R0; | 41 | SYSCFG = R0; |
41 | R0 = 0; | 42 | |
42 | 43 | /* Optimization register tricks: keep a base value in the | |
43 | /* Clear Out All the data and pointer Registers */ | 44 | * reserved P registers so we use the load/store with an |
44 | R1 = R0; | 45 | * offset syntax. R0 = [P5 + <constant>]; |
45 | R2 = R0; | 46 | * P5 - core MMR base |
46 | R3 = R0; | 47 | * R6 - 0 |
47 | R4 = R0; | 48 | */ |
48 | R5 = R0; | 49 | r6 = 0; |
49 | R6 = R0; | 50 | p5.l = 0; |
50 | 51 | p5.h = hi(COREMMR_BASE); | |
51 | P0 = R0; | 52 | |
52 | P1 = R0; | 53 | /* Zero out registers required by Blackfin ABI */ |
53 | P2 = R0; | 54 | |
54 | P3 = R0; | 55 | /* Disable circular buffers */ |
55 | P4 = R0; | 56 | L0 = r6; |
56 | P5 = R0; | 57 | L1 = r6; |
57 | 58 | L2 = r6; | |
58 | LC0 = r0; | 59 | L3 = r6; |
59 | LC1 = r0; | 60 | |
60 | L0 = r0; | 61 | /* Disable hardware loops in case we were started by 'go' */ |
61 | L1 = r0; | 62 | LC0 = r6; |
62 | L2 = r0; | 63 | LC1 = r6; |
63 | L3 = r0; | ||
64 | |||
65 | /* Clear Out All the DAG Registers */ | ||
66 | B0 = r0; | ||
67 | B1 = r0; | ||
68 | B2 = r0; | ||
69 | B3 = r0; | ||
70 | |||
71 | I0 = r0; | ||
72 | I1 = r0; | ||
73 | I2 = r0; | ||
74 | I3 = r0; | ||
75 | |||
76 | M0 = r0; | ||
77 | M1 = r0; | ||
78 | M2 = r0; | ||
79 | M3 = r0; | ||
80 | 64 | ||
81 | /* | 65 | /* |
82 | * Clear ITEST_COMMAND and DTEST_COMMAND registers, | 66 | * Clear ITEST_COMMAND and DTEST_COMMAND registers, |
83 | * Leaving these as non-zero can confuse the emulator | 67 | * Leaving these as non-zero can confuse the emulator |
84 | */ | 68 | */ |
85 | p0.L = LO(DTEST_COMMAND); | 69 | [p5 + (DTEST_COMMAND - COREMMR_BASE)] = r6; |
86 | p0.H = HI(DTEST_COMMAND); | 70 | [p5 + (ITEST_COMMAND - COREMMR_BASE)] = r6; |
87 | [p0] = R0; | ||
88 | [p0 + (ITEST_COMMAND - DTEST_COMMAND)] = R0; | ||
89 | CSYNC; | 71 | CSYNC; |
90 | 72 | ||
91 | trace_buffer_init(p0,r0); | 73 | trace_buffer_init(p0,r0); |
92 | P0 = R1; | ||
93 | R0 = R1; | ||
94 | 74 | ||
95 | /* Turn off the icache */ | 75 | /* Turn off the icache */ |
96 | p0.l = LO(IMEM_CONTROL); | 76 | r1 = [p5 + (IMEM_CONTROL - COREMMR_BASE)]; |
97 | p0.h = HI(IMEM_CONTROL); | 77 | BITCLR (r1, ENICPLB_P); |
98 | R1 = [p0]; | 78 | [p5 + (IMEM_CONTROL - COREMMR_BASE)] = r1; |
99 | R0 = ~ENICPLB; | ||
100 | R0 = R0 & R1; | ||
101 | [p0] = R0; | ||
102 | SSYNC; | 79 | SSYNC; |
103 | 80 | ||
104 | /* Turn off the dcache */ | 81 | /* Turn off the dcache */ |
105 | p0.l = LO(DMEM_CONTROL); | 82 | r1 = [p5 + (DMEM_CONTROL - COREMMR_BASE)]; |
106 | p0.h = HI(DMEM_CONTROL); | 83 | BITCLR (r1, ENDCPLB_P); |
107 | R1 = [p0]; | 84 | [p5 + (DMEM_CONTROL - COREMMR_BASE)] = r1; |
108 | R0 = ~ENDCPLB; | ||
109 | R0 = R0 & R1; | ||
110 | [p0] = R0; | ||
111 | SSYNC; | 85 | SSYNC; |
112 | 86 | ||
113 | /* in case of double faults, save a few things */ | 87 | /* in case of double faults, save a few things */ |
@@ -122,25 +96,25 @@ ENTRY(__start) | |||
122 | * below | 96 | * below |
123 | */ | 97 | */ |
124 | GET_PDA(p0, r0); | 98 | GET_PDA(p0, r0); |
125 | r6 = [p0 + PDA_DF_RETX]; | 99 | r5 = [p0 + PDA_DF_RETX]; |
126 | p1.l = _init_saved_retx; | 100 | p1.l = _init_saved_retx; |
127 | p1.h = _init_saved_retx; | 101 | p1.h = _init_saved_retx; |
128 | [p1] = r6; | 102 | [p1] = r5; |
129 | 103 | ||
130 | r6 = [p0 + PDA_DF_DCPLB]; | 104 | r5 = [p0 + PDA_DF_DCPLB]; |
131 | p1.l = _init_saved_dcplb_fault_addr; | 105 | p1.l = _init_saved_dcplb_fault_addr; |
132 | p1.h = _init_saved_dcplb_fault_addr; | 106 | p1.h = _init_saved_dcplb_fault_addr; |
133 | [p1] = r6; | 107 | [p1] = r5; |
134 | 108 | ||
135 | r6 = [p0 + PDA_DF_ICPLB]; | 109 | r5 = [p0 + PDA_DF_ICPLB]; |
136 | p1.l = _init_saved_icplb_fault_addr; | 110 | p1.l = _init_saved_icplb_fault_addr; |
137 | p1.h = _init_saved_icplb_fault_addr; | 111 | p1.h = _init_saved_icplb_fault_addr; |
138 | [p1] = r6; | 112 | [p1] = r5; |
139 | 113 | ||
140 | r6 = [p0 + PDA_DF_SEQSTAT]; | 114 | r5 = [p0 + PDA_DF_SEQSTAT]; |
141 | p1.l = _init_saved_seqstat; | 115 | p1.l = _init_saved_seqstat; |
142 | p1.h = _init_saved_seqstat; | 116 | p1.h = _init_saved_seqstat; |
143 | [p1] = r6; | 117 | [p1] = r5; |
144 | #endif | 118 | #endif |
145 | 119 | ||
146 | /* Initialize stack pointer */ | 120 | /* Initialize stack pointer */ |
@@ -155,7 +129,7 @@ ENTRY(__start) | |||
155 | sti r0; | 129 | sti r0; |
156 | #endif | 130 | #endif |
157 | 131 | ||
158 | r0 = 0 (x); | 132 | r0 = r6; |
159 | /* Zero out all of the fun bss regions */ | 133 | /* Zero out all of the fun bss regions */ |
160 | #if L1_DATA_A_LENGTH > 0 | 134 | #if L1_DATA_A_LENGTH > 0 |
161 | r1.l = __sbss_l1; | 135 | r1.l = __sbss_l1; |
@@ -210,11 +184,9 @@ ENTRY(__start) | |||
210 | 184 | ||
211 | /* EVT15 = _real_start */ | 185 | /* EVT15 = _real_start */ |
212 | 186 | ||
213 | p0.l = lo(EVT15); | ||
214 | p0.h = hi(EVT15); | ||
215 | p1.l = _real_start; | 187 | p1.l = _real_start; |
216 | p1.h = _real_start; | 188 | p1.h = _real_start; |
217 | [p0] = p1; | 189 | [p5 + (EVT15 - COREMMR_BASE)] = p1; |
218 | csync; | 190 | csync; |
219 | 191 | ||
220 | #ifdef CONFIG_EARLY_PRINTK | 192 | #ifdef CONFIG_EARLY_PRINTK |