xref: /linux/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h (revision aa7eb8e78d8ecd6cd0475d86ea8385ff9cb47ece)
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 #ifdef CONFIG_CAVIUM_OCTEON_HW_FIX_UNALIGNED
38 	# Disable unaligned load/store support but leave HW fixup enabled
39 	or  v0, v0, 0x5001
40 	xor v0, v0, 0x1001
41 #else
42 	# Disable unaligned load/store and HW fixup support
43 	or  v0, v0, 0x5001
44 	xor v0, v0, 0x5001
45 #endif
46 	# Read the processor ID register
47 	mfc0 v1, CP0_PRID_REG
48 	# Disable instruction prefetching (Octeon Pass1 errata)
49 	or  v0, v0, 0x2000
50 	# Skip reenable of prefetching for Octeon Pass1
51 	beq v1, CP0_PRID_OCTEON_PASS1, skip
52 	nop
53 	# Reenable instruction prefetching, not on Pass1
54 	xor v0, v0, 0x2000
55 	# Strip off pass number off of processor id
56 	srl v1, 8
57 	sll v1, 8
58 	# CN30XX needs some extra stuff turned off for better performance
59 	bne v1, CP0_PRID_OCTEON_CN30XX, skip
60 	nop
61 	# CN30XX Use random Icache replacement
62 	or  v0, v0, 0x400
63 	# CN30XX Disable instruction prefetching
64 	or  v0, v0, 0x2000
65 skip:
66 	# First clear off CvmCtl[IPPCI] bit and move the performance
67 	# counters interrupt to IRQ 6
68 	li	v1, ~(7 << 7)
69 	and	v0, v0, v1
70 	ori	v0, v0, (6 << 7)
71 	# Write the cavium control register
72 	dmtc0   v0, CP0_CVMCTL_REG
73 	sync
74 	# Flush dcache after config change
75 	cache   9, 0($0)
76 	# Get my core id
77 	rdhwr   v0, $0
78 	# Jump the master to kernel_entry
79 	bne     a2, zero, octeon_main_processor
80 	nop
81 
82 #ifdef CONFIG_SMP
83 
84 	#
85 	# All cores other than the master need to wait here for SMP bootstrap
86 	# to begin
87 	#
88 
89 	# This is the variable where the next core to boot os stored
90 	PTR_LA  t0, octeon_processor_boot
91 octeon_spin_wait_boot:
92 	# Get the core id of the next to be booted
93 	LONG_L  t1, (t0)
94 	# Keep looping if it isn't me
95 	bne t1, v0, octeon_spin_wait_boot
96 	nop
97 	# Get my GP from the global variable
98 	PTR_LA  t0, octeon_processor_gp
99 	LONG_L  gp, (t0)
100 	# Get my SP from the global variable
101 	PTR_LA  t0, octeon_processor_sp
102 	LONG_L  sp, (t0)
103 	# Set the SP global variable to zero so the master knows we've started
104 	LONG_S  zero, (t0)
105 #ifdef __OCTEON__
106 	syncw
107 	syncw
108 #else
109 	sync
110 #endif
111 	# Jump to the normal Linux SMP entry point
112 	j   smp_bootstrap
113 	nop
114 #else /* CONFIG_SMP */
115 
116 	#
117 	# Someone tried to boot SMP with a non SMP kernel. All extra cores
118 	# will halt here.
119 	#
120 octeon_wait_forever:
121 	wait
122 	b   octeon_wait_forever
123 	nop
124 
125 #endif /* CONFIG_SMP */
126 octeon_main_processor:
127 	.set pop
128 .endm
129 
130 /*
131  * Do SMP slave processor setup necessary before we can savely execute C code.
132  */
133 	.macro  smp_slave_setup
134 	.endm
135 
136 #endif /* __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H */
137