#
# Copyright (c) 1996-2007 Digi International Inc., All Rights Reserved
#
# This software contains proprietary and confidential information of Digi
# International Inc.  By accepting transfer of this copy, Recipient agrees
# to retain this software in confidence, to prevent disclosure to others,
# and to make no use of this software other than that for which it was
# delivered.  This is an unpublished copyrighted work of Digi International
# Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
# prohibited.
#
# Restricted Rights Legend
#
# Use, duplication, or disclosure by the Government is subject to
# restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
# Technical Data and Computer Software clause at DFARS 252.227-7031 or
# subparagraphs (c)(1) and (2) of the Commercial Computer Software -
# Restricted Rights at 48 CFR 52.227-19, as applicable.
#
# Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
#
#
#    Entry Points: reset.s
#
# Description.
# =======================================================================
# This is the startup code for the NCC ARM processor
#
# The init routine provides the Reset_handler for the NCC ARM.  The init
# routine performs the following basic features:
#
# 1. Executes software reset to initialize hardware in a known state.
# 2. Initializes ROM and RAM to provide 512K of minimum RAM.
# 3. Places RAM at address 0 and ROM at address 0x2000000.
# 4. Calls the ncc_init function to initialize NCC hardware registers.
# 5. Initializes the various ARM mode stack frames
# 6. Calls the romstart function to perform startup testing and final init.
# 7. Calls Green Hill Softeware routine _start to do C initialization.
# 8. Provides various assembly routines for the system kernel.
# 9. At the end of this file, there is a comments section, which has the LED
#    blink patterns for initialization error detection, refer to this table
#    may help you debug initialization code.
# 
#                                                                        
#                                                                         
# Edit Date/Ver   Edit Description
# ==============  ===================================================
# RAB  12/12/96   Initial version
# PCW  04/09/97   Moved the subroutine used to setup the initial stack 
#                 pointers from stk_ptr.s to here. 
# PCW  04/10/97   Reworked the stack pointer setup.
# JAD  09/30/97   Renamed ncc_initilize function to romstart
#                 Renamed ncc_init_mem function to ncc_init
#                 Include software reset at beginning
#                 Recoded the initial ROM/RAM setup
# JAD  05/27/98   I changedd the BSIZE configuration for the chip select configuration 
#                 from 16 cycles to 4.  This setting provides a much better optimization for 
#                 100BT Ethernet DMA Transmitter.
# JAD  06/16/98   I corrected a bug which caused a problem when calling the crash_for_debug
#                 function.  This bug caused the code to go into hyperspace somewhere.
#
# LZ   10/05/99   Ported to NET_OS, and CPU will run ARM mode, Green Hill 
#                 Software Assembler.
# LZ   05/22/00   Added comments here and there, took out a lot unused functions.
# 
# LZ   01/12/01   remove the code of external address mux test for FAST PAGE RAM.
#
# PMJ  04/30/01   Added the fast_memory_test (which replaces the sloth memory_test),
#                 added sense code early in initialization to load the PLL addjectment
#                 for a 50-*, removed crud from the MEM_CS0_CSOR_v value, added 
#                 some robustness to ram_test_burst, used for auto-sense.
# PMJ  05/16/01   Changed the 50-1 PLL adjustment value from 71f to e22.
# LZ   05/18/01   Changed the stack size for USER/SYS, FIQ, ABT and UND mode.
# PMJ  06/13/01   Pumped the clock up to 33 Mhz at initialization.  Added small delay
#                 after the PLL register is changed.  Cleaned up some legacy code.
# PMJ  06/14/01   Changed the PLL Adjustment value to e1e.
# PMJ  06/14/01   Reduced the Service Stack to ncc_init to 256 bytes.  (This size must be 
#                 16 byte aligned (the last byte of the address = 0).
# PMJ  07/25/01   Corrected PLL Register setting (GEN_PLL_v) to correct value of 33Mhz.
# DXL  10/18/01	  Modified to compile for GHS 3.0.1
#						=0x40000000 to #0x40000000; 
#						Image$$RO$$Base to ImageROBase
#						netos$$Stack to netosStack
# PMJ  04/05/02   Changed MEM_CS0_CSOR_v to initially address a 4Meg Block instead of 1Meg.
# LZ   04/16/02   Made changes to work with GNU.
# DXL  07/24/02	  Added code to set SRAM burst terminate in portA for new development board
#					reference to get_portB, set_portA, set_portC, and set_PLL
# DXL  07/25/02   Modified above assemble code to compile on GNU
# DXL  07/29/02	  PortB data needs to be cleared since data in register may be invalid						
#

