summaryrefslogtreecommitdiff
path: root/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h')
-rw-r--r--arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h136
1 files changed, 136 insertions, 0 deletions
diff --git a/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h b/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h
new file mode 100644
index 00000000..dedef7d2
--- /dev/null
+++ b/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h
@@ -0,0 +1,136 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005-2008 Cavium Networks, Inc
+ */
+#ifndef __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H
+#define __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H
+
+
+#define CP0_CYCLE_COUNTER $9, 6
+#define CP0_CVMCTL_REG $9, 7
+#define CP0_CVMMEMCTL_REG $11,7
+#define CP0_PRID_REG $15, 0
+#define CP0_PRID_OCTEON_PASS1 0x000d0000
+#define CP0_PRID_OCTEON_CN30XX 0x000d0200
+
+.macro kernel_entry_setup
+ # Registers set by bootloader:
+ # (only 32 bits set by bootloader, all addresses are physical
+ # addresses, and need to have the appropriate memory region set
+ # by the kernel
+ # a0 = argc
+ # a1 = argv (kseg0 compat addr)
+ # a2 = 1 if init core, zero otherwise
+ # a3 = address of boot descriptor block
+ .set push
+ .set arch=octeon
+ # Read the cavium mem control register
+ dmfc0 v0, CP0_CVMMEMCTL_REG
+ # Clear the lower 6 bits, the CVMSEG size
+ dins v0, $0, 0, 6
+ ori v0, CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE
+ dmtc0 v0, CP0_CVMMEMCTL_REG # Write the cavium mem control register
+ dmfc0 v0, CP0_CVMCTL_REG # Read the cavium control register
+#ifdef CONFIG_CAVIUM_OCTEON_HW_FIX_UNALIGNED
+ # Disable unaligned load/store support but leave HW fixup enabled
+ or v0, v0, 0x5001
+ xor v0, v0, 0x1001
+#else
+ # Disable unaligned load/store and HW fixup support
+ or v0, v0, 0x5001
+ xor v0, v0, 0x5001
+#endif
+ # Read the processor ID register
+ mfc0 v1, CP0_PRID_REG
+ # Disable instruction prefetching (Octeon Pass1 errata)
+ or v0, v0, 0x2000
+ # Skip reenable of prefetching for Octeon Pass1
+ beq v1, CP0_PRID_OCTEON_PASS1, skip
+ nop
+ # Reenable instruction prefetching, not on Pass1
+ xor v0, v0, 0x2000
+ # Strip off pass number off of processor id
+ srl v1, 8
+ sll v1, 8
+ # CN30XX needs some extra stuff turned off for better performance
+ bne v1, CP0_PRID_OCTEON_CN30XX, skip
+ nop
+ # CN30XX Use random Icache replacement
+ or v0, v0, 0x400
+ # CN30XX Disable instruction prefetching
+ or v0, v0, 0x2000
+skip:
+ # First clear off CvmCtl[IPPCI] bit and move the performance
+ # counters interrupt to IRQ 6
+ li v1, ~(7 << 7)
+ and v0, v0, v1
+ ori v0, v0, (6 << 7)
+ # Write the cavium control register
+ dmtc0 v0, CP0_CVMCTL_REG
+ sync
+ # Flush dcache after config change
+ cache 9, 0($0)
+ # Get my core id
+ rdhwr v0, $0
+ # Jump the master to kernel_entry
+ bne a2, zero, octeon_main_processor
+ nop
+
+#ifdef CONFIG_SMP
+
+ #
+ # All cores other than the master need to wait here for SMP bootstrap
+ # to begin
+ #
+
+ # This is the variable where the next core to boot os stored
+ PTR_LA t0, octeon_processor_boot
+octeon_spin_wait_boot:
+ # Get the core id of the next to be booted
+ LONG_L t1, (t0)
+ # Keep looping if it isn't me
+ bne t1, v0, octeon_spin_wait_boot
+ nop
+ # Get my GP from the global variable
+ PTR_LA t0, octeon_processor_gp
+ LONG_L gp, (t0)
+ # Get my SP from the global variable
+ PTR_LA t0, octeon_processor_sp
+ LONG_L sp, (t0)
+ # Set the SP global variable to zero so the master knows we've started
+ LONG_S zero, (t0)
+#ifdef __OCTEON__
+ syncw
+ syncw
+#else
+ sync
+#endif
+ # Jump to the normal Linux SMP entry point
+ j smp_bootstrap
+ nop
+#else /* CONFIG_SMP */
+
+ #
+ # Someone tried to boot SMP with a non SMP kernel. All extra cores
+ # will halt here.
+ #
+octeon_wait_forever:
+ wait
+ b octeon_wait_forever
+ nop
+
+#endif /* CONFIG_SMP */
+octeon_main_processor:
+ .set pop
+.endm
+
+/*
+ * Do SMP slave processor setup necessary before we can savely execute C code.
+ */
+ .macro smp_slave_setup
+ .endm
+
+#endif /* __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H */