Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:59

0001 /*!@file
0002 *
0003 *  @brief     Initialization code to set up the CPU and call boot_card()
0004 *
0005 *  This "BSP" targets the Xilinx Virtex XC4VFX60 and related parts.  This
0006 *  BSP makes no assumptions on what firmware is loaded into the FPGA.
0007 *
0008 *  Provides the .entry section code. This is the first code to run in
0009 *  the PPC after download to RAM.   Excecution in this case starts at
0010 *  'download_entry'.
0011 *
0012 *  The entrypoint 'start' is provided for the case where a bootloader has
0013 *  initialized the CPU, and all that remains to do is to set up a C
0014 *  environment and call boot_card.
0015 *
0016 *  Derived from virtex dlentry and others.
0017 *
0018 *  IBM refers to the version of the processor as PPC405F5.
0019 *  The processor version register returns 0x20011470.
0020 *  References:
0021 *      PowerPC Processor Reference Guide UG011 (v1.3)
0022 *      http://www.xilinx.com/support/documentation/user_guides/ug011.pdf
0023 *
0024 *      PowerPC Block Reference Guide
0025 *      http://www.xilinx.com/support/documentation/user_guides/ug018.pdf
0026 *
0027 *      PowerPC errata
0028 *      ftp://ftp.xilinx.com/pub/documentation/misc/ppc405f6v5_2_0.pdf
0029 *
0030 *      PowerPC 405-S Embedded Processor Core User's Manual (Version 1.2)
0031 *      https://www-01.ibm.com/chips/techlib/techlib.nsf/products/PowerPC_405_Embedded_Cores
0032 *
0033 *  @author    Richard Claus <claus@SLAC.Stanford.edu>
0034 *
0035 *  @date      March 4, 2011 -- Created
0036 *
0037 *  $Revision: 674 $
0038 *
0039 *  @verbatim                    Copyright 2011
0040 *                                      by
0041 *                         The Board of Trustees of the
0042 *                       Leland Stanford Junior University.
0043 *                              All rights reserved.
0044 *
0045 *         Work supported by the U.S. Department of Energy under contract
0046 *       DE-AC03-76SF00515.
0047 *
0048 *                               Disclaimer Notice
0049 *
0050 *        The items furnished herewith were developed under the sponsorship
0051 *   of the U.S. Government.  Neither the U.S., nor the U.S. D.O.E., nor the
0052 *   Leland Stanford Junior University, nor their employees, makes any war-
0053 *   ranty, express or implied, or assumes any liability or responsibility
0054 *   for accuracy, completeness or usefulness of any information, apparatus,
0055 *   product or process disclosed, or represents that its use will not in-
0056 *   fringe privately-owned rights.  Mention of any product, its manufactur-
0057 *   er, or suppliers shall not, nor is it intended to, imply approval, dis-
0058 *   approval, or fitness for any particular use.  The U.S. and the Univer-
0059 *   sity at all times retain the right to use and disseminate the furnished
0060 *   items for any purpose whatsoever.                       Notice 91 02 01
0061 *
0062 *  @endverbatim
0063 */
0064 
0065 #include <rtems/asm.h>
0066 #include <rtems/powerpc/powerpc.h>
0067 
0068 /*
0069  *  The virtex ELF link scripts support some special sections:
0070  *    .entry    The actual entry point
0071  *    .vectors  The section containing the interrupt entry veneers.
0072  */
0073 
0074 /*
0075  *  Downloaded code loads the vectors separately to 0x00000100,
0076  *  so .entry can be over 256 bytes.
0077  *
0078  *  The other sections are linked in the following order:
0079  *    .entry
0080  *    .text
0081  *    .data
0082  *    .bss
0083  *  see linker command file for section placement
0084  *
0085  *  The initial stack is set to _ISR_Stack_area_end.
0086  *
0087  */
0088 
0089         .section .entry
0090 
0091         PUBLIC_VAR (download_entry)
0092         PUBLIC_VAR (__rtems_entry_point)
0093 SYM(download_entry):
0094 SYM(__rtems_entry_point):
0095         b       startupDow        /* Entry point used by xmd dow command */
0096 
0097         PUBLIC_VAR (start)
0098 SYM(start):
0099         b       startupBL         /* Entry point used by bootLoader */
0100 
0101 base_addr:
0102        /*-------------------------------------------------------------------
0103         * Parameters from linker
0104         *-----------------------------------------------------------------*/
0105 toc_pointer:
0106         .long   __got_start
0107 bss_length:
0108         .long   __bss_size
0109 bss_addr:
0110         .long   __bss_start
0111 stack_top:
0112         .long   _ISR_Stack_area_end
0113 dccr_contents:
0114         .long   __dccr
0115 iccr_contents:
0116         .long   __iccr
0117 sgr_contents:
0118         .long   __sgr
0119 
0120        /*-------------------------------------------------------------------
0121         * Setup iccr, sgr, msr, cccr0, dcwr, dccr and clear bss
0122         *-----------------------------------------------------------------*/
0123 
0124 startupDow:
0125        /*-------------------------------------------------------------------
0126         * Load the parameter table base address
0127         *------------------------------------------------------------------*/
0128         lis     r1,   base_addr@h
0129         ori     r1,r1,base_addr@l
0130 
0131        /* -------------------------------------------------------------------
0132         * Clear the Machine State Register's Critical and External
0133         * interrupt enables.
0134         *------------------------------------------------------------------*/
0135         mfmsr   r3
0136         lis     r0,   0x00028000@h
0137         ori     r0,r0,0x00028000@l
0138         andc    r3,r3,r0
0139         mtmsr   r3
0140         sync
0141 
0142        /* -------------------------------------------------------------------
0143         * Initialize the memory system.
0144         *------------------------------------------------------------------*/
0145         li      r0,0
0146 
0147         /* Set the Storage Guarded Register. */
0148         lwz     r2,sgr_contents-base_addr(r1)
0149         mtsgr   r2
0150 
0151         /* Configure endianness, compression */
0152         lis     r0,0x00000000@h   // Endianess value
0153         mtsler  r0
0154         lis     r0,0x00000000@h   // Compression value
0155         mtsu0r  r0
0156 
0157         /* Invalidate the entire instruction cache. */
0158         iccci   r0,r0
0159 
0160         /* Set the Instruction Cache Cacheability Register. */
0161         lwz     r2,iccr_contents-base_addr(r1)
0162         mticcr  r2
0163         isync
0164 
0165        /*-------------------------------------------------------------------
0166         * Tell the processor where the exception vector table will be.
0167         *------------------------------------------------------------------*/
0168         .extern SYM(__vectors)
0169         lis     r2, __vectors@h    /* set EVPR exc. vector prefix */
0170         mtevpr  r2
0171 
0172        /*-------------------------------------------------------------------
0173         * Set up the debug register to freeze timers on debug events.
0174         *------------------------------------------------------------------*/
0175         mfdbcr0 r2
0176         ori     r2,r2,0x0001
0177         mtdbcr0 r2
0178         isync
0179 
0180         /* Select whether APU, Wait Enable, interrupts/exceptions and address
0181            translation should be enabled when application starts */
0182         lis     r0,0x00000000@h   /* SRR1 value */
0183         mtsrr1  r0                /* Potentially: 0x80000000 >> 6 is APU */
0184 
0185         /* Configure timer facilities */
0186         mttbl   r0                /* Clear Timebase to prevent Fixed Interval.. */
0187         mttbu   r0                /* ..timer and Watchdog Timer exceptions */
0188         mtpit   r0                /* Programmable interval timer */
0189         li      r2,-1             /* -1 to clear TSR */
0190         mttsr   r2                /* Timer status register */
0191 
0192         /* Clear out stale values in certain registers to avoid confusion */
0193         mtcrf   0xff,r0           /* Need for simulation */
0194         mtctr   r0                /* Counter register */
0195         mtxer   r0                /* Fixed-point exception register */
0196         mtesr   r0                /* Exception syndrome register */
0197         mtdear  r0                /* Data exception address register */
0198         mtmcsr  r0                /* Machine check syndrome register */
0199 
0200         /* Invalidate the data cache */
0201         li      r2,0              /* Start address */
0202         li      r3,0x100          /* Number of cache lines */
0203         mtctr   r3                /* Transfer data cache congruence class count to CTR */
0204 1:      dccci   0,r2              /* Invalidate this congruence class */
0205         addi    r2,r2,0x20        /* Point to next congruence class */
0206         bdnz    1b                /* Decrement counter and loop whilst not zero */
0207 
0208        /* -------------------------------------------------------------------
0209         * Set Core Configuration Register 0 as follows:
0210         * sum: 0x02700E00
0211         * bit 1 off:   as told by ppc405 errata to avoid CPU_213 ppc bug
0212         * bit 3 off:   as told by ppc405 errata to avoid CPU_213 ppc bug
0213                        (Note added later: PPC405F6 is not subject to CPU_213.)
0214         * bit 1 on:    Xilinx: CR 203746 Patch for PPC405 errata (RiC 12/8/11)
0215         * bit 2 on:    Xilinx: CR 203746 Patch for PPC405 errata (RiC 12/8/11)
0216         * bit 6 on:    load word as line
0217         * bit 7 off:   load  misses allocate cache line
0218         * bit 8 off:   store misses allocate cache line
0219         * bit 9-11 on: default settings to do with plb priority
0220         * bit 20 on:   prefetching for cacheable regions
0221         * bit 21 on:   prefetching for non-cacheable regions
0222         * bit 22 on:   request size of non-cacheable inst fetches is 8 words
0223         * bit 23 off:  fetch misses allocate cache line
0224         *------------------------------------------------------------------*/
0225         lis     r5,   0x52700E00@h
0226         ori     r5,r5,0x52700E00@l
0227 
0228        /* -------------------------------------------------------------------
0229         * To change CCR0 we make sure the code writing to it is
0230         *  running from the I-cache. This is needed because changing some
0231         * CCR0 fields will cause a hang if the processor is trying to
0232         * access memory at the same time.
0233         *------------------------------------------------------------------*/
0234         lis     r4,   2f@h
0235         ori     r4,r4,2f@l
0236         icbt    r0,r4
0237         b       2f
0238 
0239         .align  5 /* New cache line (32 bytes each) */
0240 2:
0241         icbt    r0,r4       /* Put this line into the I-cache. */
0242         isync
0243         mtccr0  r5
0244         isync
0245         b       3f
0246 
0247         .align  5
0248 3:
0249         /* Set the Data Cache Write-Through Register for no write-through, i.e., for write-back. */
0250         li      r0,0
0251         mtdcwr  r0
0252 
0253         /* Set the Data Cache Cacheablility Register. */
0254         lwz     r0,dccr_contents-base_addr(r1)
0255         mtdccr  r0
0256         isync
0257 
0258        /* Fall through */
0259 
0260 
0261        /* -------------------------------------------------------------------
0262         * If a bootloader has run that has already performed some
0263         * initialization, which among other things has loaded
0264         * this code into memory and jumped to start above, the initialization
0265         * above does not need to be done.  Execution thus resumes here.
0266         *------------------------------------------------------------------*/
0267 
0268 startupBL:
0269        /* -------------------------------------------------------------------
0270         * Note that some initialization has already been performed by the
0271         * bootloader code in Block RAM, which among other things has loaded
0272         * this code into memory and jumped to start above.
0273         *------------------------------------------------------------------*/
0274 
0275        /*-------------------------------------------------------------------
0276         * Load the parameter table base address
0277         *------------------------------------------------------------------*/
0278         lis     r1,   base_addr@h
0279         ori     r1,r1,base_addr@l
0280 
0281        /*-------------------------------------------------------------------
0282         * Setup stack for RTEMS and call boot_card(). From this
0283         * point forward registers will be used in accordance with the
0284         * PowerPC EABI.
0285         *
0286         * boot_card() supervises the initialization of RTEMS and the C
0287         * library.  It calls bsp_start(), etc.
0288         *------------------------------------------------------------------*/
0289         lwz     r2,toc_pointer-base_addr(r1)        /* set r2 to toc */
0290         lwz     r1,stack_top-base_addr(r1)          /* set r1 to stack_top */
0291 
0292         /* Align as required by ABI */
0293         li      r3,PPC_STACK_ALIGNMENT-1
0294         andc    r1,r1,r3
0295 
0296        /*-------------------------------------------------------------------
0297         * Set up r2 and r13. Upon entry r1 must have a nonzero value
0298         *  as it will be stored in an "init done" flag. Stupid but true.
0299         *  r1 must also be set up as a stack pointer as __eabi() jumps
0300         *  to __init() which has a standard function prolog.
0301         *------------------------------------------------------------------*/
0302         bl      __eabi
0303 
0304        /*-------------------------------------------------------------------
0305         * Zero the .bss, .sbss and .sbss2 sections.
0306         * Must have r2 and r13 properly set.
0307         *------------------------------------------------------------------*/
0308         bl      zero_bss
0309 
0310        /*-------------------------------------------------------------------
0311         * Create a minimal stack frame for this code, the caller of boot_card().
0312         *------------------------------------------------------------------*/
0313         addi    r1,r1, -PPC_MINIMUM_STACK_FRAME_SIZE
0314 
0315         xor     r3,r3,r3
0316         stw     r3,0(r1)            /* Terminate the chain of stack frames. */
0317         stw     r3,4(r1)
0318         stw     r3,8(r1)
0319         stw     r3,12(r1)
0320         lis     r5,environ@ha
0321         la      r5,environ@l(r5)    /* environp */
0322 
0323        /*-------------------------------------------------------------------
0324         * Call boot_card() with its arguments, the command-line pointer and
0325         * the argument count, set to NULL.
0326         *------------------------------------------------------------------*/
0327         li      r4,0                /* argv */
0328         li      r3,0                /* argc */
0329         .extern SYM (boot_card)
0330         b       SYM (boot_card)