NA_RESTART_SIGNATURE    = 0xCAFEBABE
NA_OLD_RESTART_SIGNATURE = 0xff808421
SOFTWARE_RESTART_FLAG   = 0x2


# Now some standard definitions...

Mode_USER	=	0x10
Mode_FIQ	=	0x11
Mode_IRQ	=	0x12
Mode_SVC	=	0x13
Mode_ABT	=	0x17
Mode_UND	=	0x1b
Mode_SYS	=	0x1f

I_Bit		=	0x80
F_Bit		=	0x40

SWI_Exit	=	0x11

# Define some hardware equates

# Addresses of NET+ARM registers.
 
MEM_MMCR        =     0xffc00000
MEM_MMCR_m      =     0xff000000
MEM_CS0_CSAR    =     0xffc00010
MEM_CS0_CSOR    =     0xffc00014
MEM_CS1_CSAR    =     0xffc00020
MEM_CS1_CSOR    =     0xffc00024
GEN_SCR         =     0xffb00000
GEN_SSR         =     0xffb00004
GEN_PLL         =     0xffb00008
GEN_SVC         =     0xffb0000c
GEN_SVC_v1      =     0x00000123
GEN_SVC_v2      =     0x00000321


        .include "settings.s"

# Set the address of the supervisor stack to be right at the
# beginning of ram until we figure out where it really belongs.

SVC_Stack   = RAM_BASE + SVC_STK_SZ

# Settling time for PLL
PLL_SETTLING_TIME   =   0x4000


# Top of DMA memory when in test mode
DMA_STACK_TOP       =   0xff9001fc
DMA_STACK_SIZE      =   0x200


# Make subroutines available to 'C' code    
     
     
     .text
#     .weak  __ghsbegin_robase  ; for Green hill tool
 

# The following routines are vectored to from the exception vector
# table which resides at address 0.  For all unexpected interrupts, we
# simply branch to the crash routine with a unique code.  The unique
# code will be used to blink an LED indicator with the crash identifier.
          
        
      .globl   Undefined_Handler
Undefined_Handler:
      
    
        STMFD sp!, {lr}              	@ make lr a temporary variable

		LDR lr, =SavedRegs           	@ Address of SavedRegs is loaded in LR
		
		STMIA lr, {r0-r12}			 	@ Starting at the address loaded in LR store the data in the registers in the following adress spaces 
		
		LDMIA sp!, {lr}					@ Retrive the original LR from the stack and put it back in LR register

	
        MOV     R0, #1
        STMDB   R13!,{R0-R12,LR}

