OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rtems-20020807/] [c/] [src/] [lib/] [libbsp/] [powerpc/] [helas403/] [flashentry/] [flashentry.S] - Rev 1026

Go to most recent revision | Compare with Previous | Blame | View Log

/*  flashentry.s
 *
 *  This file contains the entry code for RTEMS programs starting
 *  directly from Flash. 
 *
 *  Author:     Thomas Doerfler <td@imd.m.isar.de>
 *              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
 *  stored in Papyrus' flash ROM.
 *
 *  Author:     Andrew Bray <andy@i-cubed.co.uk>
 *
 *  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.
 *
 *  flashentry.S,v 1.2 2000/08/02 16:30:57 joel Exp
 */

#include "asm.h"
#include <rtems/score/ppc.h>    
                                
/*----------------------------------------------------------------------------
 * Reset_entry.
 *---------------------------------------------------------------------------*/
#if PPC_ASM == PPC_ASM_ELF
        .section .reset,"ax",@progbits 
        /* this section MUST be located at absolute address 0xFFFFFFFC
           or last word of EPROM */
#else
        .csect .text[PR]
#endif

        ba      flash_entry /* this is the first instruction after reset */

        .previous
        
/*----------------------------------------------------------------------------
 * ROM Vector area.
 *---------------------------------------------------------------------------*/
#if PPC_ASM == PPC_ASM_ELF
        .section .entry,"ax",@progbits
#else
        .csect .text[PR]
#endif
        PUBLIC_VAR (flash_entry)
SYM (flash_entry):
        bl      .startup /* call startup, link reg points to base_addr */
base_addr:
/*----------------------------------------------------------------------------
 * Parameters from linker
 *---------------------------------------------------------------------------*/
toc_pointer:
#if PPC_ASM == PPC_ASM_ELF
        .long   s.got
#else
        .long   TOC[tc0]
#endif
text_length:    
        .long   text.size
text_addr:
        .long   text.start
copy_src:       
        .long   copy.src
copy_length:
        .long   copy.size
copy_dest:      
        .long   copy.dest
bss_length:     
        .long   bss.size
bss_addr:       
        .long   bss.start
stack_top:
        .long   stack.end
        
/*----------------------------------------------------------------------------
 * from Reset_entry.
 *---------------------------------------------------------------------------*/
