⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iwmmxt.s

📁 linux 内核源代码
💻 S
字号:
/* *  linux/arch/arm/kernel/iwmmxt.S * *  XScale iWMMXt (Concan) context switching and handling * *  Initial code: *  Copyright (c) 2003, Intel Corporation * *  Full lazy switching support, optimizations and more, by Nicolas Pitre*   Copyright (c) 2003-2004, MontaVista Software, Inc. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. */#include <linux/linkage.h>#include <asm/ptrace.h>#include <asm/thread_info.h>#include <asm/asm-offsets.h>#define MMX_WR0		 	(0x00)#define MMX_WR1		 	(0x08)#define MMX_WR2		 	(0x10)#define MMX_WR3			(0x18)#define MMX_WR4		 	(0x20)#define MMX_WR5		 	(0x28)#define MMX_WR6		 	(0x30)#define MMX_WR7		 	(0x38)#define MMX_WR8		 	(0x40)#define MMX_WR9		 	(0x48)#define MMX_WR10		(0x50)#define MMX_WR11		(0x58)#define MMX_WR12		(0x60)#define MMX_WR13		(0x68)#define MMX_WR14		(0x70)#define MMX_WR15		(0x78)#define MMX_WCSSF		(0x80)#define MMX_WCASF		(0x84)#define MMX_WCGR0		(0x88)#define MMX_WCGR1		(0x8C)#define MMX_WCGR2		(0x90)#define MMX_WCGR3		(0x94)#define MMX_SIZE		(0x98)	.text/* * Lazy switching of Concan coprocessor context * * r10 = struct thread_info pointer * r9  = ret_from_exception * lr  = undefined instr exit * * called from prefetch exception handler with interrupts disabled */ENTRY(iwmmxt_task_enable)	mrc	p15, 0, r2, c15, c1, 0	tst	r2, #0x3			@ CP0 and CP1 accessible?	movne	pc, lr				@ if so no business here	orr	r2, r2, #0x3			@ enable access to CP0 and CP1	mcr	p15, 0, r2, c15, c1, 0	ldr	r3, =concan_owner	add	r0, r10, #TI_IWMMXT_STATE	@ get task Concan save area	ldr	r2, [sp, #60]			@ current task pc value	ldr	r1, [r3]			@ get current Concan owner	str	r0, [r3]			@ this task now owns Concan regs	sub	r2, r2, #4			@ adjust pc back	str	r2, [sp, #60]	mrc	p15, 0, r2, c2, c0, 0	mov	r2, r2				@ cpwait	teq	r1, #0				@ test for last ownership	mov	lr, r9				@ normal exit from exception	beq	concan_load			@ no owner, skip saveconcan_save:	tmrc	r2, wCon	@ CUP? wCx	tst	r2, #0x1	beq 	1fconcan_dump:	wstrw	wCSSF, [r1, #MMX_WCSSF]	wstrw	wCASF, [r1, #MMX_WCASF]	wstrw	wCGR0, [r1, #MMX_WCGR0]	wstrw	wCGR1, [r1, #MMX_WCGR1]	wstrw	wCGR2, [r1, #MMX_WCGR2]	wstrw	wCGR3, [r1, #MMX_WCGR3]1:	@ MUP? wRn	tst	r2, #0x2	beq	2f	wstrd	wR0,  [r1, #MMX_WR0]	wstrd	wR1,  [r1, #MMX_WR1]	wstrd	wR2,  [r1, #MMX_WR2]	wstrd	wR3,  [r1, #MMX_WR3]	wstrd	wR4,  [r1, #MMX_WR4]	wstrd	wR5,  [r1, #MMX_WR5]	wstrd	wR6,  [r1, #MMX_WR6]	wstrd	wR7,  [r1, #MMX_WR7]	wstrd	wR8,  [r1, #MMX_WR8]	wstrd	wR9,  [r1, #MMX_WR9]	wstrd	wR10, [r1, #MMX_WR10]	wstrd	wR11, [r1, #MMX_WR11]	wstrd	wR12, [r1, #MMX_WR12]	wstrd	wR13, [r1, #MMX_WR13]	wstrd	wR14, [r1, #MMX_WR14]	wstrd	wR15, [r1, #MMX_WR15]2:	teq	r0, #0				@ anything to load?	moveq	pc, lrconcan_load:	@ Load wRn	wldrd	wR0,  [r0, #MMX_WR0]	wldrd	wR1,  [r0, #MMX_WR1]	wldrd	wR2,  [r0, #MMX_WR2]	wldrd	wR3,  [r0, #MMX_WR3]	wldrd	wR4,  [r0, #MMX_WR4]	wldrd	wR5,  [r0, #MMX_WR5]	wldrd	wR6,  [r0, #MMX_WR6]	wldrd	wR7,  [r0, #MMX_WR7]	wldrd	wR8,  [r0, #MMX_WR8]	wldrd	wR9,  [r0, #MMX_WR9]	wldrd	wR10, [r0, #MMX_WR10]	wldrd	wR11, [r0, #MMX_WR11]	wldrd	wR12, [r0, #MMX_WR12]	wldrd	wR13, [r0, #MMX_WR13]	wldrd	wR14, [r0, #MMX_WR14]	wldrd	wR15, [r0, #MMX_WR15]	@ Load wCx	wldrw	wCSSF, [r0, #MMX_WCSSF]	wldrw	wCASF, [r0, #MMX_WCASF]	wldrw	wCGR0, [r0, #MMX_WCGR0]	wldrw	wCGR1, [r0, #MMX_WCGR1]	wldrw	wCGR2, [r0, #MMX_WCGR2]	wldrw	wCGR3, [r0, #MMX_WCGR3]	@ clear CUP/MUP (only if r1 != 0)	teq	r1, #0	mov 	r2, #0	moveq	pc, lr	tmcr	wCon, r2	mov	pc, lr/* * Back up Concan regs to save area and disable access to them * (mainly for gdb or sleep mode usage) * * r0 = struct thread_info pointer of target task or NULL for any */ENTRY(iwmmxt_task_disable)	stmfd	sp!, {r4, lr}	mrs	ip, cpsr	orr	r2, ip, #PSR_I_BIT		@ disable interrupts	msr	cpsr_c, r2	ldr	r3, =concan_owner	add	r2, r0, #TI_IWMMXT_STATE	@ get task Concan save area	ldr	r1, [r3]			@ get current Concan owner	teq	r1, #0				@ any current owner?	beq	1f				@ no: quit	teq	r0, #0				@ any owner?	teqne	r1, r2				@ or specified one?	bne	1f				@ no: quit	mrc	p15, 0, r4, c15, c1, 0	orr	r4, r4, #0x3			@ enable access to CP0 and CP1	mcr	p15, 0, r4, c15, c1, 0	mov	r0, #0				@ nothing to load	str	r0, [r3]			@ no more current owner	mrc	p15, 0, r2, c2, c0, 0	mov	r2, r2				@ cpwait	bl	concan_save	bic	r4, r4, #0x3			@ disable access to CP0 and CP1	mcr	p15, 0, r4, c15, c1, 0	mrc	p15, 0, r2, c2, c0, 0	mov	r2, r2				@ cpwait1:	msr	cpsr_c, ip			@ restore interrupt mode	ldmfd	sp!, {r4, pc}/* * Copy Concan state to given memory address * * r0 = struct thread_info pointer of target task * r1 = memory address where to store Concan state * * this is called mainly in the creation of signal stack frames */ENTRY(iwmmxt_task_copy)	mrs	ip, cpsr	orr	r2, ip, #PSR_I_BIT		@ disable interrupts	msr	cpsr_c, r2	ldr	r3, =concan_owner	add	r2, r0, #TI_IWMMXT_STATE	@ get task Concan save area	ldr	r3, [r3]			@ get current Concan owner	teq	r2, r3				@ does this task own it...	beq	1f	@ current Concan values are in the task save area	msr	cpsr_c, ip			@ restore interrupt mode	mov	r0, r1	mov	r1, r2	mov	r2, #MMX_SIZE	b	memcpy1:	@ this task owns Concan regs -- grab a copy from there	mov	r0, #0				@ nothing to load	mov	r2, #3				@ save all regs	mov	r3, lr				@ preserve return address	bl	concan_dump	msr	cpsr_c, ip			@ restore interrupt mode	mov	pc, r3/* * Restore Concan state from given memory address * * r0 = struct thread_info pointer of target task * r1 = memory address where to get Concan state from * * this is used to restore Concan state when unwinding a signal stack frame */ENTRY(iwmmxt_task_restore)	mrs	ip, cpsr	orr	r2, ip, #PSR_I_BIT		@ disable interrupts	msr	cpsr_c, r2	ldr	r3, =concan_owner	add	r2, r0, #TI_IWMMXT_STATE	@ get task Concan save area	ldr	r3, [r3]			@ get current Concan owner	bic	r2, r2, #0x7			@ 64-bit alignment	teq	r2, r3				@ does this task own it...	beq	1f	@ this task doesn't own Concan regs -- use its save area	msr	cpsr_c, ip			@ restore interrupt mode	mov	r0, r2	mov	r2, #MMX_SIZE	b	memcpy1:	@ this task owns Concan regs -- load them directly	mov	r0, r1	mov	r1, #0				@ don't clear CUP/MUP	mov	r3, lr				@ preserve return address	bl	concan_load	msr	cpsr_c, ip			@ restore interrupt mode	mov	pc, r3/* * Concan handling on task switch * * r0 = next thread_info pointer * * Called only from the iwmmxt notifier with task preemption disabled. */ENTRY(iwmmxt_task_switch)	mrc	p15, 0, r1, c15, c1, 0	tst	r1, #0x3			@ CP0 and CP1 accessible?	bne	1f				@ yes: block them for next task	ldr	r2, =concan_owner	add	r3, r0, #TI_IWMMXT_STATE	@ get next task Concan save area	ldr	r2, [r2]			@ get current Concan owner	teq	r2, r3				@ next task owns it?	movne	pc, lr				@ no: leave Concan disabled1:	eor	r1, r1, #3			@ flip Concan access	mcr	p15, 0, r1, c15, c1, 0	mrc	p15, 0, r1, c2, c0, 0	sub	pc, lr, r1, lsr #32		@ cpwait and return/* * Remove Concan ownership of given task * * r0 = struct thread_info pointer */ENTRY(iwmmxt_task_release)	mrs	r2, cpsr	orr	ip, r2, #PSR_I_BIT		@ disable interrupts	msr	cpsr_c, ip	ldr	r3, =concan_owner	add	r0, r0, #TI_IWMMXT_STATE	@ get task Concan save area	ldr	r1, [r3]			@ get current Concan owner	eors	r0, r0, r1			@ if equal...	streq	r0, [r3]			@ then clear ownership	msr	cpsr_c, r2			@ restore interrupts	mov	pc, lr	.dataconcan_owner:	.word	0

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -