mirror of
				https://xff.cz/git/u-boot/
				synced 2025-10-31 02:15:45 +01:00 
			
		
		
		
	This is in preparation for adapting this board to function correctly on a physical MIPS Malta board. The board is moved into an "imgtec" vendor directory at the same time in order to ready us for any other boards supported by Imagination in the future. Signed-off-by: Paul Burton <paul.burton@imgtec.com>
		
			
				
	
	
		
			268 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			268 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| /*
 | |
|  *  Startup Code for MIPS32 CPU-core
 | |
|  *
 | |
|  *  Copyright (c) 2003	Wolfgang Denk <wd@denx.de>
 | |
|  *
 | |
|  * SPDX-License-Identifier:	GPL-2.0+
 | |
|  */
 | |
| 
 | |
| #include <asm-offsets.h>
 | |
| #include <config.h>
 | |
| #include <asm/regdef.h>
 | |
| #include <asm/mipsregs.h>
 | |
| 
 | |
| #ifndef CONFIG_SYS_MIPS_CACHE_MODE
 | |
| #define CONFIG_SYS_MIPS_CACHE_MODE CONF_CM_CACHABLE_NONCOHERENT
 | |
| #endif
 | |
| 
 | |
| 	/*
 | |
| 	 * For the moment disable interrupts, mark the kernel mode and
 | |
| 	 * set ST0_KX so that the CPU does not spit fire when using
 | |
| 	 * 64-bit addresses.
 | |
| 	 */
 | |
| 	.macro	setup_c0_status set clr
 | |
| 	.set	push
 | |
| 	mfc0	t0, CP0_STATUS
 | |
| 	or	t0, ST0_CU0 | \set | 0x1f | \clr
 | |
| 	xor	t0, 0x1f | \clr
 | |
| 	mtc0	t0, CP0_STATUS
 | |
| 	.set	noreorder
 | |
| 	sll	zero, 3				# ehb
 | |
| 	.set	pop
 | |
| 	.endm
 | |
| 
 | |
| 	.set noreorder
 | |
| 
 | |
| 	.globl _start
 | |
| 	.text
 | |
| _start:
 | |
| 	/* U-boot entry point */
 | |
| 	b	reset
 | |
| 	 nop
 | |
| 
 | |
| 	.org 0x10
 | |
| #if defined(CONFIG_SYS_XWAY_EBU_BOOTCFG)
 | |
| 	/*
 | |
| 	 * Almost all Lantiq XWAY SoC devices have an external bus unit (EBU) to
 | |
| 	 * access external NOR flashes. If the board boots from NOR flash the
 | |
| 	 * internal BootROM does a blind read at address 0xB0000010 to read the
 | |
| 	 * initial configuration for that EBU in order to access the flash
 | |
| 	 * device with correct parameters. This config option is board-specific.
 | |
| 	 */
 | |
| 	.word CONFIG_SYS_XWAY_EBU_BOOTCFG
 | |
| 	.word 0x0
 | |
| #elif defined(CONFIG_MALTA)
 | |
| 	/*
 | |
| 	 * Linux expects the Board ID here.
 | |
| 	 */
 | |
| 	.word 0x00000420	# 0x420 (Malta Board with CoreLV)
 | |
| 	.word 0x00000000
 | |
| #endif
 | |
| 
 | |
| 	.org 0x200
 | |
| 	/* TLB refill, 32 bit task */
 | |
| 1:	b	1b
 | |
| 	 nop
 | |
| 
 | |
| 	.org 0x280
 | |
| 	/* XTLB refill, 64 bit task */
 | |
| 1:	b	1b
 | |
| 	 nop
 | |
| 
 | |
| 	.org 0x300
 | |
| 	/* Cache error exception */
 | |
| 1:	b	1b
 | |
| 	 nop
 | |
| 
 | |
| 	.org 0x380
 | |
| 	/* General exception */
 | |
| 1:	b	1b
 | |
| 	 nop
 | |
| 
 | |
| 	.org 0x400
 | |
| 	/* Catch interrupt exceptions */
 | |
