2009-01-08 16:46:40 -08:00
/*
* 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
2013-01-22 12:59:30 +01:00
. macro kernel_entry_setup
2009-01-08 16:46:40 -08:00
# 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
2013-01-22 12:59:30 +01:00
dmfc0 v0 , CP0_CVMMEMCTL_REG
2009-01-08 16:46:40 -08:00
# Clear the lower 6 bits, the CVMSEG size
2013-01-22 12:59:30 +01:00
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
2009-01-08 16:46:40 -08:00
# 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 :
2011-02-17 13:57:52 -08:00
# 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 )
2009-01-08 16:46:40 -08:00
# Write the cavium control register
2013-01-22 12:59:30 +01:00
dmtc0 v0 , CP0_CVMCTL_REG
2009-01-08 16:46:40 -08:00
sync
# Flush dcache after config change
2013-01-22 12:59:30 +01:00
cache 9 , 0 ( $ 0 )
2009-01-08 16:46:40 -08:00
# Get my core id
2013-01-22 12:59:30 +01:00
rdhwr v0 , $ 0
2009-01-08 16:46:40 -08:00
# Jump the master to kernel_entry
2013-01-22 12:59:30 +01:00
bne a2 , zero , octeon_main_processor
2009-01-08 16:46:40 -08:00
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
2013-01-22 12:59:30 +01:00
PTR_LA t0 , octeon_processor_boot
2009-01-08 16:46:40 -08:00
octeon_spin_wait_boot :
# Get the core id of the next to be booted
2013-01-22 12:59:30 +01:00
LONG_L t1 , ( t0 )
2009-01-08 16:46:40 -08:00
# Keep looping if it isn't me
bne t1 , v0 , octeon_spin_wait_boot
nop
# Get my GP from the global variable
2013-01-22 12:59:30 +01:00
PTR_LA t0 , octeon_processor_gp
LONG_L gp , ( t0 )
2009-01-08 16:46:40 -08:00
# Get my SP from the global variable
2013-01-22 12:59:30 +01:00
PTR_LA t0 , octeon_processor_sp
LONG_L sp , ( t0 )
2009-01-08 16:46:40 -08:00
# Set the SP global variable to zero so the master knows we've started
2013-01-22 12:59:30 +01:00
LONG_S zero , ( t0 )
2009-01-08 16:46:40 -08:00
# 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 .
*/
2013-01-22 12:59:30 +01:00
. macro smp_slave_setup
2009-01-08 16:46:40 -08:00
. endm
# endif /* __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H */