mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-11-04 14:00:19 +00:00 
			
		
		
		
	This patch adds the necessary lowlevel init code, to enable SMP Linux booting. This code will be used with the platform specific Octeon Linux boot command "bootoctlinux", which starts a configurable number of cores into Linux. Additionally some erratas and lowlevel register initializations are copied from the original Cavium / Marvell U-Boot source code, enabling booting into the Linux kernel. Signed-off-by: Stefan Roese <sr@denx.de>
		
			
				
	
	
		
			146 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			146 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
/* SPDX-License-Identifier: GPL-2.0 */
 | 
						|
/*
 | 
						|
 * Copyright (C) 2020 Stefan Roese <sr@denx.de>
 | 
						|
 */
 | 
						|
 | 
						|
#include <config.h>
 | 
						|
#include <asm-offsets.h>
 | 
						|
#include <asm/cacheops.h>
 | 
						|
#include <asm/regdef.h>
 | 
						|
#include <asm/mipsregs.h>
 | 
						|
#include <asm/addrspace.h>
 | 
						|
#include <asm/asm.h>
 | 
						|
#include <mach/octeon-model.h>
 | 
						|
 | 
						|
#define COP0_CVMCTL_REG		$9,7	/* Cavium control */
 | 
						|
#define COP0_CVMMEMCTL_REG	$11,7	/* Cavium memory control */
 | 
						|
#define COP0_PROC_ID_REG	$15,0
 | 
						|
 | 
						|
	.set noreorder
 | 
						|
 | 
						|
LEAF(lowlevel_init)
 | 
						|
 | 
						|
	/* Set LMEMSZ in CVMMEMCTL register */
 | 
						|
	dmfc0	a0, COP0_CVMMEMCTL_REG
 | 
						|
	dins	a0, zero, 0, 9
 | 
						|
	mfc0	a4, COP0_PROC_ID_REG
 | 
						|
	li	a5, OCTEON_CN63XX_PASS1_0 /* Octeon cn63xx pass1 chip id */
 | 
						|
	bgt	a5, a4, 2f
 | 
						|
	 ori	 a0, 0x104	/* setup 4 lines of scratch */
 | 
						|
	ori	a6, a5, 8	/* Octeon cn63xx pass2 chip id */
 | 
						|
	bge	a4, a6, 2f
 | 
						|
	 nop
 | 
						|
	li	a6, 4
 | 
						|
	ins	a0, a6, 11, 4	/* Set WBTHRESH=4 as per Core-14752 errata */
 | 
						|
2:
 | 
						|
	dmtc0	a0, COP0_CVMMEMCTL_REG
 | 
						|
 | 
						|
	/* Set REPUN bit in CVMCTL register */
 | 
						|
	dmfc0	a0, COP0_CVMCTL_REG
 | 
						|
	ori	a0, 1<<14	/* enable fixup of unaligned mem access */
 | 
						|
	dmtc0	a0, COP0_CVMCTL_REG
 | 
						|
 | 
						|
	jr	ra
 | 
						|
	 nop
 | 
						|
	END(lowlevel_init)
 | 
						|
 | 
						|
LEAF(mips_mach_early_init)
 | 
						|
 | 
						|
	move    s0, ra
 | 
						|
 | 
						|
	bal	__dummy
 | 
						|
	 nop
 | 
						|
 | 
						|
__dummy:
 | 
						|
	/* Get the actual address that we are running at */
 | 
						|
	PTR_LA	a7, __dummy
 | 
						|
	dsubu	t3, ra, a7	/* t3 now has reloc offset */
 | 
						|
 | 
						|
	PTR_LA	t1, _start
 | 
						|
	daddu	t0, t1, t3	/* t0 now has actual address of _start */
 | 
						|
 | 
						|
	/* Calculate end address of copy loop */
 | 
						|
	PTR_LA	t2, _end
 | 
						|
	daddiu	t2, t2, 0x4000	/* Increase size to include appended DTB */
 | 
						|
	daddiu	t2, t2, 127
 | 
						|
	ins	t2, zero, 0, 7	/* Round up to cache line for memcpy */
 | 
						|
 | 
						|
	/* Copy ourself to the L2 cache from flash, 32 bytes at a time */
 | 
						|
1:
 | 
						|
	ld	a0, 0(t0)
 | 
						|
	ld	a1, 8(t0)
 | 
						|
	ld	a2, 16(t0)
 | 
						|
	ld	a3, 24(t0)
 | 
						|
	sd	a0, 0(t1)
 | 
						|
	sd	a1, 8(t1)
 | 
						|
	sd	a2, 16(t1)
 | 
						|
	sd	a3, 24(t1)
 | 
						|
	addiu	t0, 32
 | 
						|
	addiu	t1, 32
 | 
						|
	bne	t1, t2, 1b
 | 
						|
	 nop
 | 
						|
 | 
						|
	sync
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Return to start.S now running from TEXT_BASE, which points
 | 
						|
	 * to DRAM address space, which effectively is L2 cache now.
 | 
						|
	 * This speeds up the init process extremely, especially the
 | 
						|
	 * DDR init code.
 | 
						|
	 */
 | 
						|
	dsubu	s0, s0, t3	/* Fixup return address with reloc offset */
 | 
						|
	jr.hb	s0		/* Jump back with hazard barrier */
 | 
						|
	 nop
 | 
						|
 | 
						|
	END(mips_mach_early_init)
 | 
						|
 | 
						|
LEAF(nmi_bootvector)
 | 
						|
 | 
						|
	/*
 | 
						|
	 * From Marvell original bootvector setup
 | 
						|
	 */
 | 
						|
	mfc0	k0, CP0_STATUS
 | 
						|
	/* Enable 64-bit addressing, set ERL (should already be set) */
 | 
						|
	ori	k0, 0x84
 | 
						|
	mtc0	k0, CP0_STATUS
 | 
						|
	/* Core-14345, clear L1 Dcache virtual tags if the core hit an NMI */
 | 
						|
	cache	17, 0($0)
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Needed for Linux kernel booting, otherwise it hangs while
 | 
						|
	 * zero'ing all of CVMSEG
 | 
						|
	 */
 | 
						|
	dmfc0	a0, COP0_CVMMEMCTL_REG
 | 
						|
	dins	a0, zero, 0, 9
 | 
						|
	ori	a0, 0x104	/* setup 4 lines of scratch */
 | 
						|
	dmtc0	a0, COP0_CVMMEMCTL_REG
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Load parameters and entry point
 | 
						|
	 */
 | 
						|
	PTR_LA	t9, nmi_handler_para
 | 
						|
	sync
 | 
						|
 | 
						|
	ld	s0, 0x00(t9)
 | 
						|
	ld	a0, 0x08(t9)
 | 
						|
	ld	a1, 0x10(t9)
 | 
						|
	ld	a2, 0x18(t9)
 | 
						|
	ld	a3, 0x20(t9)
 | 
						|
 | 
						|
	/* Finally jump to entry point (start kernel etc) */
 | 
						|
	j	s0
 | 
						|
	 nop
 | 
						|
 | 
						|
	END(nmi_bootvector)
 | 
						|
 | 
						|
	/*
 | 
						|
	 * Add here some space for the NMI parameters (entry point and args)
 | 
						|
	 */
 | 
						|
	.globl nmi_handler_para
 | 
						|
nmi_handler_para:
 | 
						|
	.dword	0	// entry-point
 | 
						|
	.dword	0	// arg0
 | 
						|
	.dword	0	// arg1
 | 
						|
	.dword	0	// arg2
 | 
						|
	.dword	0	// arg3
 |