| 1:	b	1b
 | |
| 	 nop
 | |
| 
 | |
| 	.org 0x480
 | |
| 	/* EJTAG debug exception */
 | |
| 1:	b	1b
 | |
| 	 nop
 | |
| 
 | |
| 	.align 4
 | |
| reset:
 | |
| 
 | |
| 	/* Clear watch registers */
 | |
| 	mtc0	zero, CP0_WATCHLO
 | |
| 	mtc0	zero, CP0_WATCHHI
 | |
| 
 | |
| 	/* WP(Watch Pending), SW0/1 should be cleared */
 | |
| 	mtc0	zero, CP0_CAUSE
 | |
| 
 | |
| 	setup_c0_status 0 0
 | |
| 
 | |
| 	/* Init Timer */
 | |
| 	mtc0	zero, CP0_COUNT
 | |
| 	mtc0	zero, CP0_COMPARE
 | |
| 
 | |
| #ifndef CONFIG_SKIP_LOWLEVEL_INIT
 | |
| 	/* CONFIG0 register */
 | |
| 	li	t0, CONF_CM_UNCACHED
 | |
| 	mtc0	t0, CP0_CONFIG
 | |
| #endif
 | |
| 
 | |
| 	/* Initialize $gp */
 | |
| 	bal	1f
 | |
| 	 nop
 | |
| 	.word	_gp
 | |
| 1:
 | |
| 	lw	gp, 0(ra)
 | |
| 
 | |
| #ifndef CONFIG_SKIP_LOWLEVEL_INIT
 | |
| 	/* Initialize any external memory */
 | |
| 	la	t9, lowlevel_init
 | |
| 	jalr	t9
 | |
| 	 nop
 | |
| 
 | |
| 	/* Initialize caches... */
 | |
| 	la	t9, mips_cache_reset
 | |
| 	jalr	t9
 | |
| 	 nop
 | |
| 
 | |
| 	/* ... and enable them */
 | |
| 	li	t0, CONFIG_SYS_MIPS_CACHE_MODE
 | |
| 	mtc0	t0, CP0_CONFIG
 | |
| #endif
 | |
| 
 | |
| 	/* Set up temporary stack */
 | |
| 	li	sp, CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_INIT_SP_OFFSET
 | |
| 
 | |
| 	la	t9, board_init_f
 | |
| 	jr	t9
 | |
| 	 nop
 | |
| 
 | |
| /*
 | |
|  * void relocate_code (addr_sp, gd, addr_moni)
 | |
|  *
 | |
|  * This "function" does not return, instead it continues in RAM
 | |
|  * after relocating the monitor code.
 | |
|  *
 | |
|  * a0 = addr_sp
 | |
|  * a1 = gd
 | |
|  * a2 = destination address
 | |
|  */
 | |
| 	.globl	relocate_code
 | |
| 	.ent	relocate_code
 | |
| relocate_code:
 | |
| 	move	sp, a0			# set new stack pointer
 | |
| 
 | |
| 	move	s0, a1			# save gd in s0
 | |
| 	move	s2, a2			# save destination address in s2
 | |
| 
 | |
| 	li	t0, CONFIG_SYS_MONITOR_BASE
 | |
| 	sub	s1, s2, t0		# s1 <-- relocation offset
 | |
| 
 | |
| 	la	t3, in_ram
 | |
| 	lw	t2, -12(t3)		# t2 <-- __image_copy_end
 | |
| 	move	t1, a2
 | |
| 
 | |
| 	add	gp, s1			# adjust gp
 | |
| 
 | |
| 	/*
 | |
| 	 * t0 = source address
 | |
| 	 * t1 = target address
 | |
| 	 * t2 = source end address
 | |
| 	 */
 | |
| 1:
 | |
| 	lw	t3, 0(t0)
 | |
| 	sw	t3, 0(t1)
 | |
| 	addu	t0, 4
 | |
| 	blt	t0, t2, 1b
 | |
| 	 addu	t1, 4
 | |
| 
 | |
