1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License.  See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2005-2008 Cavium Networks, Inc
7 */
8#ifndef __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H
9#define __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H
10
11
12#define CP0_CYCLE_COUNTER $9, 6
13#define CP0_CVMCTL_REG $9, 7
14#define CP0_CVMMEMCTL_REG $11,7
15#define CP0_PRID_REG $15, 0
16#define CP0_PRID_OCTEON_PASS1 0x000d0000
17#define CP0_PRID_OCTEON_CN30XX 0x000d0200
18
19.macro	kernel_entry_setup
20	# Registers set by bootloader:
21	# (only 32 bits set by bootloader, all addresses are physical
22	# addresses, and need to have the appropriate memory region set
23	# by the kernel
24	# a0 = argc
25	# a1 = argv (kseg0 compat addr)
26	# a2 = 1 if init core, zero otherwise
27	# a3 = address of boot descriptor block
28	.set push
29	.set arch=octeon
30	# Read the cavium mem control register
31	dmfc0	v0, CP0_CVMMEMCTL_REG
32	# Clear the lower 6 bits, the CVMSEG size
33	dins	v0, $0, 0, 6
34	ori	v0, CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE
35	dmtc0	v0, CP0_CVMMEMCTL_REG	# Write the cavium mem control register
36	dmfc0	v0, CP0_CVMCTL_REG	# Read the cavium control register
37	# Disable unaligned load/store support but leave HW fixup enabled
38	# Needed for octeon specific memcpy
39	or  v0, v0, 0x5001
40	xor v0, v0, 0x1001
41	# Read the processor ID register
42	mfc0 v1, CP0_PRID_REG
43	# Disable instruction prefetching (Octeon Pass1 errata)
44	or  v0, v0, 0x2000
45	# Skip reenable of prefetching for Octeon Pass1
46	beq v1, CP0_PRID_OCTEON_PASS1, skip
47	nop
48	# Reenable instruction prefetching, not on Pass1
49	xor v0, v0, 0x2000
50	# Strip off pass number off of processor id
51	srl v1, 8
52	sll v1, 8
53	# CN30XX needs some extra stuff turned off for better performance
54	bne v1, CP0_PRID_OCTEON_CN30XX, skip
55	nop
56	# CN30XX Use random Icache replacement
57	or  v0, v0, 0x400
58	# CN30XX Disable instruction prefetching
59	or  v0, v0, 0x2000
60skip:
61	# First clear off CvmCtl[IPPCI] bit and move the performance
62	# counters interrupt to IRQ 6
63	li	v1, ~(7 << 7)
64	and	v0, v0, v1
65	ori	v0, v0, (6 << 7)
66	# Write the cavium control register
67	dmtc0	v0, CP0_CVMCTL_REG
68	sync
69	# Flush dcache after config change
70	cache	9, 0($0)
71	# Get my core id
72	rdhwr	v0, $0
73	# Jump the master to kernel_entry
74	bne	a2, zero, octeon_main_processor
75	nop
76
77#ifdef CONFIG_SMP
78
79	#
80	# All cores other than the master need to wait here for SMP bootstrap
81	# to begin
82	#
83
84	# This is the variable where the next core to boot os stored
85	PTR_LA	t0, octeon_processor_boot
86octeon_spin_wait_boot:
87	# Get the core id of the next to be booted
88	LONG_L	t1, (t0)
89	# Keep looping if it isn't me
90	bne t1, v0, octeon_spin_wait_boot
91	nop
92	# Get my GP from the global variable
93	PTR_LA	t0, octeon_processor_gp
94	LONG_L	gp, (t0)
95	# Get my SP from the global variable
96	PTR_LA	t0, octeon_processor_sp
97	LONG_L	sp, (t0)
98	# Set the SP global variable to zero so the master knows we've started
99	LONG_S	zero, (t0)
100#ifdef __OCTEON__
101	syncw
102	syncw
103#else
104	sync
105#endif
106	# Jump to the normal Linux SMP entry point
107	j   smp_bootstrap
108	nop
109#else /* CONFIG_SMP */
110
111	#
112	# Someone tried to boot SMP with a non SMP kernel. All extra cores
113	# will halt here.
114	#
115octeon_wait_forever:
116	wait
117	b   octeon_wait_forever
118	nop
119
120#endif /* CONFIG_SMP */
121octeon_main_processor:
122	.set pop
123.endm
124
125/*
126 * Do SMP slave processor setup necessary before we can savely execute C code.
127 */
128	.macro	smp_slave_setup
129	.endm
130
131#endif /* __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H */
132