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 # Disable unaligned load/store support but leave HW fixup enabled 38 # Needed for octeon specific memcpy 39 or v0, v0, 0x5001 40 xor v0, v0, 0x1001 41 # Read the processor ID register 42 mfc0 v1, CP0_PRID_REG 43 # Disable instruction prefetching (Octeon Pass1 errata) 44 or v0, v0, 0x2000 45 # Skip reenable of prefetching for Octeon Pass1 46 beq v1, CP0_PRID_OCTEON_PASS1, skip 47 nop 48 # Reenable instruction prefetching, not on Pass1 49 xor v0, v0, 0x2000 50 # Strip off pass number off of processor id 51 srl v1, 8 52 sll v1, 8 53 # CN30XX needs some extra stuff turned off for better performance 54 bne v1, CP0_PRID_OCTEON_CN30XX, skip 55 nop 56 # CN30XX Use random Icache replacement 57 or v0, v0, 0x400 58 # CN30XX Disable instruction prefetching 59 or v0, v0, 0x2000 60 skip: 61 # First clear off CvmCtl[IPPCI] bit and move the performance 62 # counters interrupt to IRQ 6 63 li v1, ~(7 << 7) 64 and v0, v0, v1 65 ori v0, v0, (6 << 7) 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 */ 132