summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/helas403/flashentry/flashentry.S
diff options
context:
space:
mode:
Diffstat (limited to 'c/src/lib/libbsp/powerpc/helas403/flashentry/flashentry.S')
-rw-r--r--c/src/lib/libbsp/powerpc/helas403/flashentry/flashentry.S469
1 files changed, 469 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/helas403/flashentry/flashentry.S b/c/src/lib/libbsp/powerpc/helas403/flashentry/flashentry.S
new file mode 100644
index 0000000000..133e64e650
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/helas403/flashentry/flashentry.S
@@ -0,0 +1,469 @@
+/* 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.
+ *
+ * $Id$
+ */
+
+#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)
+ .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
+
+
+