cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

kernel-entry-init.h (4049B)


      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#define CP0_CVMCTL_REG $9, 7
     12#define CP0_CVMMEMCTL_REG $11,7
     13#define CP0_PRID_REG $15, 0
     14#define CP0_DCACHE_ERR_REG $27, 1
     15#define CP0_PRID_OCTEON_PASS1 0x000d0000
     16#define CP0_PRID_OCTEON_CN30XX 0x000d0200
     17
     18.macro	kernel_entry_setup
     19	# Registers set by bootloader:
     20	# (only 32 bits set by bootloader, all addresses are physical
     21	# addresses, and need to have the appropriate memory region set
     22	# by the kernel
     23	# a0 = argc
     24	# a1 = argv (kseg0 compat addr)
     25	# a2 = 1 if init core, zero otherwise
     26	# a3 = address of boot descriptor block
     27	.set push
     28	.set arch=octeon
     29	# Read the cavium mem control register
     30	dmfc0	v0, CP0_CVMMEMCTL_REG
     31	# Clear the lower 6 bits, the CVMSEG size
     32	dins	v0, $0, 0, 6
     33	ori	v0, CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE
     34	dmtc0	v0, CP0_CVMMEMCTL_REG	# Write the cavium mem control register
     35	dmfc0	v0, CP0_CVMCTL_REG	# Read the cavium control register
     36	# Disable unaligned load/store support but leave HW fixup enabled
     37	# Needed for octeon specific memcpy
     38	or  v0, v0, 0x5001
     39	xor v0, v0, 0x1001
     40	# First clear off CvmCtl[IPPCI] bit and move the performance
     41	# counters interrupt to IRQ 6
     42	dli	v1, ~(7 << 7)
     43	and	v0, v0, v1
     44	ori	v0, v0, (6 << 7)
     45
     46	mfc0	v1, CP0_PRID_REG
     47	and	t1, v1, 0xfff8
     48	xor	t1, t1, 0x9000		# 63-P1
     49	beqz	t1, 4f
     50	and	t1, v1, 0xfff8
     51	xor	t1, t1, 0x9008		# 63-P2
     52	beqz	t1, 4f
     53	and	t1, v1, 0xfff8
     54	xor	t1, t1, 0x9100		# 68-P1
     55	beqz	t1, 4f
     56	and	t1, v1, 0xff00
     57	xor	t1, t1, 0x9200		# 66-PX
     58	bnez	t1, 5f			# Skip WAR for others.
     59	and	t1, v1, 0x00ff
     60	slti	t1, t1, 2		# 66-P1.2 and later good.
     61	beqz	t1, 5f
     62
     634:	# core-16057 work around
     64	or	v0, v0, 0x2000		# Set IPREF bit.
     65
     665:	# No core-16057 work around
     67	# Write the cavium control register
     68	dmtc0	v0, CP0_CVMCTL_REG
     69	sync
     70	# Flush dcache after config change
     71	cache	9, 0($0)
     72	# Zero all of CVMSEG to make sure parity is correct
     73	dli	v0, CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE
     74	dsll	v0, 7
     75	beqz	v0, 2f
     761:	dsubu	v0, 8
     77	sd	$0, -32768(v0)
     78	bnez	v0, 1b
     792:
     80	mfc0	v0, CP0_PRID_REG
     81	bbit0	v0, 15, 1f
     82	# OCTEON II or better have bit 15 set.  Clear the error bits.
     83	and	t1, v0, 0xff00
     84	dli	v0, 0x9500
     85	bge	t1, v0, 1f  # OCTEON III has no DCACHE_ERR_REG COP0
     86	dli	v0, 0x27
     87	dmtc0	v0, CP0_DCACHE_ERR_REG
     881:
     89	# Get my core id
     90	rdhwr	v0, $0
     91	# Jump the master to kernel_entry
     92	bne	a2, zero, octeon_main_processor
     93	nop
     94
     95#ifdef CONFIG_SMP
     96
     97	#
     98	# All cores other than the master need to wait here for SMP bootstrap
     99	# to begin
    100	#
    101
    102octeon_spin_wait_boot:
    103#ifdef CONFIG_RELOCATABLE
    104	PTR_LA	t0, octeon_processor_relocated_kernel_entry
    105	LONG_L	t0, (t0)
    106	beq	zero, t0, 1f
    107	nop
    108
    109	jr	t0
    110	nop
    1111:
    112#endif /* CONFIG_RELOCATABLE */
    113
    114	# This is the variable where the next core to boot is stored
    115	PTR_LA	t0, octeon_processor_boot
    116	# Get the core id of the next to be booted
    117	LONG_L	t1, (t0)
    118	# Keep looping if it isn't me
    119	bne t1, v0, octeon_spin_wait_boot
    120	nop
    121	# Get my GP from the global variable
    122	PTR_LA	t0, octeon_processor_gp
    123	LONG_L	gp, (t0)
    124	# Get my SP from the global variable
    125	PTR_LA	t0, octeon_processor_sp
    126	LONG_L	sp, (t0)
    127	# Set the SP global variable to zero so the master knows we've started
    128	LONG_S	zero, (t0)
    129#ifdef __OCTEON__
    130	syncw
    131	syncw
    132#else
    133	sync
    134#endif
    135	# Jump to the normal Linux SMP entry point
    136	j   smp_bootstrap
    137	nop
    138#else /* CONFIG_SMP */
    139
    140	#
    141	# Someone tried to boot SMP with a non SMP kernel. All extra cores
    142	# will halt here.
    143	#
    144octeon_wait_forever:
    145	wait
    146	b   octeon_wait_forever
    147	nop
    148
    149#endif /* CONFIG_SMP */
    150octeon_main_processor:
    151	.set pop
    152.endm
    153
    154/*
    155 * Do SMP slave processor setup necessary before we can safely execute C code.
    156 */
    157	.macro	smp_slave_setup
    158	.endm
    159
    160#define USE_KEXEC_SMP_WAIT_FINAL
    161	.macro  kexec_smp_wait_final
    162	.set push
    163	.set noreorder
    164	synci		0($0)
    165	.set pop
    166	.endm
    167
    168#endif /* __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H */