diff options
Diffstat (limited to 'arch/blackfin/kernel/setup.c')
-rw-r--r-- | arch/blackfin/kernel/setup.c | 51 |
1 files changed, 28 insertions, 23 deletions
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index a58687bdee6a..0838eafed172 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c | |||
@@ -150,40 +150,45 @@ void __init bfin_relocate_l1_mem(void) | |||
150 | unsigned long l1_data_b_length; | 150 | unsigned long l1_data_b_length; |
151 | unsigned long l2_length; | 151 | unsigned long l2_length; |
152 | 152 | ||
153 | /* | ||
154 | * due to the ALIGN(4) in the arch/blackfin/kernel/vmlinux.lds.S | ||
155 | * we know that everything about l1 text/data is nice and aligned, | ||
156 | * so copy by 4 byte chunks, and don't worry about overlapping | ||
157 | * src/dest. | ||
158 | * | ||
159 | * We can't use the dma_memcpy functions, since they can call | ||
160 | * scheduler functions which might be in L1 :( and core writes | ||
161 | * into L1 instruction cause bad access errors, so we are stuck, | ||
162 | * we are required to use DMA, but can't use the common dma | ||
163 | * functions. We can't use memcpy either - since that might be | ||
164 | * going to be in the relocated L1 | ||
165 | */ | ||
166 | |||
153 | blackfin_dma_early_init(); | 167 | blackfin_dma_early_init(); |
154 | 168 | ||
169 | /* if necessary, copy _stext_l1 to _etext_l1 to L1 instruction SRAM */ | ||
155 | l1_code_length = _etext_l1 - _stext_l1; | 170 | l1_code_length = _etext_l1 - _stext_l1; |
156 | if (l1_code_length > L1_CODE_LENGTH) | 171 | if (l1_code_length) |
157 | panic("L1 Instruction SRAM Overflow\n"); | 172 | early_dma_memcpy(_stext_l1, _l1_lma_start, l1_code_length); |
158 | /* cannot complain as printk is not available as yet. | ||
159 | * But we can continue booting and complain later! | ||
160 | */ | ||
161 | |||
162 | /* Copy _stext_l1 to _etext_l1 to L1 instruction SRAM */ | ||
163 | dma_memcpy(_stext_l1, _l1_lma_start, l1_code_length); | ||
164 | 173 | ||
174 | /* if necessary, copy _sdata_l1 to _sbss_l1 to L1 data bank A SRAM */ | ||
165 | l1_data_a_length = _sbss_l1 - _sdata_l1; | 175 | l1_data_a_length = _sbss_l1 - _sdata_l1; |
166 | if (l1_data_a_length > L1_DATA_A_LENGTH) | 176 | if (l1_data_a_length) |
167 | panic("L1 Data SRAM Bank A Overflow\n"); | 177 | early_dma_memcpy(_sdata_l1, _l1_lma_start + l1_code_length, l1_data_a_length); |
168 | |||
169 | /* Copy _sdata_l1 to _sbss_l1 to L1 data bank A SRAM */ | ||
170 | dma_memcpy(_sdata_l1, _l1_lma_start + l1_code_length, l1_data_a_length); | ||
171 | 178 | ||
179 | /* if necessary, copy _sdata_b_l1 to _sbss_b_l1 to L1 data bank B SRAM */ | ||
172 | l1_data_b_length = _sbss_b_l1 - _sdata_b_l1; | 180 | l1_data_b_length = _sbss_b_l1 - _sdata_b_l1; |
173 | if (l1_data_b_length > L1_DATA_B_LENGTH) | 181 | if (l1_data_b_length) |
174 | panic("L1 Data SRAM Bank B Overflow\n"); | 182 | early_dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length + |
175 | |||
176 | /* Copy _sdata_b_l1 to _sbss_b_l1 to L1 data bank B SRAM */ | ||
177 | dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length + | ||
178 | l1_data_a_length, l1_data_b_length); | 183 | l1_data_a_length, l1_data_b_length); |
179 | 184 | ||
185 | early_dma_memcpy_done(); | ||
186 | |||
187 | /* if necessary, copy _stext_l2 to _edata_l2 to L2 SRAM */ | ||
180 | if (L2_LENGTH != 0) { | 188 | if (L2_LENGTH != 0) { |
181 | l2_length = _sbss_l2 - _stext_l2; | 189 | l2_length = _sbss_l2 - _stext_l2; |
182 | if (l2_length > L2_LENGTH) | 190 | if (l2_length) |
183 | panic("L2 SRAM Overflow\n"); | 191 | memcpy(_stext_l2, _l2_lma_start, l2_length); |
184 | |||
185 | /* Copy _stext_l2 to _edata_l2 to L2 SRAM */ | ||
186 | dma_memcpy(_stext_l2, _l2_lma_start, l2_length); | ||
187 | } | 192 | } |
188 | } | 193 | } |
189 | 194 | ||