.startup:
        /* Get start address, r1 points to label base_addr */
        mflr    r1

        /* Set up Bank regs, cache etc. */
        /* set up bank register BR0 for Flash-EPROM:
         * NOTE: bank size should stay 1MByte, this is standard size
         *       after RESET
         * base addr = Fffxxxxx -> 0b11111111........................ 
         * bank size = 1 MByte  -> 0b........000..................... (std)
         * bank use  = readonly -> 0b...........01...................
         * seq. fill = targ frst-> 0b.............0.................. 
         * burst mode= enable   -> 0b..............1.................
         * bus width = 8 bit    -> 0b...............00............... 
         * ready pin = disable  -> 0b.................0..............
         * first wait= 2 clocks -> 0b..................0010..........
         * burst wait= 2 clocks -> 0b......................10........
         * CSon time = 0 clocks -> 0b........................0.......
         * OEon time = 0 clocks -> 0b.........................0......
         * WBon time = 1 clocks -> 0b..........................1.....
         * WBoff time= 0 clocks -> 0b...........................0....
         * Hold time = 1 clocks -> 0b............................001.
         * ram type  = SRAM(ign)-> 0b...............................1
         * value                   0b11111111000010100000101000100011
         *                         0x   F   F   0   A   0   A   2   3
         */
        lis     r2,0xFF0A
        ori     r2,r2,0x0A23

        mtdcr   br0,r2 /* write to DCR BR0 */


        /*--------------------------------------------------------------------
         * test various RAM configurations (from big to small per bank)
         *------------------------------------------------------------------*/
        /*--------------------------------------------------------------------
         * test RAM config 16 MByte (1x4Mx32Bit)
         *------------------------------------------------------------------*/
        /* set up bank register BR7 for DRAM:
         * base addr = 000xxxxx -> 0b00000000........................ 
         * bank size = 16MByte  -> 0b........100.....................
         * bank use  = readwrite-> 0b...........11...................
         * seq. fill = targ.frst-> 0b.............0.................. 
         * early RAS = disabled -> 0b..............0.................
         * bus width = 32bit    -> 0b...............10............... 
         * adr mux   = internal -> 0b.................0..............
         * RAS to CAS= 2 clocks -> 0b..................1.............
         * Alt. Rfrsh= normal   -> 0b...................0............
         * page mode = enabled  -> 0b....................1...........
         * first wait= 1 clocks -> 0b.....................01.........
         * burst wait= 1 clocks -> 0b.......................01.......
         * precharge = 1 clocks -> 0b.........................0......
         * RAS Rfrsh = 2 clocks -> 0b..........................1.....
         * Rfrsh Itvl= 512 clks -> 0b...........................1000.
         * ram type  = DRAM     -> 0b...............................0
         * value                   0b00000000100110010010101010110000
         *                         0x   0   0   9   9   2   A   B   0
         */
        lis     r2,0x0099
        ori     r2,r2,0x2AB0
        mtdcr   br7,r2 /* write to DCR BR7*/    

        lis     r2,0x0000       /* start address = 0x00000000 */
        lis     r3,0x0100       /* size  16 MB   = 0x01000000 */
        bl      ramacc          /* test memory accessibility  */
        cmpi    0,0,r4,0        /* memory ok? else test smaller size */
        bne     ramcfgt18

        /*--------------------------------------------------------------------
         * test RAM config 32 MByte (2x4Mx32Bit)
         *------------------------------------------------------------------*/
        /* set up bank register BR7 like above
         * set up bank register BR6 for DRAM:   
         * base addr = 010xxxxx -> 0b00010000........................ 
         * bank size = 16MByte  -> 0b........100..................... (for now)
         * bank use  = readwrite-> 0b...........11...................
         * seq. fill = targ.frst-> 0b.............0.................. 
         * early RAS = disabled -> 0b..............0.................
         * bus width = 32bit    -> 0b...............10............... 
         * adr mux   = internal -> 0b.................0..............
         * RAS to CAS= 2 clocks -> 0b..................1.............
         * Alt. Rfrsh= normal   -> 0b...................0............
         * page mode = enabled  -> 0b....................1...........
         * first wait= 1 clocks -> 0b.....................01.........
         * burst wait= 1 clocks -> 0b.......................01.......
         * precharge = 1 clocks -> 0b.........................0......
         * RAS Rfrsh = 2 clocks -> 0b..........................1.....
         * Rfrsh Itvl= 512 clks -> 0b...........................1000.
         * ram type  = DRAM     -> 0b...............................0
         * value                   0b00010000100110010010101010110000
         *                         0x   1   0   9   9   2   A   B   0
         */
        lis     r2,0x1099
        ori     r2,r2,0x2AB0
        mtdcr   br6,r2          /* write to DCR BR6*/   

        lis     r2,0x0100       /* start address = 0x01000000 */
        lis     r3,0x0100       /* size  16 MB   = 0x01000000 */
        bl      ramacc          /* test memory accessibility  */
        cmpi    0,0,r4,0        /* memory ok? else test smaller size */
        beq     ramcfgok        /* ok, we found configuration... +/
        
        lis     r2,0x0000       /* disable BR6, config not ok */
        mtdcr   br6,r2          /* write to DCR BR6*/   
        b       ramcfgok        /* and finish configuration */
        
