arch/mips/kernel/octeon_switch.S

Source file repositories/reference/linux-study-clean/arch/mips/kernel/octeon_switch.S

File Facts

System
Linux kernel
Corpus path
arch/mips/kernel/octeon_switch.S
Extension
.S
Size
14776 bytes
Lines
548
Domain
Architecture Layer
Bucket
arch/mips
Inferred role
Architecture Layer: arch/mips
Status
atlas-only

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

#include <asm/asm.h>
#include <asm/asm-offsets.h>
#include <asm/mipsregs.h>
#include <asm/regdef.h>
#include <asm/stackframe.h>

/*
 * task_struct *resume(task_struct *prev, task_struct *next,
 *		       struct thread_info *next_ti)
 */
	.align	7
	LEAF(resume)
	.set arch=octeon
	mfc0	t1, CP0_STATUS
	LONG_S	t1, THREAD_STATUS(a0)
	cpu_save_nonscratch a0
	LONG_S	ra, THREAD_REG31(a0)

#if CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0
	/* Check if we need to store CVMSEG state */
	dmfc0	t0, $11,7	/* CvmMemCtl */
	bbit0	t0, 6, 3f	/* Is user access enabled? */

	/* Store the CVMSEG state */
	/* Extract the size of CVMSEG */
	andi	t0, 0x3f
	/* Multiply * (cache line size/sizeof(long)/2) */
	sll	t0, 7-LONGLOG-1
	li	t1, -32768	/* Base address of CVMSEG */
	LONG_ADDI t2, a0, THREAD_CVMSEG /* Where to store CVMSEG to */
	synciobdma
2:
	.set noreorder
	LONG_L	t8, 0(t1)	/* Load from CVMSEG */
	subu	t0, 1		/* Decrement loop var */
	LONG_L	t9, LONGSIZE(t1)/* Load from CVMSEG */
	LONG_ADDU t1, LONGSIZE*2 /* Increment loc in CVMSEG */
	LONG_S	t8, 0(t2)	/* Store CVMSEG to thread storage */
	LONG_ADDU t2, LONGSIZE*2 /* Increment loc in thread storage */
	bnez	t0, 2b		/* Loop until we've copied it all */
	 LONG_S t9, -LONGSIZE(t2)/* Store CVMSEG to thread storage */
	.set reorder

	/* Disable access to CVMSEG */
	dmfc0	t0, $11,7	/* CvmMemCtl */
	xori	t0, t0, 0x40	/* Bit 6 is CVMSEG user enable */
	dmtc0	t0, $11,7	/* CvmMemCtl */
#endif
3:

#if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_SMP)
	PTR_LA	t8, __stack_chk_guard
	LONG_L	t9, TASK_STACK_CANARY(a1)
	LONG_S	t9, 0(t8)
#endif

	/*
	 * The order of restoring the registers takes care of the race
	 * updating $28, $29 and kernelsp without disabling ints.
	 */
	move	$28, a2
	cpu_restore_nonscratch a1

	PTR_ADDU	t0, $28, _THREAD_SIZE - 32
	set_saved_sp	t0, t1, t2

	mfc0	t1, CP0_STATUS		/* Do we really need this? */
	li	a3, 0xff01
	and	t1, a3
	LONG_L	a2, THREAD_STATUS(a1)

Annotation

Implementation Notes