xref: /linux/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h (revision 664d699af24ee73cbc147c4c0f76c8c8ff9ef66f)
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 
125b3b1688SDavid Daney #define CP0_CYCLE_COUNTER $9, 6
135b3b1688SDavid Daney #define CP0_CVMCTL_REG $9, 7
145b3b1688SDavid Daney #define CP0_CVMMEMCTL_REG $11,7
155b3b1688SDavid Daney #define CP0_PRID_REG $15, 0
165b3b1688SDavid Daney #define CP0_PRID_OCTEON_PASS1 0x000d0000
175b3b1688SDavid Daney #define CP0_PRID_OCTEON_CN30XX 0x000d0200
185b3b1688SDavid Daney 
195b3b1688SDavid Daney .macro	kernel_entry_setup
205b3b1688SDavid Daney 	# Registers set by bootloader:
215b3b1688SDavid Daney 	# (only 32 bits set by bootloader, all addresses are physical
225b3b1688SDavid Daney 	# addresses, and need to have the appropriate memory region set
235b3b1688SDavid Daney 	# by the kernel
245b3b1688SDavid Daney 	# a0 = argc
255b3b1688SDavid Daney 	# a1 = argv (kseg0 compat addr)
265b3b1688SDavid Daney 	# a2 = 1 if init core, zero otherwise
275b3b1688SDavid Daney 	# a3 = address of boot descriptor block
285b3b1688SDavid Daney 	.set push
295b3b1688SDavid Daney 	.set arch=octeon
305b3b1688SDavid Daney 	# Read the cavium mem control register
315b3b1688SDavid Daney 	dmfc0	v0, CP0_CVMMEMCTL_REG
325b3b1688SDavid Daney 	# Clear the lower 6 bits, the CVMSEG size
335b3b1688SDavid Daney 	dins	v0, $0, 0, 6
345b3b1688SDavid Daney 	ori	v0, CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE
355b3b1688SDavid Daney 	dmtc0	v0, CP0_CVMMEMCTL_REG	# Write the cavium mem control register
365b3b1688SDavid Daney 	dmfc0	v0, CP0_CVMCTL_REG	# Read the cavium control register
375b3b1688SDavid Daney 	# Disable unaligned load/store support but leave HW fixup enabled
380ec31512SDavid Daney 	# Needed for octeon specific memcpy
395b3b1688SDavid Daney 	or  v0, v0, 0x5001
405b3b1688SDavid Daney 	xor v0, v0, 0x1001
415b3b1688SDavid Daney 	# Read the processor ID register
425b3b1688SDavid Daney 	mfc0 v1, CP0_PRID_REG
435b3b1688SDavid Daney 	# Disable instruction prefetching (Octeon Pass1 errata)
445b3b1688SDavid Daney 	or  v0, v0, 0x2000
455b3b1688SDavid Daney 	# Skip reenable of prefetching for Octeon Pass1
465b3b1688SDavid Daney 	beq v1, CP0_PRID_OCTEON_PASS1, skip
475b3b1688SDavid Daney 	nop
485b3b1688SDavid Daney 	# Reenable instruction prefetching, not on Pass1
495b3b1688SDavid Daney 	xor v0, v0, 0x2000
505b3b1688SDavid Daney 	# Strip off pass number off of processor id
515b3b1688SDavid Daney 	srl v1, 8
525b3b1688SDavid Daney 	sll v1, 8
535b3b1688SDavid Daney 	# CN30XX needs some extra stuff turned off for better performance
545b3b1688SDavid Daney 	bne v1, CP0_PRID_OCTEON_CN30XX, skip
555b3b1688SDavid Daney 	nop
565b3b1688SDavid Daney 	# CN30XX Use random Icache replacement
575b3b1688SDavid Daney 	or  v0, v0, 0x400
585b3b1688SDavid Daney 	# CN30XX Disable instruction prefetching
595b3b1688SDavid Daney 	or  v0, v0, 0x2000
605b3b1688SDavid Daney skip:
617716e654SChandrakala Chavva 	# First clear off CvmCtl[IPPCI] bit and move the performance
627716e654SChandrakala Chavva 	# counters interrupt to IRQ 6
637716e654SChandrakala Chavva 	li	v1, ~(7 << 7)
647716e654SChandrakala Chavva 	and	v0, v0, v1
657716e654SChandrakala Chavva 	ori	v0, v0, (6 << 7)
66*664d699aSDavid Daney 
67*664d699aSDavid Daney 	mfc0	v1, CP0_PRID_REG
68*664d699aSDavid Daney 	and	t1, v1, 0xfff8
69*664d699aSDavid Daney 	xor	t1, t1, 0x9000		# 63-P1
70*664d699aSDavid Daney 	beqz	t1, 4f
71*664d699aSDavid Daney 	and	t1, v1, 0xfff8
72*664d699aSDavid Daney 	xor	t1, t1, 0x9008		# 63-P2
73*664d699aSDavid Daney 	beqz	t1, 4f
74*664d699aSDavid Daney 	and	t1, v1, 0xfff8
75*664d699aSDavid Daney 	xor	t1, t1, 0x9100		# 68-P1
76*664d699aSDavid Daney 	beqz	t1, 4f
77*664d699aSDavid Daney 	and	t1, v1, 0xff00
78*664d699aSDavid Daney 	xor	t1, t1, 0x9200		# 66-PX
79*664d699aSDavid Daney 	bnez	t1, 5f			# Skip WAR for others.
80*664d699aSDavid Daney 	and	t1, v1, 0x00ff
81*664d699aSDavid Daney 	slti	t1, t1, 2		# 66-P1.2 and later good.
82*664d699aSDavid Daney 	beqz	t1, 5f
83*664d699aSDavid Daney 
84*664d699aSDavid Daney 4:	# core-16057 work around
85*664d699aSDavid Daney 	or	v0, v0, 0x2000		# Set IPREF bit.
86*664d699aSDavid Daney 
87*664d699aSDavid Daney 5:	# No core-16057 work around
885b3b1688SDavid Daney 	# Write the cavium control register
895b3b1688SDavid Daney 	dmtc0	v0, CP0_CVMCTL_REG
905b3b1688SDavid Daney 	sync
915b3b1688SDavid Daney 	# Flush dcache after config change
925b3b1688SDavid Daney 	cache	9, 0($0)
935b3b1688SDavid Daney 	# Get my core id
945b3b1688SDavid Daney 	rdhwr	v0, $0
955b3b1688SDavid Daney 	# Jump the master to kernel_entry
965b3b1688SDavid Daney 	bne	a2, zero, octeon_main_processor
975b3b1688SDavid Daney 	nop
985b3b1688SDavid Daney 
995b3b1688SDavid Daney #ifdef CONFIG_SMP
1005b3b1688SDavid Daney 
1015b3b1688SDavid Daney 	#
1025b3b1688SDavid Daney 	# All cores other than the master need to wait here for SMP bootstrap
1035b3b1688SDavid Daney 	# to begin
1045b3b1688SDavid Daney 	#
1055b3b1688SDavid Daney 
1065b3b1688SDavid Daney 	# This is the variable where the next core to boot os stored
1075b3b1688SDavid Daney 	PTR_LA	t0, octeon_processor_boot
1085b3b1688SDavid Daney octeon_spin_wait_boot:
1095b3b1688SDavid Daney 	# Get the core id of the next to be booted
1105b3b1688SDavid Daney 	LONG_L	t1, (t0)
1115b3b1688SDavid Daney 	# Keep looping if it isn't me
1125b3b1688SDavid Daney 	bne t1, v0, octeon_spin_wait_boot
1135b3b1688SDavid Daney 	nop
1145b3b1688SDavid Daney 	# Get my GP from the global variable
1155b3b1688SDavid Daney 	PTR_LA	t0, octeon_processor_gp
1165b3b1688SDavid Daney 	LONG_L	gp, (t0)
1175b3b1688SDavid Daney 	# Get my SP from the global variable
1185b3b1688SDavid Daney 	PTR_LA	t0, octeon_processor_sp
1195b3b1688SDavid Daney 	LONG_L	sp, (t0)
1205b3b1688SDavid Daney 	# Set the SP global variable to zero so the master knows we've started
1215b3b1688SDavid Daney 	LONG_S	zero, (t0)
1225b3b1688SDavid Daney #ifdef __OCTEON__
1235b3b1688SDavid Daney 	syncw
1245b3b1688SDavid Daney 	syncw
1255b3b1688SDavid Daney #else
1265b3b1688SDavid Daney 	sync
1275b3b1688SDavid Daney #endif
1285b3b1688SDavid Daney 	# Jump to the normal Linux SMP entry point
1295b3b1688SDavid Daney 	j   smp_bootstrap
1305b3b1688SDavid Daney 	nop
1315b3b1688SDavid Daney #else /* CONFIG_SMP */
1325b3b1688SDavid Daney 
1335b3b1688SDavid Daney 	#
1345b3b1688SDavid Daney 	# Someone tried to boot SMP with a non SMP kernel. All extra cores
1355b3b1688SDavid Daney 	# will halt here.
1365b3b1688SDavid Daney 	#
1375b3b1688SDavid Daney octeon_wait_forever:
1385b3b1688SDavid Daney 	wait
1395b3b1688SDavid Daney 	b   octeon_wait_forever
1405b3b1688SDavid Daney 	nop
1415b3b1688SDavid Daney 
1425b3b1688SDavid Daney #endif /* CONFIG_SMP */
1435b3b1688SDavid Daney octeon_main_processor:
1445b3b1688SDavid Daney 	.set pop
1455b3b1688SDavid Daney .endm
1465b3b1688SDavid Daney 
1475b3b1688SDavid Daney /*
1485b3b1688SDavid Daney  * Do SMP slave processor setup necessary before we can savely execute C code.
1495b3b1688SDavid Daney  */
1505b3b1688SDavid Daney 	.macro	smp_slave_setup
1515b3b1688SDavid Daney 	.endm
1525b3b1688SDavid Daney 
1535b3b1688SDavid Daney #endif /* __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H */
154