ramcfgt18:                      
        /*--------------------------------------------------------------------
         * test RAM config 8 MByte (1x2Mx32Bit)
         *------------------------------------------------------------------*/
        /* set up bank register BR7 for DRAM:
         * base addr = 000xxxxx -> 0b00000000........................ 
         * bank size =  8MByte  -> 0b........011.....................
         * bank use  = readwrite-> 0b...........11...................
         * seq. fill = targ.frst-> 0b.............0.................. 
         * early RAS = disabled -> 0b..............0.................
         * bus width = 32bit    -> 0b...............10............... 
         * adr mux   = internal -> 0b.................0..............
         * RAS to CAS= 2 clocks -> 0b..................1.............
         * Alt. Rfrsh= normal   -> 0b...................0............
         * page mode = enabled  -> 0b....................1...........
         * first wait= 1 clocks -> 0b.....................01.........
         * burst wait= 1 clocks -> 0b.......................01.......
         * precharge = 1 clocks -> 0b.........................0......
         * RAS Rfrsh = 2 clocks -> 0b..........................1.....
         * Rfrsh Itvl= 512 clks -> 0b...........................1000.
         * ram type  = DRAM     -> 0b...............................0
         * value                   0b00000000011110010010101010110000
         *                         0x   0   0   7   9   2   A   B   0
         */
        lis     r2,0x0079
        ori     r2,r2,0x2AB0
        mtdcr   br7,r2         /* write to DCR BR7           */ 

        lis     r2,0x0000       /* start address = 0x00000000 */
        lis     r3,0x0080       /* size   8 MB   = 0x00800000 */
        bl      ramacc          /* test memory accessibility  */
        cmpi    0,0,r4,0        /* memory ok? else test smaller size */
        bne     ramcfgt14

        /*--------------------------------------------------------------------
         * test RAM config 16 MByte (2x2Mx32Bit)
         *------------------------------------------------------------------*/
        /* set up bank register BR7 like above
         * set up bank register BR6 for DRAM:   
         * base addr = 008xxxxx -> 0b00001000........................ 
         * bank size = 08MByte  -> 0b........011..................... (for now)
         * bank use  = readwrite-> 0b...........11...................
         * seq. fill = targ.frst-> 0b.............0.................. 
         * early RAS = disabled -> 0b..............0.................
         * bus width = 32bit    -> 0b...............10............... 
         * adr mux   = internal -> 0b.................0..............
         * RAS to CAS= 2 clocks -> 0b..................1.............
         * Alt. Rfrsh= normal   -> 0b...................0............
         * page mode = enabled  -> 0b....................1...........
         * first wait= 1 clocks -> 0b.....................01.........
         * burst wait= 1 clocks -> 0b.......................01.......
         * precharge = 1 clocks -> 0b.........................0......
         * RAS Rfrsh = 2 clocks -> 0b..........................1.....
         * Rfrsh Itvl= 512 clks -> 0b...........................1000.
         * ram type  = DRAM     -> 0b...............................0
         * value                   0b00001000011110010010101010110000
         *                         0x   0   8   7   9   2   A   B   0
         */
        lis     r2,0x0879
        ori     r2,r2,0x2AB0
        mtdcr   br6,r2          /* write to DCR BR6*/   

        lis     r2,0x0080       /* start address = 0x00800000 */
        lis     r3,0x0080       /* size   8 MB   = 0x00800000 */
        bl      ramacc          /* test memory accessibility  */
        cmpi    0,0,r4,0        /* memory ok? else test smaller size */
        beq     ramcfgok        /* ok, we found configuration... +/
        
        lis     r2,0x0000       /* disable BR6, config not ok */
        mtdcr   br6,r2          /* write to DCR BR6*/   
        b       ramcfgok        /* and finish configuration */
        
