GNU Linux-libre 4.14.290-gnu1
[releases.git] / arch / mips / include / asm / mach-cavium-octeon / kernel-entry-init.h
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 #define CP0_CVMCTL_REG $9, 7
12 #define CP0_CVMMEMCTL_REG $11,7
13 #define CP0_PRID_REG $15, 0
14 #define CP0_DCACHE_ERR_REG $27, 1
15 #define CP0_PRID_OCTEON_PASS1 0x000d0000
16 #define CP0_PRID_OCTEON_CN30XX 0x000d0200
17
18 .macro  kernel_entry_setup
19         # Registers set by bootloader:
20         # (only 32 bits set by bootloader, all addresses are physical
21         # addresses, and need to have the appropriate memory region set
22         # by the kernel
23         # a0 = argc
24         # a1 = argv (kseg0 compat addr)
25         # a2 = 1 if init core, zero otherwise
26         # a3 = address of boot descriptor block
27         .set push
28         .set arch=octeon
29         # Read the cavium mem control register
30         dmfc0   v0, CP0_CVMMEMCTL_REG
31         # Clear the lower 6 bits, the CVMSEG size
32         dins    v0, $0, 0, 6
33         ori     v0, CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE
34         dmtc0   v0, CP0_CVMMEMCTL_REG   # Write the cavium mem control register
35         dmfc0   v0, CP0_CVMCTL_REG      # Read the cavium control register
36         # Disable unaligned load/store support but leave HW fixup enabled
37         # Needed for octeon specific memcpy
38         or  v0, v0, 0x5001
39         xor v0, v0, 0x1001
40         # First clear off CvmCtl[IPPCI] bit and move the performance
41         # counters interrupt to IRQ 6
42         dli     v1, ~(7 << 7)
43         and     v0, v0, v1
44         ori     v0, v0, (6 << 7)
45
46         mfc0    v1, CP0_PRID_REG
47         and     t1, v1, 0xfff8
48         xor     t1, t1, 0x9000          # 63-P1
49         beqz    t1, 4f
50         and     t1, v1, 0xfff8
51         xor     t1, t1, 0x9008          # 63-P2
52         beqz    t1, 4f
53         and     t1, v1, 0xfff8
54         xor     t1, t1, 0x9100          # 68-P1
55         beqz    t1, 4f
56         and     t1, v1, 0xff00
57         xor     t1, t1, 0x9200          # 66-PX
58         bnez    t1, 5f                  # Skip WAR for others.
59         and     t1, v1, 0x00ff
60         slti    t1, t1, 2               # 66-P1.2 and later good.
61         beqz    t1, 5f
62
63 4:      # core-16057 work around
64         or      v0, v0, 0x2000          # Set IPREF bit.
65
66 5:      # No core-16057 work around
67         # Write the cavium control register
68         dmtc0   v0, CP0_CVMCTL_REG
69         sync
70         # Flush dcache after config change
71         cache   9, 0($0)
72         # Zero all of CVMSEG to make sure parity is correct
73         dli     v0, CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE
74         dsll    v0, 7
75         beqz    v0, 2f
76 1:      dsubu   v0, 8
77         sd      $0, -32768(v0)
78         bnez    v0, 1b
79 2:
80         mfc0    v0, CP0_PRID_REG
81         bbit0   v0, 15, 1f
82         # OCTEON II or better have bit 15 set.  Clear the error bits.
83         and     t1, v0, 0xff00
84         dli     v0, 0x9500
85         bge     t1, v0, 1f  # OCTEON III has no DCACHE_ERR_REG COP0
86         dli     v0, 0x27
87         dmtc0   v0, CP0_DCACHE_ERR_REG
88 1:
89         # Get my core id
90         rdhwr   v0, $0
91         # Jump the master to kernel_entry
92         bne     a2, zero, octeon_main_processor
93         nop
94
95 #ifdef CONFIG_SMP
96
97         #
98         # All cores other than the master need to wait here for SMP bootstrap
99         # to begin
100         #
101
102 octeon_spin_wait_boot:
103 #ifdef CONFIG_RELOCATABLE
104         PTR_LA  t0, octeon_processor_relocated_kernel_entry
105         LONG_L  t0, (t0)
106         beq     zero, t0, 1f
107         nop
108
109         jr      t0
110         nop
111 1:
112 #endif /* CONFIG_RELOCATABLE */
113
114         # This is the variable where the next core to boot is stored
115         PTR_LA  t0, octeon_processor_boot
116         # Get the core id of the next to be booted
117         LONG_L  t1, (t0)
118         # Keep looping if it isn't me
119         bne t1, v0, octeon_spin_wait_boot
120         nop
121         # Get my GP from the global variable
122         PTR_LA  t0, octeon_processor_gp
123         LONG_L  gp, (t0)
124         # Get my SP from the global variable
125         PTR_LA  t0, octeon_processor_sp
126         LONG_L  sp, (t0)
127         # Set the SP global variable to zero so the master knows we've started
128         LONG_S  zero, (t0)
129 #ifdef __OCTEON__
130         syncw
131         syncw
132 #else
133         sync
134 #endif
135         # Jump to the normal Linux SMP entry point
136         j   smp_bootstrap
137         nop
138 #else /* CONFIG_SMP */
139
140         #
141         # Someone tried to boot SMP with a non SMP kernel. All extra cores
142         # will halt here.
143         #
144 octeon_wait_forever:
145         wait
146         b   octeon_wait_forever
147         nop
148
149 #endif /* CONFIG_SMP */
150 octeon_main_processor:
151         .set pop
152 .endm
153
154 /*
155  * Do SMP slave processor setup necessary before we can safely execute C code.
156  */
157         .macro  smp_slave_setup
158         .endm
159
160 #endif /* __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H */