/* dlentry.s * * This file contains the entry code for RTEMS programs starting * after download to RAM * * Author: Thomas Doerfler * IMD Ingenieurbuero fuer Microcomputertechnik * * COPYRIGHT (c) 1998 by IMD * * Changes from IMD are covered by the original distributions terms. * This file has been derived from the papyrus BSP: * * This file contains the entry veneer for RTEMS programs * downloaded to Papyrus. * * Author: Andrew Bray * * COPYRIGHT (c) 1995 by i-cubed ltd. * * To anyone who acknowledges that this file is provided "AS IS" * without any express or implied warranty: * permission to use, copy, modify, and distribute this file * for any purpose is hereby granted without fee, provided that * the above copyright notice and this notice appears in all * copies, and that the name of i-cubed limited not be used in * advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * i-cubed limited makes no representations about the suitability * of this software for any purpose. * * derived from "helas403/dlentry.S": * * Further changes to derive for the PPC405CR/GP/GPr/EX/EXr * by Michael Hamel ADInstruments Ltd 2008 */ #include /* * The virtex ELF link scripts support three special sections: * .entry The actual entry point * .vectors The section containing the interrupt entry veneers. */ /* * Downloaded code loads the vectors separately to 0x00000100, * so .entry can be over 256 bytes. * * The other sections are linked in the following order: * .entry * .text * .data * .bss * see linker command file for section placement * * The initial stack is set to _ISR_Stack_area_end. * * All the entry veneer has to do is to clear the BSS. */ /* * GDB likes to have debugging information for the entry veneer. * Here was some DWARF information. IMD removed it, because we * could not check, whether it was still correct. Sorry. */ .section .entry PUBLIC_VAR (start) PUBLIC_VAR (download_entry) PUBLIC_VAR (__rtems_entry_point) SYM(start): SYM(download_entry): SYM(__rtems_entry_point): .extern SYM (boot_card) bl .startup /* First word is branch to reset_entry */ /*--------------------------------------------------------------------------- * Parameters from linker *--------------------------------------------------------------------------*/ base_addr: toc_pointer: .long s.got bss_length: .long bss.size bss_addr: .long bss.start sbss_length: .long sbss.size sbss_addr: .long sbss.start stack_top: .long _ISR_Stack_area_end PUBLIC_VAR (text_addr) text_addr: .long text.start PUBLIC_VAR (text_length) text_length: .long text.size /*--------------------------------------------------------------------------- * Reset_entry. *--------------------------------------------------------------------------*/ .startup: /* Get entrypoint address in R1 so we can find linker variables */ mflr r1 /* Initialise procesor registers generally */ bl init405 /* Clear .bss and .sbss */ bl bssclr /*------------------------------------------------------------------- * C_setup. *------------------------------------------------------------------*/ lwz r1,stack_top - base_addr(r1) /* Now set R1 to stack_top */ addi r1,r1,-56-4 /* start stack at text_addr - 56 */ li r3,0 stw r3, 0(r1) /* Clear stack chain */ stw r3, 4(r1) stw r3, 8(r1) stw r3, 12(r1) bl __eabi /* Initialise EABI: sets up r2 & r13 */ li r3, 0 /* command line */ b SYM (boot_card) /* call the first C routine */ /*--------------------------------------------------------------------------- * bssclr. *--------------------------------------------------------------------------*/ bssclr: lwz r2,bss_addr-base_addr(r1) /* start of bss set by loader */ lwz r3,bss_length-base_addr(r1) /* bss length */ srwi. r3,r3,2 /* div 4 to get # of words */ li r0,0 beq dosbss /* no bss */ mtctr r3 /* set ctr reg */ subi r2,r2,4 clear_bss: stwu r0,4(r2) bdnz clear_bss /* decrement counter and loop */ dosbss: lwz r2,sbss_addr-base_addr(r1) /* start of sbss set by loader */ lwz r3,sbss_length-base_addr(r1) /* sbss length */ slwi. r3,r3,2 /* div 4 to get # of words */ subi r2,r2,4 beqlr /* no sbss */ mtctr r3 /* set ctr reg */ clear_sbss: stwu r0,4(r2) bdnz clear_sbss /* decrement counter and loop */ blr /* return */ /*--------------------------------------------------------------------------- * Generic 405 register setup *--------------------------------------------------------------------------*/ init405: li r0, 0 mtmsr r0 mticcr r0 mtdccr r0 li r3,0x7FFC # 405EX-specific mtsgr r3 # Clear guarded mode on all storage except PCIe region mtsler r0 # Storage is all big-endian mtsu0r r0 # and uncompressed iccci r3,0 # Invalidate the instruction cache li r3,1 # Enable F800 0000 to FFFF FFFF oris r3,r3,0xC000 # Enable 0000 0000 to 0FFF FFFF mticcr r3 isync li r3,0 li r4,256 # 405 has 128 or 256 32-byte lines: do 256 mtctr r4 # set loop ctr dcloop: dccci 0,r3 # invalidate line addi r3,r3,0x20 # bump to next line bdnz dcloop mtdcwr r0 # Select write-back caching lis r3,0xC000 # Enable 0000 0000 to 0FFF FFFF # mtdccr r3 # Enable data cache mtevpr r0 mtesr r0 mtxer r0 lwarx r3,r0,r0 # get some data/set resv bit stwcx. r3,r0,r0 # store out and clear resv bit lis r3,0xDEAD ori r3,r3,0xBEEF # Make distintive uninitialised value mr r4, r3 mr r5, r3 mr r6, r3 mr r7, r3 mr r8, r3 mr r9, r3 mr r10, r3 mr r11, r3 mr r12, r3 mr r13, r3 mr r14, r3 mr r15, r3 mr r16, r3 mr r17, r3 mr r18, r3 mr r19, r3 mr r20, r3 mr r21, r3 mr r22, r3 mr r23, r3 mr r24, r3 mr r25, r3 mr r26, r3 mr r27, r3 mr r28, r3 mr r29, r3 mr r30, r3 mr r31, r3 blr .L_text_e: .comm environ,4,4