Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / 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         # This is the variable where the next core to boot os stored
103         PTR_LA  t0, octeon_processor_boot
104 octeon_spin_wait_boot:
105         # Get the core id of the next to be booted
106         LONG_L  t1, (t0)
107         # Keep looping if it isn't me
108         bne t1, v0, octeon_spin_wait_boot
109         nop
110         # Get my GP from the global variable
111         PTR_LA  t0, octeon_processor_gp
112         LONG_L  gp, (t0)
113         # Get my SP from the global variable
114         PTR_LA  t0, octeon_processor_sp
115         LONG_L  sp, (t0)
116         # Set the SP global variable to zero so the master knows we've started
117         LONG_S  zero, (t0)
118 #ifdef __OCTEON__
119         syncw
120         syncw
121 #else
122         sync
123 #endif
124         # Jump to the normal Linux SMP entry point
125         j   smp_bootstrap
126         nop
127 #else /* CONFIG_SMP */
128
129         #
130         # Someone tried to boot SMP with a non SMP kernel. All extra cores
131         # will halt here.
132         #
133 octeon_wait_forever:
134         wait
135         b   octeon_wait_forever
136         nop
137
138 #endif /* CONFIG_SMP */
139 octeon_main_processor:
140         .set pop
141 .endm
142
143 /*
144  * Do SMP slave processor setup necessary before we can savely execute C code.
145  */
146         .macro  smp_slave_setup
147         .endm
148
149 #endif /* __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H */