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

5
Last change on this file since 0ce5bfb was 0ce5bfb, checked in by Sebastian Huber <sebastian.huber@…>, on 09/08/17 at 08:50:08

bsp/qoriq: Do not touch MMU as hypervisor guest

Update #3085.

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