mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-14 14:34:28 +08:00
0ec315121c
When you turn it off, the kernel is unusable, so get rid of the option and always allow unaligned access. The Octeon specific memcpy intentionally does unaligned accesses and it must not fault. Signed-off-by: David Daney <david.daney@cavium.com> Cc: linux-mips@linux-mips.org Patchwork: https://patchwork.linux-mips.org/patch/5303/ Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
132 lines
3.4 KiB
C
132 lines
3.4 KiB
C
/*
|
|
* 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
|
|
# Disable unaligned load/store support but leave HW fixup enabled
|
|
# Needed for octeon specific memcpy
|
|
or v0, v0, 0x5001
|
|
xor v0, v0, 0x1001
|
|
# 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 */
|