| 	/* If caches were enabled, we would have to flush them here. */
 | |
| 	sub	a1, t1, s2		# a1 <-- size
 | |
| 	la	t9, flush_cache
 | |
| 	jalr	t9
 | |
| 	 move	a0, s2			# a0 <-- destination address
 | |
| 
 | |
| 	/* Jump to where we've relocated ourselves */
 | |
| 	addi	t0, s2, in_ram - _start
 | |
| 	jr	t0
 | |
| 	 nop
 | |
| 
 | |
| 	.word	__rel_dyn_end
 | |
| 	.word	__rel_dyn_start
 | |
| 	.word	__image_copy_end
 | |
| 	.word	_GLOBAL_OFFSET_TABLE_
 | |
| 	.word	num_got_entries
 | |
| 
 | |
| in_ram:
 | |
| 	/*
 | |
| 	 * Now we want to update GOT.
 | |
| 	 *
 | |
| 	 * GOT[0] is reserved. GOT[1] is also reserved for the dynamic object
 | |
| 	 * generated by GNU ld. Skip these reserved entries from relocation.
 | |
| 	 */
 | |
| 	lw	t3, -4(t0)		# t3 <-- num_got_entries
 | |
| 	lw	t8, -8(t0)		# t8 <-- _GLOBAL_OFFSET_TABLE_
 | |
| 	add	t8, s1			# t8 now holds relocated _G_O_T_
 | |
| 	addi	t8, t8, 8		# skipping first two entries
 | |
| 	li	t2, 2
 | |
| 1:
 | |
| 	lw	t1, 0(t8)
 | |
| 	beqz	t1, 2f
 | |
| 	 add	t1, s1
 | |
| 	sw	t1, 0(t8)
 | |
| 2:
 | |
| 	addi	t2, 1
 | |
| 	blt	t2, t3, 1b
 | |
| 	 addi	t8, 4
 | |
| 
 | |
| 	/* Update dynamic relocations */
 | |
| 	lw	t1, -16(t0)		# t1 <-- __rel_dyn_start
 | |
| 	lw	t2, -20(t0)		# t2 <-- __rel_dyn_end
 | |
| 
 | |
| 	b	2f			# skip first reserved entry
 | |
| 	 addi	t1, 8
 | |
| 
 | |
| 1:
 | |
| 	lw	t8, -4(t1)		# t8 <-- relocation info
 | |
| 
 | |
| 	li	t3, 3
 | |
| 	bne	t8, t3, 2f		# skip non R_MIPS_REL32 entries
 | |
| 	 nop
 | |
| 
 | |
| 	lw	t3, -8(t1)		# t3 <-- location to fix up in FLASH
 | |
| 
 | |
| 	lw	t8, 0(t3)		# t8 <-- original pointer
 | |
| 	add	t8, s1			# t8 <-- adjusted pointer
 | |
| 
 | |
| 	add	t3, s1			# t3 <-- location to fix up in RAM
 | |
| 	sw	t8, 0(t3)
 | |
| 
 | |
| 2:
 | |
| 	blt	t1, t2, 1b
 | |
| 	 addi	t1, 8			# each rel.dyn entry is 8 bytes
 | |
| 
 | |
| 	/*
 | |
| 	 * Clear BSS
 | |
| 	 *
 | |
| 	 * GOT is now relocated. Thus __bss_start and __bss_end can be
 | |
| 	 * accessed directly via $gp.
 | |
| 	 */
 | |
| 	la	t1, __bss_start		# t1 <-- __bss_start
 | |
| 	la	t2, __bss_end		# t2 <-- __bss_end
 | |
| 
 | |
| 1:
 | |
| 	sw	zero, 0(t1)
 | |
| 	blt	t1, t2, 1b
 | |
| 	 addi	t1, 4
 | |
| 
 | |
| 	move	a0, s0			# a0 <-- gd
 | |
| 	la	t9, board_init_r
 | |
| 	jr	t9
 | |
| 	 move	a1, s2
 | |
| 
 | |
| 	.end	relocate_code
 |