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

📄 misc_64.s

📁 linux-2.6.15.6
💻 S
📖 第 1 页 / 共 2 页
字号:
/* *  arch/powerpc/kernel/misc64.S * * This file contains miscellaneous low-level functions. *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * * Largely rewritten by Cort Dougan (cort@cs.nmt.edu) * and Paul Mackerras. * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com) * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com)  *  * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * */#include <linux/config.h>#include <linux/sys.h>#include <asm/unistd.h>#include <asm/errno.h>#include <asm/processor.h>#include <asm/page.h>#include <asm/cache.h>#include <asm/ppc_asm.h>#include <asm/asm-offsets.h>#include <asm/cputable.h>#include <asm/thread_info.h>	.text/* * Returns (address we are running at) - (address we were linked at) * for use before the text and data are mapped to KERNELBASE. */_GLOBAL(reloc_offset)	mflr	r0	bl	1f1:	mflr	r3	LOADADDR(r4,1b)	subf	r3,r4,r3	mtlr	r0	blr/* * add_reloc_offset(x) returns x + reloc_offset(). */_GLOBAL(add_reloc_offset)	mflr	r0	bl	1f1:	mflr	r5	LOADADDR(r4,1b)	subf	r5,r4,r5	add	r3,r3,r5	mtlr	r0	blr_GLOBAL(get_msr)	mfmsr	r3	blr_GLOBAL(get_dar)	mfdar	r3	blr_GLOBAL(get_srr0)	mfsrr0  r3	blr_GLOBAL(get_srr1)	mfsrr1  r3	blr	_GLOBAL(get_sp)	mr	r3,r1	blr#ifdef CONFIG_IRQSTACKS_GLOBAL(call_do_softirq)	mflr	r0	std	r0,16(r1)	stdu	r1,THREAD_SIZE-112(r3)	mr	r1,r3	bl	.__do_softirq	ld	r1,0(r1)	ld	r0,16(r1)	mtlr	r0	blr_GLOBAL(call___do_IRQ)	mflr	r0	std	r0,16(r1)	stdu	r1,THREAD_SIZE-112(r5)	mr	r1,r5	bl	.__do_IRQ	ld	r1,0(r1)	ld	r0,16(r1)	mtlr	r0	blr#endif /* CONFIG_IRQSTACKS */	/* * To be called by C code which needs to do some operations with MMU * disabled. Note that interrupts have to be disabled by the caller * prior to calling us. The code called _MUST_ be in the RMO of course * and part of the linear mapping as we don't attempt to translate the * stack pointer at all. The function is called with the stack switched * to this CPU emergency stack * * prototype is void *call_with_mmu_off(void *func, void *data); * * the called function is expected to be of the form * * void *called(void *data);  */_GLOBAL(call_with_mmu_off)	mflr	r0			/* get link, save it on stackframe */	std	r0,16(r1)	mr	r1,r5			/* save old stack ptr */	ld	r1,PACAEMERGSP(r13)	/* get emerg. stack */	subi	r1,r1,STACK_FRAME_OVERHEAD	std	r0,16(r1)		/* save link on emerg. stack */	std	r5,0(r1)		/* save old stack ptr in backchain */	ld	r3,0(r3)		/* get to real function ptr (assume same TOC) */	bl	2f			/* we need LR to return, continue at label 2 */	ld	r0,16(r1)		/* we return here from the call, get LR and */	ld	r1,0(r1)		/* .. old stack ptr */	mtspr	SPRN_SRR0,r0		/* and get back to virtual mode with these */	mfmsr	r4	ori	r4,r4,MSR_IR|MSR_DR	mtspr	SPRN_SRR1,r4	rfid2:	mtspr	SPRN_SRR0,r3		/* coming from above, enter real mode */	mr	r3,r4			/* get parameter */	mfmsr	r0	ori	r0,r0,MSR_IR|MSR_DR	xori	r0,r0,MSR_IR|MSR_DR	mtspr	SPRN_SRR1,r0	rfid	.section	".toc","aw"PPC64_CACHES:	.tc		ppc64_caches[TC],ppc64_caches	.section	".text"/* * Write any modified data cache blocks out to memory * and invalidate the corresponding instruction cache blocks. * * flush_icache_range(unsigned long start, unsigned long stop) * *   flush all bytes from start through stop-1 inclusive */_KPROBE(__flush_icache_range)/* * Flush the data cache to memory  *  * Different systems have different cache line sizes * and in some cases i-cache and d-cache line sizes differ from * each other. */ 	ld	r10,PPC64_CACHES@toc(r2)	lwz	r7,DCACHEL1LINESIZE(r10)/* Get cache line size */	addi	r5,r7,-1	andc	r6,r3,r5		/* round low to line bdy */	subf	r8,r6,r4		/* compute length */	add	r8,r8,r5		/* ensure we get enough */	lwz	r9,DCACHEL1LOGLINESIZE(r10)	/* Get log-2 of cache line size */	srw.	r8,r8,r9		/* compute line count */	beqlr				/* nothing to do? */	mtctr	r81:	dcbst	0,r6	add	r6,r6,r7	bdnz	1b	sync/* Now invalidate the instruction cache */		lwz	r7,ICACHEL1LINESIZE(r10)	/* Get Icache line size */	addi	r5,r7,-1	andc	r6,r3,r5		/* round low to line bdy */	subf	r8,r6,r4		/* compute length */	add	r8,r8,r5	lwz	r9,ICACHEL1LOGLINESIZE(r10)	/* Get log-2 of Icache line size */	srw.	r8,r8,r9		/* compute line count */	beqlr				/* nothing to do? */	mtctr	r82:	icbi	0,r6	add	r6,r6,r7	bdnz	2b	isync	blr	.previous .text/* * Like above, but only do the D-cache. * * flush_dcache_range(unsigned long start, unsigned long stop) * *    flush all bytes from start to stop-1 inclusive */_GLOBAL(flush_dcache_range)/* * Flush the data cache to memory  *  * Different systems have different cache line sizes */ 	ld	r10,PPC64_CACHES@toc(r2)	lwz	r7,DCACHEL1LINESIZE(r10)	/* Get dcache line size */	addi	r5,r7,-1	andc	r6,r3,r5		/* round low to line bdy */	subf	r8,r6,r4		/* compute length */	add	r8,r8,r5		/* ensure we get enough */	lwz	r9,DCACHEL1LOGLINESIZE(r10)	/* Get log-2 of dcache line size */	srw.	r8,r8,r9		/* compute line count */	beqlr				/* nothing to do? */	mtctr	r80:	dcbst	0,r6	add	r6,r6,r7	bdnz	0b	sync	blr/* * Like above, but works on non-mapped physical addresses. * Use only for non-LPAR setups ! It also assumes real mode * is cacheable. Used for flushing out the DART before using * it as uncacheable memory  * * flush_dcache_phys_range(unsigned long start, unsigned long stop) * *    flush all bytes from start to stop-1 inclusive */_GLOBAL(flush_dcache_phys_range) 	ld	r10,PPC64_CACHES@toc(r2)	lwz	r7,DCACHEL1LINESIZE(r10)	/* Get dcache line size */	addi	r5,r7,-1	andc	r6,r3,r5		/* round low to line bdy */	subf	r8,r6,r4		/* compute length */	add	r8,r8,r5		/* ensure we get enough */	lwz	r9,DCACHEL1LOGLINESIZE(r10)	/* Get log-2 of dcache line size */	srw.	r8,r8,r9		/* compute line count */	beqlr				/* nothing to do? */	mfmsr	r5			/* Disable MMU Data Relocation */	ori	r0,r5,MSR_DR	xori	r0,r0,MSR_DR	sync	mtmsr	r0	sync	isync	mtctr	r80:	dcbst	0,r6	add	r6,r6,r7	bdnz	0b	sync	isync	mtmsr	r5			/* Re-enable MMU Data Relocation */	sync	isync	blr_GLOBAL(flush_inval_dcache_range) 	ld	r10,PPC64_CACHES@toc(r2)	lwz	r7,DCACHEL1LINESIZE(r10)	/* Get dcache line size */	addi	r5,r7,-1	andc	r6,r3,r5		/* round low to line bdy */	subf	r8,r6,r4		/* compute length */	add	r8,r8,r5		/* ensure we get enough */	lwz	r9,DCACHEL1LOGLINESIZE(r10)/* Get log-2 of dcache line size */	srw.	r8,r8,r9		/* compute line count */	beqlr				/* nothing to do? */	sync	isync	mtctr	r80:	dcbf	0,r6	add	r6,r6,r7	bdnz	0b	sync	isync	blr/* * Flush a particular page from the data cache to RAM. * Note: this is necessary because the instruction cache does *not* * snoop from the data cache. * *	void __flush_dcache_icache(void *page) */_GLOBAL(__flush_dcache_icache)/* * Flush the data cache to memory  *  * Different systems have different cache line sizes *//* Flush the dcache */ 	ld	r7,PPC64_CACHES@toc(r2)	clrrdi	r3,r3,PAGE_SHIFT           	    /* Page align */	lwz	r4,DCACHEL1LINESPERPAGE(r7)	/* Get # dcache lines per page */	lwz	r5,DCACHEL1LINESIZE(r7)		/* Get dcache line size */	mr	r6,r3	mtctr	r40:	dcbst	0,r6	add	r6,r6,r5	bdnz	0b	sync/* Now invalidate the icache */		lwz	r4,ICACHEL1LINESPERPAGE(r7)	/* Get # icache lines per page */	lwz	r5,ICACHEL1LINESIZE(r7)		/* Get icache line size */	mtctr	r41:	icbi	0,r3	add	r3,r3,r5	bdnz	1b	isync	blr	/* * I/O string operations * * insb(port, buf, len) * outsb(port, buf, len) * insw(port, buf, len) * outsw(port, buf, len) * insl(port, buf, len) * outsl(port, buf, len) * insw_ns(port, buf, len) * outsw_ns(port, buf, len) * insl_ns(port, buf, len) * outsl_ns(port, buf, len) * * The *_ns versions don't do byte-swapping. */_GLOBAL(_insb)	cmpwi	0,r5,0	mtctr	r5	subi	r4,r4,1	blelr-00:	lbz	r5,0(r3)	eieio	stbu	r5,1(r4)	bdnz	00b	twi	0,r5,0	isync	blr_GLOBAL(_outsb)	cmpwi	0,r5,0	mtctr	r5	subi	r4,r4,1	blelr-00:	lbzu	r5,1(r4)	stb	r5,0(r3)	bdnz	00b	sync	blr	_GLOBAL(_insw)	cmpwi	0,r5,0	mtctr	r5	subi	r4,r4,2	blelr-00:	lhbrx	r5,0,r3	eieio	sthu	r5,2(r4)	bdnz	00b	twi	0,r5,0	isync	blr_GLOBAL(_outsw)	cmpwi	0,r5,0	mtctr	r5	subi	r4,r4,2	blelr-00:	lhzu	r5,2(r4)	sthbrx	r5,0,r3		bdnz	00b	sync	blr	_GLOBAL(_insl)	cmpwi	0,r5,0	mtctr	r5	subi	r4,r4,4	blelr-00:	lwbrx	r5,0,r3	eieio	stwu	r5,4(r4)	bdnz	00b	twi	0,r5,0	isync	blr_GLOBAL(_outsl)	cmpwi	0,r5,0	mtctr	r5	subi	r4,r4,4	blelr-00:	lwzu	r5,4(r4)	stwbrx	r5,0,r3	bdnz	00b	sync	blr	/* _GLOBAL(ide_insw) now in drivers/ide/ide-iops.c */_GLOBAL(_insw_ns)	cmpwi	0,r5,0	mtctr	r5	subi	r4,r4,2	blelr-00:	lhz	r5,0(r3)	eieio	sthu	r5,2(r4)	bdnz	00b	twi	0,r5,0	isync	blr/* _GLOBAL(ide_outsw) now in drivers/ide/ide-iops.c */_GLOBAL(_outsw_ns)	cmpwi	0,r5,0	mtctr	r5	subi	r4,r4,2	blelr-00:	lhzu	r5,2(r4)	sth	r5,0(r3)	bdnz	00b	sync	blr	_GLOBAL(_insl_ns)	cmpwi	0,r5,0	mtctr	r5	subi	r4,r4,4	blelr-00:	lwz	r5,0(r3)	eieio	stwu	r5,4(r4)	bdnz	00b	twi	0,r5,0	isync	blr_GLOBAL(_outsl_ns)	cmpwi	0,r5,0	mtctr	r5	subi	r4,r4,4	blelr-00:	lwzu	r5,4(r4)	stw	r5,0(r3)	bdnz	00b	sync	blr	/* * identify_cpu and calls setup_cpu * In:	r3 = base of the cpu_specs array *	r4 = address of cur_cpu_spec *	r5 = relocation offset */_GLOBAL(identify_cpu)	mfpvr	r71:	lwz	r8,CPU_SPEC_PVR_MASK(r3)	and	r8,r8,r7	lwz	r9,CPU_SPEC_PVR_VALUE(r3)

⌨️ 快捷键说明

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