#		/* Now corrupting the registers to pass the other values */

		MOV r1, sp 		   				@ Move SP in R1
		
		MOV r2, lr		   				@ Move LR in R2 
		
		MRS r3, cpsr	          		@ Move CPSR in R3
		
		LDR r5, =SavedRegs + 0x34 		@ load R5 with the adress location 0x34 memory places from the adress of the 'SavedRegs' variable 
		
		STMIA r5, {r1-r2}          		@ Store the register R1(SP) and R2(LR) to next address locations (see above comment)
		
		STR r3, [r5, #0xc ]				@ Store data in R3(CPSR) into the next memory location 
		
		MOV r1, #1						@ Move the number in register that indicates the exception source (this is passed as second argument to the function call)
		
		LDR r0, =SavedRegs				@ The address of the variable SavedRegs is stored in R1 (it is passed as the first argument to the function call)
	
	BL CoreDump							@ C routine which prints out the crash data is called
    
	B	crash

#	.size Undefined_Handler,.-Undefined_Handler

        .globl  SWI_Handler

SWI_Handler:
    
        STMFD sp!, {lr}              	@ make lr a temporary variable

		LDR lr, =SavedRegs           	@ Address of SavedRegs is loaded in LR
		
		STMIA lr, {r0-r12}			 	@ Starting at the address loaded in LR store the data in the registers in the following adress spaces 
		
		LDMIA sp!, {lr}					@ Retrive the original LR from the stack and put it back in LR register


        MOV     R0, #2
        STMDB   R13!,{R0-R12,LR}

#		/* Now corrupting the registers to pass the other values */

		MOV r1, sp 		   				@ Move SP in R1
		
		MOV r2, lr		   				@ Move LR in R2 
		
		MRS r3, cpsr	          		@ Move CPSR in R3
		
		LDR r5, =SavedRegs + 0x34 		@ load R5 with the adress location 0x34 memory places from the adress of the 'SavedRegs' variable 
		
		STMIA r5, {r1-r2}          		@ Store the register R1(SP) and R2(LR) to next address locations (see above comment)
		
		STR r3, [r5, #0xc ]				@ Store data in R3(CPSR) into the next memory location 
		
		MOV r1, #2						@ Move the number in register that indicates the exception source (this is passed as second argument to the function call)
		
		LDR r0, =SavedRegs				@ The address of the variable SavedRegs is stored in R1 (it is passed as the first argument to the function call)
	
	BL CoreDump							@ C routine which prints out the crash data is called
	       		   
	B	crash

#	.size SWI_Handler,.-SWI_Handler

        .globl Prefetch_Handler

Prefetch_Handler:
		    
        STMFD sp!, {lr}              	@ make lr a temporary variable

		LDR lr, =SavedRegs           	@ Address of SavedRegs is loaded in LR
		
		STMIA lr, {r0-r12}			 	@ Starting at the address loaded in LR store the data in the registers in the following adress spaces 
		
		LDMIA sp!, {lr}					@ Retrive the original LR from the stack and put it back in LR register


        SUB     LR,LR,#4
        MOV     R0, #3
        STMDB   R13!,{R0-R12,LR}

#		/* Now corrupting the registers to pass the other values */

		MOV r1, sp 		   				@ Move SP in R1
		
		MOV r2, lr		   				@ Move LR in R2 
		
		MRS r3, cpsr	          		@ Move CPSR in R3
		
		LDR r5, =SavedRegs + 0x34 		@ load R5 with the adress location 0x34 memory places from the adress of the 'SavedRegs' variable 
		
		STMIA r5, {r1-r2}          		@ Store the register R1(SP) and R2(LR) to next address locations (see above comment)
		
		STR r3, [r5, #0xc ]				@ Store data in R3(CPSR) into the next memory location 
		
		MOV r1, #3						@ Move the number in register that indicates the exception source (this is passed as second argument to the function call)
		
		LDR r0, =SavedRegs				@ The address of the variable SavedRegs is stored in R1 (it is passed as the first argument to the function call)
	
	BL CoreDump							@ C routine which prints out the crash data is called
      	  
	B	crash

#	.size Prefetch_Handler,.-Prefetch_Handler

        .globl Abort_Handler
Abort_Handler:
   
        STMFD sp!, {lr}              	@ make lr a temporary variable

		LDR lr, =SavedRegs           	@ Address of SavedRegs is loaded in LR
		
		STMIA lr, {r0-r12}			 	@ Starting at the address loaded in LR store the data in the registers in the following adress spaces 
		
		LDMIA sp!, {lr}					@ Retrive the original LR from the stack and put it back in LR register

		SUB lr, lr, #4

		MOV r0, #4

		STMDB r13!, {r0-r12,lr}

#		/* Now corrupting the registers to pass the other values */

		MOV r1, sp 		   				@ Move SP in R1	
		
		ADD r1, r1, #56					@ Add 0x38 to get the original stack pointer
				
		MOV r2, lr		   				@ Move LR in R2 
						
		MRS r3, cpsr	          		@ Move CPSR in R3
		
		LDR r5, =SavedRegs + 0x34 		@ load R5 with the adress location 0x34 memory places from the adress of the 'SavedRegs' variable 
		
		STMIA r5, {r1-r2}          		@ Store the register R1(SP) and R2(LR) to next address locations (see above comment)
		
		MOV r1, pc

		STR r1, [r5, #0x8 ]	

		STR r3, [r5, #0xc ]				@ Store data in R3(CPSR) into the next memory location 
		
		MOV r1, #4						@ Move the number in register that indicates the exception source (this is passed as second argument to the function call)
		
		LDR r0, =SavedRegs				@ The address of the variable SavedRegs is stored in R1 (it is passed as the first argument to the function call)
	
	BL CoreDump							@ C routine which prints out the crash data is called
 
	B	crash

#	.size Abort_Handler,.-Abort_Handler

        .globl  Address_Error_Handler
Address_Error_Handler:
 	  	     
        STMFD sp!, {lr}              	@ make lr a temporary variable

		LDR lr, =SavedRegs           	@ Address of SavedRegs is loaded in LR
		
		STMIA lr, {r0-r12}			 	@ Starting at the address loaded in LR store the data in the registers in the following adress spaces 
		
		LDMIA sp!, {lr}					@ Retrive the original LR from the stack and put it back in LR register


        MOV     R0, #5
        STMDB   R13!,{R0-R12,LR}
		
#		/* Now corrupting the registers to pass the other values */

		MOV r1, sp 		   				@ Move SP in R1
		
		MOV r2, lr		   				@ Move LR in R2 
		
		MRS r3, cpsr	          		@ Move CPSR in R3
		
		LDR r5, =SavedRegs + 0x34 		@ load R5 with the adress location 0x34 memory places from the adress of the 'SavedRegs' variable 
		
		STMIA r5, {r1-r2}          		@ Store the register R1(SP) and R2(LR) to next address locations (see above comment)
		
		STR r3, [r5, #0xc ]				@ Store data in R3(CPSR) into the next memory location 
		
		MOV r1, #5						@ Move the number in register that indicates the exception source (this is passed as second argument to the function call)
		
		LDR r0, =SavedRegs				@ The address of the variable SavedRegs is stored in R1 (it is passed as the first argument to the function call)
	
	BL CoreDump							@ C routine which prints out the crash data is called
      
	B	crash

#	.size Address_Error_Handler,.-Address_Error_Handler        

        .globl  FIQ_Handler
        .globl  naLiveFiqHandler
naLiveFiqHandler:
FIQ_Handler:
 	  	     
        STMFD sp!, {lr}              	@ make lr a temporary variable

		LDR lr, =SavedRegs           	@ Address of SavedRegs is loaded in LR
		
		STMIA lr, {r0-r12}			 	@ Starting at the address loaded in LR store the data in the registers in the following adress spaces 
		
		LDMIA sp!, {lr}					@ Retrive the original LR from the stack and put it back in LR register



        SUB     LR, LR, #4              @ /* adjust return address before saving it  */
        STMFD   sp!, {R0-R12,LR}        @ /* stack regs and LR  */
        MRS     R12, spsr               @ /* get the SPSR */
        STMFD   sp!, {R12}              @ /* and put it on the stack */

#		/* Now corrupting the registers to pass the other values */

		MOV r1, sp 		   				@ Move SP in R1
		
		MOV r2, lr		   				@ Move LR in R2 
		
		MRS r3, cpsr	          		@ Move CPSR in R3
		
		LDR r5, =SavedRegs + 0x34 		@ load R5 with the adress location 0x34 memory places from the adress of the 'SavedRegs' variable 
		
		STMIA r5, {r1-r2}          		@ Store the register R1(SP) and R2(LR) to next address locations (see above comment)
		
		STR r3, [r5, #0xc ]				@ Store data in R3(CPSR) into the next memory location 
		
		MOV r1, #6						@ Move the number in register that indicates the exception source (this is passed as second argument to the function call)
		
		LDR r0, =SavedRegs				@ The address of the variable SavedRegs is stored in R1 (it is passed as the first argument to the function call)
	
	BL CoreDump							@ C routine which prints out the crash data is called
    

#	.size FIQ_Handler,.-FIQ_Handler          

crash:
#        IMPORT  customizeExceptionHandler
        BL      customizeExceptionHandler     @R0 is already loaded with the exception type
        LDMFD   sp!, {R0-R12, pc}^            @ pop regsister and return address and return

 


# We get here based upon a RESET boot to the Chip Select 0 Boot Device.
# The "V" bit field in Chip Select 0 is used to determine if we are operating
# in a debugger environment.  If the "V" bit is "1", we have booted from the
# CS0 ROM device.  If the "V" bit is "0", then a debugger environment has
# initialized the memory system and we shouldn't destory or corrupt the RAM.
  

# The RESET entry point

      .globl  Reset_Handler_ROM

Reset_Handler_ROM:

        .globl  Reset_Handler
Reset_Handler:
#
# Save any flags passed to use by the debugger script or by 
# blExecute
#
        MOV     R0, #Mode_UND
        ORR     R0, R0, #I_Bit
        ORR     R0, R0, #F_Bit
        MSR     cpsr_all, R0
        
@ 
@ This is getting complicated now.  Both image.bin and rom.bin run this same
@ code.  Rom.bin is suppose to set up and test memory, but image.bin is not.
@ Rom.bin sets flags that image.bin looks for so it knows that it is not suppose
@ to configure and test memory.  The problem is that rom.bin files before 7.3
@ use one method, and rom.bin files from 7.3 on use a different method.  We have
@ to check for both here so that we can boot a 7.3 image.bin with either rom.bin.
@ Old method was to set R13 of UND mode to NA_OLD_RESTART_SIGNATURE to indicate
@ a restart.  Check for this now.  If this is set, then load R13 with 
@ SOFTWARE_RESTART_FLAG to indicate a restart has occurred.
@ 
        LDR     R0,=NA_OLD_RESTART_SIGNATURE         @ This is the old restart flag 
        CMP     R14,R0                              @ see if it is in R14
        BNE     NotOldFlagMethod                    @ if not then do check for new flag value
        SUB     R14,R14,R14                         @ clear r14
        LDR     R13,=SOFTWARE_RESTART_FLAG          @ It was the old restart, load R13 with new value
        B       NoFlags                             @ branch out of here 
NotOldFlagMethod:                                   
        SUB     R13,R13,R13                         @ clear R13
        CMP     R6,R7                               @ see if R6 == R7 == 0xCAFEBABE 
        BNE     NoFlags                             
        LDR     R10,=NA_RESTART_SIGNATURE           
        CMP     R10,R7                             
        BNE     NoFlags                             @ branch out of here if not 
        MOV     R13,R8                              @ tuck flags into R13 UND
NoFlags:

# set SVC Mode and disable interrupts.

        MOV     R0, #Mode_SVC
        ORR     R0, R0, #I_Bit
        ORR     R0, R0, #F_Bit
        MSR     cpsr_all, R0


        



# don't touch PLL on 20UM
#
	    LDR     R0, =GEN_SSR            
        LDR     R0,[R0]             @ read the system status register
        AND     R0, R0, #0xff000000 @ mask off everthing but rev id
        MOV     R0, R0, LSR #24      @ check if this is 20UM
        CMP     R0, #40
	    BGE     done_pll
#
# Initialize the PLL.  The value to write into the PLL register is read
# from a table in pll.s in the bsp\customize directory.
#
        LDR     R0, =GEN_SSR            
        LDR     R0,[R0]             @ read the system status register
        AND     R0, R0, #0xff000000 @ mask off everthing but rev id
        MOV     R0, R0, LSR #22      @ compute Rev ID * sizeof(WORD32)
        LDR     R1, =NA_PLL_TABLE   @ put base address of PLL table int R1
        ADD     R0, R0, R1          @ compute address of PLL value to read
        LDR     R0, [R0]            @ read it
        LDR     R1, =GEN_PLL        @ load R1 with address of PLL register
        STR     R0, [R1]            @ program the PLL
#
# Set full bus speed.
# Execute an idle loop to wait for the PLL to resynchronize.
#
        LDR     R5, =GEN_SCR
        LDR     R6, [R5]                @ read current value of SCR
	    ORR     R4, R6, #0x40000000     @ or in bit to set bus speed 
        STR     R4, [R5]                @ then write it

        LDR     R0, =PLL_SETTLING_TIME  @ give PLL time to settle down
pll_loop:
        SUBS    R0, R0, #1
        BNE     pll_loop

done_pll:

# Let's execute a Software Reset in order to get the hardware
# into a known state.

        LDR     R0, =GEN_SVC
        LDR     R1, =GEN_SVC_v1
        STR     R1, [R0]
        LDR     R1, =GEN_SVC_v2
        STR     R1, [R0]

        LDR     R0, =GEN_SVC
        LDR     R1, =GEN_SVC_v1
        STR     R1, [R0]
        LDR     R1, =GEN_SVC_v2
        STR     R1, [R0]


	
#
# Put the DMA controller into Test mode.  This will let us use its
# internal registers as scratch pad memory.
#
        LDR     R5, =GEN_SCR
        LDR     R6, [R5]                @ read current value of SCR
	    ORR     R4, R6, #0x00001000     @ or in bit to set DMA test mode
        STR     R4, [R5]                @ write it

#    
# Set up the SVC stack pointer 

        LDR     R13, =DMA_STACK_TOP
        LDR     R0, =DMA_STACK_TOP      @ Let the routine know where the temp SVC stack is
        LDR     R1, =DMA_STACK_SIZE     @ and how big it is
#
# put the value of r14 for undefined mode into R2.  It is used to
# flag when a software restart is occuring
#
        MOV     R5, #Mode_UND
        ORR     R5, R5, #I_Bit
        ORR     R5, R5, #F_Bit
        MSR     CPSR_cxsf, R5               @ Set UND Mode
        MOV     R2, R13                     @ copy r13 to r2 so it appears as 3rd parameter
        MOV     R5, #Mode_SVC
        ORR     R5, R5, #I_Bit
        ORR     R5, R5, #F_Bit
        MSR     CPSR_cxsf, R5               @ Restore SVC Mode

# Now we call a 'C' function to initialize the RAM chip
# selects and determine the real size of RAM.

#        IMPORT  ncc_init

        BL      ncc_init
 

# Now that RAM is ready, let's setup the system stacks.
#
# 9/1/99
#we define a space called netosstack in linker file
#so we can always have enough space for stack
# 
# The stacks for each processing mode look like the following in RAM:
#       
#       -----------------------------  <--- ABT sp (Top of RAM)
#      |         ABT Stack           | 
#      |-----------------------------| <--- IRQ sp
#      |         IRQ Stack           |
#      |-----------------------------| <--- FIQ sp
#      |         FIQ Stack           |
#      |-----------------------------| <--- UND sp
#      |         UND Stack           |
#      |-----------------------------| <--- USER/SYS sp
#      |      USER/SYS Stack         |
#      |-----------------------------|  
            
 
setup_stacks:
        LDR     R0, netosStack     
     
# adjust address for CACHE considerations
        LDR     R1, =STACK_CACHE
        ADD     R0, R0, R1

# setup the ABT Stack
#    MOV     R5, #Mode_ABT:OR:I_Bit:OR:F_Bit ; No interrupts
        MOV     R5, #Mode_ABT
        ORR     R5, R5, #I_Bit
        ORR     R5, R5, #F_Bit
        MSR     cpsr_all, R5               @ Set ABT Mode
        MOV     R13,  R0                    @ set the stack pointer
        LDR     R1, =ABT_STK_SZ	            @ Compute the top of the 
        SUB     R0, R0, R1                  @ IRQ stack in R0

# setup the IRQ stack 
#    MOV     R5, #Mode_IRQ:OR:I_Bit:OR:F_Bit ; No interrupts
        MOV     R5, #Mode_IRQ
        ORR     R5, R5, #I_Bit
        ORR     R5, R5, #F_Bit
        MSR     cpsr_all, R5               @ Set IRQ Mode
        MOV     R13,  R0                    @ set the stack pointer
        LDR     R1, =IRQ_STK_SZ	            @ Compute the top of the 
        SUB     R0, R0, R1	                @ FIQ stack in R0

# setup the FIQ Stack    
#    MOV     R5, #Mode_FIQ:OR:I_Bit:OR:F_Bit ; No interrupts
        MOV     R5, #Mode_FIQ
        ORR     R5, R5, #I_Bit
        ORR     R5, R5, #F_Bit
        MSR     cpsr_all, R5               @ Set FIQ Mode
        MOV     R13,  R0                    @ set the stack pointer
        LDR     R1, =FIQ_STK_SZ	            @ Compute the top of the 
        SUB     R0, R0, R1                  @ UND stack in R0

# setup the UND Stack    
#    MOV     R5, #Mode_UND:OR:I_Bit:OR:F_Bit ; No interrupts
        MOV     R5, #Mode_UND
        ORR     R5, R5, #I_Bit
        ORR     R5, R5, #F_Bit
        MSR     cpsr_all, R5               @ Set UND Mode
        MOV     R13,  R0                    @ set the stack pointer
        LDR     R1, =UND_STK_SZ	            @ Compute the top of the 
        SUB     R0, R0, R1                  @ USER/SYS stack in R0

# setup the user/sys mode stack, and leave ourselves running
# in SYS mode.
#    MOV     R5, #Mode_SYS:OR:I_Bit:OR:F_Bit ; No interrupts
        MOV     R5, #Mode_SYS
        ORR     R5, R5, #I_Bit
        ORR     R5, R5, #F_Bit
        MSR     cpsr_all, R5               @ Set SYS Mode
        MOV     R13,  R0                    @ set the stack pointer
        LDR     R1, =SYS_STK_SZ             @ Compute the top of the 
        SUB     R0, R0, R1                  @ Highest RAM address in R0

#    MOV     R5, #Mode_SYS:OR:F_Bit
        MOV     R5, #Mode_SYS
        ORR     R5, R5, #F_Bit
        MSR     cpsr_all, R5               @ and stay in SYS mode

#
# Release DMA module from test mode
#
        LDR     R5, =GEN_SCR
        LDR     R6, [R5]                @ read current value of SCR
	    AND     R4, R6, #0xffffefff     @ mask off test mode bit
        ORR     R6, R4, #0x40           @ set DMA reset bit
        STR     R6, [R5]                @ write it and reset DMA
        MOV     R0, R1                  @ waste a few cycles
        MOV     R0, R1                  @ waste a few cycles
        MOV     R0, R1                  @ waste a few cycles
        MOV     R0, R1                  @ waste a few cycles
        STR     R4, [R5]                @ release DMA module from reset
        
#now,we finished out memory and hardware initialization, let's go to 
#Green Hill code to do C initialization we need to be in SVC mode to do this.

        MOV     R5, #Mode_SVC
        ORR     R5, R5, #F_Bit
        MSR     cpsr_all, R5 
        
#       here we are ready to call green hill C initialization code
        LDR     sp, STACK                     
        LDR     pc, START

# In a real application we do not normally expect to return, but if it
# does.  Debug monitor swi SWI_Exit is used to halt the application.
	SWI SWI_Exit

#	.size Reset_Handler,.-Reset_Handler 



# Let's execute a very simply RAM test

      .globl   nccBurstTest
nccBurstTest:
        STMFD   sp!, {R1-R6,R14}
        MOV     R6, R0
        MOV     R1, #1
        MOV     R2, #2
        MOV     R3, #4
        MOV     R4, #8
        STMIA   R0, {R1,R2,R3,R4}
        MOV     R0, R6
        LDMIA   R0, {R2,R3,R4,R5}
        CMP     R2, #1
        BNE     nccBurstTestFail
        CMP     R3, #2
        BNE     nccBurstTestFail
        CMP     R4, #4
        BNE     nccBurstTestFail
        CMP     R5, #8
        BNE     nccBurstTestFail
        MOV     R0, #1
        LDMIA	sp!,{R1-R6,R15}

nccBurstTestFail:
        MOV     R0, #0
        LDMIA	sp!,{R1-R6,R15}


        .globl  NARamSetupAbortHandler
NARamSetupAbortHandler:
        SUB R13,R13,R13
        STR R14,[R13]
        SUBS PC,R14,#4

# Let's execute a very simply RAM test


TestVector1     =   0x55aaaa55
TestVector2     =   0xaa5555aa
TestVector3     =   0x33cccc33
TestVector4     =   0xcc3333cc

        .globl  NAFastMemoryTest
NAFastMemoryTest:

#       memory test limits
#
#       Requires both low and top addresses to be aligned and zero-ed on 
#       a 16 byte boundary.  The bottom byte of these addresses must be zero.
#
#       r0 - low address
#       r1 - top address
#
        # Save the machine state
        STMFD sp!, {R0-R11}

        #   get source data
        LDR     r4,  =TestVector1
        LDR     r5,  =TestVector2
        LDR     r6,  =TestVector3
        LDR     r7,  =TestVector4

writethePatternData:
        #   initialize the counter
        MOV     r2,  r0

writeMoreData:
        STMIA   r2!, {r4,r5,r6,r7}
        CMP     r2,  r1
        BNE     writeMoreData

        MOV     r2,  r0
readTheData:
        LDMIA   r2!, {r8,r9,r10,r11}

        CMP     r8,  r4
        BNE     test_failure
        CMP     r9,  r5
        BNE     test_failure
        CMP     r10, r6
        BNE     test_failure
        CMP     r11, r7
        BNE     test_failure
        CMP     r2,  r1
        BNE     readTheData

        LDR     r3,  =TestVector2
        CMP     r3,  r4
        BEQ     WeAreDone

        LDR     r4,  =TestVector2
        LDR     r5,  =TestVector1
        LDR     r6,  =TestVector4
        LDR     r7,  =TestVector3
        B       writethePatternData

WeAreDone:
        # Load this block with 0 data
        SUB     r4,  r4,  r4
        SUB     r5,  r5,  r5
        SUB     r6,  r6,  r6
        SUB     r7,  r7,  r7
        MOV     r2,  r0

writeZerosData:
        STMIA   r2!, {r4,r5,r6,r7}
        CMP     r2,  r1
        BNE     writeZerosData

        LDMFD   sp!, {r0-r11}
        MOV     r0,  #0
        MOV     pc,  lr

test_failure:
        LDMFD   sp!, {r0-r11}
        MOV     r0,  #1
        MOV     pc,  lr

#	.size NAFastMemoryTest,.-NAFastMemoryTest

#        .include "tools.def"    
        .ifdef NETOS_GNU_TOOLS
ImageROBase:
     .word  btext                
netosStack:
     .word  netosstack_end         
STACK:
     .word  stack_end           
START:
     .word  _start

	.else
ImageROBase:
     .word  __ghsbegin_picbase  
netosStack:
     .word  __ghsend_netosstack  
STACK:
     .word  __ghsend_stack 
START:
     .word  _start
	.endif 
     
     
#     END


#**************************************************************************************************
# 
#  We use the LED blink patterns to indicate some error during initialization and some exceptions 
#  during run time.
#
#
#  -------------------------------------------------------------------------------------
#  File           Function                                   Red LED       Green LED    
#  ------------------------------------------------------------------------------------- 
#  
#  INIT.s         Undefined_Handler                          1             off
#                 SWI_Handler                                2             off
#                 Prefetch_Handler                           3             off
#                 Abort_Handler                              4             off
#                 Address_Error_Handler                      5             off
#                 RAM  failure                               6             off
#  -------------------------------------------------------------------------------------
#  NCC_INIT.c     ncc_init(), RAM problems                   6             off
#  -------------------------------------------------------------------------------------
#  romstart.c     ROM checksum failure                       7             off
#  -------------------------------------------------------------------------------------
#  IRQHAND.s      IRQ_Handler                                8             off
#                 IRQ_Handler                                9             off
#  -------------------------------------------------------------------------------------
#  NCC_POST.c     test_dma_ram()                             1             at least 1
#                 test_mem_to_mem_dma()                      2             at least 1
#                 test_parallel_ports()                      3             at least 1
#                 test_serial_loopback()                     4             at least 1
#                 test_ethernet_loopback()                   5             at least 1
#                 test_gen_irq()                             6             at least 1
#                 test_MII_interface()                       7             at least 1
#                 test_eeprom()                              8             at least 1
#                 test_cache_ram()                           9             at least 1
#  -------------------------------------------------------------------------------------
#  NCC_POST.c     ncc_post(), successfully passed POST test  off           5        
#  -------------------------------------------------------------------------------------      
#
#**************************************************************************************************
     
     








