source: rtems/c/src/lib/libbsp/powerpc/qoriq/start/start.S @ c693a3a

5
Last change on this file since c693a3a was c693a3a, checked in by Sebastian Huber <sebastian.huber@…>, on 08/11/17 at 08:44:04

powerpc: PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE

In 64-bit mode, the linker must have the ability to restore the TOC
pointer after an external function call.

Update #3082.

  • Property mode set to 100644
File size: 12.0 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup qoriq
5 *
6 * @brief BSP start.
7 */
8
9/*
10 * Copyright (c) 2010, 2017 embedded brains GmbH.  All rights reserved.
11 *
12 *  embedded brains GmbH
13 *  Dornierstr. 4
14 *  82178 Puchheim
15 *  Germany
16 *  <rtems@embedded-brains.de>
17 *
18 * The license and distribution terms for this file may be
19 * found in the file LICENSE in this distribution or at
20 * http://www.rtems.org/license/LICENSE.
21 */
22
23#include <rtems/score/percpu.h>
24
25#include <bspopts.h>
26
27#include <libcpu/powerpc-utility.h>
28
29#include <bsp/vectors.h>
30
31#if (QORIQ_INITIAL_MSR & MSR_FP) != 0
32#define INITIALIZE_FPU
33#endif
34
35#define FIRST_TLB 0
36#define SCRATCH_TLB QORIQ_TLB1_ENTRY_COUNT - 1
37#define INITIAL_MSR r14
38#define START_STACK r15
39#define SAVED_LINK_REGISTER r16
40#define FDT_REGISTER r17
41
42        .globl _start
43#ifdef RTEMS_SMP
44#if QORIQ_THREAD_COUNT > 1
45        .globl _start_thread
46#endif
47        .globl _start_secondary_processor
48#endif
49        .globl bsp_exc_vector_base
50
51        .section ".bsp_start_text", "ax"
52
53_start:
54        mr      FDT_REGISTER, r3
55        bl      .Linitearly
56
57        /* Get start stack */
58        LA      START_STACK, start_stack_end
59
60        bl      .Linitmore
61
62        /* Copy fast text */
63        LA      r3, bsp_section_fast_text_begin
64        LA      r4, bsp_section_fast_text_load_begin
65        LA      r5, bsp_section_fast_text_size
66        bl      .Lcopy
67        LA      r3, bsp_section_fast_text_begin
68        LA      r4, bsp_section_fast_text_size
69        bl      rtems_cache_flush_multiple_data_lines
70        PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
71
72        /* Copy read-only data */
73        LA      r3, bsp_section_rodata_begin
74        LA      r4, bsp_section_rodata_load_begin
75        LA      r5, bsp_section_rodata_size
76        bl      .Lcopy
77
78        /* Copy FDT into read-only data */
79        mr      r3, FDT_REGISTER
80        bl      bsp_fdt_copy
81        PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
82
83        /* Flush read-only data */
84        LA      r3, bsp_section_rodata_begin
85        LA      r4, bsp_section_rodata_size
86        bl      rtems_cache_flush_multiple_data_lines
87        PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
88
89        /* Copy fast data */
90        LA      r3, bsp_section_fast_data_begin
91        LA      r4, bsp_section_fast_data_load_begin
92        LA      r5, bsp_section_fast_data_size
93        bl      .Lcopy
94
95        /* Copy data */
96        LA      r3, bsp_section_data_begin
97        LA      r4, bsp_section_data_load_begin
98        LA      r5, bsp_section_data_size
99        bl      .Lcopy
100
101        /* NULL pointer access protection (only core 0 has to do this) */
102        mfspr   r3, BOOKE_PIR
103        cmpwi   r3, 0
104        bne     .Lnull_area_setup_done
105        LA      r3, bsp_section_start_begin
106        srawi   r3, r3, 2
107        mtctr   r3
108        li      r3, -4
109        LWI     r4, 0x44000002
110.Lnull_area_setup_loop:
111        stwu    r4, 4(r3)
112        bdnz    .Lnull_area_setup_loop
113.Lnull_area_setup_done:
114
115        li      r3, 1
116        bl      .Linitmmu
117
118        /* Clear SBSS */
119        LA      r3, bsp_section_sbss_begin
120        LA      r4, bsp_section_sbss_size
121        bl      bsp_start_zero
122        PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
123
124        /* Clear BSS */
125        LA      r3, bsp_section_bss_begin
126        LA      r4, bsp_section_bss_size
127        bl      bsp_start_zero
128        PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
129
130#ifndef __powerpc64__
131        /* Set up EABI and SYSV environment */
132        bl      __eabi
133#endif
134
135        /* Clear command line */
136        li      r3, 0
137
138        bl      boot_card
139        PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
140
141.Lcopy:
142        PPC_REG_CMP     r3, r4
143        beqlr
144        b       memcpy
145        PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
146
147.Linitearly:
148#ifdef __powerpc64__
149        /* Enable 64-bit computation mode for exceptions */
150        mfspr   r0, BOOKE_EPCR
151        oris    r0, r0, BOOKE_EPCR_ICM >> 16
152        mtspr   BOOKE_EPCR, r0
153
154        /* Enable 64-bit computation mode */
155        mfmsr   r0
156        oris    r0, r0, MSR_CM >> 16
157        mtmsr   r0
158        isync
159#endif
160
161        /* Disable decrementer */
162        mfspr   r0, BOOKE_TCR
163        LWI     r4, BOOKE_TCR_DIE
164        andc    r0, r0, r4
165        mtspr   BOOKE_TCR, r0
166
167#ifdef QORIQ_INITIAL_SPEFSCR
168        /* SPEFSCR initialization */
169        LWI     r0, QORIQ_INITIAL_SPEFSCR
170        mtspr   FSL_EIS_SPEFSCR, r0
171#endif
172
173#ifdef QORIQ_INITIAL_BUCSR
174        /* BUCSR initialization */
175        LWI     r0, QORIQ_INITIAL_BUCSR
176        mtspr   FSL_EIS_BUCSR, r0
177        isync
178#endif
179
180#ifdef QORIQ_INITIAL_HID0
181        /* HID0 initialization */
182        LWI     r0, QORIQ_INITIAL_HID0
183        mtspr   HID0, r0
184#endif
185
186#ifdef __powerpc64__
187        LA32    r2, .TOC.
188#else
189        /* Invalidate TLS anchor */
190        li      r2, 0
191
192        /* Set small-data anchor */
193        LA      r13, _SDA_BASE_
194#endif
195
196        SET_SELF_CPU_CONTROL    r4, r5
197
198        blr
199
200.Linitmore:
201        mflr    SAVED_LINK_REGISTER
202
203        /* Invalidate all TS1 MMU entries */
204        li      r3, 1
205        bl      qoriq_tlb1_invalidate_all_by_ts
206        PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
207
208        /* Add TS1 entry for the first 4GiB of RAM */
209        li      r3, SCRATCH_TLB
210        li      r4, FSL_EIS_MAS1_TS
211        li      r5, FSL_EIS_MAS2_M
212        li      r6, FSL_EIS_MAS3_SR | FSL_EIS_MAS3_SW | FSL_EIS_MAS3_SX
213        li      r7, 0
214        li      r8, 0
215        li      r9, 11
216        bl      qoriq_tlb1_write
217        PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
218
219        /* MSR initialization and use TS1 for address translation */
220        LWI     INITIAL_MSR, QORIQ_INITIAL_MSR
221        ori     r0, INITIAL_MSR, MSR_IS | MSR_DS
222        mtmsr   r0
223        isync
224
225        /*
226         * Initialize start stack.  Make sure that we do not share a cache line
227         * with the heap block management, since initial stacks for the
228         * secondary processors are allocated from the workspace.
229         */
230        subi    r1, START_STACK, 2 * PPC_DEFAULT_CACHE_LINE_SIZE
231        clrrwi  r1, r1, PPC_DEFAULT_CACHE_LINE_POWER
232        li      r0, 0
233        PPC_REG_STORE   r0, 0(r1)
234
235#ifdef INITIALIZE_FPU
236        bl      .Linitfpu
237#endif
238
239        mtlr    SAVED_LINK_REGISTER
240        blr
241
242.Linitmmu:
243        mflr    SAVED_LINK_REGISTER
244
245        /* Configure MMU */
246        li      r4, FIRST_TLB
247        li      r5, SCRATCH_TLB
248        bl      qoriq_mmu_config
249        PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
250        mtmsr   INITIAL_MSR
251        isync
252        li      r3, SCRATCH_TLB
253        bl      qoriq_tlb1_invalidate
254        PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
255
256        mtlr    SAVED_LINK_REGISTER
257        blr
258
259#ifdef INITIALIZE_FPU
260        /*
261         * Write a value to the FPRs to initialize the hidden tag bits.  See
262         * also "Core Software Initialization Requirements" of the e500mc
263         * reference manual for example.
264         */
265.Linitfpu:
266        li      r0, 0
267        stw     r0, 0(r1)
268        stw     r0, 4(r1)
269        lfd     f0, 0(r1)
270        fmr     f1, f0
271        fmr     f2, f0
272        fmr     f3, f0
273        fmr     f4, f0
274        fmr     f5, f0
275        fmr     f6, f0
276        fmr     f7, f0
277        fmr     f8, f0
278        fmr     f9, f0
279        fmr     f10, f0
280        fmr     f11, f0
281        fmr     f12, f0
282        fmr     f13, f0
283        fmr     f14, f0
284        fmr     f15, f0
285        fmr     f16, f0
286        fmr     f17, f0
287        fmr     f18, f0
288        fmr     f19, f0
289        fmr     f20, f0
290        fmr     f21, f0
291        fmr     f22, f0
292        fmr     f23, f0
293        fmr     f24, f0
294        fmr     f25, f0
295        fmr     f26, f0
296        fmr     f27, f0
297        fmr     f28, f0
298        fmr     f29, f0
299        fmr     f30, f0
300        fmr     f31, f0
301        blr
302#endif
303
304#ifdef RTEMS_SMP
305#if QORIQ_THREAD_COUNT > 1
306_start_thread:
307        /* Adjust PIR */
308        mfspr   r0, BOOKE_PIR
309        srawi   r0, r0, 2
310        ori     r0, r0, 1
311        mtspr   BOOKE_PIR, r0
312
313        bl      .Linitearly
314
315        /* Initialize start stack */
316        GET_SELF_CPU_CONTROL    r3
317        PPC_REG_LOAD    r3, PER_CPU_INTERRUPT_STACK_HIGH(r3)
318        subi    r1, r3, PPC_MINIMUM_STACK_FRAME_SIZE
319        clrrwi  r1, r1, PPC_STACK_ALIGN_POWER
320        li      r0, 0
321        PPC_REG_STORE   r0, 0(r1)
322
323#ifdef INITIALIZE_FPU
324        bl      .Linitfpu
325#endif
326
327        b       qoriq_start_thread
328        PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
329#endif
330_start_secondary_processor:
331        bl      .Linitearly
332
333        /* Get start stack */
334        mr      START_STACK, r3
335
336        bl      .Linitmore
337        li      r3, 0
338        bl      .Linitmmu
339        b       bsp_start_on_secondary_processor
340        PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
341#endif /* RTEMS_SMP */
342
343#ifdef __powerpc64__
344#define START_NOP_FOR_LINKER_TOC_POINTER_RESTORE nop; nop; nop; nop
345#else
346#define START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
347#endif
348
349        /* Exception vector prologues area */
350        .section ".bsp_start_text", "ax"
351        .align 4
352bsp_exc_vector_base:
353        /* Critical input */
354        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
355        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
356        li      r3, 0
357        b       ppc_exc_fatal_critical
358        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
359        /* Machine check */
360        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
361        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
362        li      r3, 1
363        b       ppc_exc_fatal_machine_check
364        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
365        /* Data storage */
366        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
367        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
368        li      r3, 2
369        b       ppc_exc_fatal_normal
370        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
371        /* Instruction storage */
372        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
373        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
374        li      r3, 3
375        b       ppc_exc_fatal_normal
376        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
377        /* External input */
378        PPC_REG_STORE_UPDATE    r1, -PPC_EXC_INTERRUPT_FRAME_SIZE(r1)
379        b       ppc_exc_interrupt
380        nop
381        nop
382        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
383        /* Alignment */
384        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
385        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
386        li      r3, 5
387        b       ppc_exc_fatal_normal
388        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
389        /* Program */
390        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
391        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
392        li      r3, 6
393        b       ppc_exc_fatal_normal
394        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
395#ifdef __PPC_CPU_E6500__
396        /* Floating-point unavailable */
397        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
398        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
399        li      r3, 7
400        b       ppc_exc_fatal_normal
401        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
402#endif
403        /* System call */
404        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
405        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
406        li      r3, 8
407        b       ppc_exc_fatal_normal
408        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
409#ifdef __PPC_CPU_E6500__
410        /* APU unavailable */
411        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
412        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
413        li      r3, 9
414        b       ppc_exc_fatal_normal
415        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
416#endif
417        /* Decrementer */
418        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
419        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
420        li      r3, 10
421        b       ppc_exc_fatal_normal
422        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
423        /* Fixed-interval timer interrupt */
424        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
425        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
426        li      r3, 11
427        b       ppc_exc_fatal_normal
428        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
429        /* Watchdog timer interrupt */
430        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
431        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
432        li      r3, 12
433        b       ppc_exc_fatal_critical
434        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
435        /* Data TLB error */
436        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
437        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
438        li      r3, 13
439        b       ppc_exc_fatal_normal
440        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
441        /* Instruction TLB error */
442        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
443        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
444        li      r3, 14
445        b       ppc_exc_fatal_normal
446        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
447        /* Debug */
448        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
449        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
450        li      r3, 15
451        b       ppc_exc_fatal_debug
452        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
453        /* SPE APU unavailable or AltiVec unavailable */
454        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
455        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
456        li      r3, 32
457        b       ppc_exc_fatal_normal
458        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
459        /* SPE floating-point data exception or AltiVec assist */
460        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
461        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
462        li      r3, 33
463        b       ppc_exc_fatal_normal
464        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
465#ifndef __PPC_CPU_E6500__
466        /* SPE floating-point round exception */
467        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
468        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
469        li      r3, 34
470        b       ppc_exc_fatal_normal
471        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
472#endif
473        /* Performance monitor */
474        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
475        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
476        li      r3, 35
477        b       ppc_exc_fatal_normal
478        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
479#ifdef __PPC_CPU_E6500__
480        /* Processor doorbell interrupt */
481        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
482        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
483        li      r3, 36
484        b       ppc_exc_fatal_normal
485        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
486        /* Processor doorbell critical interrupt */
487        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
488        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
489        li      r3, 37
490        b       ppc_exc_fatal_critical
491        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
492        /* Guest processor doorbell */
493        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
494        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
495        li      r3, 38
496        b       ppc_exc_fatal_normal
497        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
498        /* Guest processor doorbell critical and machine check */
499        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
500        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
501        li      r3, 39
502        b       ppc_exc_fatal_critical
503        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
504        /* Hypervisor system call */
505        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
506        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
507        li      r3, 40
508        b       ppc_exc_fatal_normal
509        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
510        /* Hypervisor privilege */
511        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
512        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
513        li      r3, 41
514        b       ppc_exc_fatal_normal
515        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
516        /* LRAT error */
517        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
518        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
519        li      r3, 42
520        b       ppc_exc_fatal_normal
521        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
522#endif
523
524/* Symbol provided for debugging and tracing */
525bsp_exc_vector_end:
526
527        /* Start stack area */
528        .section ".bsp_rwextra", "aw", @nobits
529        .align 4
530        .space 4096
531start_stack_end:
Note: See TracBrowser for help on using the repository browser.