xref: /linux/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h (revision 8be98d2f2a0a262f8bf8a0bc1fdf522b3c7aab17)
15b3b1688SDavid Daney /*
25b3b1688SDavid Daney  * This file is subject to the terms and conditions of the GNU General Public
35b3b1688SDavid Daney  * License.  See the file "COPYING" in the main directory of this archive
45b3b1688SDavid Daney  * for more details.
55b3b1688SDavid Daney  *
65b3b1688SDavid Daney  * Copyright (C) 2005-2008 Cavium Networks, Inc
75b3b1688SDavid Daney  */
85b3b1688SDavid Daney #ifndef __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H
95b3b1688SDavid Daney #define __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H
105b3b1688SDavid Daney 
115b3b1688SDavid Daney #define CP0_CVMCTL_REG $9, 7
125b3b1688SDavid Daney #define CP0_CVMMEMCTL_REG $11,7
135b3b1688SDavid Daney #define CP0_PRID_REG $15, 0
14726da2f8SDavid Daney #define CP0_DCACHE_ERR_REG $27, 1
155b3b1688SDavid Daney #define CP0_PRID_OCTEON_PASS1 0x000d0000
165b3b1688SDavid Daney #define CP0_PRID_OCTEON_CN30XX 0x000d0200
175b3b1688SDavid Daney 
185b3b1688SDavid Daney .macro	kernel_entry_setup
195b3b1688SDavid Daney 	# Registers set by bootloader:
205b3b1688SDavid Daney 	# (only 32 bits set by bootloader, all addresses are physical
215b3b1688SDavid Daney 	# addresses, and need to have the appropriate memory region set
225b3b1688SDavid Daney 	# by the kernel
235b3b1688SDavid Daney 	# a0 = argc
245b3b1688SDavid Daney 	# a1 = argv (kseg0 compat addr)
255b3b1688SDavid Daney 	# a2 = 1 if init core, zero otherwise
265b3b1688SDavid Daney 	# a3 = address of boot descriptor block
275b3b1688SDavid Daney 	.set push
285b3b1688SDavid Daney 	.set arch=octeon
295b3b1688SDavid Daney 	# Read the cavium mem control register
305b3b1688SDavid Daney 	dmfc0	v0, CP0_CVMMEMCTL_REG
315b3b1688SDavid Daney 	# Clear the lower 6 bits, the CVMSEG size
325b3b1688SDavid Daney 	dins	v0, $0, 0, 6
335b3b1688SDavid Daney 	ori	v0, CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE
345b3b1688SDavid Daney 	dmtc0	v0, CP0_CVMMEMCTL_REG	# Write the cavium mem control register
355b3b1688SDavid Daney 	dmfc0	v0, CP0_CVMCTL_REG	# Read the cavium control register
365b3b1688SDavid Daney 	# Disable unaligned load/store support but leave HW fixup enabled
370ec31512SDavid Daney 	# Needed for octeon specific memcpy
385b3b1688SDavid Daney 	or  v0, v0, 0x5001
395b3b1688SDavid Daney 	xor v0, v0, 0x1001
407716e654SChandrakala Chavva 	# First clear off CvmCtl[IPPCI] bit and move the performance
417716e654SChandrakala Chavva 	# counters interrupt to IRQ 6
42726da2f8SDavid Daney 	dli	v1, ~(7 << 7)
437716e654SChandrakala Chavva 	and	v0, v0, v1
447716e654SChandrakala Chavva 	ori	v0, v0, (6 << 7)
45664d699aSDavid Daney 
46664d699aSDavid Daney 	mfc0	v1, CP0_PRID_REG
47664d699aSDavid Daney 	and	t1, v1, 0xfff8
48664d699aSDavid Daney 	xor	t1, t1, 0x9000		# 63-P1
49664d699aSDavid Daney 	beqz	t1, 4f
50664d699aSDavid Daney 	and	t1, v1, 0xfff8
51664d699aSDavid Daney 	xor	t1, t1, 0x9008		# 63-P2
52664d699aSDavid Daney 	beqz	t1, 4f
53664d699aSDavid Daney 	and	t1, v1, 0xfff8
54664d699aSDavid Daney 	xor	t1, t1, 0x9100		# 68-P1
55664d699aSDavid Daney 	beqz	t1, 4f
56664d699aSDavid Daney 	and	t1, v1, 0xff00
57664d699aSDavid Daney 	xor	t1, t1, 0x9200		# 66-PX
58664d699aSDavid Daney 	bnez	t1, 5f			# Skip WAR for others.
59664d699aSDavid Daney 	and	t1, v1, 0x00ff
60664d699aSDavid Daney 	slti	t1, t1, 2		# 66-P1.2 and later good.
61664d699aSDavid Daney 	beqz	t1, 5f
62664d699aSDavid Daney 
63664d699aSDavid Daney 4:	# core-16057 work around
64664d699aSDavid Daney 	or	v0, v0, 0x2000		# Set IPREF bit.
65664d699aSDavid Daney 
66664d699aSDavid Daney 5:	# No core-16057 work around
675b3b1688SDavid Daney 	# Write the cavium control register
685b3b1688SDavid Daney 	dmtc0	v0, CP0_CVMCTL_REG
695b3b1688SDavid Daney 	sync
705b3b1688SDavid Daney 	# Flush dcache after config change
715b3b1688SDavid Daney 	cache	9, 0($0)
72726da2f8SDavid Daney 	# Zero all of CVMSEG to make sure parity is correct
73726da2f8SDavid Daney 	dli	v0, CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE
74726da2f8SDavid Daney 	dsll	v0, 7
75726da2f8SDavid Daney 	beqz	v0, 2f
76726da2f8SDavid Daney 1:	dsubu	v0, 8
77726da2f8SDavid Daney 	sd	$0, -32768(v0)
78726da2f8SDavid Daney 	bnez	v0, 1b
79726da2f8SDavid Daney 2:
80726da2f8SDavid Daney 	mfc0	v0, CP0_PRID_REG
81726da2f8SDavid Daney 	bbit0	v0, 15, 1f
82726da2f8SDavid Daney 	# OCTEON II or better have bit 15 set.  Clear the error bits.
83ac6d9b3aSChandrakala Chavva 	and	t1, v0, 0xff00
84ac6d9b3aSChandrakala Chavva 	dli	v0, 0x9500
85ac6d9b3aSChandrakala Chavva 	bge	t1, v0, 1f  # OCTEON III has no DCACHE_ERR_REG COP0
86726da2f8SDavid Daney 	dli	v0, 0x27
87726da2f8SDavid Daney 	dmtc0	v0, CP0_DCACHE_ERR_REG
88726da2f8SDavid Daney 1:
895b3b1688SDavid Daney 	# Get my core id
905b3b1688SDavid Daney 	rdhwr	v0, $0
915b3b1688SDavid Daney 	# Jump the master to kernel_entry
925b3b1688SDavid Daney 	bne	a2, zero, octeon_main_processor
935b3b1688SDavid Daney 	nop
945b3b1688SDavid Daney 
955b3b1688SDavid Daney #ifdef CONFIG_SMP
965b3b1688SDavid Daney 
975b3b1688SDavid Daney 	#
985b3b1688SDavid Daney 	# All cores other than the master need to wait here for SMP bootstrap
995b3b1688SDavid Daney 	# to begin
1005b3b1688SDavid Daney 	#
1015b3b1688SDavid Daney 
1025b3b1688SDavid Daney octeon_spin_wait_boot:
1033ff72be4SSteven J. Hill #ifdef CONFIG_RELOCATABLE
1043ff72be4SSteven J. Hill 	PTR_LA	t0, octeon_processor_relocated_kernel_entry
1053ff72be4SSteven J. Hill 	LONG_L	t0, (t0)
1063ff72be4SSteven J. Hill 	beq	zero, t0, 1f
1073ff72be4SSteven J. Hill 	nop
1083ff72be4SSteven J. Hill 
1093ff72be4SSteven J. Hill 	jr	t0
1103ff72be4SSteven J. Hill 	nop
1113ff72be4SSteven J. Hill 1:
1123ff72be4SSteven J. Hill #endif /* CONFIG_RELOCATABLE */
1133ff72be4SSteven J. Hill 
1143ff72be4SSteven J. Hill 	# This is the variable where the next core to boot is stored
1153ff72be4SSteven J. Hill 	PTR_LA	t0, octeon_processor_boot
1165b3b1688SDavid Daney 	# Get the core id of the next to be booted
1175b3b1688SDavid Daney 	LONG_L	t1, (t0)
1185b3b1688SDavid Daney 	# Keep looping if it isn't me
1195b3b1688SDavid Daney 	bne t1, v0, octeon_spin_wait_boot
1205b3b1688SDavid Daney 	nop
1215b3b1688SDavid Daney 	# Get my GP from the global variable
1225b3b1688SDavid Daney 	PTR_LA	t0, octeon_processor_gp
1235b3b1688SDavid Daney 	LONG_L	gp, (t0)
1245b3b1688SDavid Daney 	# Get my SP from the global variable
1255b3b1688SDavid Daney 	PTR_LA	t0, octeon_processor_sp
1265b3b1688SDavid Daney 	LONG_L	sp, (t0)
1275b3b1688SDavid Daney 	# Set the SP global variable to zero so the master knows we've started
1285b3b1688SDavid Daney 	LONG_S	zero, (t0)
1295b3b1688SDavid Daney #ifdef __OCTEON__
1305b3b1688SDavid Daney 	syncw
1315b3b1688SDavid Daney 	syncw
1325b3b1688SDavid Daney #else
1335b3b1688SDavid Daney 	sync
1345b3b1688SDavid Daney #endif
1355b3b1688SDavid Daney 	# Jump to the normal Linux SMP entry point
1365b3b1688SDavid Daney 	j   smp_bootstrap
1375b3b1688SDavid Daney 	nop
1385b3b1688SDavid Daney #else /* CONFIG_SMP */
1395b3b1688SDavid Daney 
1405b3b1688SDavid Daney 	#
1415b3b1688SDavid Daney 	# Someone tried to boot SMP with a non SMP kernel. All extra cores
1425b3b1688SDavid Daney 	# will halt here.
1435b3b1688SDavid Daney 	#
1445b3b1688SDavid Daney octeon_wait_forever:
1455b3b1688SDavid Daney 	wait
1465b3b1688SDavid Daney 	b   octeon_wait_forever
1475b3b1688SDavid Daney 	nop
1485b3b1688SDavid Daney 
1495b3b1688SDavid Daney #endif /* CONFIG_SMP */
1505b3b1688SDavid Daney octeon_main_processor:
1515b3b1688SDavid Daney 	.set pop
1525b3b1688SDavid Daney .endm
1535b3b1688SDavid Daney 
1545b3b1688SDavid Daney /*
15592a76f6dSAdam Buchbinder  * Do SMP slave processor setup necessary before we can safely execute C code.
1565b3b1688SDavid Daney  */
1575b3b1688SDavid Daney 	.macro	smp_slave_setup
1585b3b1688SDavid Daney 	.endm
1595b3b1688SDavid Daney 
160*6ce48897SHuacai Chen #define USE_KEXEC_SMP_WAIT_FINAL
161*6ce48897SHuacai Chen 	.macro  kexec_smp_wait_final
162*6ce48897SHuacai Chen 	.set push
163*6ce48897SHuacai Chen 	.set noreorder
164*6ce48897SHuacai Chen 	synci		0($0)
165*6ce48897SHuacai Chen 	.set pop
166*6ce48897SHuacai Chen 	.endm
167*6ce48897SHuacai Chen 
1685b3b1688SDavid Daney #endif /* __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H */
169