Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
kernel-entry-init.h
Go to the documentation of this file.
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
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
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
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
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 */