Commit | Line | Data |
---|---|---|
5b3b1688 DD |
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 | # 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 | |
86 | octeon_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 | # | |
115 | octeon_wait_forever: | |
116 | wait | |
117 | b octeon_wait_forever | |
118 | nop | |
119 | ||
120 | #endif /* CONFIG_SMP */ | |
121 | octeon_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 */ |