ramcfgt14:                      
        /*--------------------------------------------------------------------
         * test RAM config 4 MByte (1x1Mx32Bit)
         *------------------------------------------------------------------*/
        /* set up bank register BR7 for DRAM:
         * base addr = 000xxxxx -> 0b00000000........................ 
         * bank size =  4MByte  -> 0b........010.....................
         * bank use  = readwrite-> 0b...........11...................
         * seq. fill = targ.frst-> 0b.............0.................. 
         * early RAS = disabled -> 0b..............0.................
         * bus width = 32bit    -> 0b...............10............... 
         * adr mux   = internal -> 0b.................0..............
         * RAS to CAS= 2 clocks -> 0b..................1.............
         * Alt. Rfrsh= normal   -> 0b...................0............
         * page mode = enabled  -> 0b....................1...........
         * first wait= 1 clocks -> 0b.....................01.........
         * burst wait= 1 clocks -> 0b.......................01.......
         * precharge = 1 clocks -> 0b.........................0......
         * RAS Rfrsh = 2 clocks -> 0b..........................1.....
         * Rfrsh Itvl= 512 clks -> 0b...........................1000.
         * ram type  = DRAM     -> 0b...............................0
         * value                   0b00000000010110010010101010110000
         *                         0x   0   0   5   9   2   A   B   0
         */
        /*
         * FIXME: this is the minimum size supported, should test and
         * report error, when failed
         */
        lis     r2,0x0059
        ori     r2,r2,0x2AB0
        mtdcr   br7,r2 /* write to DCR BR7*/    

        /*--------------------------------------------------------------------
         * test RAM config  8 MByte (2x1Mx32Bit)
         *------------------------------------------------------------------*/
        /* set up bank register BR7 like above
         * set up bank register BR6 for DRAM:   
         * base addr = 004xxxxx -> 0b00000100........................ 
         * bank size =  4MByte  -> 0b........010..................... (for now)
         * bank use  = readwrite-> 0b...........11...................
         * seq. fill = targ.frst-> 0b.............0.................. 
         * early RAS = disabled -> 0b..............0.................
         * bus width = 32bit    -> 0b...............10............... 
         * adr mux   = internal -> 0b.................0..............
         * RAS to CAS= 2 clocks -> 0b..................1.............
         * Alt. Rfrsh= normal   -> 0b...................0............
         * page mode = enabled  -> 0b....................1...........
         * first wait= 1 clocks -> 0b.....................01.........
         * burst wait= 1 clocks -> 0b.......................01.......
         * precharge = 1 clocks -> 0b.........................0......
         * RAS Rfrsh = 2 clocks -> 0b..........................1.....
         * Rfrsh Itvl= 512 clks -> 0b...........................1000.
         * ram type  = DRAM     -> 0b...............................0
         * value                   0b00000100010110010010101010110000
         *                         0x   0   4   5   9   2   A   B   0
         */
        lis     r2,0x0459
        ori     r2,r2,0x2AB0
        mtdcr   br6,r2          /* write to DCR BR6*/   

        lis     r2,0x0040       /* start address = 0x00400000 */
        lis     r3,0x0040       /* size   4 MB   = 0x00400000 */
        bl      ramacc          /* test memory accessibility  */
        cmpi    0,0,r4,0        /* memory ok? else test smaller size */
        beq     ramcfgok        /* ok, we found configuration... +/
        
        lis     r2,0x0000       /* disable BR6, config not ok */
        mtdcr   br6,r2          /* write to DCR BR6*/   
        b       ramcfgok        /* and finish configuration */

ramcfgok:       
        /*--------------------------------------------------------------------
         * init the DRAM where STACK+ DATA+ BBS will be placed.  If this is OK
         * we will return here.
         *-------------------------------------------------------------------*/
        bl      rom2ram

        /* clear caches */
        addi    r2,0,PPC_I_CACHE/PPC_CACHE_ALIGNMENT
        mtctr   r2              /* count the loops needed... */
        xor     r2,r2,r2        /* start at adr zero */
icinvlp:        
        iccci   0,r2
        addi    r2,r2,PPC_CACHE_ALIGNMENT
        bdnz    icinvlp
        
        addi    r2,r0,PPC_D_CACHE/PPC_CACHE_ALIGNMENT
        mtctr   r2              /* count the loops needed... */
        xor     r2,r2,r2        /* start at adr 0 */
