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

5
Last change on this file since f100a58 was f100a58, checked in by Sebastian Huber <sebastian.huber@…>, on Sep 19, 2017 at 12:35:02 PM

bsp/qoriq: Add hypervisor guest SMP support

Update #3085.

  • Property mode set to 100644
File size: 12.5 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 <bsp.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#if defined(QORIQ_INITIAL_HID0) && !defined(QORIQ_IS_HYPERVISOR_GUEST)
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#ifdef QORIQ_IS_HYPERVISOR_GUEST
223        oris    r0, r0, MSR_GS >> 16
224#endif
225        mtmsr   r0
226        isync
227
228        /*
229         * Initialize start stack.  Make sure that we do not share a cache line
230         * with the heap block management, since initial stacks for the
231         * secondary processors are allocated from the workspace.
232         */
233        subi    r1, START_STACK, 2 * PPC_DEFAULT_CACHE_LINE_SIZE
234        clrrwi  r1, r1, PPC_DEFAULT_CACHE_LINE_POWER
235        li      r0, 0
236        PPC_REG_STORE   r0, 0(r1)
237
238#ifdef INITIALIZE_FPU
239        bl      .Linitfpu
240#endif
241
242        mtlr    SAVED_LINK_REGISTER
243        blr
244
245.Linitmmu:
246        mflr    SAVED_LINK_REGISTER
247
248        /* Configure MMU */
249        li      r4, FIRST_TLB
250        li      r5, SCRATCH_TLB
251        bl      qoriq_mmu_config
252        PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
253        mtmsr   INITIAL_MSR
254        isync
255        li      r3, SCRATCH_TLB
256        bl      qoriq_tlb1_invalidate
257        PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
258
259        mtlr    SAVED_LINK_REGISTER
260        blr
261
262#ifdef INITIALIZE_FPU
263        /*
264         * Write a value to the FPRs to initialize the hidden tag bits.  See
265         * also "Core Software Initialization Requirements" of the e500mc
266         * reference manual for example.
267         */
268.Linitfpu:
269        li      r0, 0
270        stw     r0, 0(r1)
271        stw     r0, 4(r1)
272        lfd     f0, 0(r1)
273        fmr     f1, f0
274        fmr     f2, f0
275        fmr     f3, f0
276        fmr     f4, f0
277        fmr     f5, f0
278        fmr     f6, f0
279        fmr     f7, f0
280        fmr     f8, f0
281        fmr     f9, f0
282        fmr     f10, f0
283        fmr     f11, f0
284        fmr     f12, f0
285        fmr     f13, f0
286        fmr     f14, f0
287        fmr     f15, f0
288        fmr     f16, f0
289        fmr     f17, f0
290        fmr     f18, f0
291        fmr     f19, f0
292        fmr     f20, f0
293        fmr     f21, f0
294        fmr     f22, f0
295        fmr     f23, f0
296        fmr     f24, f0
297        fmr     f25, f0
298        fmr     f26, f0
299        fmr     f27, f0
300        fmr     f28, f0
301        fmr     f29, f0
302        fmr     f30, f0
303        fmr     f31, f0
304        blr
305#endif
306
307#ifdef RTEMS_SMP
308#if QORIQ_THREAD_COUNT > 1
309_start_thread:
310        /* Adjust PIR */
311        mfspr   r0, BOOKE_PIR
312        srawi   r0, r0, 2
313        ori     r0, r0, 1
314        mtspr   BOOKE_PIR, r0
315
316        bl      .Linitearly
317
318        /* Initialize start stack */
319        GET_SELF_CPU_CONTROL    r3
320        PPC_REG_LOAD    r3, PER_CPU_INTERRUPT_STACK_HIGH(r3)
321        subi    r1, r3, PPC_MINIMUM_STACK_FRAME_SIZE
322        clrrwi  r1, r1, PPC_STACK_ALIGN_POWER
323        li      r0, 0
324        PPC_REG_STORE   r0, 0(r1)
325
326#ifdef INITIALIZE_FPU
327        bl      .Linitfpu
328#endif
329
330        b       qoriq_start_thread
331        PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
332#endif
333_start_secondary_processor:
334        bl      .Linitearly
335
336        /* Get start stack */
337        mr      START_STACK, r3
338
339        bl      .Linitmore
340        li      r3, 0
341        bl      .Linitmmu
342        b       bsp_start_on_secondary_processor
343        PPC64_NOP_FOR_LINKER_TOC_POINTER_RESTORE
344#endif /* RTEMS_SMP */
345
346#ifdef __powerpc64__
347#define START_NOP_FOR_LINKER_TOC_POINTER_RESTORE nop; nop; nop; nop
348#else
349#define START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
350#endif
351
352        /* Exception vector prologues area */
353        .section ".bsp_start_text", "ax"
354        .align 4
355bsp_exc_vector_base:
356        /* Critical input */
357        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
358        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
359        li      r3, 0
360        b       ppc_exc_fatal_critical
361        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
362        /* Machine check */
363        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
364        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
365        li      r3, 1
366        b       ppc_exc_fatal_machine_check
367        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
368        /* Data storage */
369        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
370        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
371        li      r3, 2
372        b       ppc_exc_fatal_normal
373        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
374        /* Instruction storage */
375        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
376        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
377        li      r3, 3
378        b       ppc_exc_fatal_normal
379        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
380        /* External input */
381        PPC_REG_STORE_UPDATE    r1, -PPC_EXC_INTERRUPT_FRAME_SIZE(r1)
382        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
383        li      r3, 4
384        b       ppc_exc_interrupt
385        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
386        /* Alignment */
387        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
388        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
389        li      r3, 5
390        b       ppc_exc_fatal_normal
391        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
392        /* Program */
393        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
394        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
395        li      r3, 6
396        b       ppc_exc_fatal_normal
397        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
398#ifdef __PPC_CPU_E6500__
399        /* Floating-point unavailable */
400        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
401        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
402        li      r3, 7
403        b       ppc_exc_fatal_normal
404        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
405#endif
406        /* System call */
407        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
408        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
409        li      r3, 8
410        b       ppc_exc_fatal_normal
411        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
412#ifdef __PPC_CPU_E6500__
413        /* APU unavailable */
414        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
415        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
416        li      r3, 9
417        b       ppc_exc_fatal_normal
418        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
419#endif
420        /* Decrementer */
421#ifdef QORIQ_IS_HYPERVISOR_GUEST
422        PPC_REG_STORE_UPDATE    r1, -PPC_EXC_INTERRUPT_FRAME_SIZE(r1)
423#else
424        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
425#endif
426        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
427        li      r3, 10
428#ifdef QORIQ_IS_HYPERVISOR_GUEST
429        b       ppc_exc_interrupt
430#else
431        b       ppc_exc_fatal_normal
432#endif
433        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
434        /* Fixed-interval timer interrupt */
435        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
436        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
437        li      r3, 11
438        b       ppc_exc_fatal_normal
439        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
440        /* Watchdog timer interrupt */
441        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
442        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
443        li      r3, 12
444        b       ppc_exc_fatal_critical
445        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
446        /* Data TLB error */
447        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
448        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
449        li      r3, 13
450        b       ppc_exc_fatal_normal
451        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
452        /* Instruction TLB error */
453        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
454        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
455        li      r3, 14
456        b       ppc_exc_fatal_normal
457        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
458        /* Debug */
459        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
460        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
461        li      r3, 15
462        b       ppc_exc_fatal_debug
463        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
464        /* SPE APU unavailable or AltiVec unavailable */
465        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
466        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
467        li      r3, 32
468        b       ppc_exc_fatal_normal
469        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
470        /* SPE floating-point data exception or AltiVec assist */
471        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
472        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
473        li      r3, 33
474        b       ppc_exc_fatal_normal
475        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
476#ifndef __PPC_CPU_E6500__
477        /* SPE floating-point round exception */
478        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
479        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
480        li      r3, 34
481        b       ppc_exc_fatal_normal
482        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
483#endif
484        /* Performance monitor */
485        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
486        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
487        li      r3, 35
488        b       ppc_exc_fatal_normal
489        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
490#ifdef __PPC_CPU_E6500__
491        /* Processor doorbell interrupt */
492#if defined(QORIQ_IS_HYPERVISOR_GUEST) && defined(RTEMS_SMP)
493        PPC_REG_STORE_UPDATE    r1, -PPC_EXC_INTERRUPT_FRAME_SIZE(r1)
494#else
495        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
496#endif
497        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
498        li      r3, 36
499#if defined(QORIQ_IS_HYPERVISOR_GUEST) && defined(RTEMS_SMP)
500        b       ppc_exc_interrupt
501#else
502        b       ppc_exc_fatal_normal
503#endif
504        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
505        /* Processor doorbell critical interrupt */
506        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
507        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
508        li      r3, 37
509        b       ppc_exc_fatal_critical
510        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
511        /* Guest processor doorbell */
512        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
513        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
514        li      r3, 38
515        b       ppc_exc_fatal_normal
516        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
517        /* Guest processor doorbell critical and machine check */
518        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
519        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
520        li      r3, 39
521        b       ppc_exc_fatal_critical
522        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
523        /* Hypervisor system call */
524        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
525        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
526        li      r3, 40
527        b       ppc_exc_fatal_normal
528        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
529        /* Hypervisor privilege */
530        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
531        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
532        li      r3, 41
533        b       ppc_exc_fatal_normal
534        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
535        /* LRAT error */
536        PPC_REG_STORE_UPDATE    r1, -EXC_GENERIC_SIZE(r1)
537        PPC_REG_STORE   r3, GPR3_OFFSET(r1)
538        li      r3, 42
539        b       ppc_exc_fatal_normal
540        START_NOP_FOR_LINKER_TOC_POINTER_RESTORE
541#endif
542
543/* Symbol provided for debugging and tracing */
544bsp_exc_vector_end:
545
546        /* Start stack area */
547        .section ".bsp_rwextra", "aw", @nobits
548        .align 4
549        .space 4096
550start_stack_end:
Note: See TracBrowser for help on using the repository browser.