/*
*
*                Language Independent Library
*
*       Copyright 2004-2005 Green Hills Software,Inc.
*
*  This program is the property of Green Hills Software, Inc,
*  its contents are proprietary information and no part of it
*  is to be disclosed to anyone except employees of Green Hills
*  Software, Inc., or as agreed in writing signed by the President
*  of Green Hills Software, Inc.
*
*/
	.section ".vector", "ax"
	.weak __ghs_rambootcodestart
	.weak __ghs_rombootcodestart

entRESET::
	b	go_to_start
entUNDEF::
	b	entUNDEF	; loop forever
entSWI::
	b	entSWI		; loop forever
entIABRT::
	b	entIABRT	; loop forever
entDABRT::
	b	entDABRT	; loop forever
entUNUSED::
	b	entUNUSED	; loop forever
entIRQ::
	b	entIRQ		; loop forever
entFIQ::
	b	entFIQ		; loop forever

go_to_start:
	ldr	r4, pool_start
	ldr	r8, pool_text
	ldr	r9, pool_rtext
	cmp	r8, 0
	bxeq	r4
InRam:
	sub	r4, r4, r8
	add	r4, r4, r9
	bx	r4
pool_start:
	.data.w	_start
pool_text:
	.data.w	__ghs_rambootcodestart
pool_rtext:
	.data.w	__ghs_rombootcodestart

	.section ".text", "ax"
__ghsautoimport_ghs_board_memory_init::
__ghs_board_memory_init::

; code from: Programmer's Reference
; Copyright (c) 2000, 2002 ARM Limited. All rights reserved.


CM_BASE EQU 0x10000000 ; base address of Core Module registers
SPD_BASE EQU 0x10000100 ; base address of SPD information
SC_BASE EQU 0x11000000 ; base address of System Control registers

initialize_oscillator
	LDR r0, =SC_BASE	; load in System Control base
	LDR r3, =CM_BASE	; load in Core Module base
	LDR r1, =0x0000A05F	; unlock code
	LDR r2, =0x48		; 20MHz - PCI problems start at 33MHz
	LDR r4, [r3, #8]	; load current core clock
	LDR r5, [r3, #0x24]	; load current CM init
	LDR r12, [r3, #0x10]	; load current CM status
	AND r4, r4, #0xffffff00	; mask off PLL_VDW
	AND r5, r5, #0xffffff8f ; mask off HCLKDIV
#if defined MAX_CORE_SPEED
	ORR r4, r4, #0xc0	; 200MHz -- too fast for trace
	ORR r5, r5, #0x40	; divide by 5 for 40Mhz local bus
#elif defined MEDIUM_CORE_SPEED
	ORR r4, r4, #0x70	; 120MHz -- good trace
	ORR r5, r5, #0x20	; divide by 3 for 40Mhz local bus
#else
# if defined (__ARM11)
	ORR r4, r4, #0xac	; 180MHz -- default out of boot
# else
	ORR r4, r4, #0x48	; 80MHz -- default out of boot
	ORR r5, r5, #0x10	; divide by 2 for 40Mhz local bus
# endif
#endif
	AND	r12, r12, 0xff	; grab the ID from the status 
	CMP	r12, 0xff	; do we have a motherboard?
	STRNE	r1, [r0, #0x1c]	; unlock the SC oscillator if so
	STR	r1, [r3, #0x14]	; unlock the CM oscillator
	STRNE	r2, [r0, #4]	; speed up the system clock if so
	STR	r5, [r3, #0x24]	; change divisor
	STR	r4, [r3, #8]	; speed up the core clock
	STRNE	r2, [r0, #0x1c]	; relock the SC oscillator if so
	STR	r2, [r3, #0x14]	; relock the CM oscillator
	
lightled
	; turn on header LED and remap memory
	LDR r0, =CM_BASE ; load register base address
	MOV r1,#5 ; set remap and led bits
	STR r1,[r0,#0xc] ; write the register
	; setup SDRAM
	
readspdbit

	; check SPD bit is set
	LDR r1,[r0,#0x20] ; read the status register
	AND r1,r1,#0x20 ; mask SPD bit (5)
	CMP r1,#0x20 ; test if set
	BNE readspdbit ; branch until the SPD memory has been read

setupsdram
	; work out the SDRAM size
	LDR r0, =SPD_BASE ; point at SPD memory
	LDRB r1,[r0,#3] ; number of row address lines
	LDRB r2,[r0,#4] ; number of column address lines
	LDRB r3,[r0,#5] ; number of banks
	LDRB r4,[r0,#31] ; module bank density
	MUL r5,r4,r3 ; calculate size of SDRAM (MB divided by 4)
	MOV r5,r5,LSL#2 ; size in MB
	CMP r5,#0x10 ; is it 16MB?
	BNE not16 ; if no, move on
	MOV r12,#0x2 ; store size and CAS latency of 2
	B writesize

not16
	CMP r5,#0x20 ; is it 32MB?
	BNE not32 ; if no, move on
	MOV r12,#0x6 ; store size and CAS latency of 2
	B writesize

not32
	CMP r5,#0x40 ; is it 64MB?
	BNE not64 ; if no, move on
	MOV r12,#0xa ; store size and CAS latency of 2
	B writesize

not64
	CMP r5,#0x80 ; is it 128MB?
	BNE not128 ; if no, move on
	MOV r12,#0xe ; store size and CAS latency of 2
	B writesize

not128
	; if it is none of these sizes then it is either 256MB, or
	; there is no SDRAM fitted so default to 256MB.
	MOV r12,#0x12 ; store size and CAS latency of 2

writesize
	MOV r1,r1,LSL#8 ; get row address lines for SDRAM register
	ORR r2,r1,r2,LSL#12 ; OR in column address lines
	ORR r3,r2,r3,LSL#16 ; OR in number of banks
	ORR r12,r12,r3 ; OR in size and CAS latency
	LDR r0, =CM_BASE ; point at module registers
	STR r12,[r0,#0x20] ; store SDRAM parameters

  
	RET
	.type	__ghs_board_memory_init, $function
	.size	__ghs_board_memory_init, . - __ghs_board_memory_init
        .fsize  __ghs_board_memory_init, 0