dcinvlp:                
        dccci   0,r2
        addi    r2,r2,PPC_CACHE_ALIGNMENT
        bdnz    dcinvlp
        /*--------------------------------------------------------------------
         * Enable two 128MB cachable regions.
         * FEPROM is cachable    at 0xFFF00000..0xFFFFFFFF
         * DRAM   is cachable    at 0x00000000..0x00FFFFFF      
         * FEPROM is noncachable at 0x7FF00000..0x7FFFFFFF
         * DRAM   is noncachable at 0x80000000..0x80FFFFFF      
         *-------------------------------------------------------------------*/
        addis   r2,r0,0x8000
        addi    r2,r2,0x0001

        mtspr   iccr, r2               /* ICCR */
        mtspr   dccr, r2               /* DCCR */

        .extern SYM(__vectors)

        lis     r2,__vectors@h          /* set EVPR exc. vector prefix */
        mtspr   evpr,r2

        lis     r2,0x0000
        ori     r2,r2,0x0000
        mtmsr   r2                      /* set default msr           */
        lis     r2,0x0000               /* do not allow critical IRQ */
        ori     r2,r2,0x0000
        mtdcr   exier, r2               /* disable all external IRQs */
        
        addi    r2,r0,-1                /* r2 = 0xffffffff               */
        mtdcr   exisr, r2               /* clear all pendingdisable IRQs */
        
        /*--------------------------------------------------------------------
         * C_setup.
         *-------------------------------------------------------------------*/

        lwz     r2,toc_pointer-base_addr(r1)       /* set r2 to toc */
        lwz     r1,stack_top-base_addr(r1)         /* set r1 to stack_top */
        
        addi    r1,r1,-56                /* start stack at data_addr - 56 */
        addi    r3,r0,0x0                /* clear r3 */
        stw     r3, 0(r1)                /* Clear stack chain */
        stw     r3, 4(r1)
        stw     r3, 8(r1)
        stw     r3, 12(r1)
        lis     r5,environ@ha
        la      r5,environ@l(r5)        /* environp */
        li      r4, 0                   /* argv */
        li      r3, 0                   /* argc */
        .extern SYM (boot_card)
        b       SYM (boot_card)          /* call the first C routine */

/*----------------------------------------------------------------------------
 * Rom2ram.
 *---------------------------------------------------------------------------*/
rom2ram:
        lwz     r2,copy_dest-base_addr(r1)    /* start of data set by loader */
        lwz     r3,copy_length-base_addr(r1)  /* data length                 */
        rlwinm  r3,r3,30,0x3FFFFFFF           /* form length/4               */
        mtctr   r3                            /* set ctr reg                 */
        /*--------------------------------------------------------------------
         * Calculate offset of data in image.
         *-------------------------------------------------------------------*/
        lwz     r4,copy_src-base_addr(r1)      /* get start of copy area */
move_data:
        lswi    r6,r4,0x4               /* load r6 */
        stswi   r6,r2,0x4               /* store r6 */
        addi    r4,r4,0x4               /* update r4 */
        addi    r2,r2,0x4               /* update r2 */
        bdnz    move_data               /* decrement counter and loop */
        /*--------------------------------------------------------------------
         * Data move finished, zero out bss.
         *-------------------------------------------------------------------*/
        lwz     r2,bss_addr-base_addr(r1) /* start of bss set by loader */
        lwz     r3,bss_length-base_addr(r1)       /* bss length */
        rlwinm. r3,r3,30,0x3FFFFFFF     /* form length/4 */
        beqlr                           /* no bss */
        mtctr   r3                      /* set ctr reg */
        xor     r6,r6,r6                /* r6 = 0 */
clear_bss:
        stswi   r6,r2,0x4               /* store r6 */
        addi    r2,r2,0x4               /* update r2 */
        bdnz    clear_bss               /* decrement counter and loop */
        blr                             /* return */

/*----------------------------------------------------------------------------
 * ramacc test accessibility of RAM
 * input:       r2 = start address, r3 = length (in byte)
 * output:      r4 = 0 -> ok, !=0 -> fail
 *---------------------------------------------------------------------------*/
ramacc:
        xor     r4,r4,r4                /* r4 = 0                    */
        stw     r4,0(r2)                /* init ram at start address */
        addi    r4,r0,0x04              /* set start shift           */
ramaccf1:       
        cmp     0,0,r4,r3               /* compare with length       */
        bge     ramaccfx                /* r4 >= r3? then finished   */
        add     r5,r4,r2                /* get next address to fill  */
        stw     r4,0(r5)                /* store new pattern         */
        add     r4,r4,r4                /* r4 = r4*2                 */
        b       ramaccf1                /* and then next loop        */

ramaccfx:
        lwz     r4,0(r2)                /* get memory at start adr  */
        blr
        

#if PPC_ABI == PPC_ABI_POWEROPEN
        DESCRIPTOR (startup)
#endif


        .comm   environ,4,4


Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.